emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] master d499cc3: Add ada-ref-man document and program sources


From: Stephen Leake
Subject: [elpa] master d499cc3: Add ada-ref-man document and program sources
Date: Fri, 22 Sep 2017 17:53:17 -0400 (EDT)

branch: master
commit d499cc30a4e69065d87dea326bb26d1c87c52689
Author: Stephen Leake <address@hidden>
Commit: Stephen Leake <address@hidden>

    Add ada-ref-man document and program sources
    
    * packages/ada-ref-man/README: Describe upstream sources, local copies.
    
    * packages/ada-ref-man/.elpaignore: New file.
    
    * packages/ada-ref-man/progs/: New directory; Ada files to process ARM
    sources into info and other formats.
    
    * packages/ada-ref-man/source_2012/: New directory; ARM sources.
---
 packages/ada-ref-man/.elpaignore                   |     2 +
 packages/ada-ref-man/README                        |     8 +
 packages/ada-ref-man/progs/alkc.bat                |     7 +
 packages/ada-ref-man/progs/arm_cont.adb            |   669 ++
 packages/ada-ref-man/progs/arm_cont.ads            |   187 +
 packages/ada-ref-man/progs/arm_corr.adb            |  1719 +++
 packages/ada-ref-man/progs/arm_corr.ads            |   432 +
 packages/ada-ref-man/progs/arm_db.adb              |   327 +
 packages/ada-ref-man/progs/arm_db.ads              |   118 +
 packages/ada-ref-man/progs/arm_file.adb            |   186 +
 packages/ada-ref-man/progs/arm_file.ads            |   100 +
 packages/ada-ref-man/progs/arm_form.ada            |   329 +
 packages/ada-ref-man/progs/arm_frm.adb             | 11211 +++++++++++++++++++
 packages/ada-ref-man/progs/arm_frm.ads             |   476 +
 packages/ada-ref-man/progs/arm_frmd.adb            |   552 +
 packages/ada-ref-man/progs/arm_frmd.ads            |   319 +
 packages/ada-ref-man/progs/arm_frms.adb            |  1016 ++
 packages/ada-ref-man/progs/arm_html.adb            |  5755 ++++++++++
 packages/ada-ref-man/progs/arm_html.ads            |   617 +
 packages/ada-ref-man/progs/arm_indx.adb            |  1050 ++
 packages/ada-ref-man/progs/arm_indx.ads            |   110 +
 packages/ada-ref-man/progs/arm_inp.adb             |   444 +
 packages/ada-ref-man/progs/arm_inp.ads             |   170 +
 packages/ada-ref-man/progs/arm_mast.adb            |  1456 +++
 packages/ada-ref-man/progs/arm_mast.ads            |    58 +
 packages/ada-ref-man/progs/arm_out.ads             |   633 ++
 packages/ada-ref-man/progs/arm_rtf.adb             |  6242 +++++++++++
 packages/ada-ref-man/progs/arm_rtf.ads             |   524 +
 packages/ada-ref-man/progs/arm_str.adb             |   172 +
 packages/ada-ref-man/progs/arm_str.ads             |    98 +
 packages/ada-ref-man/progs/arm_sub.adb             |   773 ++
 packages/ada-ref-man/progs/arm_sub.ads             |    91 +
 packages/ada-ref-man/progs/arm_syn.adb             |   452 +
 packages/ada-ref-man/progs/arm_syn.ads             |   109 +
 packages/ada-ref-man/progs/arm_texi.adb            |  1832 +++
 packages/ada-ref-man/progs/arm_texi.ads            |   304 +
 packages/ada-ref-man/progs/arm_text.adb            |  1547 +++
 packages/ada-ref-man/progs/arm_text.ads            |   453 +
 packages/ada-ref-man/progs/command.txt             |  1360 +++
 packages/ada-ref-man/progs/gpl-3-0.txt             |   674 ++
 packages/ada-ref-man/progs/makeana.bat             |     1 +
 packages/ada-ref-man/progs/makearm.bat             |     1 +
 packages/ada-ref-man/progs/mklnk.bat               |     3 +
 packages/ada-ref-man/progs/rtf2form.ada            |   686 ++
 packages/ada-ref-man/source_2012/01.mss            |  2387 ++++
 packages/ada-ref-man/source_2012/02.mss            |  2186 ++++
 packages/ada-ref-man/source_2012/03a.mss           |  7529 +++++++++++++
 packages/ada-ref-man/source_2012/03b.mss           |  2745 +++++
 packages/ada-ref-man/source_2012/03c.mss           |  6595 +++++++++++
 packages/ada-ref-man/source_2012/04a.mss           |  5748 ++++++++++
 packages/ada-ref-man/source_2012/04b.mss           |  3082 +++++
 packages/ada-ref-man/source_2012/05.mss            |  1942 ++++
 packages/ada-ref-man/source_2012/06.mss            |  5368 +++++++++
 packages/ada-ref-man/source_2012/07.mss            |  4924 ++++++++
 packages/ada-ref-man/source_2012/08.mss            |  3841 +++++++
 packages/ada-ref-man/source_2012/09.mss            |  5936 ++++++++++
 packages/ada-ref-man/source_2012/10.mss            |  4083 +++++++
 packages/ada-ref-man/source_2012/11.mss            |  2650 +++++
 packages/ada-ref-man/source_2012/12.mss            |  3897 +++++++
 packages/ada-ref-man/source_2012/13a.mss           |  5165 +++++++++
 packages/ada-ref-man/source_2012/13b.mss           |  7071 ++++++++++++
 packages/ada-ref-man/source_2012/aa-aarm.msm       |   110 +
 packages/ada-ref-man/source_2012/aa-rm.msm         |   111 +
 packages/ada-ref-man/source_2012/aarm.msm          |   106 +
 packages/ada-ref-man/source_2012/attribs.mss       |    41 +
 packages/ada-ref-man/source_2012/ds.mss            |  2441 ++++
 packages/ada-ref-man/source_2012/front_matter.mss  |  1576 +++
 packages/ada-ref-man/source_2012/glossary.mss      |    19 +
 packages/ada-ref-man/source_2012/impldef.mss       |    83 +
 packages/ada-ref-man/source_2012/index.mss         |    29 +
 packages/ada-ref-man/source_2012/infosys.mss       |  1349 +++
 packages/ada-ref-man/source_2012/interface.mss     |  3669 ++++++
 packages/ada-ref-man/source_2012/iso-rm.msm        |   107 +
 packages/ada-ref-man/source_2012/langdef.mss       |    81 +
 packages/ada-ref-man/source_2012/library.mss       |     9 +
 packages/ada-ref-man/source_2012/numerics.mss      |  4383 ++++++++
 packages/ada-ref-man/source_2012/obsolescent.mss   |  1873 ++++
 packages/ada-ref-man/source_2012/pragmas.mss       |    20 +
 packages/ada-ref-man/source_2012/pre.mss           |   426 +
 packages/ada-ref-man/source_2012/pre_ada.mss       |    53 +
 packages/ada-ref-man/source_2012/pre_chars.mss     |  1346 +++
 packages/ada-ref-man/source_2012/pre_cmdln.mss     |   128 +
 packages/ada-ref-man/source_2012/pre_con2.mss      |  5147 +++++++++
 .../ada-ref-man/source_2012/pre_containers.mss     |  9389 ++++++++++++++++
 packages/ada-ref-man/source_2012/pre_dirs.mss      |  1561 +++
 packages/ada-ref-man/source_2012/pre_environ.mss   |   259 +
 packages/ada-ref-man/source_2012/pre_io.mss        |  4096 +++++++
 packages/ada-ref-man/source_2012/pre_locales.mss   |   132 +
 packages/ada-ref-man/source_2012/pre_math.mss      |   927 ++
 packages/ada-ref-man/source_2012/pre_standard.mss  |   497 +
 packages/ada-ref-man/source_2012/pre_strings.mss   |  4052 +++++++
 packages/ada-ref-man/source_2012/real_attribs.mss  |   732 ++
 packages/ada-ref-man/source_2012/rm.msm            |   107 +
 packages/ada-ref-man/source_2012/rt.mss            |  6683 +++++++++++
 packages/ada-ref-man/source_2012/safety.mss        |  1373 +++
 packages/ada-ref-man/source_2012/sp.mss            |  2670 +++++
 packages/ada-ref-man/source_2012/syntax.mss        |    40 +
 packages/ada-ref-man/source_2012/title.mss         |   289 +
 98 files changed, 174336 insertions(+)

diff --git a/packages/ada-ref-man/.elpaignore b/packages/ada-ref-man/.elpaignore
new file mode 100755
index 0000000..4c65740
--- /dev/null
+++ b/packages/ada-ref-man/.elpaignore
@@ -0,0 +1,2 @@
+source_2012
+progs
diff --git a/packages/ada-ref-man/README b/packages/ada-ref-man/README
index 536b7b1..f33558c 100644
--- a/packages/ada-ref-man/README
+++ b/packages/ada-ref-man/README
@@ -1,3 +1,11 @@
 Emacs info version of Ada Reference Manual 2012 TC1
 
+The upstream source for the ARM is http://www.ada-auth.org/arm-files/;
+ELPA git copy in packages/ada-ref-man/source_2012.
+
+The upstream source for the Ada code that processes the ARM source is
+in the ada-france monotone repository; access information is given at
+http://stephe-leake.org/ada/arm.html. ELPA git copy in
+packages/ada-ref-man/progs.
+
 
diff --git a/packages/ada-ref-man/progs/alkc.bat 
b/packages/ada-ref-man/progs/alkc.bat
new file mode 100755
index 0000000..f2b8b64
--- /dev/null
+++ b/packages/ada-ref-man/progs/alkc.bat
@@ -0,0 +1,7 @@
+Move .\Object\%1.Obj .
+link  -subsystem:console -entry:mainCRTStartup -out:%1.exe %1.obj libc.lib 
kernel32.lib -map:%1.map
+Del %1.Obj
+Rem Del %1.Map
+Copy %1.Exe \RRS\Docs
+Move %1.Exe ..\Source
+Move .\Object\%1.Dbg ..\Source
diff --git a/packages/ada-ref-man/progs/arm_cont.adb 
b/packages/ada-ref-man/progs/arm_cont.adb
new file mode 100755
index 0000000..624111a
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_cont.adb
@@ -0,0 +1,669 @@
+with Ada.Characters.Handling;
+--with Ada.Text_IO; -- Debug.
+--with Ada.Exceptions;
+package body ARM_Contents is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the routines to manage section/clause/subclause
+    -- references.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  4/19/00 - RLB - Created base package.
+    --  4/26/00 - RLB - Added Previous_Clause and Next_Clause.
+    --  5/15/00 - RLB - Added rules about unnumbered sections.
+    --  5/22/00 - RLB - Added Unnumbered_Section level.
+    --  8/22/00 - RLB - Added Old_Title handling.
+    --  9/ 9/04 - RLB - Removed unused with.
+    --  2/ 2/05 - RLB - Allowed more old titles.
+    --  1/16/06 - RLB - Added debugging.
+    --  9/22/06 - RLB - Created type Clause_Number_Type and added SubSubClause.
+    -- 10/12/07 - RLB - Extended the range of properly formatted clause 
numbers.
+    -- 12/18/07 - RLB - Added Plain_Annex.
+    -- 10/24/08 - RLB - More old titles.
+    --  5/07/09 - RLB - Added Dead_Clause.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/19/11 - RLB - Added Parent_Clause from Stephen Leake's version.
+    -- 10/25/11 - RLB - Added version to Old name strings.
+    --  8/30/12 - RLB - Added traps if we're reading Section = UNKNOWN.
+
+    function "<" (Left, Right : Clause_Number_Type) return Boolean is
+       -- True if Left comes before Right in the collating order.
+    begin
+       if Left.Section = UNKNOWN then
+           raise Bad_Clause_Error with "Left has Unknown section";
+       elsif Right.Section = UNKNOWN then
+           raise Bad_Clause_Error with "Right has Unknown section";
+       elsif Left.Section < Right.Section then
+           return True;
+       elsif Left.Section > Right.Section then
+           return False;
+       elsif Left.Clause < Right.Clause then
+           return True;
+       elsif Left.Clause > Right.Clause then
+           return False;
+       elsif Left.Subclause < Right.Subclause then
+           return True;
+       elsif Left.Subclause > Right.Subclause then
+           return False;
+       elsif Left.Subsubclause < Right.Subsubclause then
+           return True;
+       else
+           return False;
+       end if;
+    end "<";
+
+    function ">" (Left, Right : Clause_Number_Type) return Boolean is
+       -- True if Left comes after Right in the collating order.
+    begin
+       return Right < Left;
+    end ">";
+
+    function "<=" (Left, Right : Clause_Number_Type) return Boolean is
+       -- True if Left comes before or is the same as Right in the
+       -- collating order.
+    begin
+       return not (Right < Left);
+    end "<=";
+
+    function ">=" (Left, Right : Clause_Number_Type) return Boolean is
+       -- True if Left comes after or is the same as Right in the
+       -- collating order.
+    begin
+       return not (Left < Right);
+    end ">=";
+
+
+    type Title_Record is record
+       Title : Title_Type; -- Title in original format.
+       Search_Title : Title_Type; -- Title in all lower case.
+       Level : Level_Type;
+       Clause_Number : Clause_Number_Type;
+        Version : ARM_Contents.Change_Version_Type := '0';
+    end record;
+
+    Title_List : array (1 .. 900) of Title_Record;
+    Last_Title : Natural;
+
+    Old_Title_List : array (1 .. 300) of Title_Record;
+    Last_Old_Title : Natural;
+
+    procedure Initialize is
+       -- Initialize this package; make sure the contents are empty.
+    begin
+       Last_Title := 0;
+    end Initialize;
+
+
+    procedure Add (Title : in Title_Type;
+                  Level : in Level_Type;
+                  Clause_Number : in Clause_Number_Type;
+                   Version : in ARM_Contents.Change_Version_Type := '0') is
+       -- Add a section or clause to the contents. It has the specified
+       -- characteristics.
+    begin
+       if Level /= Subsubclause and then Clause_Number.Subsubclause /= 0 then
+           raise Bad_Clause_Error with "not a subsubclause but non-zero 
subsubclause number";
+       end if;
+       if Level /= Subsubclause and then
+          Level /= Subclause and then Clause_Number.Subclause /= 0 then
+           raise Bad_Clause_Error with "not a subclause but non-zero subclause 
number";
+       end if;
+       if (Level /= Subsubclause and then Level /= Subclause and then
+           Level /= Clause and then Level /= Unnumbered_Section and then
+           Level /= Dead_Clause) and then
+          Clause_Number.Clause /= 0 then
+           raise Bad_Clause_Error with "not a clause but non-zero clause 
number";
+       end if;
+       Last_Title := Last_Title + 1;
+       Title_List (Last_Title) :=
+           (Title => Title,
+            Search_Title => Ada.Characters.Handling.To_Lower (Title),
+            Level => Level,
+            Clause_Number => Clause_Number,
+             Version => Version);
+--Ada.Text_IO.Put_Line ("  Add " & Title &
+-- " Index=" & Natural'Image(Last_Title) & " Level=" & 
Level_Type'Image(Level));
+--Ada.Text_IO.Put_Line ("    Section" & 
Section_Number_Type'Image(Clause_Number.Section) &
+-- " Clause" & Natural'Image(Clause_Number.Clause) & " Subclause" & 
Natural'Image(Clause_Number.Subclause) &
+-- " Subsubclause" & Natural'Image(Clause_Number.Subsubclause));
+    end Add;
+
+
+    procedure Add_Old (Old_Title : in Title_Type;
+                      Level : in Level_Type;
+                      Clause_Number : in Clause_Number_Type;
+                       Version : in ARM_Contents.Change_Version_Type := '0') is
+       -- Add an old title for a section or clause to the contents. It has
+       -- the specified characteristics; the version is the version for which
+       -- it first was present in the document.
+    begin
+       if Level /= Subsubclause and then Clause_Number.Subsubclause /= 0 then
+           raise Bad_Clause_Error with "not a subsubclause but non-zero 
subsubclause number";
+       end if;
+       if Level /= Subsubclause and then
+          Level /= Subclause and then Clause_Number.Subclause /= 0 then
+           raise Bad_Clause_Error with "not a subclause but non-zero subclause 
number";
+       end if;
+       if (Level /= Subsubclause and then Level /= Subclause and then
+           Level /= Clause and then Level /= Unnumbered_Section and then
+           Level /= Dead_Clause) and then
+          Clause_Number.Clause /= 0 then
+           raise Bad_Clause_Error with "not a clause but non-zero clause 
number";
+       end if;
+       Last_Old_Title := Last_Old_Title + 1;
+       Old_Title_List (Last_Old_Title) :=
+           (Title => Old_Title,
+            Search_Title => Ada.Characters.Handling.To_Lower (Old_Title),
+            Level => Level,
+            Clause_Number => Clause_Number,
+             Version => Version);
+--Ada.Text_IO.Put_Line ("  Add_Old " & Old_Title &
+-- " Index=" & Natural'Image(Last_Old_Title) & " Level=" & 
Level_Type'Image(Level));
+--Ada.Text_IO.Put_Line ("    Section" & 
Section_Number_Type'Image(Section_Number) &
+-- " Clause" & Natural'Image(Clause_Number.Clause) & " Subclause" & 
Natural'Image(Clause_Number.Subclause) &
+-- " Subsubclause" & Natural'Image(Clause_Number.Subsubclause));
+    end Add_Old;
+
+
+    function Make_Clause_Number (Level : in Level_Type;
+                  Clause_Number : in Clause_Number_Type) return String is
+       -- Returns a properly formatted Section or clause number reference.
+    begin
+       if Clause_Number.Section = UNKNOWN then
+           raise Bad_Clause_Error with "unknown section number";
+       -- else not unknown
+       end if;
+       case Level is
+           when Plain_Annex | Normative_Annex | Informative_Annex =>
+               if Clause_Number.Clause /= 0 or else Clause_Number.Subclause /= 
0 or else
+                  Clause_Number.Subsubclause /= 0 or else 
Clause_Number.Section <= 30 then
+                   raise Bad_Clause_Error; -- Illegal numbers.
+               end if;
+               return "Annex " & Character'Val (Character'Pos('A') + 
(Clause_Number.Section - ANNEX_START));
+           when Section =>
+               if Clause_Number.Clause /= 0 or else Clause_Number.Subclause /= 
0 or else
+                  Clause_Number.Section >= ANNEX_START then
+                   raise Bad_Clause_Error; -- Illegal numbers.
+               end if;
+               if Clause_Number.Section < 10 then
+                   return Character'Val (Character'Pos('0') + 
Clause_Number.Section) & "";
+               elsif Clause_Number.Section < 20 then
+                   return "1" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 10);
+               elsif Clause_Number.Section < 30 then
+                   return "2" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 20);
+               else
+                   return "3" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 30);
+               end if;
+           when Unnumbered_Section =>
+               if Clause_Number.Clause = 0 or else Clause_Number.Subclause /= 
0 or else
+                  Clause_Number.Section /= 0 then
+                   raise Bad_Clause_Error; -- Illegal numbers.
+               end if;
+               if Clause_Number.Clause < 10 then
+                   return "0." & Character'Val (Character'Pos('0') + 
Clause_Number.Clause);
+               elsif Clause_Number.Clause < 20 then
+                   return "0.1" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 10);
+               elsif Clause_Number.Clause < 30 then
+                   return "0.2" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 20);
+               else
+                   return "0.3" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 30);
+               end if;
+           when Clause =>
+               if Clause_Number.Subclause /= 0 then
+                   raise Bad_Clause_Error; -- Illegal number.
+               end if;
+               if Clause_Number.Section < 10 then
+                   if Clause_Number.Clause < 10 then
+                       return Character'Val (Character'Pos('0') + 
Clause_Number.Section) &
+                           "." & Character'Val (Character'Pos('0') + 
Clause_Number.Clause);
+                   elsif Clause_Number.Clause < 20 then
+                       return Character'Val (Character'Pos('0') + 
Clause_Number.Section) &
+                           ".1" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 10);
+                   elsif Clause_Number.Clause < 30 then
+                       return Character'Val (Character'Pos('0') + 
Clause_Number.Section) &
+                           ".2" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 20);
+                   elsif Clause_Number.Clause < 40 then
+                       return Character'Val (Character'Pos('0') + 
Clause_Number.Section) &
+                           ".3" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 30);
+                   elsif Clause_Number.Clause < 50 then
+                       return Character'Val (Character'Pos('0') + 
Clause_Number.Section) &
+                           ".4" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 40);
+                   elsif Clause_Number.Clause < 60 then
+                       return Character'Val (Character'Pos('0') + 
Clause_Number.Section) &
+                           ".5" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 50);
+                   else
+                       raise Bad_Clause_Error; -- Out of range.
+                   end if;
+               elsif Clause_Number.Section < 20 then
+                   if Clause_Number.Clause < 10 then
+                       return "1" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 10) &
+                           "." & Character'Val (Character'Pos('0') + 
Clause_Number.Clause);
+                   elsif Clause_Number.Clause < 20 then
+                       return "1" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 10) &
+                           ".1" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 10);
+                   elsif Clause_Number.Clause < 30 then
+                       return "1" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 10) &
+                           ".2" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 20);
+                   elsif Clause_Number.Clause < 40 then
+                       return "1" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 10) &
+                           ".3" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 30);
+                   elsif Clause_Number.Clause < 50 then
+                       return "1" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 10) &
+                           ".4" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 40);
+                   elsif Clause_Number.Clause < 60 then
+                       return "1" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 10) &
+                           ".5" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 50);
+                   else
+                       raise Bad_Clause_Error; -- Out of range.
+                   end if;
+               elsif Clause_Number.Section < 30 then
+                   if Clause_Number.Clause < 10 then
+                       return "2" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 20) &
+                           "." & Character'Val (Character'Pos('0') + 
Clause_Number.Clause);
+                   elsif Clause_Number.Clause < 20 then
+                       return "2" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 20) &
+                           ".1" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 10);
+                   elsif Clause_Number.Clause < 30 then
+                       return "2" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 20) &
+                           ".2" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 20);
+                   elsif Clause_Number.Clause < 40 then
+                       return "2" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 20) &
+                           ".3" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 30);
+                   elsif Clause_Number.Clause < 50 then
+                       return "2" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 20) &
+                           ".4" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 40);
+                   elsif Clause_Number.Clause < 60 then
+                       return "2" & Character'Val (Character'Pos('0') + 
Clause_Number.Section - 20) &
+                           ".5" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 50);
+                   else
+                       raise Bad_Clause_Error; -- Out of range.
+                   end if;
+               elsif Clause_Number.Section = 30 then
+                   if Clause_Number.Clause < 10 then
+                       return "30." & Character'Val (Character'Pos('0') + 
Clause_Number.Clause);
+                   elsif Clause_Number.Clause < 20 then
+                       return "30.1" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 10);
+                   elsif Clause_Number.Clause < 30 then
+                       return "30.2" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 20);
+                   elsif Clause_Number.Clause < 40 then
+                       return "30.3" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 30);
+                   elsif Clause_Number.Clause < 50 then
+                       return "30.4" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 40);
+                   elsif Clause_Number.Clause < 60 then
+                       return "30.5" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 50);
+                   else
+                       raise Bad_Clause_Error; -- Out of range.
+                   end if;
+               else
+                   if Clause_Number.Clause < 10 then
+                       return Character'Val (Character'Pos('A') + 
(Clause_Number.Section - ANNEX_START)) &
+                           "." & Character'Val (Character'Pos('0') + 
Clause_Number.Clause);
+                   elsif Clause_Number.Clause < 20 then
+                       return Character'Val (Character'Pos('A') + 
(Clause_Number.Section - ANNEX_START)) &
+                           ".1" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 10);
+                   elsif Clause_Number.Clause < 30 then
+                       return Character'Val (Character'Pos('A') + 
(Clause_Number.Section - ANNEX_START)) &
+                           ".2" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 20);
+                   elsif Clause_Number.Clause < 40 then
+                       return Character'Val (Character'Pos('A') + 
(Clause_Number.Section - ANNEX_START)) &
+                           ".3" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 30);
+                   elsif Clause_Number.Clause < 50 then
+                       return Character'Val (Character'Pos('A') + 
(Clause_Number.Section - ANNEX_START)) &
+                           ".4" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 40);
+                   elsif Clause_Number.Clause < 60 then
+                       return Character'Val (Character'Pos('A') + 
(Clause_Number.Section - ANNEX_START)) &
+                           ".4" & Character'Val (Character'Pos('0') + 
Clause_Number.Clause - 50);
+                   else
+                       raise Bad_Clause_Error; -- Out of range.
+                   end if;
+               end if;
+           when Subclause =>
+               if Clause_Number.Section = UNKNOWN then
+                   raise Bad_Clause_Error with "unknown section number";
+               elsif Clause_Number.Subclause < 10 then
+                   return Make_Clause_Number (Clause, (Clause_Number.Section, 
Clause_Number.Clause, 0, 0)) &
+                       "." & Character'Val (Character'Pos('0') + 
Clause_Number.Subclause);
+               elsif Clause_Number.Subclause < 20 then
+                   return Make_Clause_Number (Clause, (Clause_Number.Section, 
Clause_Number.Clause, 0, 0)) &
+                       ".1" & Character'Val (Character'Pos('0') + 
Clause_Number.Subclause - 10);
+               elsif Clause_Number.Subclause < 30 then
+                   return Make_Clause_Number (Clause, (Clause_Number.Section, 
Clause_Number.Clause, 0, 0)) &
+                       ".2" & Character'Val (Character'Pos('0') + 
Clause_Number.Subclause - 20);
+               elsif Clause_Number.Subclause < 40 then
+                   return Make_Clause_Number (Clause, (Clause_Number.Section, 
Clause_Number.Clause, 0, 0)) &
+                       ".3" & Character'Val (Character'Pos('0') + 
Clause_Number.Subclause - 30);
+               elsif Clause_Number.Subclause < 50 then
+                   return Make_Clause_Number (Clause, (Clause_Number.Section, 
Clause_Number.Clause, 0, 0)) &
+                       ".4" & Character'Val (Character'Pos('0') + 
Clause_Number.Subclause - 40);
+               else
+                   raise Bad_Clause_Error; -- Out of range.
+               end if;
+           when Subsubclause =>
+               if Clause_Number.Subsubclause < 10 then
+                   return Make_Clause_Number (Subclause, 
(Clause_Number.Section, Clause_Number.Clause, Clause_Number.Subclause, 0)) &
+                       "." & Character'Val (Character'Pos('0') + 
Clause_Number.Subsubclause);
+               elsif Clause_Number.Subclause < 20 then
+                   return Make_Clause_Number (Subclause, 
(Clause_Number.Section, Clause_Number.Clause, Clause_Number.Subclause, 0)) &
+                       ".1" & Character'Val (Character'Pos('0') + 
Clause_Number.Subsubclause - 10);
+               elsif Clause_Number.Subclause < 30 then
+                   return Make_Clause_Number (Subclause, 
(Clause_Number.Section, Clause_Number.Clause, Clause_Number.Subclause, 0)) &
+                       ".2" & Character'Val (Character'Pos('0') + 
Clause_Number.Subsubclause - 20);
+               elsif Clause_Number.Subclause < 40 then
+                   return Make_Clause_Number (Subclause, 
(Clause_Number.Section, Clause_Number.Clause, Clause_Number.Subclause, 0)) &
+                       ".3" & Character'Val (Character'Pos('0') + 
Clause_Number.Subsubclause - 30);
+               elsif Clause_Number.Subclause < 50 then
+                   return Make_Clause_Number (Subclause, 
(Clause_Number.Section, Clause_Number.Clause, Clause_Number.Subclause, 0)) &
+                       ".4" & Character'Val (Character'Pos('0') + 
Clause_Number.Subsubclause - 40);
+               else
+                   raise Bad_Clause_Error; -- Out of range.
+               end if;
+           when Dead_Clause =>
+               return "X.X";
+       end case;
+    end Make_Clause_Number;
+
+
+    procedure Make_Clause (Clause_String : in String;
+                          Clause_Number : out Clause_Number_Type) is
+       -- Returns the clause number for a properly formatted Section or
+       -- clause string.
+
+       Next : Positive;
+       function Get_Section_Number return Section_Number_Type is
+           -- Extract the section number:
+       begin
+           if Clause_String'Length = 1 or else
+               Clause_String(Clause_String'First + 1) = '.' then
+               Next := Clause_String'First + 2;
+               if Clause_String (Clause_String'First) in '0' .. '9' then
+                   return Character'Pos(Clause_String (Clause_String'First)) - 
Character'Pos('0');
+               else
+                   return Character'Pos(Clause_String (Clause_String'First)) - 
Character'Pos('A') + ANNEX_START;
+               end if;
+           else
+               Next := Clause_String'First + 3;
+               return (Character'Pos(Clause_String (Clause_String'First)) - 
Character'Pos('0')) * 10 +
+                   Character'Pos(Clause_String (Clause_String'First + 1)) - 
Character'Pos('0');
+           end if;
+       end Get_Section_Number;
+
+       function Get_Clause_Number return Natural is
+           -- Extract the clause:
+       begin
+           if Clause_String'Last - Next + 1 = 1 or else
+               Clause_String(Next + 1) = '.' then
+               Next := Next + 2;
+               return Character'Pos(Clause_String (Next - 2)) - 
Character'Pos('0');
+           else
+               Next := Next + 3;
+               return (Character'Pos(Clause_String (Next - 3)) - 
Character'Pos('0')) * 10 +
+                   Character'Pos(Clause_String (Next - 3 + 1)) - 
Character'Pos('0');
+           end if;
+       end Get_Clause_Number;
+
+    begin
+       if Clause_String'Length = 7 and then
+          Clause_String (Clause_String'First .. Clause_String'First + 5) =
+           "Annex " then -- Annex clauses.
+           Clause_Number :=
+               (Section => Character'Pos(Clause_String (Clause_String'First + 
6)) - Character'Pos('A') + ANNEX_START,
+                Clause | Subclause | Subsubclause => 0);
+       elsif Clause_String'Length = 1 then
+           Clause_Number :=
+               (Section => Get_Section_Number,
+                Clause | Subclause | Subsubclause => 0);
+       elsif Clause_String'Length = 2 then
+           Clause_Number :=
+               (Section => Get_Section_Number,
+                Clause | Subclause | Subsubclause => 0);
+       else
+           Clause_Number :=
+               (Section => Get_Section_Number,
+                Clause | Subclause | Subsubclause => 0);
+           -- Next is now the start of the Clause:
+           if Clause_String'Last - Next + 1 = 1 then
+               Clause_Number.Clause := Get_Clause_Number;
+           elsif Clause_String'Last - Next + 1 = 2 then
+               Clause_Number.Clause := Get_Clause_Number;
+           else
+               Clause_Number.Clause := Get_Clause_Number;
+               -- Next is now the start of the Subclause:
+               if Clause_String'Last - Next + 1 = 1 then
+                   Clause_Number.Subclause := Character'Pos(Clause_String 
(Next)) - Character'Pos('0');
+               elsif Clause_String'Last - Next + 1 = 2 then
+                   Clause_Number.Subclause := (Character'Pos(Clause_String 
(Next)) -
+                       Character'Pos('0')) * 10 +
+                           Character'Pos(Clause_String (Next + 1)) - 
Character'Pos('0');
+               else
+                   if Clause_String'Last - Next + 1 = 1 or else
+                       Clause_String(Next + 1) = '.' then
+                       Next := Next + 2;
+                       Clause_Number.Subclause := Character'Pos(Clause_String 
(Next - 2)) - Character'Pos('0');
+                   else
+                       Next := Next + 3;
+                       Clause_Number.Subclause := (Character'Pos(Clause_String 
(Next - 3)) - Character'Pos('0')) * 10 +
+                           Character'Pos(Clause_String (Next - 3 + 1)) - 
Character'Pos('0');
+                   end if;
+                   if Clause_String'Last - Next + 1 = 1 then
+                       Clause_Number.Subsubclause := 
Character'Pos(Clause_String (Next)) - Character'Pos('0');
+                   else -- Two digit.
+                       Clause_Number.Subsubclause := 
(Character'Pos(Clause_String (Next)) -
+                           Character'Pos('0')) * 10 +
+                               Character'Pos(Clause_String (Next + 1)) - 
Character'Pos('0');
+                   end if;
+               end if;
+           end if;
+       end if;
+       if Clause_Number.Section = UNKNOWN then
+           raise Bad_Clause_Error with "unknown section number";
+       -- else not unknown
+       end if;
+    end Make_Clause;
+
+
+    function Lookup_Clause_Number (Title : in Title_Type) return String is
+       -- Given the title of a clause, returns the formatted Section or
+       -- clause number reference for that title. The Title must match
+       -- exactly, except for case. Raises Not_Found_Error if not found.
+       Lower_Title : constant Title_Type := Ada.Characters.Handling.To_Lower 
(Title);
+    begin
+       for I in 1 .. Last_Title loop
+           if Lower_Title = Title_List(I).Search_Title then
+               return Make_Clause_Number (Title_List(I).Level,
+                                          Title_List(I).Clause_Number);
+           end if;
+       end loop;
+       raise Not_Found_Error;
+    end Lookup_Clause_Number;
+
+
+    function Lookup_Level (Title : in Title_Type) return Level_Type is
+       -- Given the title of a clause, returns the level for that title. The 
Title must match
+       -- exactly, except for case. Raises Not_Found_Error if not found.
+       Lower_Title : constant Title_Type := Ada.Characters.Handling.To_Lower 
(Title);
+    begin
+       for I in 1 .. Last_Title loop
+           if Lower_Title = Title_List(I).Search_Title then
+               return Title_List(I).Level;
+           end if;
+       end loop;
+       raise Not_Found_Error;
+    end Lookup_Level;
+
+
+    function Lookup_Title (Level : in Level_Type;
+                          Clause_Number : in Clause_Number_Type) return 
Title_Type is
+       -- Given the level and clause numbers, return the appropriate
+       -- title. Raises Not_Found_Error if not found.
+    begin
+       if Clause_Number.Section = UNKNOWN then
+           raise Bad_Clause_Error with "unknown section number";
+       -- else not unknown
+       end if;
+       for I in 1 .. Last_Title loop
+           if Title_List(I).Level = Level and then
+              Title_List(I).Clause_Number = Clause_Number then
+               return Title_List(I).Title;
+           end if;
+       end loop;
+       raise Not_Found_Error;
+    end Lookup_Title;
+
+
+    function Lookup_Old_Title (Level : in Level_Type;
+                  Clause_Number : in Clause_Number_Type) return Title_Type is
+       -- Given the level and clause numbers, return the appropriate
+       -- old title. Calls Lookup_Title if not found (thus returning the
+       -- regular (new) title.
+    begin
+       if Clause_Number.Section = UNKNOWN then
+           raise Bad_Clause_Error with "unknown section number";
+       -- else not unknown
+       end if;
+       for I in 1 .. Last_Old_Title loop
+           if Old_Title_List(I).Level = Level and then
+              Old_Title_List(I).Clause_Number = Clause_Number then
+               return Old_Title_List(I).Title;
+           end if;
+       end loop;
+       return Lookup_Title (Level, Clause_Number);
+    end Lookup_Old_Title;
+
+
+    function Previous_Clause (Clause : in String) return String is
+       -- Returns the string of the previous clause (in the table of contents)
+       -- for the properly formatted clause string Clause.
+       -- Raises Not_Found_Error if not found.
+        Clause_Number : Clause_Number_Type;
+    begin
+       Make_Clause (Clause, Clause_Number);
+       for I in 1 .. Last_Title loop
+           if Title_List(I).Clause_Number = Clause_Number then
+               for J in reverse 1 .. I - 1 loop
+                   if Title_List(J).Level /= Dead_Clause then
+                       return Make_Clause_Number (Title_List(J).Level,
+                                                  Title_List(J).Clause_Number);
+                   -- else skip it and continue.
+                   end if;
+               end loop;
+               -- If we get here, it was not found.
+               raise Not_Found_Error;
+           end if;
+       end loop;
+       raise Not_Found_Error;
+    end Previous_Clause;
+
+
+    function Next_Clause (Clause : in String) return String is
+       -- Returns the string of the next clause (in the table of contents)
+       -- for the properly formatted clause string Clause.
+       -- Raises Not_Found_Error if not found.
+        Clause_Number : Clause_Number_Type;
+    begin
+       Make_Clause (Clause, Clause_Number);
+       for I in 1 .. Last_Title loop
+           if Title_List(I).Clause_Number = Clause_Number then
+               for J in I + 1 .. Last_Title loop
+                   if Title_List(J).Level /= Dead_Clause then
+                       return Make_Clause_Number (Title_List(J).Level,
+                                                  Title_List(J).Clause_Number);
+                   -- else skip it and continue.
+                   end if;
+               end loop;
+               -- If we get here, it was not found.
+               raise Not_Found_Error;
+           end if;
+       end loop;
+       raise Not_Found_Error;
+    end Next_Clause;
+
+
+    function Parent_Clause (Clause : in String) return String is
+        -- Returns the string of the parent clause (in the table of contents)
+        -- for the properly formatted clause string Clause.
+        --
+        -- Result is a null string if Clause is a top level clause;
+        -- Section, Unnumbered_Section, Normative_Annex,
+        -- Informative_Annex, Plain_Annex.
+        Clause_Number : Clause_Number_Type;
+    begin
+       Make_Clause (Clause, Clause_Number);
+
+       if Clause_Number.Clause = 0 then
+          -- Clause is a section; no parent
+          return "";
+
+       elsif Clause_Number.Subclause = 0 then
+          -- Clause is a clause; parent is Section or Annex
+          if Clause_Number.Section >= ANNEX_START then
+             return Make_Clause_Number (Normative_Annex, 
(Clause_Number.Section, 0, 0, 0));
+          else
+             return Make_Clause_Number (Section, (Clause_Number.Section, 0, 0, 
0));
+          end if;
+
+       elsif Clause_Number.Subsubclause = 0 then
+          -- Clause is a subclause; clause is parent
+          return Make_Clause_Number (ARM_Contents.Clause, 
(Clause_Number.Section, Clause_Number.Clause, 0, 0));
+
+       else
+          -- Clause is a subsubclause; subclause is parent
+          return Make_Clause_Number
+            (Subclause, (Clause_Number.Section, Clause_Number.Clause, 
Clause_Number.Subclause, 0));
+       end if;
+    end Parent_Clause;
+
+
+    procedure For_Each is
+       -- Call Operate for each title in the contents, in the order that
+       -- they were added to the contents (other than dead clauses). If the
+       -- Quit parameter to Operate is True when Operate returns, the
+       -- iteration is abandoned.
+       Quit : Boolean := False;
+    begin
+       for I in 1 .. Last_Title loop
+           if Title_List(I).Level /= Dead_Clause then
+               Operate (Title_List(I).Title,
+                        Title_List(I).Level,
+                        Title_List(I).Clause_Number,
+                        Title_List(I).Version,
+                        Quit);
+           -- else skip it.
+           end if;
+           if Quit then
+               return;
+           end if;
+       end loop;
+    end For_Each;
+
+end ARM_Contents;
diff --git a/packages/ada-ref-man/progs/arm_cont.ads 
b/packages/ada-ref-man/progs/arm_cont.ads
new file mode 100755
index 0000000..aeca794
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_cont.ads
@@ -0,0 +1,187 @@
+with Ada.Strings.Unbounded;
+package ARM_Contents is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the routines to manage section/clause/subclause
+    -- references.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2004, 2006, 2007, 2009, 2011, 2012
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  4/19/00 - RLB - Created base package.
+    --  4/26/00 - RLB - Added Previous_Clause and Next_Clause.
+    --  5/15/00 - RLB - Added rules about unnumbered sections.
+    --  5/22/00 - RLB - Added Unnumbered_Section level.
+    --  8/ 7/00 - RLB - Made Make_Clause visible.
+    --  8/22/00 - RLB - Added Old_Title handling.
+    --  9/14/04 - RLB - Moved Change_Version_Type here, to avoid mutual
+    --                 dependence.
+    --         - RLB - Added version to changes.
+    --  9/22/06 - RLB - Created type Clause_Number_Type and added SubSubClause.
+    -- 12/18/07 - RLB - Added Plain_Annex.
+    --  5/06/09 - RLB - Added Versioned_String.
+    --  5/07/09 - RLB - Added Dead_Clause.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/19/11 - RLB - Added Parent_Clause from Stephen Leake's version.
+    -- 10/25/11 - RLB - Added version to Old name strings.
+    --  8/30/12 - RLB - Added initialization of Section to UNKNOWN to
+    --                 detect bugs earlier.
+
+    subtype Title_Type is String (1 .. 80);
+       -- The type of a title.
+
+    type Section_Number_Type is range 0 .. 58;
+       -- Values > 30 represent annex letters (31 => A, 32 => B, etc.)
+       -- Value = 0 represents the preface, introduction, etc. No
+       -- number is generated if Section_Number = 0.
+    ANNEX_START : constant := 31; -- First annex section number.
+    UNKNOWN : constant Section_Number_Type := 58; -- Uninitialized sections 
get this.
+
+    subtype Change_Version_Type is Character range '0' .. '9';
+       -- Defines the change version. Version 0 is the original text.
+
+    type Versioned_String is array (ARM_Contents.Change_Version_Type) of
+       Ada.Strings.Unbounded.Unbounded_String;
+
+    type Clause_Number_Type is record
+       Section : Section_Number_Type := UNKNOWN;
+       Clause : Natural := 0;
+       Subclause : Natural := 0;
+       Subsubclause : Natural := 0;
+    end record;
+
+    Not_Found_Error  : exception;
+
+    Bad_Clause_Error : exception;
+       -- Raised by any of the below if the Clause_Number is
+       -- invalid (potentially depending on the other parameters,
+       -- like the level).
+
+    procedure Initialize;
+       -- Initialize this package; make sure the contents are empty.
+
+    type Level_Type is (Section, Unnumbered_Section, Plain_Annex,
+                       Normative_Annex, Informative_Annex,
+                       Clause, Subclause, Subsubclause, Dead_Clause);
+       -- Defines the level of a clause header.
+       -- Clause is "xx.nn"; Subclause is "xx.nn.nn"; Subsubclause is 
"xx.nn.nn.nn".
+
+    function "<" (Left, Right : Clause_Number_Type) return Boolean;
+       -- True if Left comes before Right in the collating order.
+
+    function ">" (Left, Right : Clause_Number_Type) return Boolean;
+       -- True if Left comes after Right in the collating order.
+
+    function "<=" (Left, Right : Clause_Number_Type) return Boolean;
+       -- True if Left comes before or is the same as Right in the
+       -- collating order.
+
+    function ">=" (Left, Right : Clause_Number_Type) return Boolean;
+       -- True if Left comes after or is the same as Right in the
+       -- collating order.
+
+    procedure Add (Title : in Title_Type;
+                  Level : in Level_Type;
+                  Clause_Number : in Clause_Number_Type;
+                   Version : in ARM_Contents.Change_Version_Type := '0');
+       -- Add a section or clause to the contents. It has the specified
+       -- characteristics.
+
+    procedure Add_Old (Old_Title : in Title_Type;
+                      Level : in Level_Type;
+                      Clause_Number : in Clause_Number_Type;
+                       Version : in ARM_Contents.Change_Version_Type := '0');
+       -- Add an old title for a section or clause to the contents. It has
+       -- the specified characteristics; the version is the version for which
+       -- it first was present in the document.
+
+    function Make_Clause_Number (Level : in Level_Type;
+                  Clause_Number : in Clause_Number_Type) return String;
+       -- Returns a properly formatted Section or clause number reference.
+       -- Note that an unnumbered section returns a number with a
+       -- Section_Number of zero (for sorting purposes).
+
+    procedure Make_Clause (Clause_String : in String;
+                          Clause_Number : out Clause_Number_Type);
+       -- Returns the clause number for a properly formatted Section or
+       -- clause string.
+
+    function Lookup_Clause_Number (Title : in Title_Type) return String;
+       -- Given the title of a clause, returns the formatted Section or
+       -- clause number reference for that title. The Title must match
+       -- exactly, except for case. Raises Not_Found_Error if not found.
+
+    function Lookup_Level (Title : in Title_Type) return Level_Type;
+       -- Given the title of a clause, returns the level for that title. The 
Title must match
+       -- exactly, except for case. Raises Not_Found_Error if not found.
+
+    function Lookup_Title (Level : in Level_Type;
+                          Clause_Number : in Clause_Number_Type) return 
Title_Type;
+       -- Given the level and clause numbers, return the appropriate
+       -- title. Raises Not_Found_Error if not found.
+
+    function Lookup_Old_Title (Level : in Level_Type;
+                  Clause_Number : in Clause_Number_Type) return Title_Type;
+       -- Given the level and clause numbers, return the appropriate
+       -- old title. Calls Lookup_Title if not found (thus returning the
+       -- regular (new) title.
+
+    function Previous_Clause (Clause : in String) return String;
+       -- Returns the string of the previous clause (in the table of contents)
+       -- for the properly formatted clause string Clause.
+       -- Raises Not_Found_Error if not found.
+
+    function Next_Clause (Clause : in String) return String;
+       -- Returns the string of the next clause (in the table of contents)
+       -- for the properly formatted clause string Clause.
+       -- Raises Not_Found_Error if not found.
+
+    function Parent_Clause (Clause : in String) return String;
+        -- Returns the string of the parent clause (in the table of contents)
+        -- for the properly formatted clause string Clause.
+        --
+        -- Result is a null string if Clause is a top level clause;
+        -- Section, Unnumbered_Section, Normative_Annex,
+        -- Informative_Annex, Plain_Annex.
+
+    generic
+       with procedure Operate (Title : in Title_Type;
+                  Level : in Level_Type;
+                  Clause_Number : in Clause_Number_Type;
+                   Version : in ARM_Contents.Change_Version_Type;
+                  Quit : out Boolean) is <>;
+    procedure For_Each;
+       -- Call Operate for each title in the contents, in the order that
+       -- they were added to the contents. If the Quit parameter to Operate
+       -- is True when Operate returns, the iteration is abandoned.
+
+end ARM_Contents;
diff --git a/packages/ada-ref-man/progs/arm_corr.adb 
b/packages/ada-ref-man/progs/arm_corr.adb
new file mode 100755
index 0000000..57dcf3f
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_corr.adb
@@ -0,0 +1,1719 @@
+with --ARM_Output,
+     --ARM_Contents,
+     --Ada.Text_IO,
+     Ada.Exceptions,
+     Ada.Strings.Fixed,
+     Ada.Strings.Maps;
+package body ARM_Corr is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package defines the text output object.
+    -- Output objects are responsible for implementing the details of
+    -- a particular format.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2004, 2005, 2006, 2007, 2011, 2012
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  6/ 2/05 - RLB - Created package from text and HTML versions.
+    --  1/11/06 - RLB - Eliminated dispatching Create in favor of tailored
+    --                 versions.
+    --  1/18/06 - RLB - Added additional styles.
+    --  2/ 8/06 - RLB - Added additional parameters to the table command.
+    --  2/10/06 - RLB - Added even more additional parameters to the
+    --                 table command.
+    --         - RLB - Added picture command.
+    --  9/22/06 - RLB - Added missing with.
+    --  9/25/06 - RLB - Handled optional renaming of TOC.
+    --         - RLB - Added Last_Column_Width to Start_Table.
+    -- 10/13/06 - RLB - Added Local_Link_Start and Local_Link_End to allow
+    --                 formatting in the linked text.
+    --  2/ 9/07 - RLB - Changed comments on AI_Reference.
+    --  2/13/07 - RLB - Revised to separate style and indent information
+    --                 for paragraphs.
+    -- 12/18/07 - RLB - Added Plain_Annex.
+    -- 12/19/07 - RLB - Added limited colors to Text_Format.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/25/11 - RLB - Added old insertion version to Revised_Clause_Header.
+    --  8/31/12 - RLB - Added Output_Path.
+    -- 10/18/12 - RLB - Added additional hanging styles.
+    -- 11/26/12 - RLB - Added subdivision names to Clause_Header and
+    --                 Revised_Clause_Header.
+
+    LINE_LENGTH : constant := 78;
+       -- Maximum intended line length.
+
+    Special_Set : constant Ada.Strings.Maps.Character_Set :=
+         Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('>'),
+           Ada.Strings.Maps.To_Set ('@'));
+
+    procedure Create (Output_Object : in out Corr_Output_Type;
+                     File_Prefix : in String;
+                     Output_Path : in String;
+                     Title : in String := "") is
+       -- Create an Output_Object for a document.
+       -- The prefix of the output file names is File_Prefix - this
+       -- should be no more then 5 characters allowed in file names.
+       -- The result files will be written to Output_Path.
+       -- The title of the document is Title.
+    begin
+       if Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Already valid object");
+       end if;
+       Output_Object.Is_Valid := True;
+       Ada.Strings.Fixed.Move (Target => Output_Object.File_Prefix,
+                               Source => File_Prefix);
+       Ada.Strings.Fixed.Move (Target => Output_Object.Output_Path,
+                               Source => Output_Path);
+        Output_Object.Output_Path_Len := Output_Path'Length;
+       -- We don't use the title.
+    end Create;
+
+
+    procedure Close (Output_Object : in out Corr_Output_Type) is
+       -- Close an Output_Object. No further output to the object is
+       -- allowed after this call.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Ada.Text_IO.Is_Open (Output_Object.Output_File) then
+           Ada.Text_IO.Close (Output_Object.Output_File);
+       end if;
+       Output_Object.Is_Valid := False;
+    end Close;
+
+
+    procedure Section (Output_Object : in out Corr_Output_Type;
+                      Section_Title : in String;
+                      Section_Name : in String) is
+       -- Start a new section. The title is Section_Title (this is
+       -- intended for humans). The name is Section_Name (this is
+       -- intended to be suitable to be a portion of a file name).
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Section in paragraph");
+       end if;
+       if Ada.Text_IO.Is_Open (Output_Object.Output_File) then
+           Ada.Text_IO.Close (Output_Object.Output_File);
+       end if;
+       -- Create a new file for this section:
+        -- Unix directory separator for Windows and Debian
+       Ada.Text_IO.Create (Output_Object.Output_File, Ada.Text_IO.Out_File,
+            Output_Object.Output_Path(1..Output_Object.Output_Path_Len) &
+               Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right) &
+               "-Corr-" & Section_Name & ".TXT");
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+    end Section;
+
+
+    procedure Set_Columns (Output_Object : in out Corr_Output_Type;
+                          Number_of_Columns : in ARM_Output.Column_Count) is
+       -- Set the number of columns.
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "In paragraph");
+       end if;
+       -- No columns in text format.
+    end Set_Columns;
+
+
+    procedure Make_Indent (Output_Object : in out Corr_Output_Type) is
+       -- Internal:
+       -- Output the appropriate indent after a New_Line or Put_Line.
+    begin
+--Ada.Text_IO.Put_Line("Make_Indent: Amount=" & 
Natural'Image(Output_Object.Indent_Amount));
+        for I in 1 .. Output_Object.Indent_Amount loop
+           Ada.Text_IO.Put (Output_Object.Output_File, ' ');
+        end loop;
+        Output_Object.Char_Count := Output_Object.Indent_Amount;
+        Output_Object.Out_Char_Count := Output_Object.Indent_Amount;
+       Output_Object.Output_Buffer_Space_Before := False;
+    end Make_Indent;
+
+
+    procedure Spill (Output_Object : in out Corr_Output_Type) is
+       -- Internal:
+       -- Empty the output buffer in preperation for a New_Line or Put_Line.
+    begin
+        if Output_Object.Output_Buffer_Space_Before then
+           Ada.Text_IO.Put (Output_Object.Output_File, ' ');
+           Output_Object.Char_Count := Output_Object.Char_Count + 1; -- Count 
the space.
+           Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + 1; 
-- Count the space.
+        end if;
+       if Output_Object.Output_Buffer_Len /= 0 then
+           Ada.Text_IO.Put (Output_Object.Output_File,
+               Output_Object.Output_Buffer (1 .. 
Output_Object.Output_Buffer_Len));
+--Ada.Text_IO.Put_Line("Spill: Len=" & 
Natural'Image(Output_Object.Output_Buffer_Len) &
+--     " Space added=" &  
Boolean'Image(Output_Object.Output_Buffer_Space_Before) & " Text=" &
+--     Output_Object.Output_Buffer (1 .. Output_Object.Output_Buffer_Len));
+           Output_Object.Output_Buffer_Len := 0;
+           Output_Object.Out_Char_Count := Output_Object.Out_Char_Count +
+               Output_Object.Output_Buffer_Len;
+       end if;
+        Output_Object.Output_Buffer_Space_Before := False;
+    end Spill;
+
+
+    procedure Buffer (Output_Object : in out Corr_Output_Type;
+                     Char : in Character) is
+       -- Internal:
+       -- Add Char to the output buffer. Char will *not* be a word break
+       -- character.
+    begin
+       if Output_Object.Output_Buffer_Len = Output_Object.Output_Buffer'Last 
then
+           -- Oops, buffer is full. Spill it, and this character.
+--Ada.Text_IO.Put_Line("** Buffer overflow!!");
+           Spill (Output_Object);
+           Ada.Text_IO.Put (Output_Object.Output_File, Char);
+           Output_Object.Char_Count := Output_Object.Char_Count + 1;
+           Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + 1;
+           return;
+       end if;
+       Output_Object.Output_Buffer_Len := Output_Object.Output_Buffer_Len + 1;
+       Output_Object.Output_Buffer(Output_Object.Output_Buffer_Len) := Char;
+        Output_Object.Char_Count := Output_Object.Char_Count + 1;
+    end Buffer;
+
+
+    procedure Buffer (Output_Object : in out Corr_Output_Type;
+                     Str : in String) is
+       -- Internal:
+       -- Add Char to the output buffer. String will *not* include a word
+       -- break character.
+    begin
+       if Output_Object.Output_Buffer_Len+Str'Length >= 
Output_Object.Output_Buffer'Last then
+           -- Oops, buffer is full. Spill it.
+--Ada.Text_IO.Put_Line("** Buffer overflow!!");
+           Spill (Output_Object);
+       end if;
+       
Output_Object.Output_Buffer(Output_Object.Output_Buffer_Len+1..Output_Object.Output_Buffer_Len+Str'Length)
+           := Str;
+       Output_Object.Output_Buffer_Len := Output_Object.Output_Buffer_Len + 
Str'Length;
+        Output_Object.Char_Count := Output_Object.Char_Count + Str'Length;
+    end Buffer;
+
+
+    procedure Start_Paragraph (Output_Object : in out Corr_Output_Type;
+                              Style     : in ARM_Output.Paragraph_Style_Type;
+                              Indent    : in ARM_Output.Paragraph_Indent_Type;
+                              Number    : in String;
+                              No_Prefix : in Boolean := False;
+                              Tab_Stops : in ARM_Output.Tab_Info := 
ARM_Output.NO_TABS;
+                              No_Breaks : in Boolean := False;
+                              Keep_with_Next : in Boolean := False;
+                              Space_After : in ARM_Output.Space_After_Type
+                                  := ARM_Output.Normal;
+                              Justification : in ARM_Output.Justification_Type
+                                  := ARM_Output.Default) is
+       -- Start a new paragraph. The style and indent of the paragraph is as
+       -- specified. The (AA)RM paragraph number (which might include update
+       -- and version numbers as well: [12.1/1]) is Number. If the format is
+       -- a type with a prefix (bullets, hangining items), the prefix is
+       -- omitted if No_Prefix is true. Tab_Stops defines the tab stops for
+       -- the paragraph. If No_Breaks is True, we will try to avoid page breaks
+       -- in the paragraph. If Keep_with_Next is true, we will try to avoid
+       -- separating this paragraph and the next one. (These may have no
+       -- effect in formats that don't have page breaks). Space_After
+       -- specifies the amount of space following the paragraph. Justification
+       -- specifies the text justification for the paragraph. Not_Valid_Error
+       -- is raised if Tab_Stops /= NO_TABS for a hanging or bulleted format.
+       use type ARM_Output.Paragraph_Indent_Type;
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Already in paragraph");
+       end if;
+       Output_Object.Is_In_Paragraph := True;
+       Output_Object.Is_Hanging := False;
+       Output_Object.Saw_Hang_End := False;
+       Output_Object.Char_Count := 0;
+       Output_Object.Out_Char_Count := 0;
+       Output_Object.Output_Buffer_Space_Before := False; -- Nothing in it or 
on the line.
+       Output_Object.Output_Buffer_Len := 0;
+        Output_Object.Font := ARM_Output.Default;
+        Output_Object.Is_Bold := False;
+        Output_Object.Is_Italic := False;
+        Output_Object.Size := 0;
+        Output_Object.Para_Style := Style;
+        Output_Object.Para_Indent := Indent;
+        Output_Object.Is_Fixed_Format := False;
+
+       if Output_Object.Clause_Len /= 0 and then
+          Number /= "" then
+           Ada.Text_IO.New_Line (Output_Object.Output_File);
+           Ada.Text_IO.Put (Output_Object.Output_File, "!paragraph ");
+           Ada.Text_IO.Put (Output_Object.Output_File, 
Output_Object.Clause_Num(1..Output_Object.Clause_Len));
+           Ada.Text_IO.Put (Output_Object.Output_File, '(');
+           Ada.Text_IO.Put (Output_Object.Output_File, Number);
+           Ada.Text_IO.Put (Output_Object.Output_File, ") [");
+           Ada.Text_IO.Put (Output_Object.Output_File, 
ARM_Output.Paragraph_Style_Type'Image(Style) &
+                       " :" & ARM_Output.Paragraph_Indent_Type'Image(Indent));
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "]");
+           Ada.Text_IO.New_Line (Output_Object.Output_File);
+       else
+           Ada.Text_IO.New_Line (Output_Object.Output_File);
+       end if;
+
+        Output_Object.Indent_Amount := Integer(Indent)*4 + 2;
+
+       case Style is
+           when ARM_Output.Normal =>
+               if Indent = 0 then
+                   null; -- %% Temp.
+                   Output_Object.Indent_Amount := 0; -- %% Temp.
+               elsif Indent = 3 then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "@xindent<");
+                   Output_Object.Char_Count := 9;
+                   Output_Object.Indent_Amount := 0; -- %% Temp.
+               else -- Unknown case.
+                   null; -- ** Tbd.
+               end if;
+           when ARM_Output.Wide_Above => null;
+               if Indent = 0 then
+                   null; -- %% Temp.
+                   Output_Object.Indent_Amount := 0; -- %% Temp.
+               else -- Unknown case.
+                   null; -- ** Tbd.
+               end if;
+
+           when ARM_Output.Small =>
+               if Indent = 1 then -- Notes.
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
"@xindent<@s9<");
+                   Output_Object.Char_Count := 13;
+                   Output_Object.Indent_Amount := 0; -- %% Temp.
+               else -- Unknown case.
+                   null; -- ** Tbd.
+               end if;
+           when ARM_Output.Small_Wide_Above =>
+               null; -- ** TBD (Unknown cases).
+
+           when ARM_Output.Header =>
+               null; -- ** TBD (Unknown cases).
+
+           when ARM_Output.Small_Header =>
+               if Indent = 1 then -- Notes Header.
+                   null;
+                   --Output_Object.Indent_Amount := 6; --** TBD.
+               else -- Unknown case.
+                   null; -- ** Tbd.
+               end if;
+
+           when ARM_Output.Index => null; --** TBD.
+           when ARM_Output.Syntax_Summary => null; --** TBD.
+           when ARM_Output.Title =>
+               null; -- ** TBD (Unknown cases).
+
+           when ARM_Output.Examples =>
+               if Indent = 1 then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "@xcode<");
+                   Output_Object.Char_Count := 7;
+                   Output_Object.Is_Fixed_Format := True;
+                   Output_Object.Indent_Amount := 0; -- %% Temp.
+               else -- Unknown case.
+                   null; -- ** Tbd.
+               end if;
+
+           when ARM_Output.Small_Examples => null; --** TBD.
+
+           when ARM_Output.Swiss_Examples =>
+               if Indent = 1 then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "@xcode<");
+                   Output_Object.Char_Count := 7;
+                   Output_Object.Is_Fixed_Format := True;
+                   Output_Object.Indent_Amount := 0; -- %% Temp.
+               else -- Unknown case.
+                   null; -- ** Tbd.
+               end if;
+
+           when ARM_Output.Small_Swiss_Examples => null; --** TBD.
+
+           when ARM_Output.Bulleted =>
+               if Indent = 1 then
+                   Output_Object.Indent_Amount := 0; -- %% Temp.
+                   if No_Prefix then
+                       Ada.Text_IO.Put (Output_Object.Output_File, 
"@xindent<");
+                       Output_Object.Char_Count := 9;
+                   else
+                       Ada.Text_IO.Put (Output_Object.Output_File, 
"@xbullet<");
+                       Output_Object.Char_Count := 9;
+                   end if;
+               else -- Unknown/unimplemented case.
+                   null; -- ** Tbd.
+               end if;
+
+           when ARM_Output.Nested_Bulleted => null; --** TBD.
+
+           when ARM_Output.Small_Bulleted => null; --** TBD.
+
+           when ARM_Output.Small_Nested_Bulleted => null; --** TBD.
+
+           when ARM_Output.Giant_Hanging => null; --** TBD.
+
+           when ARM_Output.Wide_Hanging =>
+               if Indent = 3 then
+                   Output_Object.Indent_Amount := 0; -- %% Temp.
+                   Output_Object.Is_Hanging := True;
+                   if No_Prefix then
+                       Output_Object.Saw_Hang_End := True;
+                       Output_Object.Char_Count := 0;
+                   else -- Has prefix
+                       -- No units on first line.
+                       Output_Object.Saw_Hang_End := False;
+                       Ada.Text_IO.Put (Output_Object.Output_File, 
"@xhang<@xterm<");
+                       Output_Object.Char_Count := 14;
+                   end if;
+               else -- Unknown/unimplemented case.
+                   null; -- ** Tbd.
+               end if;
+
+           when ARM_Output.Medium_Hanging => null; --** TBD.
+
+           when ARM_Output.Narrow_Hanging => null; --** TBD.
+
+           when ARM_Output.Hanging_in_Bulleted => null; --** TBD.
+
+           when ARM_Output.Small_Giant_Hanging => null; --** TBD.
+
+           when ARM_Output.Small_Wide_Hanging => null; --** TBD.
+
+           when ARM_Output.Small_Medium_Hanging => null; --** TBD.
+
+           when ARM_Output.Small_Narrow_Hanging => null; --** TBD.
+
+           when ARM_Output.Small_Hanging_in_Bulleted => null; --** TBD.
+
+           when ARM_Output.Enumerated => null; --** TBD.
+
+           when ARM_Output.Small_Enumerated => null; --** TBD.
+
+       end case;
+
+       if Output_Object.Indent_Amount > 6 then
+           for I in 1 .. (Output_Object.Indent_Amount-6)/4 loop
+               Ada.Text_IO.Put (Output_Object.Output_File, "    ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 4;
+           end loop;
+       end if;
+
+       case Style is
+           when ARM_Output.Normal | ARM_Output.Wide_Above |
+                ARM_Output.Small | ARM_Output.Small_Wide_Above |
+                ARM_Output.Header | ARM_Output.Small_Header |
+                ARM_Output.Index | ARM_Output.Syntax_Summary |
+                ARM_Output.Title |
+                ARM_Output.Examples | ARM_Output.Small_Examples |
+                ARM_Output.Swiss_Examples | ARM_Output.Small_Swiss_Examples =>
+               Output_Object.Tab_Stops := Tab_Stops;
+                   -- We'll expand proportional stops here (text characters
+                   -- are larger than the variable ones these are set up for).
+               for I in 1 .. Tab_Stops.Number loop
+                   if ARM_Output."=" (Tab_Stops.Stops(I).Kind,
+                                      ARM_Output.Left_Proportional) then
+                       Output_Object.Tab_Stops.Stops(I).Stop :=
+                               (Tab_Stops.Stops(I).Stop * 5 / 4) + 
Output_Object.Indent_Amount;
+                   else
+                       Output_Object.Tab_Stops.Stops(I).Stop :=
+                               Tab_Stops.Stops(I).Stop + 
Output_Object.Indent_Amount;
+                   end if;
+               end loop;
+           when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted |
+                ARM_Output.Small_Bulleted | ARM_Output.Small_Nested_Bulleted |
+                ARM_Output.Giant_Hanging | ARM_Output.Wide_Hanging |
+                ARM_Output.Medium_Hanging | ARM_Output.Narrow_Hanging |
+                ARM_Output.Hanging_in_Bulleted |
+                ARM_Output.Small_Giant_Hanging | ARM_Output.Small_Wide_Hanging 
|
+                ARM_Output.Small_Medium_Hanging | 
ARM_Output.Small_Narrow_Hanging |
+                ARM_Output.Small_Hanging_in_Bulleted |
+                ARM_Output.Enumerated | ARM_Output.Small_Enumerated =>
+               if Tab_Stops.Number /= 0 then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Tabs in hanging/bulleted paragraph");
+               end if;
+       end case;
+       Output_Object.Out_Char_Count := Output_Object.Char_Count;
+
+       -- Note: No_Breaks, Keep_with_Next, and Justification have no effect
+       -- here.
+--Ada.Text_IO.Put_Line ("Start_Paragraph - Indent=" & 
Natural'Image(Output_Object.Indent_Amount) & " Cnt=" &
+--    Natural'Image(Output_Object.Char_Count));
+    end Start_Paragraph;
+
+
+    procedure End_Paragraph (Output_Object : in out Corr_Output_Type) is
+       -- End a paragraph.
+       use type ARM_Output.Paragraph_Indent_Type;
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       case Output_Object.Para_Style is
+           when ARM_Output.Normal =>
+               if Output_Object.Para_Indent = 0 then
+                   null;
+               elsif Output_Object.Para_Indent = 3 then
+                   Buffer (Output_Object, '>');
+               else -- Unknown case.
+                   null; -- ** Tbd.
+               end if;
+           when ARM_Output.Wide_Above => null;
+               if Output_Object.Para_Indent = 0 then
+                   null; -- %% Temp.
+               else -- Unknown case.
+                   null; -- ** Tbd.
+               end if;
+
+           when ARM_Output.Small =>
+               if Output_Object.Para_Indent = 1 then -- Notes.
+                   Buffer (Output_Object, ">>");
+               else -- Unknown case.
+                   null; -- ** Tbd.
+               end if;
+           when ARM_Output.Small_Wide_Above =>
+               null; -- ** TBD (Unknown cases).
+
+           when ARM_Output.Header =>
+               null; -- ** TBD (Unknown cases).
+
+           when ARM_Output.Small_Header =>
+               if Output_Object.Para_Indent = 1 then -- Notes Header.
+                   null;
+               else -- Unknown case.
+                   null; -- ** Tbd.
+               end if;
+
+           when ARM_Output.Index => null; --** TBD.
+           when ARM_Output.Syntax_Summary => null; --** TBD.
+           when ARM_Output.Title => null; --** TBD.
+           when ARM_Output.Examples =>
+               if Output_Object.Para_Indent = 1 then
+                   Buffer (Output_Object, '>');
+               else -- Unknown case.
+                   null; -- ** Tbd.
+               end if;
+
+           when ARM_Output.Small_Examples => null; --** TBD.
+
+           when ARM_Output.Swiss_Examples =>
+               if Output_Object.Para_Indent = 1 then
+                   Buffer (Output_Object, '>');
+               else -- Unknown case.
+                   null; -- ** Tbd.
+               end if;
+
+           when ARM_Output.Small_Swiss_Examples => null; --** TBD.
+
+           when ARM_Output.Bulleted =>
+               if Output_Object.Para_Indent = 1 then
+                   Buffer (Output_Object, '>');
+               else -- Unknown/unimplemented case.
+                   null; -- ** Tbd.
+               end if;
+
+           when ARM_Output.Nested_Bulleted => null; --** TBD.
+
+           when ARM_Output.Small_Bulleted => null; --** TBD.
+
+           when ARM_Output.Small_Nested_Bulleted => null; --** TBD.
+
+           when ARM_Output.Giant_Hanging => null; --** TBD.
+
+           when ARM_Output.Wide_Hanging =>
+               if Output_Object.Para_Indent = 3 then
+                   Buffer (Output_Object, '>');
+               else -- Unknown/unimplemented case.
+                   null; -- ** Tbd.
+               end if;
+
+           when ARM_Output.Medium_Hanging => null; --** TBD.
+
+           when ARM_Output.Narrow_Hanging => null; --** TBD.
+
+           when ARM_Output.Hanging_in_Bulleted => null; --** TBD.
+
+           when ARM_Output.Small_Giant_Hanging => null; --** TBD.
+
+           when ARM_Output.Small_Wide_Hanging => null; --** TBD.
+
+           when ARM_Output.Small_Medium_Hanging => null; --** TBD.
+
+           when ARM_Output.Small_Narrow_Hanging => null; --** TBD.
+
+           when ARM_Output.Small_Hanging_in_Bulleted => null; --** TBD.
+
+           when ARM_Output.Enumerated => null; --** TBD.
+
+           when ARM_Output.Small_Enumerated => null; --** TBD.
+
+       end case;
+
+       if Output_Object.Output_Buffer_Len /= 0 then
+           Spill (Output_Object);
+       end if;
+       Output_Object.Is_In_Paragraph := False;
+       Ada.Text_IO.New_Line (Output_Object.Output_File, 2); -- Double space 
paragraphs.
+    end End_Paragraph;
+
+
+    procedure Category_Header (Output_Object : in out Corr_Output_Type;
+                              Header_Text : String) is
+       -- Output a Category header (that is, "Legality Rules",
+       -- "Dynamic Semantics", etc.)
+       -- (Note: We did not use a enumeration here to insure that these
+       -- headers are spelled the same in all output versions).
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Header in paragraph");
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "!subheader");
+       Ada.Text_IO.Put (Output_Object.Output_File, "@i<@s8<");
+       if Ada.Strings.Fixed.Count (Header_Text, Special_Set) = 0 then
+            Ada.Text_IO.Put (Output_Object.Output_File, Header_Text);
+       else
+           for I in Header_Text'Range loop
+               if Header_Text(I) = '>' then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "@>");
+               elsif Header_Text(I) = '@' then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "@@");
+               else
+                   Ada.Text_IO.Put (Output_Object.Output_File, Header_Text(I));
+               end if;
+           end loop;
+       end if;
+       Ada.Text_IO.Put (Output_Object.Output_File, ">>");
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+       Output_Object.Char_Count := 0;
+       Output_Object.Out_Char_Count := 0;
+    end Category_Header;
+
+
+    procedure Clause_Header (Output_Object     : in out Corr_Output_Type;
+                            Header_Text       : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False) is
+       -- Output a Clause header. The level of the header is specified
+       -- in Level. The Clause Number is as specified; the top-level (and
+       -- other) subdivision names are as specified. These should appear in
+       -- the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Header in paragraph");
+       end if;
+        Ada.Text_IO.New_Line (Output_Object.Output_File);
+
+       Output_Object.Clause_Len := Clause_Number'Length;
+       Output_Object.Clause_Num(1..Output_Object.Clause_Len) :=
+           Clause_Number;
+       -- Special for table of contents:
+       if Clause_Number = "" and then
+               (Header_Text = "Table of Contents" or else
+                Header_Text = "Contents") then
+           Ada.Text_IO.Put (Output_Object.Output_File,
+                              "!clause ");
+           Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                              Header_Text);
+           Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+           Output_Object.Char_Count := 0;
+           Output_Object.Out_Char_Count := 0;
+           return;
+       end if;
+
+        Ada.Text_IO.Put (Output_Object.Output_File,
+                        "!clause ");
+       case Level is
+           when ARM_Contents.Plain_Annex =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  Clause_Number); -- Note: Clause_Number 
includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  Header_Text);
+           when ARM_Contents.Normative_Annex =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  Clause_Number); -- Note: Clause_Number 
includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  "(normative)");
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  Header_Text);
+           when ARM_Contents.Informative_Annex =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  Clause_Number); -- Note: Clause_Number 
includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  "(informative)");
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  Header_Text);
+           when ARM_Contents.Section =>
+               case Top_Level_Subdivision_Name is
+                   when ARM_Output.Chapter =>
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                             "Chapter " & Clause_Number & ": " 
& Header_Text);
+                   when ARM_Output.Section =>
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                             "Section " & Clause_Number & ": " 
& Header_Text);
+                   when ARM_Output.Clause =>
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                             Clause_Number & "   " & 
Header_Text);
+               end case;
+           when ARM_Contents.Unnumbered_Section =>
+               if Header_Text /= "" then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                      Header_Text);
+               end if;
+           when ARM_Contents.Clause | ARM_Contents.Subclause |
+                ARM_Contents.Subsubclause =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                     Clause_Number & ' ' & Header_Text);
+           when ARM_Contents.Dead_Clause =>
+               raise Program_Error; -- No headers for dead clauses.
+       end case;
+       Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+       Output_Object.Char_Count := 0;
+       Output_Object.Out_Char_Count := 0;
+       -- We don't have any page breaks here to suppress.
+    end Clause_Header;
+
+
+    procedure Revised_Clause_Header
+                           (Output_Object     : in out Corr_Output_Type;
+                            New_Header_Text   : in String;
+                            Old_Header_Text   : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Version           : in 
ARM_Contents.Change_Version_Type;
+                            Old_Version       : in 
ARM_Contents.Change_Version_Type;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False) is
+       -- Output a revised clause header. Both the original and new text will
+       -- be output. The level of the header is specified in Level. The Clause
+       -- Number is as specified; the top-level (and other) subdivision names
+       -- are as specified. These should appear in the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- Version is the insertion version of the new text; Old_Version is
+       -- the insertion version of the old text.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+       function Header_Text return String is
+           -- Note: Version and Old_Version are not used.
+       begin
+           return '{' & New_Header_Text & "} [" & Old_Header_Text & ']';
+       end Header_Text;
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Header in paragraph");
+       end if;
+        Ada.Text_IO.New_Line (Output_Object.Output_File);
+
+       Output_Object.Clause_Len := Clause_Number'Length;
+       Output_Object.Clause_Num(1..Output_Object.Clause_Len) :=
+           Clause_Number;
+       -- Special for table of contents:
+       if Clause_Number = "" and then
+               (Header_Text = "Table of Contents" or else -- Ada 95 format
+                Header_Text = "Contents") then -- ISO 2004 format.
+            Ada.Text_IO.Put (Output_Object.Output_File,
+                            "!clause ");
+           Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                              Header_Text);
+           Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+           Output_Object.Char_Count := 0;
+           Output_Object.Out_Char_Count := 0;
+           return;
+       end if;
+
+        Ada.Text_IO.Put (Output_Object.Output_File,
+                        "!clause ");
+       case Level is
+           when ARM_Contents.Plain_Annex =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  Clause_Number); -- Note: Clause_Number 
includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  Header_Text);
+           when ARM_Contents.Normative_Annex =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  Clause_Number); -- Note: Clause_Number 
includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  "(normative)");
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  Header_Text);
+           when ARM_Contents.Informative_Annex =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  Clause_Number); -- Note: Clause_Number 
includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  "(informative)");
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                  Header_Text);
+           when ARM_Contents.Section =>
+               case Top_Level_Subdivision_Name is
+                   when ARM_Output.Chapter =>
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                             "Chapter " & Clause_Number & ": " 
& Header_Text);
+                   when ARM_Output.Section =>
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                             "Section " & Clause_Number & ": " 
& Header_Text);
+                   when ARM_Output.Clause =>
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                             Clause_Number & "   " & 
Header_Text);
+               end case;
+
+           when ARM_Contents.Unnumbered_Section =>
+               if Header_Text /= "" then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                      Header_Text);
+               end if;
+           when ARM_Contents.Clause | ARM_Contents.Subclause |
+                ARM_Contents.Subsubclause =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                     Clause_Number & ' ' & Header_Text);
+           when ARM_Contents.Dead_Clause =>
+               raise Program_Error; -- No headers for dead clauses.
+       end case;
+       Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+       Output_Object.Char_Count := 0;
+       Output_Object.Out_Char_Count := 0;
+       -- We don't have any page breaks here to suppress.
+    end Revised_Clause_Header;
+
+
+    procedure TOC_Marker (Output_Object : in out Corr_Output_Type;
+                         For_Start : in Boolean) is
+       -- Mark the start (if For_Start is True) or end (if For_Start is
+       -- False) of the table of contents data. Output objects that
+       -- auto-generate the table of contents can use this to do needed
+       -- actions.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       null; -- We don't care about this.
+    end TOC_Marker;
+
+
+    procedure New_Page (Output_Object : in out Corr_Output_Type;
+                       Kind : ARM_Output.Page_Kind_Type := 
ARM_Output.Any_Page) is
+       -- Output a page break.
+       -- Note that this has no effect on non-printing formats.
+       -- Any_Page breaks to the top of the next page (whatever it is);
+       -- Odd_Page_Only breaks to the top of the odd-numbered page;
+       -- Soft_Page allows a page break but does not force one (use in
+       -- "No_Breaks" paragraphs.)
+       -- Raises Not_Valid_Error if in a paragraph if Kind = Any_Page or
+       -- Odd_Page, and if not in a paragraph if Kind = Soft_Page.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       case Kind is
+           when ARM_Output.Any_Page | ARM_Output.Odd_Page_Only =>
+               if Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Page in paragraph");
+               end if;
+               Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+           when ARM_Output.Soft_Page =>
+               if not Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Soft page not in paragraph");
+               end if;
+               null; -- No page breaks.
+               Spill (Output_Object);
+       end case;
+    end New_Page;
+
+
+    procedure New_Column (Output_Object : in out Corr_Output_Type) is
+       -- Output a column break.
+       -- Raises Not_Valid_Error if in a paragraph, or if the number of
+       -- columns is 1.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "New column in paragraph");
+       end if;
+       -- No columns in text format.
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+    end New_Column;
+
+
+    procedure Start_Table (Output_Object : in out Corr_Output_Type;
+                          Columns : in ARM_Output.Column_Count;
+                          First_Column_Width : in ARM_Output.Column_Count;
+                          Last_Column_Width : in ARM_Output.Column_Count;
+                          Alignment : in ARM_Output.Column_Text_Alignment;
+                          No_Page_Break : in Boolean;
+                          Has_Border : in Boolean;
+                          Small_Text_Size : in Boolean;
+                          Header_Kind : in ARM_Output.Header_Kind_Type) is
+       -- Starts a table. The number of columns is Columns; the first
+       -- column has First_Column_Width times the normal column width, and
+       -- the last column has Last_Column_Width times the normal column width.
+       -- Alignment is the horizontal text alignment within the columns.
+       -- No_Page_Break should be True to keep the table intact on a single
+       -- page; False to allow it to be split across pages.
+       -- Has_Border should be true if a border is desired, false otherwise.
+       -- Small_Text_Size means that the contents will have the AARM size;
+       -- otherwise it will have the normal size.
+       -- Header_Kind determines whether the table has headers.
+       -- This command starts a paragraph; the entire table is a single
+       -- paragraph. Text will be considered part of the caption until the
+       -- next table marker call.
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       -- Alignment, No_Page_Break, Border, Small_Text_Size, and Header_Kind
+       -- not used here.
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Table in paragraph");
+       end if;
+
+       Output_Object.Tab_Stops.Number := Columns;
+       declare
+            Column_Units : constant ARM_Output.Column_Count :=
+               Columns+First_Column_Width+Last_Column_Width-2;
+            Width : Natural :=
+               (72/(Column_Units));
+       begin
+           if Column_Units <= 3 then -- Keep it from getting too wide.
+               Width := 22;
+           end if;
+           for I in 1 .. Columns loop
+               Output_Object.Tab_Stops.Stops(I) := (Kind => 
ARM_Output.Left_Fixed,
+                                                    Stop => 
Width*(I+First_Column_Width-1)+10);
+           end loop;
+       end;
+
+       Output_Object.Indent_Amount := 10;
+        Ada.Text_IO.Put (Output_Object.Output_File, "          ");
+       Output_Object.Char_Count := 10;
+       Output_Object.Out_Char_Count := 10;
+
+       Output_Object.Is_In_Paragraph := True;
+       Output_Object.Is_In_Table := True;
+    end Start_Table;
+
+
+    procedure Table_Marker (Output_Object : in out Corr_Output_Type;
+                           Marker : in ARM_Output.Table_Marker_Type) is
+       -- Marks the end of an entity in a table.
+       -- If Marker is End_Caption, the table caption ends and the
+       --      future text is part of the table header.
+       -- If Marker is End_Header, the table header ends and the
+       --      future text is part of the table body.
+       -- If Marker is End_Row, a row in the table is completed, and another
+       --      row started.
+       -- If Marker is End_Row_Next_Is_Last, a row in the table is completed,
+       --      and another row started. That row is the last row in the table.
+       -- If Marker is End_Item, an item in the table header or body is ended,
+       --      and another started.
+       -- If Marker is End_Table, the entire table is finished.
+       -- Raises Not_Valid_Error if not in a table.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if (not Output_Object.Is_In_Paragraph) or (not 
Output_Object.Is_In_Table) then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Table marker not in table");
+       end if;
+       case Marker is
+           when ARM_Output.End_Item =>
+               -- Just tab over one row:
+               Spill (Output_Object);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, " ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 1;
+               Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + 
1;
+               for I in 1 .. Output_Object.Tab_Stops.Number loop
+                   if Output_Object.Tab_Stops.Stops(I).Stop > 
Output_Object.Char_Count then
+                       for J in Output_Object.Char_Count+1 .. 
Output_Object.Tab_Stops.Stops(I).Stop-1 loop
+                           Ada.Text_IO.Put_Line (Output_Object.Output_File, " 
");
+                           Output_Object.Char_Count := 
Output_Object.Char_Count + 1;
+                           Output_Object.Out_Char_Count := 
Output_Object.Out_Char_Count + 1;
+                       end loop;
+                   end if;
+               end loop;
+
+           when ARM_Output.End_Caption =>
+               Spill (Output_Object);
+               Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+               Ada.Text_IO.Put (Output_Object.Output_File, "          ");
+               Output_Object.Char_Count := 10;
+               Output_Object.Out_Char_Count := 10;
+           when ARM_Output.End_Header =>
+               Spill (Output_Object);
+               Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+               Ada.Text_IO.Put (Output_Object.Output_File, "          ");
+               Output_Object.Char_Count := 10;
+               Output_Object.Out_Char_Count := 10;
+           when ARM_Output.End_Row | ARM_Output.End_Row_Next_Is_Last =>
+               Spill (Output_Object);
+               Ada.Text_IO.New_Line (Output_Object.Output_File, 1);
+               Ada.Text_IO.Put (Output_Object.Output_File, "          ");
+               Output_Object.Char_Count := 10;
+               Output_Object.Out_Char_Count := 10;
+           when ARM_Output.End_Table =>
+               Spill (Output_Object);
+               Output_Object.Is_In_Paragraph := False;
+               Output_Object.Is_In_Table := False;
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Output_Object.Tab_Stops := ARM_Output.NO_TABS;
+       end case;
+    end Table_Marker;
+
+
+    procedure Separator_Line (Output_Object : in out Corr_Output_Type;
+                             Is_Thin : Boolean := True) is
+       -- Output a separator line. It is thin if "Is_Thin" is true.
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Separator in paragraph");
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+       if Is_Thin then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"---------------------------------------------------------------------");
+       else
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"=====================================================================");
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+    end Separator_Line;
+
+
+    -- Text output: These are only allowed after a Start_Paragraph and
+    -- before any End_Paragraph. Raises Not_Valid_Error if not allowed.
+
+    procedure Ordinary_Text (Output_Object : in out Corr_Output_Type;
+                            Text : in String) is
+       -- Output ordinary text.
+       -- The text must end at a word break, never in the middle of a word.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+--Ada.Text_IO.Put_Line ("Ordinary_Text: Cnt=" & 
Natural'Image(Output_Object.Char_Count) &
+--" Buffer=" & Natural'Image(Output_Object.Output_Buffer_Len));
+       if Output_Object.Char_Count + Text'Length >= LINE_LENGTH - 2 and then
+          Output_Object.Out_Char_Count > Output_Object.Indent_Amount then
+           -- We want a line break here if the line is too long and something 
was output:
+           Ada.Text_IO.New_Line (Output_Object.Output_File);
+           Make_Indent (Output_Object);
+           --Output_Object.Output_Buffer_Space_Before := False;
+               -- Start of line, this is done by Make_Indent.
+           Spill (Output_Object);
+       else
+           Spill (Output_Object);
+       end if;
+       if Ada.Strings.Fixed.Count (Text, Special_Set) = 0 then
+            Ada.Text_IO.Put (Output_Object.Output_File, Text);
+            Output_Object.Char_Count := Output_Object.Char_Count + Text'Length;
+            Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + 
Text'Length;
+       else
+           for I in Text'Range loop
+               if Text(I) = '>' then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "@>");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 2;
+                   Output_Object.Out_Char_Count := 
Output_Object.Out_Char_Count + 2;
+               elsif Text(I) = '@' then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "@@");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 2;
+                   Output_Object.Out_Char_Count := 
Output_Object.Out_Char_Count + 2;
+               else
+                   Ada.Text_IO.Put (Output_Object.Output_File, Text(I));
+                   Output_Object.Char_Count := Output_Object.Char_Count + 1;
+                   Output_Object.Out_Char_Count := 
Output_Object.Out_Char_Count + 1;
+               end if;
+           end loop;
+       end if;
+        Output_Object.Output_Buffer_Space_Before := False; -- No space between
+                                                          -- this and any 
following text.
+    end Ordinary_Text;
+
+
+    procedure Ordinary_Character (Output_Object : in out Corr_Output_Type;
+                                 Char : in Character) is
+       -- Output an ordinary character.
+       -- Spaces will be used to break lines as needed.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+
+       if Output_Object.Char_Count >= LINE_LENGTH and then
+          Output_Object.Out_Char_Count > Output_Object.Indent_Amount then
+           -- Insert a break here if anything has been output (but don't
+           -- Spill the buffer):
+--Ada.Text_IO.Put_Line ("Ordinary_Char [Break, no spill]: Cnt=" & 
Natural'Image(Output_Object.Char_Count));
+           Ada.Text_IO.New_Line (Output_Object.Output_File);
+           Make_Indent (Output_Object);
+           --Output_Object.Output_Buffer_Space_Before := False;
+               -- Start of line, this is done by Make_Indent.
+               -- Note that this may make the space disappear.
+           -- Add the contents of the buffer to the character count for this 
line:
+           Output_Object.Char_Count := Output_Object.Char_Count +
+               Output_Object.Output_Buffer_Len;
+           if Char = '>' then
+               Buffer (Output_Object, "@>");
+           elsif Char = '@' then
+               Buffer (Output_Object, "@@");
+           elsif Char /= ' ' then
+               Buffer (Output_Object, Char);
+           else -- Break character, spill on the new line:
+               if Output_Object.Output_Buffer_Len /= 0 then
+                   Spill (Output_Object); -- Output the buffer up to the space.
+                   Output_Object.Output_Buffer_Space_Before := True; -- 
Mid-line now.
+               -- else nothing in buffer, so nothing to output; just skip it.
+               end if;
+           end if;
+       elsif Char = ' ' then
+           -- Break character, and it fits on this line:
+           if Output_Object.Output_Buffer_Len /= 0 then
+--Ada.Text_IO.Put_Line ("Ordinary_Char [Space spill]: Cnt=" & 
Natural'Image(Output_Object.Char_Count));
+               Spill (Output_Object); -- Output the buffer up to the space.
+               Output_Object.Output_Buffer_Space_Before := True; -- Mid-line 
now.
+           else -- nothing in buffer.
+               -- nothing to output. But make sure we display a space before
+               -- the next item.
+               Output_Object.Output_Buffer_Space_Before := True; -- Mid-line 
now.
+           end if;
+        elsif Char = '>' then
+           Buffer (Output_Object, "@>");
+        elsif Char = '@' then
+           Buffer (Output_Object, "@@");
+       else
+           Buffer (Output_Object, Char);
+       end if;
+    end Ordinary_Character;
+
+
+    procedure Hard_Space (Output_Object : in out Corr_Output_Type) is
+       -- Output a hard space. No line break should happen at a hard space.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.Is_Fixed_Format then
+           -- In this format, all spaces are hard spaces.
+           Buffer (Output_Object, ' ');
+       else -- A hard space command.
+           Buffer (Output_Object, "@ ");
+       end if;
+    end Hard_Space;
+
+
+    procedure Line_Break (Output_Object : in out Corr_Output_Type) is
+       -- Output a line break. This does not start a new paragraph.
+       -- This corresponds to a "<BR>" in HTML.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+--Ada.Text_Io.Put_Line ("Line_Break");
+       if Output_Object.Is_Fixed_Format then
+           -- In this format, all line breaks are significant.
+           null;
+       else -- A hard space command.
+            Buffer (Output_Object, "@hr");
+       end if;
+       if Output_Object.Output_Buffer_Len /= 0 then
+           Spill (Output_Object);
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+        Make_Indent (Output_Object);
+    end Line_Break;
+
+
+    procedure Index_Line_Break (Output_Object : in out Corr_Output_Type;
+                               Clear_Keep_with_Next : in Boolean) is
+       -- Output a line break for the index. This does not start a new
+       -- paragraph in terms of spacing. This corresponds to a "<BR>"
+       -- in HTML. If Clear_Keep_with_Next is true, insure that the next
+       -- line does not require the following line to stay with it.
+       -- Raises Not_Valid_Error if the paragraph is not in the index format.
+    begin
+       Line_Break (Output_Object);
+    end Index_Line_Break;
+
+
+    procedure Soft_Line_Break (Output_Object : in out Corr_Output_Type) is
+       -- Output a soft line break. This is a place (in the middle of a
+       -- "word") that we allow a line break. It is usually used after
+       -- underscores in long non-terminals.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+--     if Output_Object.Char_Count >= LINE_LENGTH - 10 then
+--         if Output_Object.Output_Buffer_Len /= 0 then
+--             Spill (Output_Object);
+--         end if;
+--         Ada.Text_IO.New_Line (Output_Object.Output_File);
+--            Make_Indent (Output_Object);
+--     -- else we don't need a line break.
+--     end if;
+       null; -- Ignore this, there is no counterpart in Corrigendum formatting.
+    end Soft_Line_Break;
+
+
+    procedure Soft_Hyphen_Break (Output_Object : in out Corr_Output_Type) is
+       -- Output a soft line break, with a hyphen. This is a place (in the 
middle of
+       -- a "word") that we allow a line break. If the line break is used,
+       -- a hyphen will be added to the text.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+--     if Output_Object.Char_Count >= LINE_LENGTH - 8 then
+--         Spill (Output_Object);
+--         Ada.Text_IO.Put_Line (Output_Object.Output_File, "-"); -- Add the 
hyphen and break.
+--            Make_Indent (Output_Object);
+--     -- else we don't need a line break.
+--     end if;
+       null; -- Ignore this, there is no counterpart in Corrigendum formatting.
+    end Soft_Hyphen_Break;
+
+
+    procedure Tab (Output_Object : in out Corr_Output_Type) is
+       -- Output a tab, inserting space up to the next tab stop.
+       -- Raises Not_Valid_Error if the paragraph was created with
+       -- Tab_Stops = ARM_Output.NO_TABS.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if ARM_Output."="(Output_Object.Tab_Stops, ARM_Output.NO_TABS) then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Tab, but none set");
+       end if;
+       -- We use the tab stops as characters here, and fixed and proportional
+       -- stops are treated identically.
+       -- Find the first stop greater than the current character count. (After
+       -- writing a space).
+--Ada.Text_IO.Put_Line ("Tab");
+        Buffer (Output_Object, "@tab");
+       Output_Object.Output_Buffer_Space_Before := False; -- Spaces needed 
were output.
+    end Tab;
+
+
+    procedure Special_Character (Output_Object : in out Corr_Output_Type;
+                                Char : in ARM_Output.Special_Character_Type) is
+       -- Output an special character.
+    begin
+       --** Could use Latin1 and Unicode equivalents for most of these.
+       case Char is
+           when ARM_Output.EM_Dash =>
+               Buffer (Output_Object, "@emdash");
+           when ARM_Output.EN_Dash =>
+               Buffer (Output_Object, "@endash");
+           when ARM_Output.GEQ =>
+               Ordinary_Text (Output_Object, ">="); -- Not available in 
Corrigendum, use the Ada one.
+           when ARM_Output.LEQ =>
+               Ordinary_Text (Output_Object, "<="); -- Not available in 
Corrigendum, use the Ada one.
+           when ARM_Output.NEQ =>
+               Ordinary_Text (Output_Object, "/="); -- Not available in 
Corrigendum, use the Ada one.
+           when ARM_Output.PI =>
+               Buffer (Output_Object, "@pi");
+           when ARM_Output.Left_Ceiling =>
+               Ordinary_Text (Output_Object, "Ceiling("); -- Not available in 
Corrigendum.
+           when ARM_Output.Right_Ceiling =>
+               Ordinary_Text (Output_Object, ")"); -- Not available in 
Corrigendum.
+           when ARM_Output.Left_Floor =>
+               Ordinary_Text (Output_Object, "Floor("); -- Not available in 
Corrigendum.
+           when ARM_Output.Right_Floor =>
+               Ordinary_Text (Output_Object, ")"); -- Not available in 
Corrigendum.
+           when ARM_Output.Thin_Space =>
+               Ordinary_Text (Output_Object, " "); -- Not available in 
Corrigendum.
+           when ARM_Output.Left_Quote =>
+               Buffer (Output_Object, "@lquote");
+           when ARM_Output.Right_Quote =>
+               Buffer (Output_Object, "@rquote");
+           when ARM_Output.Left_Double_Quote =>
+               Ordinary_Text (Output_Object, """"); -- Not available in 
Corrigendum, use double quote.
+           when ARM_Output.Right_Double_Quote =>
+               Ordinary_Text (Output_Object, """"); -- Not available in 
Corrigendum, use double quote.
+           when ARM_Output.Small_Dotless_I =>
+               Ordinary_Text (Output_Object, "i"); -- Not available in 
Corrigendum, use the nearest text.
+           when ARM_Output.Capital_Dotted_I =>
+               Ordinary_Text (Output_Object, "I"); -- Not available in 
Corrigendum, use the nearest text.
+       end case;
+    end Special_Character;
+
+
+    procedure Unicode_Character (Output_Object : in out Corr_Output_Type;
+                                Char : in ARM_Output.Unicode_Type) is
+       -- Output a Unicode character, with code position Char.
+       Char_Code : constant String := ARM_Output.Unicode_Type'Image(Char);
+    begin
+       -- We don't check, but we assume this is not a normal character.
+       Buffer (Output_Object, "@unicode<" & Char_Code(2..Char_Code'Last) & 
">");
+    end Unicode_Character;
+
+
+    procedure End_Hang_Item (Output_Object : in out Corr_Output_Type) is
+       -- Marks the end of a hanging item. Call only once per paragraph.
+       -- Raises Not_Valid_Error if the paragraph style is not in
+       -- Text_Prefixed_Style_Subtype, or if this has already been
+       -- called for the current paragraph, or if the paragraph was started
+       -- with No_Prefix = True.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if not Output_Object.Is_Hanging then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not a hanging paragraph");
+       end if;
+       if Output_Object.Saw_Hang_End then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Already saw the end of the hanging part");
+       end if;
+       Output_Object.Saw_Hang_End := True;
+
+        Buffer (Output_Object, ">"); -- Close @Xterm<
+    end End_Hang_Item;
+
+
+    procedure Text_Format (Output_Object : in out Corr_Output_Type;
+                          Format : in ARM_Output.Format_Type) is
+       -- Change the text format so that all of the properties are as 
specified.
+       -- Note: Changes to these properties ought be stack-like; that is,
+       -- Bold on, Italic on, Italic off, Bold off is OK; Bold on, Italic on,
+       -- Bold off, Italic off should be avoided (as separate commands).
+       use type ARM_Output.Change_Type;
+       use type ARM_Output.Location_Type;
+       use type ARM_Output.Size_Type;
+       -- Note: We ignore colors here, no colors in !Corrigendum markup.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+
+       if not Format.Bold and Output_Object.Is_Bold then
+           Buffer (Output_Object, '>');
+           Output_Object.Is_Bold := False;
+       end if;
+
+       if not Format.Italic and Output_Object.Is_Italic then
+           Buffer (Output_Object, '>');
+           Output_Object.Is_Italic := False;
+       end if;
+
+       if Format.Size /= Output_Object.Size then
+           if Output_Object.Size /= 0 then
+               Buffer (Output_Object, '>');
+           end if;
+       end if;
+
+       if Format.Location /= Output_Object.Location then
+           if Output_Object.Location /= ARM_Output.Normal then
+               --Buffer (Output_Object, '>');
+               null; -- Corrigendum doesn't support this.
+           end if;
+       end if;
+
+       if ARM_Output."/=" (Format.Font, Output_Object.Font) then
+           case Output_Object.Font is
+               when ARM_Output.Default => null;
+               when ARM_Output.Fixed =>
+                   Buffer (Output_Object, '>');
+               when ARM_Output.Roman =>
+                   Buffer (Output_Object, '>');
+               when ARM_Output.Swiss =>
+                   Buffer (Output_Object, '>');
+           end case;
+       end if;
+
+       -- For the intended purpose, there should be no Change commands.
+       if Format.Change /= Output_Object.Change then
+           if Format.Change = ARM_Output.Both then
+               -- Open only the one(s) needed:
+               case Output_Object.Change is
+                   -- Note: Version is not used.
+                   when ARM_Output.Insertion =>
+                       -- Open the deletion:
+                       Buffer(Output_Object, '[');
+                   when ARM_Output.Deletion =>
+                       -- Open the insertion:
+                       Buffer(Output_Object, '{');
+                   when ARM_Output.None =>
+                       Buffer(Output_Object, '{');
+                       Buffer(Output_Object, '[');
+                   when ARM_Output.Both =>
+                       null;
+               end case;
+           elsif Output_Object.Change = ARM_Output.Both then
+               -- Close only the one(s) needed:
+               case Format.Change is
+                   -- Note: Version is not used.
+                   when ARM_Output.Insertion =>
+                       -- Close the deletion:
+                       Buffer(Output_Object, ']');
+                   when ARM_Output.Deletion =>
+                       -- Close the insertion:
+                       Buffer(Output_Object, '}');
+                   when ARM_Output.None =>
+                       Buffer(Output_Object, ']');
+                       Buffer(Output_Object, '}');
+                   when ARM_Output.Both =>
+                       null;
+               end case;
+           else -- Both can't get here.
+               case Output_Object.Change is
+                   when ARM_Output.Insertion =>
+                       Buffer(Output_Object, '}');
+                   when ARM_Output.Deletion =>
+                       Buffer(Output_Object, ']');
+                   when ARM_Output.None =>
+                       null;
+                   when ARM_Output.Both =>
+                       Buffer(Output_Object, ']');
+                       Buffer(Output_Object, '}');
+               end case;
+               case Format.Change is
+                   -- Note: Version is not used.
+                   when ARM_Output.Insertion =>
+                       Buffer(Output_Object, '{');
+                   when ARM_Output.Deletion =>
+                       Buffer(Output_Object, '[');
+                   when ARM_Output.None =>
+                       null;
+                   when ARM_Output.Both =>
+                       Buffer(Output_Object, '{');
+                       Buffer(Output_Object, '[');
+               end case;
+           end if;
+           Output_Object.Change := Format.Change;
+       end if;
+       if ARM_Output."/=" (Format.Font, Output_Object.Font) then
+           case Format.Font is
+               when ARM_Output.Default => null;
+               when ARM_Output.Fixed =>
+                   Buffer (Output_Object, "@fc<");
+               when ARM_Output.Roman =>
+                   Buffer (Output_Object, "@ft<");
+               when ARM_Output.Swiss =>
+                   Buffer (Output_Object, "@fa<");
+           end case;
+           Output_Object.Font := Format.Font;
+       end if;
+
+       if Format.Location /= Output_Object.Location then
+           case Format.Location is
+               when ARM_Output.Superscript =>
+                   --Buffer (Output_Object, "@+<");
+                   null; -- Corrigendum doesn't support this.
+               when ARM_Output.Subscript =>
+                   --Buffer (Output_Object, "@+<");
+                   null; -- Corrigendum doesn't support this.
+               when ARM_Output.Normal =>
+                   null;
+           end case;
+           Output_Object.Location := Format.Location;
+       end if;
+
+       if Format.Size /= Output_Object.Size then
+           if Format.Size < 0 then
+               Buffer (Output_Object, "@s" & 
Character'Val(10+Format.Size+Character'Pos('0')) & '<');
+           else
+               Buffer (Output_Object, "@s1" & 
Character'Val(Format.Size+Character'Pos('0')) & '<');
+           end if;
+           Output_Object.Size := Format.Size;
+       end if;
+
+       if Format.Italic and (not Output_Object.Is_Italic) then
+           Buffer (Output_Object, "@i<");
+           Output_Object.Is_Italic := True;
+       end if;
+       if Format.Bold and (not Output_Object.Is_Bold) then
+           Buffer (Output_Object, "@b<");
+           Output_Object.Is_Bold := True;
+       end if;
+
+    end Text_Format;
+
+
+    procedure Clause_Reference (Output_Object : in out Corr_Output_Type;
+                               Text : in String;
+                               Clause_Number : in String) is
+       -- Generate a reference to a clause in the standard. The text of
+       -- the reference is "Text", and the number of the clause is
+       -- Clause_Number. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end Clause_Reference;
+
+
+    procedure Index_Target (Output_Object : in out Corr_Output_Type;
+                           Index_Key : in Natural) is
+       -- Generate a index target. This marks the location where an index
+       -- reference occurs. Index_Key names the index item involved.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, nothing is generated.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       null; -- Nothing to do for plain text.
+    end Index_Target;
+
+
+    procedure Index_Reference (Output_Object : in out Corr_Output_Type;
+                              Text : in String;
+                              Index_Key : in Natural;
+                              Clause_Number : in String) is
+       -- Generate a reference to an index target in the standard. The text
+       -- of the reference is "Text", and Index_Key and Clause_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end Index_Reference;
+
+
+    procedure DR_Reference (Output_Object : in out Corr_Output_Type;
+                           Text : in String;
+                           DR_Number : in String) is
+       -- Generate a reference to an DR from the standard. The text
+       -- of the reference is "Text", and DR_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end DR_Reference;
+
+
+    procedure AI_Reference (Output_Object : in out Corr_Output_Type;
+                           Text : in String;
+                           AI_Number : in String) is
+       -- Generate a reference to an AI from the standard. The text
+       -- of the reference is "Text", and AI_Number denotes
+       -- the target (in unfolded format). For hyperlinked formats, this
+       -- should generate a link; for other formats, the text alone is
+       -- generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end AI_Reference;
+
+
+    procedure Local_Target (Output_Object : in out Corr_Output_Type;
+                           Text : in String;
+                           Target : in String) is
+       -- Generate a local target. This marks the potential target of local
+       -- links identified by "Target". Text is the text of the target.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, only the text is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end Local_Target;
+
+
+    procedure Local_Link (Output_Object : in out Corr_Output_Type;
+                         Text : in String;
+                         Target : in String;
+                         Clause_Number : in String) is
+       -- Generate a local link to the target and clause given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end Local_Link;
+
+
+    procedure Local_Link_Start (Output_Object : in out Corr_Output_Type;
+                               Target : in String;
+                               Clause_Number : in String) is
+       -- Generate a local link to the target and clause given.
+       -- The link will surround text until Local_Link_End is called.
+       -- Local_Link_End must be called before this routine can be used again.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       null; -- No link, nothing to do.
+    end Local_Link_Start;
+
+
+    procedure Local_Link_End (Output_Object : in out Corr_Output_Type;
+                             Target : in String;
+                             Clause_Number : in String) is
+       -- End a local link for the target and clause given.
+       -- This must be in the same paragraph as the Local_Link_Start.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       null; -- No link, nothing to do.
+    end Local_Link_End;
+
+
+    procedure URL_Link (Output_Object : in out Corr_Output_Type;
+                       Text : in String;
+                       URL : in String) is
+       -- Generate a link to the URL given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end URL_Link;
+
+
+    procedure Picture  (Output_Object : in out Corr_Output_Type;
+                       Name  : in String;
+                       Descr : in String;
+                       Alignment : in ARM_Output.Picture_Alignment;
+                       Height, Width : in Natural;
+                       Border : in ARM_Output.Border_Kind) is
+       -- Generate a picture.
+       -- Name is the (simple) file name of the picture; Descr is a
+       -- descriptive name for the picture (it will appear in some web
+       -- browsers).
+       -- We assume that it is a .GIF or .JPG and that it will be present
+       -- in the same directory as the input files and the same directory as
+       -- the .HTML output files.
+       -- Alignment specifies the picture alignment.
+       -- Height and Width specify the picture size in pixels.
+       -- Border specifies the kind of border.
+    begin
+       Ordinary_Text (Output_Object, "[Picture: " & Name &
+         " - " & Descr & "]");
+    end Picture;
+
+end ARM_Corr;
diff --git a/packages/ada-ref-man/progs/arm_corr.ads 
b/packages/ada-ref-man/progs/arm_corr.ads
new file mode 100755
index 0000000..e6f7bcf
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_corr.ads
@@ -0,0 +1,432 @@
+with ARM_Output,
+     ARM_Contents,
+     Ada.Text_IO;
+package ARM_Corr is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package defines the text output object.
+    -- Output objects are responsible for implementing the details of
+    -- a particular format.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2004, 2005, 2006, 2007, 2011, 2012
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  6/ 2/05 - RLB - Created base package from text and HTML versions.
+    --  1/11/06 - RLB - Eliminated dispatching Create in favor of tailored
+    --                 versions.
+    --  1/13/06 - RLB - Added new Link operations.
+    --  2/ 8/06 - RLB - Added additional parameters to the table command.
+    --  2/10/06 - RLB - Added even more additional parameters to the
+    --                 table command.
+    --         - RLB - Added picture command.
+    --  9/25/06 - RLB - Added Last_Column_Width to Start_Table.
+    -- 10/13/06 - RLB - Added Local_Link_Start and Local_Link_End to allow
+    --                 formatting in the linked text.
+    --  2/ 9/07 - RLB - Changed comments on AI_Reference.
+    --  2/13/07 - RLB - Revised to separate style and indent information
+    --                 for paragraphs.
+    -- 12/19/07 - RLB - Added limited colors to Text_Format.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/25/11 - RLB - Added old insertion version to Revised_Clause_Header.
+    --  8/31/12 - RLB - Added Output_Path.
+    -- 11/26/12 - RLB - Added subdivision names to Clause_Header and
+    --                 Revised_Clause_Header.
+
+    type Corr_Output_Type is new ARM_Output.Output_Type with private;
+
+    procedure Create (Output_Object : in out Corr_Output_Type;
+                     File_Prefix : in String;
+                     Output_Path : in String;
+                     Title : in String := "");
+       -- Create an Output_Object for a document.
+       -- The prefix of the output file names is File_Prefix - this
+       -- should be no more then 5 characters allowed in file names.
+       -- The result files will be written to Output_Path.
+       -- The title of the document is Title.
+
+    procedure Close (Output_Object : in out Corr_Output_Type);
+       -- Close an Output_Object. No further output to the object is
+       -- allowed after this call.
+
+
+    procedure Section (Output_Object : in out Corr_Output_Type;
+                      Section_Title : in String;
+                      Section_Name : in String);
+       -- Start a new section. The title is Section_Title (this is
+       -- intended for humans). The name is Section_Name (this is
+       -- intended to be suitable to be a portion of a file name).
+
+    procedure Set_Columns (Output_Object : in out Corr_Output_Type;
+                          Number_of_Columns : in ARM_Output.Column_Count);
+       -- Set the number of columns.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Start_Paragraph (Output_Object : in out Corr_Output_Type;
+                              Style     : in ARM_Output.Paragraph_Style_Type;
+                              Indent    : in ARM_Output.Paragraph_Indent_Type;
+                              Number    : in String;
+                              No_Prefix : in Boolean := False;
+                              Tab_Stops : in ARM_Output.Tab_Info := 
ARM_Output.NO_TABS;
+                              No_Breaks : in Boolean := False;
+                              Keep_with_Next : in Boolean := False;
+                              Space_After : in ARM_Output.Space_After_Type
+                                  := ARM_Output.Normal;
+                              Justification : in ARM_Output.Justification_Type
+                                  := ARM_Output.Default);
+       -- Start a new paragraph. The style and indent of the paragraph is as
+       -- specified. The (AA)RM paragraph number (which might include update
+       -- and version numbers as well: [12.1/1]) is Number. If the format is
+       -- a type with a prefix (bullets, hangining items), the prefix is
+       -- omitted if No_Prefix is true. Tab_Stops defines the tab stops for
+       -- the paragraph. If No_Breaks is True, we will try to avoid page breaks
+       -- in the paragraph. If Keep_with_Next is true, we will try to avoid
+       -- separating this paragraph and the next one. (These may have no
+       -- effect in formats that don't have page breaks). Space_After
+       -- specifies the amount of space following the paragraph. Justification
+       -- specifies the text justification for the paragraph. Not_Valid_Error
+       -- is raised if Tab_Stops /= NO_TABS for a hanging or bulleted format.
+
+    procedure End_Paragraph (Output_Object : in out Corr_Output_Type);
+       -- End a paragraph.
+
+    procedure Category_Header (Output_Object : in out Corr_Output_Type;
+                              Header_Text : String);
+       -- Output a Category header (that is, "Legality Rules",
+       -- "Dynamic Semantics", etc.)
+       -- (Note: We did not use a enumeration here to insure that these
+       -- headers are spelled the same in all output versions).
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Clause_Header (Output_Object     : in out Corr_Output_Type;
+                            Header_Text       : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False);
+       -- Output a Clause header. The level of the header is specified
+       -- in Level. The Clause Number is as specified; the top-level (and
+       -- other) subdivision names are as specified. These should appear in
+       -- the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Revised_Clause_Header
+                           (Output_Object     : in out Corr_Output_Type;
+                            New_Header_Text   : in String;
+                            Old_Header_Text   : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Version           : in 
ARM_Contents.Change_Version_Type;
+                            Old_Version       : in 
ARM_Contents.Change_Version_Type;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False);
+       -- Output a revised clause header. Both the original and new text will
+       -- be output. The level of the header is specified in Level. The Clause
+       -- Number is as specified; the top-level (and other) subdivision names
+       -- are as specified. These should appear in the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- Version is the insertion version of the new text; Old_Version is
+       -- the insertion version of the old text.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure TOC_Marker (Output_Object : in out Corr_Output_Type;
+                         For_Start : in Boolean);
+       -- Mark the start (if For_Start is True) or end (if For_Start is
+       -- False) of the table of contents data. Output objects that
+       -- auto-generate the table of contents can use this to do needed
+       -- actions.
+
+    procedure New_Page (Output_Object : in out Corr_Output_Type;
+                       Kind : ARM_Output.Page_Kind_Type := 
ARM_Output.Any_Page);
+       -- Output a page break.
+       -- Note that this has no effect on non-printing formats.
+       -- Any_Page breaks to the top of the next page (whatever it is);
+       -- Odd_Page_Only breaks to the top of the odd-numbered page;
+       -- Soft_Page allows a page break but does not force one (use in
+       -- "No_Breaks" paragraphs.)
+       -- Raises Not_Valid_Error if in a paragraph if Kind = Any_Page or
+       -- Odd_Page, and if not in a paragraph if Kind = Soft_Page.
+
+    procedure New_Column (Output_Object : in out Corr_Output_Type);
+       -- Output a column break.
+       -- Raises Not_Valid_Error if in a paragraph, or if the number of
+       -- columns is 1.
+
+    procedure Separator_Line (Output_Object : in out Corr_Output_Type;
+                             Is_Thin : Boolean := True);
+       -- Output a separator line. It is thin if "Is_Thin" is true.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Start_Table (Output_Object : in out Corr_Output_Type;
+                          Columns : in ARM_Output.Column_Count;
+                          First_Column_Width : in ARM_Output.Column_Count;
+                          Last_Column_Width : in ARM_Output.Column_Count;
+                          Alignment : in ARM_Output.Column_Text_Alignment;
+                          No_Page_Break : in Boolean;
+                          Has_Border : in Boolean;
+                          Small_Text_Size : in Boolean;
+                          Header_Kind : in ARM_Output.Header_Kind_Type);
+       -- Starts a table. The number of columns is Columns; the first
+       -- column has First_Column_Width times the normal column width, and
+       -- the last column has Last_Column_Width times the normal column width.
+       -- Alignment is the horizontal text alignment within the columns.
+       -- No_Page_Break should be True to keep the table intact on a single
+       -- page; False to allow it to be split across pages.
+       -- Has_Border should be true if a border is desired, false otherwise.
+       -- Small_Text_Size means that the contents will have the AARM size;
+       -- otherwise it will have the normal size.
+       -- Header_Kind determines whether the table has headers.
+       -- This command starts a paragraph; the entire table is a single
+       -- paragraph. Text will be considered part of the caption until the
+       -- next table marker call.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Table_Marker (Output_Object : in out Corr_Output_Type;
+                           Marker : in ARM_Output.Table_Marker_Type);
+       -- Marks the end of an entity in a table.
+       -- If Marker is End_Caption, the table caption ends and the
+       --      future text is part of the table header.
+       -- If Marker is End_Header, the table header ends and the
+       --      future text is part of the table body.
+       -- If Marker is End_Row, a row in the table is completed, and another
+       --      row started.
+       -- If Marker is End_Item, an item in the table header or body is ended,
+       --      and another started.
+       -- If Marker is End_Table, the entire table is finished.
+       -- Raises Not_Valid_Error if not in a table.
+
+    -- Text output: These are only allowed after a Start_Paragraph and
+    -- before any End_Paragraph. Raises Not_Valid_Error if not allowed.
+
+    procedure Ordinary_Text (Output_Object : in out Corr_Output_Type;
+                            Text : in String);
+       -- Output ordinary text.
+       -- The text must end at a word break, never in the middle of a word.
+
+    procedure Ordinary_Character (Output_Object : in out Corr_Output_Type;
+                                 Char : in Character);
+       -- Output an ordinary character.
+       -- Spaces will be used to break lines as needed.
+
+    procedure Hard_Space (Output_Object : in out Corr_Output_Type);
+       -- Output a hard space. No line break should happen at a hard space.
+
+    procedure Line_Break (Output_Object : in out Corr_Output_Type);
+       -- Output a line break. This does not start a new paragraph.
+       -- This corresponds to a "<BR>" in HTML.
+
+    procedure Index_Line_Break (Output_Object : in out Corr_Output_Type;
+                               Clear_Keep_with_Next : in Boolean);
+       -- Output a line break for the index. This does not start a new
+       -- paragraph in terms of spacing. This corresponds to a "<BR>"
+       -- in HTML. If Clear_Keep_with_Next is true, insure that the next
+       -- line does not require the following line to stay with it.
+
+    procedure Soft_Line_Break (Output_Object : in out Corr_Output_Type);
+       -- Output a soft line break. This is a place (in the middle of a
+       -- "word") that we allow a line break. It is usually used after
+       -- underscores in long non-terminals.
+
+    procedure Soft_Hyphen_Break (Output_Object : in out Corr_Output_Type);
+       -- Output a soft line break, with a hyphen. This is a place (in the 
middle of
+       -- a "word") that we allow a line break. If the line break is used,
+       -- a hyphen will be added to the text.
+
+    procedure Tab (Output_Object : in out Corr_Output_Type);
+       -- Output a tab, inserting space up to the next tab stop.
+       -- Raises Not_Valid_Error if the paragraph was created with
+       -- Tab_Stops = ARM_Output.NO_TABS.
+
+    procedure Special_Character (Output_Object : in out Corr_Output_Type;
+                                Char : in ARM_Output.Special_Character_Type);
+       -- Output an special character.
+
+    procedure Unicode_Character (Output_Object : in out Corr_Output_Type;
+                                Char : in ARM_Output.Unicode_Type);
+       -- Output a Unicode character, with code position Char.
+
+    procedure End_Hang_Item (Output_Object : in out Corr_Output_Type);
+       -- Marks the end of a hanging item. Call only once per paragraph.
+       -- Raises Not_Valid_Error if the paragraph style is not in
+       -- Text_Prefixed_Style_Subtype, or if this has already been
+       -- called for the current paragraph, or if the paragraph was started
+       -- with No_Prefix = True.
+
+    procedure Text_Format (Output_Object : in out Corr_Output_Type;
+                          Format : in ARM_Output.Format_Type);
+       -- Change the text format so that all of the properties are as 
specified.
+       -- Note: Changes to these properties ought be stack-like; that is,
+       -- Bold on, Italic on, Italic off, Bold off is OK; Bold on, Italic on,
+       -- Bold off, Italic off should be avoided (as separate commands).
+
+    procedure Clause_Reference (Output_Object : in out Corr_Output_Type;
+                               Text : in String;
+                               Clause_Number : in String);
+       -- Generate a reference to a clause in the standard. The text of
+       -- the reference is "Text", and the number of the clause is
+       -- Clause_Number. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure Index_Target (Output_Object : in out Corr_Output_Type;
+                           Index_Key : in Natural);
+       -- Generate a index target. This marks the location where an index
+       -- reference occurs. Index_Key names the index item involved.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, nothing is generated.
+
+    procedure Index_Reference (Output_Object : in out Corr_Output_Type;
+                              Text : in String;
+                              Index_Key : in Natural;
+                              Clause_Number : in String);
+       -- Generate a reference to an index target in the standard. The text
+       -- of the reference is "Text", and Index_Key and Clause_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure DR_Reference (Output_Object : in out Corr_Output_Type;
+                           Text : in String;
+                           DR_Number : in String);
+       -- Generate a reference to an DR from the standard. The text
+       -- of the reference is "Text", and DR_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure AI_Reference (Output_Object : in out Corr_Output_Type;
+                           Text : in String;
+                           AI_Number : in String);
+       -- Generate a reference to an AI from the standard. The text
+       -- of the reference is "Text", and AI_Number denotes
+       -- the target (in unfolded format). For hyperlinked formats, this should
+       -- generate a link; for other formats, the text alone is generated.
+
+    procedure Local_Target (Output_Object : in out Corr_Output_Type;
+                           Text : in String;
+                           Target : in String);
+       -- Generate a local target. This marks the potential target of local
+       -- links identified by "Target". Text is the text of the target.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link (Output_Object : in out Corr_Output_Type;
+                         Text : in String;
+                         Target : in String;
+                         Clause_Number : in String);
+       -- Generate a local link to the target and clause given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link_Start (Output_Object : in out Corr_Output_Type;
+                               Target : in String;
+                               Clause_Number : in String);
+       -- Generate a local link to the target and clause given.
+       -- The link will surround text until Local_Link_End is called.
+       -- Local_Link_End must be called before this routine can be used again.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link_End (Output_Object : in out Corr_Output_Type;
+                             Target : in String;
+                             Clause_Number : in String);
+       -- End a local link for the target and clause given.
+       -- This must be in the same paragraph as the Local_Link_Start.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure URL_Link (Output_Object : in out Corr_Output_Type;
+                       Text : in String;
+                       URL : in String);
+       -- Generate a link to the URL given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Picture  (Output_Object : in out Corr_Output_Type;
+                       Name  : in String;
+                       Descr : in String;
+                       Alignment : in ARM_Output.Picture_Alignment;
+                       Height, Width : in Natural;
+                       Border : in ARM_Output.Border_Kind);
+       -- Generate a picture.
+       -- Name is the (simple) file name of the picture; Descr is a
+       -- descriptive name for the picture (it will appear in some web
+       -- browsers).
+       -- We assume that it is a .GIF or .JPG and that it will be present
+       -- in the same directory as the output files.
+       -- Alignment specifies the picture alignment.
+       -- Height and Width specify the picture size in pixels.
+       -- Border specifies the kind of border.
+
+private
+
+    subtype Buffer_String is String (1 .. 120);
+    subtype Prefix_String is String(1..5);
+    subtype Clause_String is String(1..20);
+    type Corr_Output_Type is new ARM_Output.Output_Type with record
+       Is_Valid : Boolean := False;
+       Is_In_Paragraph : Boolean := False;
+       Is_In_Table : Boolean := False; -- Are we processing a table?
+       Is_Hanging : Boolean := False; -- If we are in a paragraph,
+                                      -- is it a hanging paragraph?
+       Saw_Hang_End : Boolean := False; -- If we are in a hanging paragraph,
+                                      -- have we seen the end of the hanging 
part yet?
+       Output_Buffer : Buffer_String;  -- Output buffer to make smarter breaks.
+       Output_Buffer_Len : Natural := 0; -- This should be empty between 
paragraphs.
+                       -- The idea is that the buffer is always logically
+                       -- preceeded by a space. Thus it is always OK to
+                       -- move the text in the buffer to the next line.
+       Output_Buffer_Space_Before : Boolean := False;
+                       -- Do we need to output a space before the buffer?
+       Output_File : Ada.Text_IO.File_Type;
+       Output_Path : Buffer_String;
+       Output_Path_Len : Natural := 0;
+       File_Prefix : Prefix_String; -- Blank padded.
+       Char_Count : Natural := 0; -- Characters on current line.
+       Out_Char_Count : Natural := 0; -- Characters output on current line.
+       Indent_Amount : Natural := 0; -- Amount to indent paragraphs.
+       Para_Style : ARM_Output.Paragraph_Style_Type := ARM_Output.Normal;
+       Para_Indent : ARM_Output.Paragraph_Indent_Type := 0; -- Specified 
indent.
+       Is_Fixed_Format : Boolean; -- Is the text currently in a fixed format? 
(@Xcode)
+       Is_Bold : Boolean; -- Is the text currently bold?
+       Is_Italic : Boolean; -- Is the text current italics?
+       Font : ARM_Output.Font_Family_Type; -- What is the current font family?
+       Size : ARM_Output.Size_Type; -- What is the current relative size?
+       Change : ARM_Output.Change_Type := ARM_Output.None;
+       Location : ARM_Output.Location_Type := ARM_Output.Normal;
+       Tab_Stops : ARM_Output.Tab_Info := ARM_Output.NO_TABS;
+       Clause_Num : Clause_String; -- The number of the current clause
+       Clause_Len : Natural := 0;
+    end record;
+
+end ARM_Corr;
diff --git a/packages/ada-ref-man/progs/arm_db.adb 
b/packages/ada-ref-man/progs/arm_db.adb
new file mode 100755
index 0000000..502e6c5
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_db.adb
@@ -0,0 +1,327 @@
+--  with Ada.Text_IO; -- Debug.
+with Ada.Unchecked_Deallocation,
+     Ada.Strings.Fixed,
+     Ada.Characters.Handling;
+package body ARM_Database is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the database to store items for non-normative
+    -- appendixes.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2004, 2005, 2006, 2009, 2011, 2012
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/16/00 - RLB - Created package.
+    --  8/28/00 - RLB - Added revision info to database.
+    -- 10/28/04 - RLB - Added Inserted_Normal_Number change kind.
+    -- 11/02/04 - RLB - Added Deleted_Inserted_Number change kind.
+    -- 12/06/04 - RLB - Added Revised_Inserted_Number change kind.
+    -- 12/14/04 - RLB - Made the hang item bigger.
+    --  1/19/05 - RLB - Added Added_Version.
+    -- 10/17/05 - RLB - Fixed indexing of the Glossary.
+    -- 10/18/06 - RLB - Added No_Deleted_Paragraph_Messages to Report.
+    -- 11/30/09 - RLB - Made the hang item bigger again (to make room to
+    --                 handle commands like @ChgAdded).
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/20/11 - RLB - Added Initial_Version parameter.
+    --  3/19/12 - RLB - Added code to suppress indexing of deleted glossary 
items.
+
+    type String_Ptr is access String;
+    type Item is record
+       Next : Item_List;
+       Sort_Key : String(1 .. 50);
+       Hang : String(1 .. 75);
+       Hang_Len : Natural;
+       Text : String_Ptr;
+       Change_Kind : Paragraph_Change_Kind_Type;
+       Version : Character;
+       Initial_Version : Character;
+    end record;
+
+    procedure Free is new Ada.Unchecked_Deallocation (Item, Item_List);
+    procedure Free is new Ada.Unchecked_Deallocation (String, String_Ptr);
+
+    procedure Create (Database_Object : in out Database_Type) is
+       -- Initialize a database object.
+    begin
+       Database_Object.Is_Valid := True;
+       Database_Object.List := null;
+       Database_Object.Item_Count := 0;
+    end Create;
+
+
+    procedure Destroy (Database_Object : in out Database_Type) is
+       -- Destroy a database object, freeing any resources used.
+       Temp : Item_List;
+    begin
+       if not Database_Object.Is_Valid then
+           raise Not_Valid_Error;
+       end if;
+       while Database_Object.List /= null loop
+           Temp := Database_Object.List;
+           Database_Object.List := Temp.Next;
+           Free (Temp.Text);
+           Free (Temp);
+       end loop;
+       Database_Object.Is_Valid := False;
+    end Destroy;
+
+
+    procedure Insert (Database_Object : in out Database_Type;
+                     Sort_Key : in String;
+                     Hang_Item : in String;
+                     Text : in String;
+                     Change_Kind : in Paragraph_Change_Kind_Type := 
ARM_Database.None;
+                     Version : in Character := '0';
+                     Initial_Version : in Character := '0') is
+       -- Insert an item into the database object.
+       -- Sort_Key is the string on which this item will be sorted (if it
+       -- is sorted). Hang_Item is the item which hangs out for the item
+       -- in the report (if any). Text is the text for the item; the text
+       -- may include formatting codes. Change_Kind and Version are the
+       -- revision status for this item. Initial_Version is the version of
+       -- the initial text for this item.
+       Temp_Item : Item;
+    begin
+       if not Database_Object.Is_Valid then
+           raise Not_Valid_Error;
+       end if;
+       Ada.Strings.Fixed.Move (Target => Temp_Item.Sort_Key,
+                               Source => 
Ada.Characters.Handling.To_Lower(Sort_Key),
+                               Drop   => Ada.Strings.Right,
+                               Pad    => ' ');
+       Ada.Strings.Fixed.Move (Target => Temp_Item.Hang,
+                               Source => Hang_Item,
+                               Drop   => Ada.Strings.Error,
+                               Pad    => ' ');
+       Temp_Item.Hang_Len := Hang_Item'Length;
+           -- Note: If this second item doesn't fit, we error so we can make
+           -- the size larger.
+       Temp_Item.Text := new String'(Text);
+       Temp_Item.Change_Kind := Change_Kind;
+       Temp_Item.Version := Version;
+       Temp_Item.Initial_Version := Initial_Version;
+       Temp_Item.Next := Database_Object.List;
+        Database_Object.List := new Item'(Temp_Item);
+       Database_Object.Item_Count := Database_Object.Item_Count + 1;
+    end Insert;
+
+
+    --generic
+    -- with procedure Format_Text (Text : in String;
+    --                             Text_Name : in String);
+    procedure Report (Database_Object : in out Database_Type;
+                     In_Format : in Format_Type;
+                     Sorted : in Boolean;
+                     Added_Version : Character := '0';
+                     No_Deleted_Paragraph_Messages : in Boolean := False) is
+       -- Output the items with the appropriate format to the
+       -- "Format_Text" routine. "Format_Text" allows all commands
+       -- for the full formatter. (Text_Name is an identifying name
+       -- for error messages). This is an added list for Added_Version
+       -- ('0' meaning it is not added); in that case, use normal numbers
+       -- for items with a version less than or equal to Added_Version.
+       -- (This is intended to be used to output the items to
+       -- appropriate Format and Output objects; but we can't do that
+       -- directly because that would make this unit recursive with
+       -- ARM_Format.
+       -- No paragraphs will be have deleted paragraph messages if
+       -- No_Deleted_Paragraph_Messages is True.
+       Temp : Item_List;
+
+       function Change_if_Needed (Item : in Item_List) return String is
+       begin
+           -- Note: In the report, we always decide inserted/not inserted
+           -- as determined by the initial version number, and not the
+           -- original class.
+           case Item.Change_Kind is
+               when None => return "";
+               when Inserted | Inserted_Normal_Number =>
+                   if Item.Initial_Version <= Added_Version then
+                       return "@ChgRef{Version=[" & Item.Version &
+                           "],Kind=[AddedNormal]}";
+                   else
+                       return "@ChgRef{Version=[" & Item.Version &
+                           "],Kind=[Added]}";
+                   end if;
+               when Revised | Revised_Inserted_Number =>
+                   if Item.Initial_Version <= Added_Version then
+                       return "@ChgRef{Version=[" & Item.Version &
+                           "],Kind=[Revised]}";
+                   else
+                       return "@ChgRef{Version=[" & Item.Version &
+                           "],Kind=[RevisedAdded]}";
+                   end if;
+               when Deleted | Deleted_Inserted_Number =>
+                   if Item.Initial_Version <= Added_Version then
+                       if No_Deleted_Paragraph_Messages then
+                           return "@ChgRef{Version=[" & Item.Version &
+                               "],Kind=[DeletedNoDelMsg]}";
+                       else
+                           return "@ChgRef{Version=[" & Item.Version &
+                               "],Kind=[Deleted]}";
+                       end if;
+                   else
+                       if No_Deleted_Paragraph_Messages then
+                           return "@ChgRef{Version=[" & Item.Version &
+                               "],Kind=[DeletedAddedNoDelMsg]}";
+                       else
+                           return "@ChgRef{Version=[" & Item.Version &
+                               "],Kind=[DeletedAdded]}";
+                       end if;
+                   end if;
+               when Deleted_No_Delete_Message |
+                    Deleted_Inserted_Number_No_Delete_Message =>
+                   if Item.Initial_Version <= Added_Version then
+                       return "@ChgRef{Version=[" & Item.Version &
+                           "],Kind=[DeletedNoDelMsg]}";
+                   else
+                       return "@ChgRef{Version=[" & Item.Version &
+                           "],Kind=[DeletedAddedNoDelMsg]}";
+                   end if;
+           end case;
+       end Change_if_Needed;
+
+    begin
+       if not Database_Object.Is_Valid then
+           raise Not_Valid_Error;
+       end if;
+       if Sorted then
+           declare
+               Items : array (1..Database_Object.Item_Count) of Item_List;
+           begin
+               -- Load the items:
+               Temp := Database_Object.List;
+               for I in Items'range loop
+                   Items(I) := Temp;
+                   Temp := Temp.Next;
+               end loop;
+
+               -- Sort the items array (use an insertion sort because it is
+               -- stable):
+               declare
+                   Left : Natural;  -- Left sorting stop
+               begin
+                   for Right In Items'First+1 .. Items'Last loop -- Right 
sorting stop
+                       Temp := Items(Right);
+                       Left := Right - 1;
+                       while Temp.Sort_Key <= Items(Left).Sort_Key loop -- 
Switch items
+                           Items(Left + 1) := Items(Left);
+                           Left := Left - 1;
+                           exit when Left = 0;
+                       end loop;
+                       Items(Left + 1) := Temp;
+                   end loop;
+               end;
+
+               -- Relink the items in the sorted order:
+               for I in Items'First .. Items'Last - 1 loop
+                   Items(I).Next := Items(I+1);
+               end loop;
+               if Items'Length > 0 then
+                   Items(Items'Last).Next := null;
+                   Database_Object.List := Items(1);
+               else
+                   Database_Object.List := null;
+               end if;
+           end;
+       end if;
+       case In_Format is
+           when Hanging_List =>
+               Format_Text ("@begin(description)" & Ascii.LF, "Prefix");
+               Temp := Database_Object.List;
+               while Temp /= null loop
+--** Debug:
+--Ada.Text_IO.Put_Line ("^^ " & 
Paragraph_Change_Kind_Type'Image(Temp.Change_Kind) &
+--   " for " & Temp.Hang(1..Temp.Hang_Len) & " ref=" & Change_if_Needed 
(Temp));
+--Ada.Text_IO.Put_Line ("   " & Change_if_Needed (Temp) &
+--Temp.Hang(1..Temp.Hang_Len) & "@\" &
+--Temp.Text.all & Ascii.LF & Ascii.LF);
+                   Format_Text (Change_if_Needed (Temp) &
+                       Temp.Hang(1..Temp.Hang_Len) & "@\" &
+                       Temp.Text.all & Ascii.LF & Ascii.LF, Temp.Sort_Key);
+                   Temp := Temp.Next;
+               end loop;
+               Format_Text ("@end(description)" & Ascii.LF, "Suffix");
+           when Bullet_List =>
+               Format_Text ("@begin(itemize)" & Ascii.LF, "Prefix");
+               Temp := Database_Object.List;
+               while Temp /= null loop
+                   Format_Text (Change_if_Needed (Temp) &
+                                Temp.Text.all & Ascii.LF & Ascii.LF, 
Temp.Sort_Key);
+                   Temp := Temp.Next;
+               end loop;
+               Format_Text ("@end(itemize)" & Ascii.LF, "Suffix");
+           when Normal_List =>
+               Format_Text ("@begin(intro)" & Ascii.LF, "Prefix");
+               Temp := Database_Object.List;
+               while Temp /= null loop
+                   Format_Text (Change_if_Needed (Temp) &
+                                Temp.Text.all & Ascii.LF & Ascii.LF, 
Temp.Sort_Key);
+                   Temp := Temp.Next;
+               end loop;
+               Format_Text ("@end(intro)" & Ascii.LF, "Suffix");
+           when Normal_Indexed_List =>
+               Format_Text ("@begin(intro)" & Ascii.LF, "Prefix");
+               Temp := Database_Object.List;
+               while Temp /= null loop
+                   case Temp.Change_Kind is
+                       when None |
+                            Inserted | Inserted_Normal_Number |
+                            Revised | Revised_Inserted_Number =>
+--** Debug:
+--Ada.Text_IO.Put_Line("Format " & Change_if_Needed (Temp) &
+--                     "@defn{" & Ada.Strings.Fixed.Trim (Temp.Sort_Key, 
Ada.Strings.Right) & "}" & Ascii.LF &
+--                     Temp.Text.all);
+                           -- Index this item.
+                           Format_Text (Change_if_Needed (Temp) &
+                               "@defn{" & Ada.Strings.Fixed.Trim 
(Temp.Sort_Key, Ada.Strings.Right) & "}" & Ascii.LF &
+                               Temp.Text.all & Ascii.LF & Ascii.LF, 
Temp.Sort_Key);
+                       when Deleted | Deleted_Inserted_Number |
+                            Deleted_No_Delete_Message |
+                            Deleted_Inserted_Number_No_Delete_Message =>
+--** Debug:
+--Ada.Text_IO.Put_Line("Format " & Change_if_Needed (Temp) & Ascii.LF &
+--                     Temp.Text.all);
+                           -- Don't index deleted items.
+                           Format_Text (Change_if_Needed (Temp) & Ascii.LF &
+                               Temp.Text.all & Ascii.LF & Ascii.LF, 
Temp.Sort_Key);
+                   end case;
+                   Temp := Temp.Next;
+               end loop;
+               Format_Text ("@end(intro)" & Ascii.LF, "Suffix");
+       end case;
+    end Report;
+
+end ARM_Database;
+
+
diff --git a/packages/ada-ref-man/progs/arm_db.ads 
b/packages/ada-ref-man/progs/arm_db.ads
new file mode 100755
index 0000000..4adf04b
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_db.ads
@@ -0,0 +1,118 @@
+package ARM_Database is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the database to store items for non-normative
+    -- appendixes.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2004, 2005, 2006, 2011
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/16/00 - RLB - Created package.
+    --  8/10/00 - RLB - Added Normal_Indexed_List to fix glossary problems.
+    --  8/28/00 - RLB - Added revision info to database.
+    -- 10/28/04 - RLB - Added Inserted_Normal_Number change kind.
+    -- 11/02/04 - RLB - Added Deleted_Inserted_Number change kind.
+    -- 12/06/04 - RLB - Added Revised_Inserted_Number change kind.
+    --  1/19/05 - RLB - Added Added_Version.
+    --  2/15/06 - RLB - Added Deleted_No_Delete_Message and
+    --                 Deleted_Inserted_Number_No_Delete_Message change kinds.
+    -- 10/18/06 - RLB - Added No_Deleted_Paragraph_Messages to Report.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/20/11 - RLB - Added Initial_Version parameter.
+
+    type Database_Type is tagged limited private;
+
+    type Paragraph_Change_Kind_Type is (None, Inserted, Inserted_Normal_Number,
+       Deleted, Deleted_Inserted_Number,
+       Deleted_No_Delete_Message,
+       Deleted_Inserted_Number_No_Delete_Message,
+       Revised, Revised_Inserted_Number);
+
+    Not_Valid_Error : exception;
+
+    procedure Create (Database_Object : in out Database_Type);
+       -- Initialize a database object.
+
+    procedure Destroy (Database_Object : in out Database_Type);
+       -- Destroy a database object, freeing any resources used.
+
+    procedure Insert (Database_Object : in out Database_Type;
+                     Sort_Key : in String;
+                     Hang_Item : in String;
+                     Text : in String;
+                     Change_Kind : in Paragraph_Change_Kind_Type := 
ARM_Database.None;
+                     Version : in Character := '0';
+                     Initial_Version : in Character := '0');
+       -- Insert an item into the database object.
+       -- Sort_Key is the string on which this item will be sorted (if it
+       -- is sorted). Hang_Item is the item which hangs out for the item
+       -- in the report (if any). Text is the text for the item; the text
+       -- may include formatting codes. Change_Kind and Version are the
+       -- revision status for this item. Initial_Version is the version of
+       -- the initial text for this item.
+
+    type Format_Type is
+       (Normal_List, Normal_Indexed_List, Bullet_List, Hanging_List);
+
+    generic
+       with procedure Format_Text (Text : in String;
+                                   Text_Name : in String);
+    procedure Report (Database_Object : in out Database_Type;
+                     In_Format : in Format_Type;
+                     Sorted : in Boolean;
+                     Added_Version : Character := '0';
+                     No_Deleted_Paragraph_Messages : in Boolean := False);
+       -- Output the items with the appropriate format to the
+       -- "Format_Text" routine. "Format_Text" allows all commands
+       -- for the full formatter. (Text_Name is an identifying name
+       -- for error messages). This is an added list for Added_Version
+       -- ('0' meaning it is not added); in that case, use normal numbers
+       -- for items with a version less than or equal to Added_Version.
+       -- (This is intended to be used to output the items to
+       -- appropriate Format and Output objects; but we can't do that
+       -- directly because that would make this unit recursive with
+       -- ARM_Format.
+       -- No paragraphs will be have deleted paragraph messages if
+       -- No_Deleted_Paragraph_Messages is True.
+private
+
+    type Item;
+    type Item_List is access all Item;
+    type Database_Type is tagged limited record
+       Is_Valid : Boolean := False;
+       List : Item_List;
+       Item_Count : Natural;
+    end record;
+
+end ARM_Database;
+
+
diff --git a/packages/ada-ref-man/progs/arm_file.adb 
b/packages/ada-ref-man/progs/arm_file.adb
new file mode 100755
index 0000000..8e0d971
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_file.adb
@@ -0,0 +1,186 @@
+--with ARM_Input,
+--     Ada.Text_IO;
+package body ARM_File is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the definition of reading an input file.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2011
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53704
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/15/00 - RLB - Created package.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+
+    procedure Open (Input_Object : in out File_Input_Type;
+                   File_Name : in String) is
+       -- Open an input object for a file.
+       -- This may propagate file exceptions.
+    begin
+        Ada.Text_IO.Open (Input_Object.Fyle, Ada.Text_IO.In_File, File_Name);
+        Input_Object.Line_Counter := 0;
+        Input_Object.Buffer_Last := 0;
+        Input_Object.Buffer_Index := 0;
+        Input_Object.Is_Valid := True;
+       if File_Name'Length > Input_Object.Name'Length then
+           Input_Object.Name := File_Name(File_Name'First .. File_Name'First + 
Input_Object.Name'Length - 1);
+           Input_Object.Name_Len := Input_Object.Name'Length;
+       else
+           Input_Object.Name(1..File_Name'Length) := File_Name;
+           Input_Object.Name_Len := File_Name'Length;
+       end if;
+    end Open;
+
+
+    procedure Close (Input_Object : in out File_Input_Type) is
+       -- Close the input object (entity).
+       -- May propagate exceptions from the underlying implementation
+       -- (that is, I/O exceptions).
+    begin
+       if not Input_Object.Is_Valid then
+           raise ARM_Input.Not_Valid_Error;
+       end if;
+       Input_Object.Is_Valid := False;
+        Ada.Text_IO.Close (Input_Object.Fyle);
+    end Close;
+
+
+    procedure Get_Char (Input_Object : in out File_Input_Type;
+                       Char : out Character) is
+        -- We represent end of line by Ascii.LF.
+        -- Raises: End_Error when the end of file is reached.
+       --         Not_Valid_Error if Input_Object is not valid (open).
+    begin
+       if not Input_Object.Is_Valid then
+           raise ARM_Input.Not_Valid_Error;
+       end if;
+        if Input_Object.Buffer_Index >= Input_Object.Buffer_Last then
+           begin
+               Ada.Text_IO.Get_Line (Input_Object.Fyle,
+                                     Input_Object.Buffer,
+                                     Input_Object.Buffer_Last);
+                   -- Raises End_Error when the end of the file is reached.
+           exception
+               when Ada.Text_IO.End_Error =>
+                   -- Set so we can do a Replace_Char on this.
+                   Input_Object.Buffer_Index := 1;
+                   Input_Object.Buffer_Last := 1;
+                   Input_Object.Buffer(1) := Ascii.SUB; -- File end marker.
+                   Char := Ascii.SUB;
+                   return;
+           end;
+           if Input_Object.Buffer_Last < Input_Object.Buffer'Last then
+               Input_Object.Buffer_Last := Input_Object.Buffer_Last + 1;
+               Input_Object.Buffer(Input_Object.Buffer_Last) := Ascii.LF; -- 
Line end marker.
+           -- else broken line, no end needed.
+           end if;
+           --Ada.Text_IO.Put(Natural'Image(Input_Object.Line_Counter) & ":");
+           --Ada.Text_IO.Put_Line ("&& " & 
Input_Object.Buffer(1..Input_Object.Buffer_Last));
+           Input_Object.Buffer_Index := 0;
+           Input_Object.Line_Counter := Input_Object.Line_Counter + 1;
+        end if;
+        Input_Object.Buffer_Index := Input_Object.Buffer_Index + 1;
+        if Input_Object.Recording then
+           Input_Object.Recording_Len := Input_Object.Recording_Len + 1;
+           Input_Object.Recording_Buffer(Input_Object.Recording_Len) :=
+               Input_Object.Buffer(Input_Object.Buffer_Index);
+        end if;
+        Char := Input_Object.Buffer(Input_Object.Buffer_Index);
+    end Get_Char;
+
+
+    procedure Replace_Char (Input_Object : in out File_Input_Type) is
+       -- Replaces the last character read (with Get_Char); the next call
+       -- to Get_Char will return it.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+    begin
+       if not Input_Object.Is_Valid then
+           raise ARM_Input.Not_Valid_Error;
+       end if;
+        if Input_Object.Buffer_Index = 0 then
+           raise Program_Error; -- Called twice or before any calls to 
Get_Char.
+        end if;
+        Input_Object.Buffer_Index := Input_Object.Buffer_Index - 1;
+        if Input_Object.Recording then
+           Input_Object.Recording_Len := Input_Object.Recording_Len - 1;
+        end if;
+    end Replace_Char;
+
+
+    function Line_String (Input_Object : in File_Input_Type) return String is
+        -- Returns a string representing the line number and entity.
+       -- Usually used in error messages.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+    begin
+       if not Input_Object.Is_Valid then
+           raise ARM_Input.Not_Valid_Error;
+       end if;
+        return Natural'Image(Input_Object.Line_Counter) & " - " &
+               Input_Object.Name(1..Input_Object.Name_Len);
+    end Line_String;
+
+
+    procedure Start_Recording (Input_Object : in out File_Input_Type) is
+        -- Start recording all characters read into a local buffer.
+        -- Use this when text needs to be formatted into the output
+        -- file *and* be saved for future use.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+    begin
+       if not Input_Object.Is_Valid then
+           raise ARM_Input.Not_Valid_Error;
+       end if;
+        Input_Object.Recording := True;
+        Input_Object.Recording_Len := 0;
+    end Start_Recording;
+
+
+    procedure Stop_Recording_and_Read_Result
+        (Input_Object : in out File_Input_Type; Result : out String;
+        Len : out Natural) is
+        -- Stop recording characters read. Put the result into Result,
+        -- and the number of characters written into Len.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+    begin
+       if not Input_Object.Is_Valid then
+           raise ARM_Input.Not_Valid_Error;
+       end if;
+        if Input_Object.Recording_Len > Result'Length then
+           Ada.Text_IO.Put_Line ("  ** Too many characters recorded on line " 
& Line_String (Input_Object));
+           Len := 0;
+        else
+           Result (Result'First .. Result'First + Input_Object.Recording_Len - 
1) :=
+                Input_Object.Recording_Buffer (1 .. 
Input_Object.Recording_Len);
+           Len := Input_Object.Recording_Len;
+        end if;
+        Input_Object.Recording := False;
+    end Stop_Recording_and_Read_Result;
+
+end ARM_File;
diff --git a/packages/ada-ref-man/progs/arm_file.ads 
b/packages/ada-ref-man/progs/arm_file.ads
new file mode 100755
index 0000000..d3e509f
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_file.ads
@@ -0,0 +1,100 @@
+with ARM_Input,
+     Ada.Text_IO;
+package ARM_File is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the definition of reading an input file.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2011
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53704
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/15/00 - RLB - Created package.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+
+    type File_Input_Type is new ARM_Input.Input_Type with private;
+
+    procedure Open (Input_Object : in out File_Input_Type;
+                   File_Name : in String);
+       -- Open an input object for a file.
+       -- This may propagate file exceptions.
+
+    procedure Close (Input_Object : in out File_Input_Type);
+       -- Close the input object (entity).
+       -- May propagate exceptions from the underlying implementation
+       -- (that is, I/O exceptions).
+
+    procedure Get_Char (Input_Object : in out File_Input_Type;
+                       Char : out Character);
+        -- We represent end of line by Ascii.LF.
+        -- Raises: End_Error when the end of file is reached.
+       --         Not_Valid_Error if Input_Object is not valid (open).
+
+    procedure Replace_Char (Input_Object : in out File_Input_Type);
+       -- Replaces the last character read (with Get_Char); the next call
+       -- to Get_Char will return it.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+
+    function Line_String (Input_Object : in File_Input_Type) return String;
+        -- Returns a string representing the line number and entity.
+       -- Usually used in error messages.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+
+    procedure Start_Recording (Input_Object : in out File_Input_Type);
+        -- Start recording all characters read into a local buffer.
+        -- Use this when text needs to be formatted into the output
+        -- file *and* be saved for future use.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+
+    procedure Stop_Recording_and_Read_Result
+        (Input_Object : in out File_Input_Type; Result : out String;
+        Len : out Natural);
+        -- Stop recording characters read. Put the result into Result,
+        -- and the number of characters written into Len.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+
+private
+    type File_Input_Type is new ARM_Input.Input_Type with record
+       Is_Valid : Boolean := False;
+       Fyle : Ada.Text_IO.File_Type;
+       Line_Counter : Natural := 0;
+       Buffer : String(1..250);
+       Buffer_Last : Natural := 0;
+       Buffer_Index : Natural := 0; -- Last character read from buffer.
+       -- For recording:
+       Recording : Boolean := False;
+       Recording_Buffer : String(1..ARM_Input.MAX_RECORDING_SIZE);
+       Recording_Len : Natural := 0;
+       -- Name:
+       Name : String(1..120);
+       Name_Len : Natural;
+    end record;
+end ARM_File;
diff --git a/packages/ada-ref-man/progs/arm_form.ada 
b/packages/ada-ref-man/progs/arm_form.ada
new file mode 100755
index 0000000..3606442
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_form.ada
@@ -0,0 +1,329 @@
+with Ada.Text_IO,
+     Ada.Strings.Fixed,
+     Ada.Strings.Unbounded,
+     Ada.Characters.Handling,
+     Ada.Command_Line;
+with ARM_Master,
+     ARM_Contents,
+     ARM_Format;
+procedure ARM_Formatter is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This is the main subprogram: format the sources for the
+    -- Ada reference manual and other documents
+    -- (in a vaguely Scribe-like macro language) into the actual
+    -- reference manual files (in various formats).
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2004, 2005, 2006, 2011, 2012, 2016
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  3/ 9/00 - RLB - Created base program.
+    --  4/14/00 - RLB - Created from analysis program.
+    --  4/18/00 - RLB - Added scanning pass.
+    --  4/19/00 - RLB - Split 03 into two files. Added HTML output object.
+    --  4/24/00 - RLB - Added Change_Kind and Display_Index_Entries.
+    --  5/15/00 - RLB - Split formatter from input.
+    --  5/16/00 - RLB - Added missing Destroy for formatting objects.
+    --  5/18/00 - RLB - Added RTF output object.
+    --  5/25/00 - RLB - Added the Big-Files option. Added the library 
separator.
+    --  5/28/00 - RLB - Added index.
+    --  8/31/00 - RLB - Added the New-Changes option.
+    --  7/18/02 - RLB - Changed copyright date.
+    --          - RLB - Changed Creates to include title and header.
+    --          - RLB - Added Version parameter to command line and formatting
+    --                  commands.
+    --  9/10/04 - RLB - Updated descriptions of standard commands.
+    --  9/14/04 - RLB - Moved version to ARM_Contents.
+    -- 12/05/04 - RLB - Split/added various source files.
+    --  6/ 2/05 - RLB - Added Corrigendum output module for comparisons to
+    --                  Amendment document.
+    -- 10/12/05 - RLB - Changed the title to reflect what we learned from ISO.
+    -- 10/28/05 - RLB - Added Annex Q.
+    --  1/ 5/06 - RLB - Revised to use master files, rather than hard-coded
+    --                  properties.
+    --  1/12/06 - RLB - Removed Document completely.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/19/11 - RLB - Removed junk withs (now in master file handler).
+    --  4/ 3/12 - RLB - Removed dead variable.
+    --  8/31/12 - RLB - Added output path parameter.
+    --  3/17/16 - RLB - Added lower version to command line.
+
+    -- Standard commands for Ada standards:
+    -- For Original (Ada 95) RM:
+    --     Arm_Form RM <Format> No-Changes 0 0
+    -- For Original AARM:
+    --     Arm_Form AARM <Format> No-Changes 0 0
+    -- For RM with Corr:
+    --     [With change bars for Word 97/2000:]
+    --     Arm_Form RM RTF New-Changes 1 1
+    --     [Final versions with no changes:]
+    --     Arm_Form RM <Format> New-Only 1 1
+    -- For AARM with Corr:
+    --     [HTML; RTF for display]:
+    --        Arm_Form AARM <Format> Show-Changes 1 1
+    --     [TXT; RTF for printing]:
+    --        Arm_Form AARM <Format> New-Only 1 1
+    -- For RM with Corr and Amd:
+    --     [With change bars for Word 97/2000:]
+    --     Arm_Form RM RTF New-Changes 1 2
+    --     [With change ballons for Word XP/2003:]
+    --     Arm_Form RM RTF Show-Changes 1 2
+    --     [Final versions with no changes:]
+    --     Arm_Form RM <Format> New-Only 1 2
+    -- For AARM with Corr and Amd:
+    --     [HTML; RTF for display]:
+    --        Arm_Form AARM <Format> Show-Changes 2 2
+    --        (for only Amd changes) or
+    --        Arm_Form AARM <Format> Show-Changes 1 2
+    --        (for all changes)
+    --     [TXT; RTF for printing]:
+    --        Arm_Form AARM <Format> New-Only 2 2
+    -- For Ada 2012 RM: (To include TC1, change 3 to 4).
+    --     [With change ballons for Word XP/2003:]
+    --     Arm_Form RM RTF Show-Changes 1 3
+    --     [For change bar version for Word 97/2000:]
+    --     Arm_Form RM RTF Show-Changes 3 3
+    --     [Final versions with no changes:]
+    --     Arm_Form RM <Format> New-Only 3 3
+    -- For Ada 2012 AARM: (To include TC1, change 3 to 4).
+    --     [HTML; RTF for display]:
+    --        Arm_Form AARM <Format> Show-Changes 3 3
+    --        (for only Amd 2012 changes) or
+    --        Arm_Form AARM <Format>  Show-Changes 1 3
+    --        (for all changes)
+    --     [TXT; RTF for printing]:
+    --        Arm_Form AARM <Format> New-Only 1 3
+    -- For Ada 202x RM:
+    --     [For change bar version:]
+    --     Arm_Form RM RTF Show-Changes 4 5
+    --     [Final versions with no changes:]
+    --     Arm_Form RM <Format> New-Only 5 5
+    -- For Ada 202x AARM with:
+    --     [HTML; RTF for display]:
+    --        Arm_Form AARM <Format> Show-Changes 4 5
+    --        (for only Amd 2012 changes) or
+    --        Arm_Form AARM <Format>  Show-Changes 1 5
+    --        (for all changes)
+    --     [TXT; RTF for printing]:
+    --        Arm_Form AARM <Format> New-Only 5 5
+
+
+    No_Command_Error : exception;
+
+    Format : ARM_Master.Output_Format_Type; -- Format to generate.
+    Master_File : Ada.Strings.Unbounded.Unbounded_String; -- Master file for 
document to generate.
+    Change_Kind : ARM_Format.Change_Kind; -- Changes to generate.
+    Base_Change_Version : ARM_Contents.Change_Version_Type; -- Lower Change 
version.
+    Change_Version : ARM_Contents.Change_Version_Type; -- (Upper) Change 
version.
+    Output_Path : Ada.Strings.Unbounded.Unbounded_String; -- Output path.
+
+    procedure Get_Commands is
+        -- Process the command line for this program.
+    begin
+        if Ada.Command_Line.Argument_Count not in 1 .. 6 then
+            Ada.Text_IO.Put_Line ("** Wrong number of arguments");
+            raise No_Command_Error;
+        end if;
+        if Ada.Command_Line.Argument_Count >= 6 then
+            Output_Path := Ada.Strings.Unbounded.To_Unbounded_String(
+                    Ada.Strings.Fixed.Trim (Ada.Command_Line.Argument(6),
+                       Ada.Strings.Right));
+            -- Check that the Output_Path ends with a path separator.
+            -- Note: This is a simple Windows check; it doesn't check for and
+            -- allow bare disk names. This check works on Linux but allows
+            -- ending with '\' which does not work on Linux (that will be
+            -- failed when the files are opened).
+            declare
+                Last : constant Character :=
+                    Ada.Strings.Unbounded.Element (Ada.Strings.Unbounded.Tail 
(Output_Path, 1), 1);
+            begin
+                if Last = '/' or else Last = '\' then
+                    null; -- OK; this ends with a path separator.
+                else
+                    Ada.Text_IO.Put_Line ("** Output path does not end with a 
path separator: " &
+                        Ada.Strings.Unbounded.To_String (Output_Path));
+                    raise No_Command_Error;
+                end if;
+            end;
+        else
+            Output_Path := Ada.Strings.Unbounded.To_Unbounded_String
+                ("./output/"); -- Use '/' so this works on Linux and Windows.
+        end if;
+        if Ada.Command_Line.Argument_Count >= 5 then
+            declare
+                Version_Arg : String :=
+                     Ada.Characters.Handling.To_Lower (
+                        Ada.Strings.Fixed.Trim (Ada.Command_Line.Argument(5),
+                        Ada.Strings.Right));
+            begin
+                if Version_Arg'Length = 1 and then
+                   Version_Arg(Version_Arg'First) in 
ARM_Contents.Change_Version_Type then
+                    Change_Version := Version_Arg(Version_Arg'First);
+                else
+                    Ada.Text_IO.Put_Line ("** Unrecognized change version: " & 
Version_Arg);
+                    raise No_Command_Error;
+                end if;
+            end;
+        else
+            Change_Version := '0';
+        end if;
+        if Ada.Command_Line.Argument_Count >= 4 then
+            declare
+                Version_Arg : String :=
+                     Ada.Characters.Handling.To_Lower (
+                        Ada.Strings.Fixed.Trim (Ada.Command_Line.Argument(4),
+                        Ada.Strings.Right));
+            begin
+                if Version_Arg'Length = 1 and then
+                   Version_Arg(Version_Arg'First) in 
ARM_Contents.Change_Version_Type then
+                    Base_Change_Version := Version_Arg(Version_Arg'First);
+                else
+                    Ada.Text_IO.Put_Line ("** Unrecognized change version: " & 
Version_Arg);
+                    raise No_Command_Error;
+                end if;
+            end;
+        else
+            Base_Change_Version := '0';
+        end if;
+        if Ada.Command_Line.Argument_Count >= 3 then
+            declare
+                Changes_Arg : String :=
+                     Ada.Characters.Handling.To_Lower (
+                        Ada.Strings.Fixed.Trim (Ada.Command_Line.Argument(3),
+                        Ada.Strings.Right));
+            begin
+                if Changes_Arg = "no-changes" then
+                    Change_Kind := ARM_Format.Old_Only;
+                elsif Changes_Arg = "new-only" then
+                    Change_Kind := ARM_Format.New_Only;
+                elsif Changes_Arg = "show-changes" then
+                    Change_Kind := ARM_Format.Show_Changes;
+                elsif Changes_Arg = "new-changes" then
+                    Change_Kind := ARM_Format.New_Changes;
+                else
+                    Ada.Text_IO.Put_Line ("** Unrecognized changes: " & 
Changes_Arg);
+                    raise No_Command_Error;
+                end if;
+            end;
+        else
+            Change_Kind := ARM_Format.New_Only;
+        end if;
+        if Ada.Command_Line.Argument_Count >= 2 then
+            declare
+                Format_Arg : String :=
+                     Ada.Characters.Handling.To_Lower (
+                        Ada.Strings.Fixed.Trim (Ada.Command_Line.Argument(2),
+                        Ada.Strings.Right));
+            begin
+                if Format_Arg = "rtf" then
+                    Format := ARM_Master.RTF;
+                elsif Format_Arg = "html" then
+                    Format := ARM_Master.HTML;
+                elsif Format_Arg = "text" then
+                    Format := ARM_Master.Text;
+                elsif Format_Arg = "corr" then
+                    Format := ARM_Master.Corr;
+                elsif Format_Arg = "info" then
+                    Format := ARM_Master.Info;
+                else
+                    Ada.Text_IO.Put_Line ("** Unrecognized format: " & 
Format_Arg);
+                    raise No_Command_Error;
+                end if;
+            end;
+        else
+            Format := ARM_Master.HTML;
+        end if;
+        declare
+            use type Ada.Strings.Unbounded.Unbounded_String;
+        begin
+            Master_File := Ada.Strings.Unbounded.To_Unbounded_String
+              (Ada.Characters.Handling.To_Lower
+                 (Ada.Strings.Fixed.Trim (Ada.Command_Line.Argument(1), 
Ada.Strings.Right)));
+            if Ada.Strings.Unbounded.Index (Master_File, ".") = 0 then
+                -- Add extension if it is missing.
+                Master_File := Master_File & ".msm";
+            end if;
+        end;
+    exception
+        when No_Command_Error =>
+            Ada.Text_IO.Put_Line ("  Usage: Arm_Form <Master_File> [<Format>[ 
<Changes>[ <BaseVers>[ <ChgVers>[ <Output Path>]]]]]}");
+            Ada.Text_IO.Put_Line ("     where: <Master_File> is the file name 
(and optional path) for the master file");
+            Ada.Text_IO.Put_Line ("                        for the document;");
+            Ada.Text_IO.Put_Line ("     where: <Format> = 'Text' (text 
files),");
+            Ada.Text_IO.Put_Line ("                       'HTML' (HTML 
files),");
+            Ada.Text_IO.Put_Line ("                       'RTF' (RTF files for 
Word 97 or later),");
+            Ada.Text_IO.Put_Line ("                       'Corr' 
(Corrigendum-style command files for comparisons);");
+            Ada.Text_IO.Put_Line ("     where: <Changes> = 'No-Changes' 
(Original RM text),");
+            Ada.Text_IO.Put_Line ("                        'New-Only' (Revised 
RM text only up to <ChgVers>),");
+            Ada.Text_IO.Put_Line ("                        'Show-Changes' 
(Text with changes marked between");
+            Ada.Text_IO.Put_Line ("                                        
<BaseVers> and <ChgVers>),");
+            Ada.Text_IO.Put_Line ("                        'New-Changes' (Text 
with insertions marked between");
+            Ada.Text_IO.Put_Line ("                                        
<BaseVers> and <ChgVers>);");
+            Ada.Text_IO.Put_Line ("     where: <BaseVers> and <ChgVers> = a 
value in 0 .. 9 representing the");
+            Ada.Text_IO.Put_Line ("                        base and primary 
change versions, respectively");
+            Ada.Text_IO.Put_Line ("                        0-Original Ada 95 
(equivalent to No-Changes)");
+            Ada.Text_IO.Put_Line ("                        1-Technical 
Corrigendum 1");
+            Ada.Text_IO.Put_Line ("                        2-Amendment 1");
+            Ada.Text_IO.Put_Line ("                        3-Ada 2012");
+            Ada.Text_IO.Put_Line ("                        4-Ada 2012 
Technical Corrigendum 1");
+            Ada.Text_IO.Put_Line ("                        5-Ada 202x");
+            Ada.Text_IO.Put_Line ("     where: <Output_Path> = it the path 
where to write the result files. This must");
+            Ada.Text_IO.Put_Line ("                        end with a path 
separator. It defaults to ./output/");
+            raise No_Command_Error;
+    end Get_Commands;
+
+
+begin
+    Ada.Text_IO.Put_Line ("Ada Manual formatter");
+    Ada.Text_IO.Put_Line ("  Copyright 2000, 2002, 2004, 2005, 2006, 2011, 
2012, 2016  AXE Consultants");
+    Ada.Text_IO.Put_Line ("  P.O. Box 1512, Madison WI  53701");
+
+    Get_Commands;
+
+Ada.Text_IO.Put_Line ("  Master File = " & 
Ada.Strings.Unbounded.To_String(Master_File));
+Ada.Text_IO.Put_Line ("  Format = " & 
ARM_Master.Output_Format_Type'Image(Format));
+Ada.Text_IO.Put_Line ("  Changes = " & 
ARM_Format.Change_Kind'Image(Change_Kind));
+Ada.Text_IO.Put_Line ("  Version = " & Change_Version);
+
+    ARM_Master.Read_and_Process_Master_File (
+                File_Name => Ada.Strings.Unbounded.To_String(Master_File),
+                The_Change_Kind => Change_Kind,
+                The_Change_Version => Change_Version,
+                The_Base_Change_Version => Base_Change_Version,
+                Output_Format => Format,
+                Output_Path => Ada.Strings.Unbounded.To_String(Output_Path));
+
+    Ada.Text_IO.Put_Line ("Ada document created");
+exception
+    when No_Command_Error =>
+        null; -- Error message displayed by command line processor.
+end ARM_Formatter;
diff --git a/packages/ada-ref-man/progs/arm_frm.adb 
b/packages/ada-ref-man/progs/arm_frm.adb
new file mode 100755
index 0000000..f730483
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_frm.adb
@@ -0,0 +1,11211 @@
+with -- ARM_Output, -- redudant with spec
+--   ARM_Input,
+     ARM_File,
+     ARM_String,
+--   ARM_Contents,
+--   ARM_Database,
+     ARM_Syntax,
+     ARM_Index,
+--   ARM_Subindex,
+     ARM_Format.Data,
+     Ada.Text_IO,
+     Ada.Characters.Handling,
+     Ada.Strings.Fixed;
+package body ARM_Format is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the routines to parse the input files, and
+    -- determine what to output.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+    --           2010, 2011, 2012, 2013, 2016
+    -- AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  4/14/00 - RLB - Created base package.
+    --  4/17/00 - RLB - Starting implementation of commands.
+    --  4/19/00 - RLB - Implemented contents package and section references.
+    --  4/21/00 - RLB - Added hard_space and line_break output routines.
+    --  4/24/00 - RLB - Added Change_Kind and Display_Index_Entries.
+    --         - RLB - Added Change and ChgRef.
+    --  4/26/00 - RLB - Added paragraph commands and formats.
+    --  4/29/00 - RLB - Loose ends: "Part", fixes for the example format,
+    --                 "DescribeCode" and "Itemize".
+    --  5/10/00 - RLB - Added missing "MetricsName" and "MetricsTitle".
+    --                 Added additional paragraph format kinds.
+    --  5/11/00 - RLB - Implemented numbers on enumerated paragraphs.
+    -- 5/12/00 - RLB - Added NoPrefix.
+    --         - RLB - Added attribute commands.
+    --  5/13/00 - RLB - Added various character macros.
+    --  5/15/00 - RLB - Split input from parsing/formatting.
+    --  5/16/00 - RLB - Added database objects and Destroy.
+    --         - RLB - Implemented pragma commands.
+    --  5/17/00 - RLB - Implemented syntax commands.
+    --  5/19/00 - RLB - Added hinge analysis.
+    --  5/23/00 - RLB - Added column commands.
+    --         - RLB - Added tab commands.
+    --  5/24/00 - RLB - Implemented subscript/superscript commands.
+    --  5/25/00 - RLB - Added more formatting commands and styles.
+    --  5/26/00 - RLB - Removed hinge analysis, other junk.
+    --  5/28/00 - RLB - Implemented index operations.
+    --  6/ 2/00 - RLB - Implemented @|.
+    --         - RLB - Added AdaDefn and AdaSubDefn commands, and unit saving.
+    --  8/ 2/00 - RLB - Implemented @! (as @| doesn't work); implemented
+    --                 lquote, etc.
+    --  8/ 4/00 - RLB - Added additional styles.
+    --  8/ 8/00 - RLB - Added Attribute_Leading.
+    --  8/11/00 - RLB - Fixed glossary report.
+    --         - RLB - Added Hanging_in_Bulleted low-level style.
+    --  8/15/00 - RLB - Replaced "LangDefType" with "AdaTypeDefn" (much 
smaller).
+    --  8/16/00 - RLB - Added double nesting support for InnerItemize.
+    --         - RLB - Added "noparanum" command; removed no paranum formats.
+    --  8/17/00 - RLB - Changed Leading flag to Space_After, added Trailing 
command.
+    --         - RLB - Added Nested_Enumerated styles.
+    --  8/18/00 - RLB - Fixed a variety of errors in the AARM paragraph 
numbering.
+    --         - RLB - Fixed Display_Index_Entry so it would work right when
+    --                 given in an insertion or deletion.
+    --  8/21/00 - RLB - Fixed so send and later references in a ChgReg command
+    --                 don't accidentally include all preceding ones.
+    --  8/22/00 - RLB - Added Labeled_Revised_Clause and
+    --                 Labeled_Revised_Subclause commands.
+    --  8/23/00 - RLB - Fixed Syntax_Rules to allow @Chg commands in the
+    --                 LHS.
+    --         - RLB - Fixed error in display of Defn2 index entries.
+    --  8/28/00 - RLB - Added implementation-defined changes command.
+    --  8/30/00 - RLB - Adjusted code in index entries to match old AARM.
+    --         - RLB - Made the deleted paragraph text appear in all new
+    --                 versions.
+    --         - RLB - Added AddedSubheading.
+    --  8/31/00 - RLB - Added the New_Changes change kind.
+    --         - RLB - Added RM_New_Page command.
+    --  9/ 1/00 - RLB - Fixed bugs that prevented "deleted paragraph" messages
+    --                 from appearing and caused junk headers to appear for
+    --                 sections not appearing in the old document.
+    --  9/ 8/00 - RLB - Added information about the language-defined
+    --                 subprograms to the index introduction.
+    --  9/26/00 - RLB - Added Syntax_Display format.
+    --  9/28/00 - RLB - Added RefSecbyNum command.
+    -- 10/30/00 - RLB - Added ISOOnly paragraph grouping.
+    --         - RLB - Fixed inserted paragraph numbers to support more than 9.
+    --  6/17/02 - RLB - Added Ada95 changes sections.
+    --  7/18/02 - RLB - Moved document type here.
+    --         - RLB - Added ARef= parameter to ChgRef.
+    --          - RLB - Added Changes_Only and versioning for individual 
changes.
+    --  4/10/03 - RLB - Fixed Index_Pragma to include "<name> pragma".
+    --  4/11/03 - RLB - Fixed order of removal for formatting for Heading and
+    --                 Subheading, so that the nesting is right (it needs to
+    --                 be exactly like the order of application).
+    --         - RLB - Fixed code so that parameter version numbers aren't
+    --                 displayed higher than the item we're generating.
+    --         - RLB - Fixed ChgRef and others not to generate anything if
+    --                 we're not generating the version that the reference is
+    --                 for. Similarly, avoid changing the paragraph kind if
+    --                 we're not going to use the changes.
+    --         - RLB - Fixed font for changing non-terminals in @Syn.
+    --  9/09/04 - RLB - Removed unused junk noticed by Stephen Leake.
+    --  9/10/04 - RLB - Added Version to many Text_Format commands.
+    --         - RLB - Fixed Get_NT to allow the Version parameter in @Chg.
+    --         - RLB - Updated to allow @Chg nesting.
+    --  9/14/04 - RLB - Moved Change_Version_Type to ARM_Contents.
+    --         - RLB - Added version number parameters to revised header
+    --                 commands; added additional header commands.
+    --         - RLB - Added code so that section references in Annex L and M
+    --                 are links.
+    --  9/15/04 - RLB - Fixed incorrect name for LabeledAddedSubClause command.
+    --         - RLB - Fixed to lift limit on number of inserted paragraphs.
+    -- 10/28/04 - RLB - Replaced double single quotes with double quotes,
+    --                 as directed by the ARG.
+    --         - RLB - Added "AddedNormal" ChgRef kind.
+    -- 10/29/04 - RLB - Added code so that section references in Annex K are
+    --                 links.
+    -- 11/02/04 - RLB - Added "DeletedAdded" ChgRef kind.
+    -- 11/03/04 - RLB - Fixed @Chg nesting glitch.
+    --         - RLB - Added InnerInnerItemize == Nested_X2_Bulleted.
+    -- 11/04/04 - RLB - Fixed a problem that reset the insertion number for
+    --                 paragraphs have a normal AARM para. was encountered.
+    -- 11/15/04 - RLB - Added Indented_Nested_Bulleted style.
+    -- 12/06/04 - RLB - Added "RevisedAdded" ChgRef kind.
+    --         - RLB - Delayed generation of references until the start of
+    --                 the paragraph. That avoids "pinning" problems,
+    --                 especially for multiple changes in a single paragraph.
+    --         - RLB - Allow multiple Ref and ARef params in ChgAttribute.
+    --         - RLB - Added ChgAdded and ChgDeleted for entire paragraph
+    --                 operations.
+    -- 12/11/04 - RLB - Fixed brackets in Added_Pragma_Syntax to allow {} in
+    --                 text.
+    --         - RLB - Implemented attribute adding in Change_Attribute.
+    -- 12/13/04 - RLB - Fixed problems in the new change commands.
+    -- 12/15/04 - RLB - Fixed so a change is not left open across
+    --                 an End_Hang_Item.
+    --         - RLB - Fixed glitches with deleted paragraphs.
+    --  1/19/05 - RLB - Added LabeledRevisedInformativeAnnex.
+    --         - RLB - Fixed AARM paragraph numbers to allow more than 52,
+    --                 and to put out an error message if we exceed the 
maximum.
+    --         - RLB - Added ChgDocReq and ChgImplAdvice.
+    --         - RLB - Added AddedDocReqList and AddedImplAdviceList.
+    --  1/20/05 - RLB - Added debugging for stack overflows.
+    --  1/24/05 - RLB - Added Inner_Indented.
+    -- 1/25/05 - RLB - Added AddedSyn and DeleteSyn commands.
+    --  2/ 1/05 - RLB - Added Turkish Is.
+    --  2/ 2/05 - RLB - Corrected so normal AARM numbers don't reset the
+    --                 RM insertion number.
+    --  3/15/05 - RLB - Corrected spelling.
+    --  5/27/05 - RLB - Added @Unicode command for examples.
+    --  8/ 9/05 - RLB - Changed the capitalization of some AARM note headers.
+    -- 10/17/05 - RLB - Added Glossary change commands.
+    -- 10/28/05 - RLB - Made index changes for Ada 200Y.
+    --         - RLB - Added added Annex headers.
+    --         - RLB - Added Language-Defined Entity indexes.
+    -- 10/31/05 - RLB - Fixed the "this paragraph was deleted" code to
+    --                 not change the version; it's not necessarily
+    --                 initialized, and the Kind isn't set anyway if the
+    --                 version is too new.
+    --  1/ 5/06 - RLB - Corrected a comment.
+    --  1/12/06 - RLB - Replaced "Document" with a number of new more general
+    --                 properties.
+    --  1/13/06 - RLB - Added various link commands.
+    --  1/16/06 - RLB - Added missing initializations.
+    --         - RLB - Added IndexList command.
+    --         - RLB - Added Unnumbered_Section counter to ensure that
+    --                 such sections are uniquely named.
+    --  1/18/06 - RLB - Added "Example_Font".
+    --         - RLB - Redid formatting command nesting so that closing
+    --                 restores to the initial state for the command, not the
+    --                 default state.
+    --  1/20/06 - RLB - Added AILink command.
+    --  2/ 8/06 - RLB - Added command checking at the end of each table row.
+    --  2/ 9/06 - RLB - Implemented enhanced Table command.
+    --  2/10/06 - RLB - Split scanning phase into a separate file.
+    --         - RLB - Added additional features to the Table command.
+    --         - RLB - Added the picture command.
+    -- 2/15/06 - RLB - Added code to prevent the generation of note numbers
+    --                 for deleted notes in final documents.
+    --  2/17/06 - RLB - Tracked down issues with @ChgImplDef.
+    --         - RLB - Added code so that index entries don't display soft
+    --                 hyphens.
+    --         - RLB - Fixed glossary entries to not display insertions if
+    --                 the mode would prevent that.
+    --  6/22/06 - RLB - Added non-terminal linking.
+    --  8/ 4/06 - RLB - Added checking for bad unit indexing.
+    --  9/22/06 - RLB - Added "Use_ISO_2004_Note_Format", and implemented that
+    --                 format.
+    --         - RLB - Revised to use Clause_Number_Type, and to support
+    --                 Subsubclauses.
+    --  9/25/06 - RLB - Added "Use_ISO_2004_Contents_Format".
+    --         - RLB - Added LastColWidth to @Table.
+    --         - RLB - Fixed Enumerated in Notes styles.
+    --  9/29/06 - RLB - Added Element_Ref and Child_Ref for ASIS.
+    -- 10/04/06 - RLB - Added and implemented "Use_ISO_2004_List_Format".
+    --         - RLB - Added "InnerEnumerate" text block.
+    -- 10/13/06 - RLB - Added the @ntf command to handle cases where the
+    --                 text needs to look like a non-terminal but it isn't
+    --                 a real non-terminal.
+    --         - RLB - Added code to handle simple embedded commands in
+    --                 @nt{} to generate links.
+    -- 10/16/06 - RLB - Added code to register deleted non-terminals (so
+    --                 that they can be linked).
+    -- 10/18/06 - RLB - Fixed so that deleted glossary items still get
+    --                 deleted paragraph numbers.
+    --  2/ 5/07 - RLB - Added a paragraph kind, and changed ones that
+    --                 appear in ASIS. Also renamed "Wide" to "Wide_Above"
+    --                 so the purpose is more obvious.
+    --  2/ 9/07 - RLB - Moved AI interpretation and folding to the HTML
+    --                 driver, as constructing the link should be its
+    --                 responsibility. This also allows new kinds of AI here.
+    --  2/13/07 - RLB - Redid output formating to use an explict indent;
+    --                  added ChildExample.
+    --  2/16/07 - RLB - Added Indent format.
+    --  2/19/07 - RLB - Added Title format.
+    -- 12/18/07 - RLB - Initialized Version in some cases.
+    --         - RLB - Added check for open formatting commands
+    --                 in Check_End_Paragraph.
+    --         - RLB - Added Plain_Annex and associated commands.
+    -- 12/19/07 - RLB - Added color commands.
+    --  6/12/08 - RLB - Corrected handling of the ChgGlossary command.
+    --  3/ 4/09 - RLB - Added code to suppress bullets and the like when
+    --                 displaying a deleted paragraph in New-Only mode
+    --                 and no paragraph numbers are shown.
+    --  5/ 6/09 - RLB - Added Labeled_Deleted_xxx.
+    --  5/15/09 - RLB - Fixed missing code for note numbers in revised/added 
clauses.
+    --  4/23/10 - RLB - Added Ada 2005 clause headers for Ada 2012 edition.
+    --  8/ 8/11 - RLB - Split various data items to reduce the size of this
+    --                 package.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/19/11 - RLB - Added AspectDefn command.
+    -- 10/20/11 - RLB - Added optional initial version parameter to ChgImplDef
+    --                 and related commands.
+    --         - RLB - Added DeletedPragmaSyn command.
+    -- 10/25/11 - RLB - Added optional initial version parameter to
+    --                 LabeledRevisedSomething commands.
+    -- 10/26/11 - RLB - Added versioned break commands.
+    --  3/19/12 - RLB - Fixed bug that occurred only when paragraph numbers
+    --                 are off (ISO versions). Fixed sort order of attributes.
+    --  3/27/12 - RLB - Added more versioned break commands.
+    --  4/ 3/12 - RLB - Removed dead variables.
+    --  8/31/12 - RLB - Put glossary components into a subrecord to prevent
+    --                 inappropriate usage.
+    -- 10/18/12 - RLB - Put impdef components into a subrecord to prevent
+    --                 inappropriate usage. Fixed problem caused by putting
+    --                 newer items than the generated version into the DB.
+    --         - RLB - Added four specific indent hanging formats and
+    --                 "small" format.
+    -- 11/ 5/12 - RLB - Added stupidly missing compare for "small" format.
+    -- 11/26/12 - RLB - Added subdivision names.
+    --  7/ 5/13 - RLB - Added a nasty hack so added aspect names are marked
+    --                 as such in Show_Changes versions.
+    -- 12/13/13 - RLB - Added InitialVersion parameter to ChgAttrib.
+    --  3/17/16 - RLB - Removed Changes_Only, added Base_Change_Version.
+
+    type Command_Kind_Type is (Normal, Begin_Word, Parameter);
+
+    use ARM_Format.Data; -- use all type ARM_Format.Data.Command_Type;
+       -- Make the enumeration literals visible.
+
+    Free_References : Reference_Ptr := null; -- Unused reference objects.
+       -- We don't expect there ever to be many of these, so we don't try
+       -- to deallocate them.
+    Allocated_Reference_Count : Natural := 0;
+
+    function Allocate_Reference return Reference_Ptr is
+       -- Allocate a reference object from either the free list, or allocate
+       -- it.
+       T : Reference_Ptr;
+    begin
+       if Free_References /= null then
+           T := Free_References;
+           Free_References := Free_References.Next;
+           return T;
+       else
+           Allocated_Reference_Count := Allocated_Reference_Count + 1;
+           if Allocated_Reference_Count > 20 then -- Never more than this on 
one paragraph.
+                Ada.Text_IO.Put_Line ("  ** Too many references allocated");
+           end if;
+           return new Reference;
+       end if;
+    end Allocate_Reference;
+
+
+    procedure Free_Reference (Reference : in out Reference_Ptr) is
+       -- Put a reference object on the free list; setting Reference to null.
+    begin
+       Reference.Next := Free_References;
+       Free_References := Reference;
+       Reference.Ref_Len := 0; -- Clear length, so we don't reuse by accident.
+       Reference := null;
+    end Free_Reference;
+
+
+    procedure Create (Format_Object : in out Format_Type;
+                     Changes : in ARM_Format.Change_Kind;
+                     Change_Version : in ARM_Contents.Change_Version_Type;
+                     Base_Change_Version : in ARM_Contents.Change_Version_Type;
+                     Display_Index_Entries : in Boolean;
+                     Include_Annotations : in Boolean;
+                     Include_ISO : in Boolean;
+                     Link_Non_Terminals : in Boolean;
+                     Number_Paragraphs : in Boolean;
+                     Examples_Font : in ARM_Output.Font_Family_Type;
+                     Use_ISO_2004_Note_Format : in Boolean;
+                     Use_ISO_2004_Contents_Format : in Boolean;
+                     Use_ISO_2004_List_Format : in Boolean;
+                     Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind) is
+       -- Initialize an input object. Changes, Change_Version,
+       -- and Base_Change_Version determine
+       -- which changes should be displayed. If Display_Index_Entries is True,
+       -- index entries will be printed in the document; otherwise, they
+       -- will not generate any visible text (although they might generate
+       -- a link anchor). If Include_Annotations is True, annotations (AARM
+       -- text) will be included in the output; otherwise it will not be.
+       -- If Include_ISO is True, ISOOnly text will be included in the output
+       -- (and NotISO text will not); otherwise the reverse is true.
+       -- If Link_Non_Terminals is True, links will be generated for
+       -- each Non_Terminal, linking it to its definition.
+       -- If Number_Paragraphs is true, paragraphs will be numbered (per
+       -- subclause); otherwise they will not be.
+       -- Example_Font specifies the font that examples will be set in.
+       -- If Use_ISO_2004_Note_Format is true, that format will be used;
+       -- else the Ada95 standard's format will be used for notes.
+       -- If Use_ISO_2004_Contents_Format is true, that format will be used;
+       -- else the Ada95 standard's format will be used for the table of 
contents.
+       -- If Use_ISO_2004_List_Format is true, then lists will be lettered;
+       -- else the Ada95 standard's numbering format will be used for
+       -- enumerated lists.
+        -- The top-level (and other) subdivision names are as specified
+        -- in Top_Level_Subdivision_Name.
+    begin
+       Format_Object.Changes := Changes;
+       Format_Object.Change_Version := Change_Version;
+       Format_Object.Base_Change_Version := Base_Change_Version;
+       Format_Object.Display_Index_Entries := Display_Index_Entries;
+       Format_Object.Include_Annotations := Include_Annotations;
+       Format_Object.Include_ISO := Include_ISO;
+       Format_Object.Link_Non_Terminals := Link_Non_Terminals;
+       Format_Object.Number_Paragraphs := Number_Paragraphs;
+       Format_Object.Examples_Font := Examples_Font;
+       Format_Object.Use_ISO_2004_Note_Format := Use_ISO_2004_Note_Format;
+       Format_Object.Use_ISO_2004_Contents_Format := 
Use_ISO_2004_Contents_Format;
+       Format_Object.Use_ISO_2004_List_Format := Use_ISO_2004_List_Format;
+       Format_Object.Top_Level_Subdivision_Name := Top_Level_Subdivision_Name;
+
+       Format_Object.Clause_Number := (Section => 0, Clause => 0,
+                                       Subclause => 0, Subsubclause => 0);
+       Format_Object.Unnumbered_Section := 0;
+        Format_Object.Next_Note := 1;
+        Format_Object.Next_Paragraph := 1;
+        Format_Object.Next_Insert_Para := 1;
+        Format_Object.Next_AARM_Sub := 'a';
+        Format_Object.Next_AARM_Insert_Para := 1;
+        Format_Object.Next_Enumerated_Num := 1;
+        Format_Object.Enumerated_Level := 0;
+        Format_Object.Last_Paragraph_Subhead_Type := Plain;
+        Format_Object.Next_Paragraph_Subhead_Type := Plain;
+        Format_Object.Next_Paragraph_Format_Type := Plain;
+       ARM_Database.Create (Format_Object.Aspect_DB);
+       ARM_Database.Create (Format_Object.Attr_DB);
+       ARM_Database.Create (Format_Object.Pragma_DB);
+       ARM_Database.Create (Format_Object.Glossary_DB);
+       ARM_Database.Create (Format_Object.Impdef_DB);
+       ARM_Database.Create (Format_Object.Impladv_DB);
+       ARM_Database.Create (Format_Object.Docreq_DB);
+       ARM_Syntax.Create;
+       ARM_Index.Create;
+       ARM_Subindex.Create (Format_Object.Package_Index);
+       ARM_Subindex.Create (Format_Object.Type_Index);
+       ARM_Subindex.Create (Format_Object.Subprogram_Index);
+       ARM_Subindex.Create (Format_Object.Exception_Index);
+       ARM_Subindex.Create (Format_Object.Object_Index);
+    end Create;
+
+
+    procedure Destroy (Format_Object : in out Format_Type) is
+       -- Destroy a format object, releasing any resources.
+    begin
+       ARM_Database.Destroy (Format_Object.Aspect_DB);
+       ARM_Database.Destroy (Format_Object.Attr_DB);
+       ARM_Database.Destroy (Format_Object.Pragma_DB);
+       ARM_Database.Destroy (Format_Object.Glossary_DB);
+       ARM_Database.Destroy (Format_Object.Impdef_DB);
+       ARM_Database.Destroy (Format_Object.Impladv_DB);
+       ARM_Database.Destroy (Format_Object.Docreq_DB);
+       ARM_Syntax.Destroy;
+       ARM_Index.Destroy;
+       ARM_Subindex.Destroy (Format_Object.Package_Index);
+       ARM_Subindex.Destroy (Format_Object.Type_Index);
+       ARM_Subindex.Destroy (Format_Object.Subprogram_Index);
+       ARM_Subindex.Destroy (Format_Object.Exception_Index);
+       ARM_Subindex.Destroy (Format_Object.Object_Index);
+    end Destroy;
+
+
+    function Clause_String (Format_Object : in Format_Type) return String is
+        -- Returns a string for a clause reference.
+        use type ARM_Contents.Section_Number_Type;
+    begin
+        if Format_Object.Clause_Number.Subsubclause /= 0 then
+           return ARM_Contents.Make_Clause_Number (
+                   ARM_Contents.SubSubClause,
+                   Format_Object.Clause_Number);
+        elsif Format_Object.Clause_Number.Subclause /= 0 then
+           return ARM_Contents.Make_Clause_Number (
+                   ARM_Contents.SubClause,
+                   Format_Object.Clause_Number);
+        elsif Format_Object.Clause_Number.Clause /= 0 then
+           return ARM_Contents.Make_Clause_Number (
+                   ARM_Contents.Clause,
+                   Format_Object.Clause_Number);
+        else
+           if Format_Object.Clause_Number.Section = 0 then
+               return ARM_Contents.Make_Clause_Number (
+                       ARM_Contents.Unnumbered_Section,
+                       Format_Object.Clause_Number);
+           elsif Format_Object.Clause_Number.Section < 
ARM_Contents.ANNEX_START then
+               return ARM_Contents.Make_Clause_Number (
+                       ARM_Contents.Section,
+                       Format_Object.Clause_Number);
+           else
+               return ARM_Contents.Make_Clause_Number (
+                       ARM_Contents.Plain_Annex, -- Same for all kinds of 
annex.
+                       Format_Object.Clause_Number);
+           end if;
+        end if;
+    end Clause_String;
+
+
+    Do_Not_Display_Text : constant ARM_Output.Change_Type := ARM_Output.Both;
+        -- Special meaning for Calc_Change_Disposition, below.
+    procedure Calc_Change_Disposition
+               (Format_Object : in Format_Type;
+                Version       : in ARM_Contents.Change_Version_Type;
+                Operation     : in ARM_Output.Change_Type;
+                Text_Kind     : out ARM_Output.Change_Type) is
+        -- Determine the appropriate disposition for text.
+        -- The text is to be inserted if Operation is Insertion;
+        -- and deleted if Operation is Deletion.
+        -- The appropriate Change_Type to use is returned in Text_Kind.
+        -- If Text_Kind is None, the text should be displayed normally.
+        -- If Text_Kind is Insertion, the text should be displayed as inserted.
+        -- If Text_Kind is Deletion, the text should be displayed as deletion.
+        -- If Text_Kind is Do_Not_Display_Text (same as Both), the
+        --   text should not be shown at all.
+        -- Program_Error is raised if Operation is None or Both.
+        -- This routine assumes that we are not nested
+        -- in some other change item.
+        use type ARM_Output.Change_Type;
+    begin
+        if Operation = ARM_Output.None or else
+          Operation = ARM_Output.Both then
+           raise Program_Error;
+        end if;
+        -- We can't check for nesting, because in some cases it happens
+        -- harmlessly (i.e. Added_Pragma_Syn).
+
+        case Format_Object.Changes is
+           when ARM_Format.Old_Only =>
+               -- Display only the original version ('0').
+               if Operation = ARM_Output.Insertion then
+                   if Version > '0' then
+                       Text_Kind := Do_Not_Display_Text; -- Newer than 
original.
+                   else
+                       Text_Kind := ARM_Output.None; -- Display normally.
+                   end if;
+               else -- Deletion
+                   if Version > '0' then
+                       Text_Kind := ARM_Output.None; -- Display normally, not 
deleted in original code.
+                   else
+                       Text_Kind := Do_Not_Display_Text; -- Deleted in 
original.
+                   end if;
+               end if;
+           when ARM_Format.New_Only =>
+               -- Display only the version
+               -- Format_Object.Change_Version, no insertions or deletions.
+               if Operation = ARM_Output.Insertion then
+                   if Version > Format_Object.Change_Version then
+                       -- Change version newer than we're displaying;
+                       -- ignore the item.
+                       Text_Kind := Do_Not_Display_Text;
+                   else
+                       -- Display the change normally.
+                       Text_Kind := ARM_Output.None;
+                   end if;
+               else -- Deletion
+                   if Version > Format_Object.Change_Version then
+                       -- Change version newer than we're displaying;
+                       -- leave the item in and display normally.
+                       Text_Kind := ARM_Output.None;
+                   else
+                       -- Delete the item.
+                       Text_Kind := Do_Not_Display_Text;
+                   end if;
+               end if;
+           when ARM_Format.Show_Changes |
+                ARM_Format.New_Changes =>
+               -- Display only the the changes for versions
+               -- Format_Object.Base_Change_Version ..
+               -- Format_Object.Change_Version, older changes
+               -- are applied and newer changes are ignored.
+               -- (New_Changes shows deletions as a single
+               -- character for older versions of Word, but otherwise
+               -- is the same.)
+               if Operation = ARM_Output.Insertion then
+                   if Version > Format_Object.Change_Version then
+                       -- Change version is newer than we're displaying;
+                       -- ignore the item.
+                       Text_Kind := Do_Not_Display_Text;
+                   elsif Version < Format_Object.Base_Change_Version then
+                       -- Change version is older than we're displaying;
+                       -- display the change normally.
+                       Text_Kind := ARM_Output.None;
+                   else
+                       -- This version or older, display the change
+                       -- as an insertion.
+                       Text_Kind := ARM_Output.Insertion;
+                   end if;
+               else -- Deletion.
+                   if Version > Format_Object.Change_Version then
+                       -- Change version is newer than we're displaying;
+                       -- the item isn't deleted yet, display the change
+                       -- normally.
+                       Text_Kind := ARM_Output.None;
+                   elsif Version < Format_Object.Base_Change_Version then
+                       -- Change version is older than we're displaying;
+                       -- the item is deleted, so ignore the item.
+                       Text_Kind := Do_Not_Display_Text;
+                   else
+                       -- The correct version, display the change
+                       -- as a deletion.
+                       Text_Kind := ARM_Output.Deletion;
+                   end if;
+               end if;
+        end case;
+    end Calc_Change_Disposition;
+
+
+    function Get_Current_Item (Format_Object : in Format_Type;
+                              Input_Object : in ARM_Input.Input_Type'Class;
+                              Item : in String) return String is
+        -- Return the "current" item from Item. This is Item itself,
+       -- unless Item includes an @Chg.
+       New_Pos : Natural;
+        Close_Ch : Character;
+        Open_Cnt : Natural;
+       My_Item : constant String (1 .. Item'Length) := Item;
+               -- Just to slide the bounds.
+       Version : ARM_Contents.Change_Version_Type := '0';
+       Disposition : ARM_Output.Change_Type;
+        use type ARM_Output.Change_Type;
+    begin
+        if My_Item'Length < 11 or else
+          My_Item (1) /= '@' or else
+          Ada.Characters.Handling.To_Lower (My_Item (2 .. 4)) /= "chg" then
+           -- No @Chg command here.
+           return My_Item;
+       end if;
+       if Ada.Characters.Handling.To_Lower (My_Item (6 .. 9)) = "new=" then
+           -- No version parameter:
+           New_Pos := 6;
+           Version := '1';
+       elsif My_Item'Length > 22 and then
+           Ada.Characters.Handling.To_Lower (My_Item (6 .. 14)) = "version=[" 
and then
+           Ada.Characters.Handling.To_Lower (My_Item (16 .. 21)) = "],new=" 
then
+           New_Pos := 18;
+           Version := My_Item(15);
+       else
+Ada.Text_IO.Put_Line ("%% Oops, can't find either Version or New in item chg 
command, line " & ARM_Input.Line_String (Input_Object));
+           return My_Item;
+       end if;
+
+       Calc_Change_Disposition (Format_Object => Format_Object,
+                Version => Version,
+                Operation => ARM_Output.Insertion,
+                Text_Kind => Disposition);
+
+       if Disposition = Do_Not_Display_Text then
+           -- Find the end of the "New" parameter, and return the "Old"
+           -- parameter.
+           Close_Ch := ARM_Input.Get_Close_Char (
+               My_Item(New_Pos+4));
+           Open_Cnt := 1;
+           for I in New_Pos+5 .. My_Item'Last loop
+               if My_Item(I) = My_Item(New_Pos+4) then
+                   Open_Cnt := Open_Cnt + 1;
+               elsif My_Item(I) = Close_Ch then
+                   if Open_Cnt <= 1 then
+                       -- OK, the end of the "New" parameter is at 'I'.
+                       if My_Item'Last < I+7 or else
+                          My_Item (I+1) /= ',' or else
+                          Ada.Characters.Handling.To_Lower (My_Item (I+2 .. 
I+4)) /= "old" or else
+                          My_Item (I+5) /= '=' then
+                           exit; -- Heck if I know.
+                       end if;
+                       Close_Ch := ARM_Input.Get_Close_Char (
+                           My_Item(I+6));
+                       Open_Cnt := 1;
+                       for J in I+7 .. My_Item'Last loop
+                           if My_Item(J) = My_Item(I+6) then
+                               Open_Cnt := Open_Cnt + 1;
+                           elsif My_Item(J) = Close_Ch then
+                               if Open_Cnt <= 1 then
+                                   return My_Item (I + 7 .. J - 1);
+                               else
+                                   Open_Cnt := Open_Cnt - 1;
+                               end if;
+                           -- else continue looking.
+                           end if;
+                       end loop;
+Ada.Text_IO.Put_Line ("%% Oops, can't find end of item chg old command, line " 
& ARM_Input.Line_String (Input_Object));
+                       return My_Item (I + 7 .. My_Item'Last);
+                   else
+                       Open_Cnt := Open_Cnt - 1;
+                   end if;
+               -- else continue looking.
+               end if;
+           end loop;
+Ada.Text_IO.Put_Line ("%% Oops, can't find end of item chg new command, line " 
& ARM_Input.Line_String (Input_Object));
+           return My_Item (New_Pos+5 .. My_Item'Length);
+        else -- Some new format, use the new name.
+           -- Find the end of the "New" parameter, and
+           -- return it.
+           Close_Ch := ARM_Input.Get_Close_Char (My_Item(New_Pos+4));
+           Open_Cnt := 1;
+           for I in New_Pos+5 .. My_Item'Last loop
+               if My_Item(I) = My_Item(New_Pos+4) then
+                   Open_Cnt := Open_Cnt + 1;
+               elsif My_Item(I) = Close_Ch then
+                   if Open_Cnt <= 1 then
+                       return My_Item (New_Pos+5 .. I - 1);
+                   else
+                       Open_Cnt := Open_Cnt - 1;
+                   end if;
+               -- else continue looking.
+               end if;
+           end loop;
+           -- Weird if we get here, can't find end of parameter.
+Ada.Text_IO.Put_Line ("%% Oops, can't find end of NT chg new command, line " & 
ARM_Input.Line_String (Input_Object));
+           return My_Item (New_Pos+5 .. My_Item'Last);
+        end if;
+    end Get_Current_Item;
+
+
+    function Get_Old_Item (Format_Object : in Format_Type;
+                          Input_Object : in ARM_Input.Input_Type'Class;
+                          Item : in String) return String is
+        -- Return the "old" item from Item, or nothing if there is no
+       -- old item. This is nothing unless Item includes an @Chg,
+       -- *and* the new item in the @Chg is displayed.
+       New_Pos : Natural;
+        Close_Ch : Character;
+        Open_Cnt : Natural;
+       My_Item : constant String (1 .. Item'Length) := Item;
+               -- Just to slide the bounds.
+       Version : ARM_Contents.Change_Version_Type := '0';
+       Disposition : ARM_Output.Change_Type;
+        use type ARM_Output.Change_Type;
+    begin
+        if My_Item'Length < 11 or else
+          My_Item (1) /= '@' or else
+          Ada.Characters.Handling.To_Lower (My_Item (2 .. 4)) /= "chg" then
+           -- No @Chg command here.
+           return "";
+       end if;
+       if Ada.Characters.Handling.To_Lower (My_Item (6 .. 9)) = "new=" then
+           -- No version parameter:
+           New_Pos := 6;
+           Version := '1';
+       elsif My_Item'Length > 22 and then
+           Ada.Characters.Handling.To_Lower (My_Item (6 .. 14)) = "version=[" 
and then
+           Ada.Characters.Handling.To_Lower (My_Item (16 .. 21)) = "],new=" 
then
+           New_Pos := 18;
+           Version := My_Item(15);
+       else
+Ada.Text_IO.Put_Line ("%% Oops, can't find either Version or New in item chg 
command, line " & ARM_Input.Line_String (Input_Object));
+           return "";
+       end if;
+
+       Calc_Change_Disposition (Format_Object => Format_Object,
+                Version => Version,
+                Operation => ARM_Output.Insertion,
+                Text_Kind => Disposition);
+
+       if Disposition /= Do_Not_Display_Text then
+           -- Some new item was shown.
+           -- Find the end of the "New" parameter, and return the "Old"
+           -- parameter.
+           Close_Ch := ARM_Input.Get_Close_Char (
+               My_Item(New_Pos+4));
+           Open_Cnt := 1;
+           for I in New_Pos+5 .. My_Item'Last loop
+               if My_Item(I) = My_Item(New_Pos+4) then
+                   Open_Cnt := Open_Cnt + 1;
+               elsif My_Item(I) = Close_Ch then
+                   if Open_Cnt <= 1 then
+                       -- OK, the end of the "New" parameter is at 'I'.
+                       if My_Item'Last < I+7 or else
+                          My_Item (I+1) /= ',' or else
+                          Ada.Characters.Handling.To_Lower (My_Item (I+2 .. 
I+4)) /= "old" or else
+                          My_Item (I+5) /= '=' then
+                           exit; -- Heck if I know.
+                       end if;
+                       Close_Ch := ARM_Input.Get_Close_Char (
+                           My_Item(I+6));
+                       Open_Cnt := 1;
+                       for J in I+7 .. My_Item'Last loop
+                           if My_Item(J) = My_Item(I+6) then
+                               Open_Cnt := Open_Cnt + 1;
+                           elsif My_Item(J) = Close_Ch then
+                               if Open_Cnt <= 1 then
+                                   return My_Item (I + 7 .. J - 1);
+                               else
+                                   Open_Cnt := Open_Cnt - 1;
+                               end if;
+                           -- else continue looking.
+                           end if;
+                       end loop;
+Ada.Text_IO.Put_Line ("%% Oops, can't find end of item chg old command, line " 
& ARM_Input.Line_String (Input_Object));
+                       return My_Item (I + 7 .. My_Item'Last);
+                   else
+                       Open_Cnt := Open_Cnt - 1;
+                   end if;
+               -- else continue looking.
+               end if;
+           end loop;
+Ada.Text_IO.Put_Line ("%% Oops, can't find end of item chg new command, line " 
& ARM_Input.Line_String (Input_Object));
+           return "";
+        else -- The new item wasn't displayed, so we already have used the
+            -- old item.
+           return "";
+        end if;
+    end Get_Old_Item;
+
+
+    procedure Scan (Format_Object : in out Format_Type;
+                   File_Name : in String;
+                   Section_Number : in ARM_Contents.Section_Number_Type;
+                   Starts_New_Section : in Boolean) is separate;
+       -- Scans the contents for File_Name, determining the table of contents
+       -- for the section. The results are written to the contents package.
+       -- Starts_New_Section is True if the file starts a new section.
+       -- Section_Number is the number (or letter) of the section.
+       -- See ARM_FRMS.ADB.
+
+
+    procedure Write_Table_of_Contents (
+                      Format_Object : in out Format_Type;
+                      Output_Object : in out ARM_Output.Output_Type'Class) is
+       -- Writes the table of contents for the document. (It will have
+       -- a section name of "TOC"). This should be done after all calls to
+       -- Scan and before any calls to Process.
+
+       In_Paragraph : Boolean := False;
+
+       procedure Write_It (Title : in ARM_Contents.Title_Type;
+                  Level : in ARM_Contents.Level_Type;
+                  Clause_Number : in ARM_Contents.Clause_Number_Type;
+                   Version : in ARM_Contents.Change_Version_Type;
+                  Quit : out Boolean) is
+           Clause_Text : constant String :=
+               ARM_Contents.Make_Clause_Number (Level, Clause_Number);
+           Old_Title : ARM_Contents.Title_Type :=
+                       ARM_Contents.Lookup_Old_Title (
+                           Level, Clause_Number);
+       begin
+           Quit := False;
+           if Old_Title = ARM_Contents.Title_Type'(others => ' ') and then
+              (Format_Object.Change_Version < Version or else
+               ARM_Format."=" (Format_Object.Changes, ARM_Format.Old_Only)) 
then
+               -- This is an added item, and we're generating a version
+               -- that does not include it. Skip it completely.
+               return;
+           end if;
+           if ARM_Contents."=" (Level, ARM_Contents.Clause) then
+               ARM_Output.Line_Break (Output_Object);
+               ARM_Output.Ordinary_Text (Output_Object, "    ");
+               ARM_Output.Ordinary_Text (Output_Object, Clause_Text);
+               ARM_Output.Hard_Space (Output_Object);
+           elsif ARM_Contents."=" (Level, ARM_Contents.Subclause) then
+               ARM_Output.Line_Break (Output_Object);
+               ARM_Output.Ordinary_Text (Output_Object, "        ");
+               ARM_Output.Ordinary_Text (Output_Object, Clause_Text);
+               ARM_Output.Hard_Space (Output_Object);
+           elsif ARM_Contents."=" (Level, ARM_Contents.Subsubclause) then
+               ARM_Output.Line_Break (Output_Object);
+               ARM_Output.Ordinary_Text (Output_Object, "            ");
+               ARM_Output.Ordinary_Text (Output_Object, Clause_Text);
+               ARM_Output.Hard_Space (Output_Object);
+           elsif ARM_Contents."=" (Level, ARM_Contents.Unnumbered_Section) then
+               if In_Paragraph then
+                   ARM_Output.End_Paragraph (Output_Object);
+               end if;
+               ARM_Output.Start_Paragraph (Output_Object,
+                                           ARM_Output.Normal,
+                                           Indent => 0, Number => "",
+                                           Justification => ARM_Output.Left);
+               In_Paragraph := True;
+           else
+               if In_Paragraph then
+                   ARM_Output.End_Paragraph (Output_Object);
+               end if;
+               ARM_Output.Start_Paragraph (Output_Object,
+                                           ARM_Output.Normal,
+                                           Indent => 0, Number => "",
+                                           Justification => ARM_Output.Left);
+               In_Paragraph := True;
+               if ARM_Contents."=" (Level, ARM_Contents.Section) then
+                   ARM_Output.Ordinary_Text (Output_Object, Clause_Text);
+                   ARM_Output.Ordinary_Text (Output_Object, ". ");
+               else -- Annexes.
+                   ARM_Output.Ordinary_Character (Output_Object, 
Clause_Text(Clause_Text'Last)); -- We don't want the "Annex" part.
+                   ARM_Output.Ordinary_Text (Output_Object, ". ");
+               end if;
+           end if;
+           if Format_Object.Change_Version < Version then
+               -- Ignore the change:
+               ARM_Output.Clause_Reference (Output_Object,
+                   Ada.Strings.Fixed.Trim (
+                       ARM_Contents.Lookup_Old_Title (
+                           Level, Clause_Number), Ada.Strings.Right),
+                   Clause_Text);
+           else
+               case Format_Object.Changes is
+                   when ARM_Format.Old_Only =>
+                       ARM_Output.Clause_Reference (Output_Object,
+                           Ada.Strings.Fixed.Trim (
+                               ARM_Contents.Lookup_Old_Title (
+                                   Level, Clause_Number), Ada.Strings.Right),
+                           Clause_Text);
+                   when ARM_Format.New_Only |
+                        ARM_Format.Show_Changes |
+                        ARM_Format.New_Changes =>
+                       ARM_Output.Clause_Reference (Output_Object,
+                           Ada.Strings.Fixed.Trim (Title, Ada.Strings.Right),
+                           Clause_Text);
+               end case;
+           end if;
+       end Write_It;
+
+       procedure Write_Contents is new ARM_Contents.For_Each (Write_It);
+
+    begin
+       -- Note: For .RTF version, the result of this call will not be used,
+       -- preferring to let Word make the TOC (it can include page numbers).
+       if Format_Object.Use_ISO_2004_Contents_Format then
+            ARM_Output.Section (Output_Object,
+                               Section_Title => "Contents",
+                               Section_Name => "TOC");
+
+           ARM_Output.Clause_Header (Output_Object,
+                                     Header_Text => "Contents",
+                                     Level => ARM_Contents.Section,
+                                     Clause_Number => "",
+                                     Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+       else
+            ARM_Output.Section (Output_Object,
+                               Section_Title => "Table of Contents",
+                               Section_Name => "TOC");
+
+           ARM_Output.Clause_Header (Output_Object,
+                                     Header_Text => "Table of Contents",
+                                     Level => ARM_Contents.Section,
+                                     Clause_Number => "",
+                                     Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+       end if;
+
+       ARM_Output.TOC_Marker (Output_Object, For_Start => True);
+
+       Write_Contents;
+
+       if In_Paragraph then
+           ARM_Output.End_Paragraph (Output_Object);
+       end if;
+
+       ARM_Output.TOC_Marker (Output_Object, For_Start => False);
+
+    end Write_Table_of_Contents;
+
+
+    procedure Make_References (List : in out Reference_Ptr;
+                              Format_Object : in out Format_Type;
+                              Output_Object : in out 
ARM_Output.Output_Type'Class) is
+       -- Write the references to the Output_Object, using the format
+       -- of Format_Object.
+       -- Deallocate the references on List; List will be null afterwards.
+       Temp : Reference_Ptr;
+       Our_Text_Format : ARM_Output.Format_Type;
+    begin
+       -- We assume these are only stored here if we want to see them
+       -- on *this* paragraph. Thus, we just output them if they exist
+       -- here.
+       Our_Text_Format := Format_Object.Text_Format;
+       Our_Text_Format.Change := ARM_Output.None; -- No changes should be 
reflected in references.
+
+       while List /= null loop
+           -- Output a reference. These are *never* marked as
+           -- inserted or deleted, so set the style properly.
+           ARM_Output.Text_Format (Output_Object,
+                                   Format => Our_Text_Format);
+           ARM_Output.Ordinary_Character (Output_Object, '{');
+           Our_Text_Format.Italic := True;
+           ARM_Output.Text_Format (Output_Object,
+                                   Format => Our_Text_Format);
+           if List.Is_DR_Ref then
+               -- Output a DR reference.
+               ARM_Output.DR_Reference (Output_Object,
+                                        Text => List.Ref_Name(1..List.Ref_Len),
+                                        DR_Number => 
List.Ref_Name(1..List.Ref_Len));
+           else
+               -- Output an AI reference.
+               ARM_Output.AI_Reference (Output_Object,
+                                        Text => List.Ref_Name(1..List.Ref_Len),
+                                        AI_Number => 
List.Ref_Name(1..List.Ref_Len));
+           end if;
+           Our_Text_Format.Italic := Format_Object.Text_Format.Italic;
+           ARM_Output.Text_Format (Output_Object,
+                                   Format => Our_Text_Format);
+           ARM_Output.Ordinary_Character (Output_Object, '}');
+           ARM_Output.Ordinary_Character (Output_Object, ' ');
+           -- Reset to the current format.
+           ARM_Output.Text_Format (Output_Object,
+                                   Format => Format_Object.Text_Format);
+           Format_Object.Last_Non_Space := False;
+
+           Temp := List;
+           List := List.Next;
+           Free_Reference (Temp);
+       end loop;
+    end Make_References;
+
+
+    procedure Dump_References (List : in out Reference_Ptr) is
+       -- Destroy any references in List; List will be null afterwards.
+       Temp : Reference_Ptr;
+    begin
+       while List /= null loop
+           Temp := List;
+           List := List.Next;
+           Free_Reference (Temp);
+       end loop;
+    end Dump_References;
+
+
+    type Items is record
+        Kind : Command_Kind_Type;
+        Name : ARM_Input.Command_Name_Type;
+        Command : Data.Command_Type;
+        Close_Char : Character; -- Ought to be }, ], >, or ).
+       Text_Format : ARM_Output.Format_Type;
+           -- Format at the start of the command.
+
+        -- The next four are only used if Kind=Begin_Word, or for
+        -- Command=Implementation_Defined, Glossary_Text_Param, or
+       --    Syntax_Rule_RHS.
+        Old_Last_Subhead_Paragraph : Paragraph_Type;
+        Old_Next_Subhead_Paragraph : Paragraph_Type;
+        Old_Next_Paragraph_Format : Paragraph_Type;
+       Old_Tab_Stops : ARM_Output.Tab_Info;
+       Old_Next_Enum_Num : Positive;
+       Is_Formatting : Boolean; -- Only used if Kind=Begin_Word.
+                                -- The command changes the PARAGRAPH format.
+                                -- Otherwise, it should be ignored when
+                                -- when determining the format.
+       -- The following is only used if Command = Change, Change_Added,
+       -- Change_Deleted, Added_Subheading,
+       -- Added_Pragma_Syntax, Deleted_Pragma_Syntax,
+       -- Added_Syntax, Deleted_Syntax,
+       -- New_Page_for_Version, New_Column_for_Version,
+       -- RM_New_Page_for_Version, Not_ISO_RM_New_Page_for_Version, and
+       -- ISO_Only_RM_New_Page_for_Version.
+       Change_Version : ARM_Contents.Change_Version_Type;
+       -- The following are only used if Command = Change,
+       -- Added_Pragma_Syntax, and Deleted_Pragma_Syntax.
+       Prev_Change_Version : ARM_Contents.Change_Version_Type;
+       -- The following are only used if Command = Change.
+       Was_Text : Boolean; -- Did the current subcommand have text?
+       Prev_Change : ARM_Output.Change_Type;
+       Prev_Added_Change_Version : ARM_Contents.Change_Version_Type;
+    end record;
+    type Nesting_Stack_Type is array (1 .. 40) of Items;
+    type Format_State_Type is record
+       Nesting_Stack : Nesting_Stack_Type;
+       Nesting_Stack_Ptr : Natural := 0;
+    end record;
+
+
+    procedure Real_Process (Format_Object : in out Format_Type;
+                           Format_State : in out Format_State_Type;
+                           Input_Object : in out ARM_Input.Input_Type'Class;
+                           Output_Object : in out 
ARM_Output.Output_Type'Class) is
+       -- Process the contents of Input_Object, writing the results to
+       -- Output_Object. (Output_Object uses dispatching calls to provide
+       -- the correct formatting). Format_Object holds information about
+       -- the state of the formatting.
+
+       procedure Set_Nesting_for_Command (Name : in 
ARM_Input.Command_Name_Type;
+                                          Kind : in Command_Kind_Type;
+                                          Param_Ch : in Character) is
+           -- Push the command onto the nesting stack.
+       begin
+           Format_State.Nesting_Stack_Ptr := Format_State.Nesting_Stack_Ptr + 
1;
+           Format_State.Nesting_Stack (Format_State.Nesting_Stack_Ptr) :=
+               (Name => Name,
+                Kind => Kind,
+                Command => Data.Command (Name),
+                Close_Char => ' ', -- Set below.
+                Text_Format => Format_Object.Text_Format, -- Save the current 
format.
+                -- Other things next necessarily used:
+                Old_Last_Subhead_Paragraph => Plain, -- Not used.
+                Old_Next_Subhead_Paragraph => Plain, -- Not used.
+                Old_Next_Paragraph_Format => Plain, -- Not used.
+                Old_Tab_Stops => ARM_Output.NO_TABS, -- Not used.
+                Old_Next_Enum_Num => 1, -- Not used.
+                Is_Formatting => False, -- Not used.
+                Change_Version => '0', -- Not used.
+                Was_Text => False, -- Not used.
+                Prev_Change => ARM_Output.None, -- Not used.
+                Prev_Change_Version => '0', -- Not used.
+                Prev_Added_Change_Version => '0'); -- Not used.
+           Format_State.Nesting_Stack 
(Format_State.Nesting_Stack_Ptr).Close_Char := ARM_Input.Get_Close_Char 
(Param_Ch);
+--Ada.Text_IO.Put_Line (" &Stack (" & Name & "); Close-Char=" &
+--  Format_State.Nesting_Stack (Format_State.Nesting_Stack_Ptr).Close_Char);
+       end Set_Nesting_for_Command;
+
+
+       procedure Set_Nesting_for_Parameter (Command  : in Data.Command_Type;
+                                            Close_Ch : in Character) is
+           -- Push the parameter onto the nesting stack.
+       begin
+           Format_State.Nesting_Stack_Ptr := Format_State.Nesting_Stack_Ptr + 
1;
+           Format_State.Nesting_Stack (Format_State.Nesting_Stack_Ptr) :=
+               (Name => (others => ' '),
+                Kind => Parameter,
+                Command => Command,
+                Close_Char => Close_Ch,
+                Text_Format => Format_Object.Text_Format, -- Save the current
+                       -- format (not really used here).
+                Old_Last_Subhead_Paragraph => Plain, -- Not used.
+                Old_Next_Subhead_Paragraph => Plain, -- Not used.
+                Old_Next_Paragraph_Format => Plain, -- Not used.
+                Old_Tab_Stops => ARM_Output.NO_TABS, -- Not used.
+                Old_Next_Enum_Num => 1, -- Not used.
+                Is_Formatting => False, -- Not used.
+                Change_Version => '0', -- Not used.
+                Was_Text => False, -- Not used.
+                Prev_Change => ARM_Output.None, -- Not used.
+                Prev_Change_Version => '0', -- Not used.
+                Prev_Added_Change_Version => '0'); -- Not used.
+--Ada.Text_IO.Put_Line (" &Stack (Parameter)");
+       end Set_Nesting_for_Parameter;
+
+
+        function Is_AARM_Paragraph (Kind : in Paragraph_Type) return Boolean is
+        begin
+           case Kind is
+               when Plain | Introduction | Syntax | Resolution | Legality |
+                    Static_Semantics | Link_Time |
+                    Run_Time | Bounded_Errors |
+                    Erroneous | Requirements | Documentation |
+                    Metrics | Permissions | Advice | Notes | Single_Note |
+                    Examples =>
+                   return False;
+               when Language_Design | Ada83_Inconsistencies |
+                    Ada83_Incompatibilities | Ada83_Extensions |
+                    Ada83_Wording | Ada95_Inconsistencies |
+                    Ada95_Incompatibilities | Ada95_Extensions |
+                    Ada95_Wording | Ada2005_Inconsistencies |
+                    Ada2005_Incompatibilities | Ada2005_Extensions |
+                    Ada2005_Wording | Ada2012_Inconsistencies |
+                    Ada2012_Incompatibilities | Ada2012_Extensions |
+                    Ada2012_Wording | Reason | Ramification | Proof |
+                    Imp_Note | Corr_Change | Discussion |
+                    Honest | Glossary_Marker | Bare_Annotation |
+                    Element_Ref | Child_Ref | Usage_Note =>
+                   return True;
+               when In_Table =>
+                   return False; -- Tables are never considered part of the
+                           -- AARM for formatting purposes, even when they are.
+               when Wide_Above | Example_Text | Indented_Example_Text |
+                    Child_Example_Text | Code_Indented | Indent |
+                    Bulleted |
+                    Nested_Bulleted | Nested_X2_Bulleted |
+                    Display | Syntax_Display |
+                    Syntax_Indented | Syntax_Production |
+                    Enumerated | Nested_Enumerated |
+                    Hanging_Indented_1 | Hanging_Indented_2 |
+                    Hanging_Indented_3 | Hanging_Indented_4 |
+                    Small | Title =>
+                   -- This depends on the containing paragraph kind;
+                   -- Last_Paragraph_Subhead_Type should contain that.
+                   if Format_Object.Last_Paragraph_Subhead_Type = Wide_Above 
or else
+                      Format_Object.Last_Paragraph_Subhead_Type = Example_Text 
or else
+                      Format_Object.Last_Paragraph_Subhead_Type = 
Child_Example_Text or else
+                      Format_Object.Last_Paragraph_Subhead_Type = 
Indented_Example_Text or else
+                      Format_Object.Last_Paragraph_Subhead_Type = Bulleted or 
else
+                      Format_Object.Last_Paragraph_Subhead_Type = 
Code_Indented or else
+                      Format_Object.Last_Paragraph_Subhead_Type = Indent or 
else
+                      Format_Object.Last_Paragraph_Subhead_Type = 
Nested_Bulleted or else
+                      Format_Object.Last_Paragraph_Subhead_Type = 
Nested_X2_Bulleted or else
+                      Format_Object.Last_Paragraph_Subhead_Type = Display or 
else
+                      Format_Object.Last_Paragraph_Subhead_Type = 
Syntax_Display or else
+                      Format_Object.Last_Paragraph_Subhead_Type = 
Syntax_Indented or else
+                      Format_Object.Last_Paragraph_Subhead_Type = 
Syntax_Production or else
+                      Format_Object.Last_Paragraph_Subhead_Type = Enumerated 
or else
+                      Format_Object.Last_Paragraph_Subhead_Type = 
Nested_Enumerated or else
+                      Format_Object.Last_Paragraph_Subhead_Type = 
Hanging_Indented_1 or else
+                      Format_Object.Last_Paragraph_Subhead_Type = 
Hanging_Indented_2 or else
+                      Format_Object.Last_Paragraph_Subhead_Type = 
Hanging_Indented_3 or else
+                      Format_Object.Last_Paragraph_Subhead_Type = 
Hanging_Indented_4 or else
+                      Format_Object.Last_Paragraph_Subhead_Type = Title or else
+                      Format_Object.Last_Paragraph_Subhead_Type = In_Table then
+Ada.Text_IO.Put_Line ("%% Oops, can't find out if AARM paragraph, line " & 
ARM_Input.Line_String (Input_Object));
+                       return False; -- Oops, can't tell (double nesting).
+                           -- We make this check to avoid infinite recursion.
+                   else
+                       return Is_AARM_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type);
+                   end if;
+           end case;
+        end Is_AARM_Paragraph;
+
+
+       procedure Paragraph_Number_String (Update_Numbers : in Boolean) is
+           -- Generate the current (next) paragraph number string into
+           -- Format_Object.Current_Paragraph_String. Update the paragraph
+           -- numbers if Update_Numbers is True.
+            PNum : constant String := 
Integer'Image(Format_Object.Next_Paragraph);
+            PNum_Pred : constant String := 
Integer'Image(Format_Object.Next_Paragraph-1);
+           use type Arm_Database.Paragraph_Change_Kind_Type;
+
+           procedure AARM_Sub_Num (Sub_Letter : in Character) is
+               -- Adds a properly formatted AARM sub letter, with leading '.'.
+               -- Sets the length appropriately.
+           begin
+               Format_Object.Current_Paragraph_String(PNum_Pred'Last) :=
+                   '.';
+               if Sub_Letter <= 'z' then
+                   Format_Object.Current_Paragraph_String(PNum_Pred'Last+1) :=
+                       Sub_Letter;
+                   Format_Object.Current_Paragraph_Len :=
+                           PNum_Pred'Last + 1;
+               elsif Character'Val(Character'Pos(Sub_Letter) - 26) <= 'z' then
+                   -- Double letter.
+                   Format_Object.Current_Paragraph_String(PNum_Pred'Last+1) :=
+                       Character'Val(Character'Pos(Sub_Letter) - 26);
+                   Format_Object.Current_Paragraph_String(PNum_Pred'Last+2) :=
+                       Character'Val(Character'Pos(Sub_Letter) - 26);
+                   Format_Object.Current_Paragraph_Len :=
+                           PNum_Pred'Last + 2;
+               elsif Character'Val(Character'Pos(Sub_Letter) - 52) <= 'z' then
+                   -- Triple letter.
+                   Format_Object.Current_Paragraph_String(PNum_Pred'Last+1) :=
+                       Character'Val(Character'Pos(Sub_Letter) - 52);
+                   Format_Object.Current_Paragraph_String(PNum_Pred'Last+2) :=
+                       Character'Val(Character'Pos(Sub_Letter) - 52);
+                   Format_Object.Current_Paragraph_String(PNum_Pred'Last+3) :=
+                       Character'Val(Character'Pos(Sub_Letter) - 52);
+                   Format_Object.Current_Paragraph_Len :=
+                           PNum_Pred'Last + 3;
+               else -- Doesn't fit!
+                   Ada.Text_IO.Put_Line ("** AARM paragraph number out of 
range, line " & ARM_Input.Line_String (Input_Object));
+                   Format_Object.Current_Paragraph_String(PNum_Pred'Last+1) := 
'$';
+                   Format_Object.Current_Paragraph_String(PNum_Pred'Last+2) := 
'$';
+                   Format_Object.Current_Paragraph_String(PNum_Pred'Last+3) := 
'$';
+                   Format_Object.Current_Paragraph_Len :=
+                           PNum_Pred'Last + 3;
+               end if;
+            end AARM_Sub_Num;
+
+       begin
+           -- The full paragraph number is:
+           -- Num.AARM.Ins/Vers
+           -- where Num is a paragraph number in the RM; AARM is the
+           -- paragraph subletter for AARM text; Ins is the number of
+           -- inserted paragraph; and Vers is the version number ('1'
+           -- for Technical Corrigendum 1; '0' for original RM.;
+           -- '2' for Amendment 1). Note that we don't include change
+           -- versions greater than the one we're currently processing.
+           -- Unused parts are omitted.
+
+           -- %%%% Buglet: If a paragraph was changed by multiple versions,
+           -- we only know the last one. So we guess. If there was a change
+           -- visible here, there must be a revision number, so we use the
+           -- one we're generating. That could be wrong if we have three
+           -- or more versions. I hope we don't need to regenerate old
+           -- versions that far back.
+
+           if Format_Object.Next_Paragraph_Change_Kind = ARM_Database.None or 
else
+              Format_Object.Changes = Old_Only then
+               -- Either there is no change, or we are only producing
+               -- the original document (which means we ignore all
+               -- marked changes).
+               if Is_AARM_Paragraph 
(Format_Object.Next_Paragraph_Subhead_Type) then
+                   Format_Object.Current_Paragraph_String(1 .. 
PNum_Pred'Last-1) :=
+                       PNum_Pred(2..PNum_Pred'Last);
+                   AARM_Sub_Num (Format_Object.Next_AARM_Sub);
+                   if Update_Numbers then
+                       Format_Object.Next_AARM_Sub := 
Character'Succ(Format_Object.Next_AARM_Sub);
+                       Format_Object.Next_AARM_Insert_Para := 1;
+                   end if;
+               else
+                   Format_Object.Current_Paragraph_String(1 .. PNum'Last-1) :=
+                       PNum(2..PNum'Last);
+                   Format_Object.Current_Paragraph_Len := PNum'Last - 1;
+                   if Update_Numbers then
+                       Format_Object.Next_Paragraph := 
Format_Object.Next_Paragraph + 1;
+                       Format_Object.Next_Insert_Para := 1;
+                       Format_Object.Next_AARM_Sub := 'a';
+                       Format_Object.Next_AARM_Insert_Para := 1;
+                   end if;
+               end if;
+           elsif Format_Object.Next_Paragraph_Change_Kind = 
ARM_Database.Inserted or else
+                 Format_Object.Next_Paragraph_Change_Kind = 
ARM_Database.Revised_Inserted_Number or else
+                 Format_Object.Next_Paragraph_Change_Kind = 
ARM_Database.Deleted_Inserted_Number or else
+                 Format_Object.Next_Paragraph_Change_Kind = 
ARM_Database.Deleted_Inserted_Number_No_Delete_Message then
+               -- We'll assume that there are no more than 99 inserted
+               -- paragraphs in a row.
+               Format_Object.Current_Paragraph_String(1 .. PNum_Pred'Last-1) :=
+                   PNum_Pred(2..PNum_Pred'Last);
+               if Is_AARM_Paragraph 
(Format_Object.Next_Paragraph_Subhead_Type) then
+                   if Format_Object.Next_AARM_Sub = 'a' then
+                       AARM_Sub_Num ('a'); -- No paras before the insertion.
+                   else
+                       AARM_Sub_Num 
(Character'Pred(Format_Object.Next_AARM_Sub));
+                           -- Insertions use the preceeding paragraph letter.
+                   end if;
+                   
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 1) 
:=
+                       '.';
+                   if Format_Object.Next_AARM_Insert_Para >= 10 then
+                       
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 2) 
:=
+                           
Character'Val((Format_Object.Next_AARM_Insert_Para/10) + Character'Pos('0'));
+                       
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 3) 
:=
+                           Character'Val((Format_Object.Next_AARM_Insert_Para 
mod 10) + Character'Pos('0'));
+                       Format_Object.Current_Paragraph_Len := 
Format_Object.Current_Paragraph_Len + 1;
+                           -- Make this consistent with the other cases.
+                   else
+                       
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 2) 
:=
+                           Character'Val(Format_Object.Next_AARM_Insert_Para + 
Character'Pos('0'));
+                   end if;
+                   if Update_Numbers then
+                       Format_Object.Next_AARM_Insert_Para :=
+                           Format_Object.Next_AARM_Insert_Para + 1;
+                   end if;
+               else -- None inserted paragraphs.
+                   Format_Object.Current_Paragraph_Len := PNum_Pred'Last - 1;
+                   
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 1) 
:=
+                       '.';
+                   if Format_Object.Next_Insert_Para >= 10 then
+                       
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 2) 
:=
+                           Character'Val((Format_Object.Next_Insert_Para/10) + 
Character'Pos('0'));
+                       
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 3) 
:=
+                           Character'Val((Format_Object.Next_Insert_Para mod 
10) + Character'Pos('0'));
+                       Format_Object.Current_Paragraph_Len := 
Format_Object.Current_Paragraph_Len + 1;
+                           -- Make this consistent with the other cases.
+                   else
+                       
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 2) 
:=
+                           Character'Val(Format_Object.Next_Insert_Para + 
Character'Pos('0'));
+                   end if;
+                   if Update_Numbers then
+                       Format_Object.Next_Insert_Para := 
Format_Object.Next_Insert_Para + 1;
+                       -- Note: We don't update the AARM numbers for
+                       -- inserted paragraphs, as the insertion number is
+                       -- not included in them.
+                   end if;
+               end if;
+               if Format_Object.Next_Paragraph_Version /= '0' then
+                   
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 3) 
:=
+                       '/';
+                   if Format_Object.Next_Paragraph_Version <= 
Format_Object.Change_Version then
+                       
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 4) 
:=
+                           Format_Object.Next_Paragraph_Version;
+                   else -- Use the number we're generating.
+                       
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 4) 
:=
+                           Format_Object.Change_Version;
+                   end if;
+                   Format_Object.Current_Paragraph_Len := 
Format_Object.Current_Paragraph_Len + 4;
+               else
+                   Format_Object.Current_Paragraph_Len := 
Format_Object.Current_Paragraph_Len + 2;
+                end if;
+           else --if Format_Object.Next_Paragraph_Change_Kind = 
ARM_Database.Revised or else
+                --   Format_Object.Next_Paragraph_Change_Kind = 
ARM_Database.Deleted or else
+                --   Format_Object.Next_Paragraph_Change_Kind = 
ARM_Database.Inserted_Normal_Number then
+               if Is_AARM_Paragraph 
(Format_Object.Next_Paragraph_Subhead_Type) then
+                   Format_Object.Current_Paragraph_String(1 .. 
PNum_Pred'Last-1) :=
+                       PNum_Pred(2..PNum_Pred'Last);
+                   AARM_Sub_Num (Format_Object.Next_AARM_Sub);
+                   -- Format_Object.Current_Paragraph_Len := 
Format_Object.Current_Paragraph_Len; -- useless assign
+                   if Update_Numbers then
+                       Format_Object.Next_AARM_Sub := 
Character'Succ(Format_Object.Next_AARM_Sub);
+                       Format_Object.Next_AARM_Insert_Para := 1;
+                   end if;
+               else
+                   Format_Object.Current_Paragraph_String(1 .. PNum'Last-1) :=
+                       PNum(2..PNum'Last);
+                   Format_Object.Current_Paragraph_Len := PNum'Last - 1;
+                   if Update_Numbers then
+                       Format_Object.Next_Paragraph := 
Format_Object.Next_Paragraph + 1;
+                       Format_Object.Next_Insert_Para := 1;
+                       Format_Object.Next_AARM_Sub := 'a';
+                       Format_Object.Next_AARM_Insert_Para := 1;
+                   end if;
+               end if;
+               if Format_Object.Next_Paragraph_Version /= '0' then
+                   
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 1) 
:=
+                       '/';
+                   if Format_Object.Next_Paragraph_Version <= 
Format_Object.Change_Version then
+                       
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 2) 
:=
+                           Format_Object.Next_Paragraph_Version;
+                   else -- Use the number we're generating.
+                       
Format_Object.Current_Paragraph_String(Format_Object.Current_Paragraph_Len + 2) 
:=
+                           Format_Object.Change_Version;
+                   end if;
+                   Format_Object.Current_Paragraph_Len := 
Format_Object.Current_Paragraph_Len + 2;
+               -- else no version to display.
+               end if;
+           end if;
+       end Paragraph_Number_String;
+
+
+        function Paragraph_String return String is
+           -- Returns a string for a paragraph reference, for use in an
+           -- index entry.
+        begin
+           if Format_Object.In_Paragraph then
+               null; -- It is already is stored.
+           else -- Generate the next paragraph number.
+               Paragraph_Number_String (Update_Numbers => False);
+           end if;
+           return Format_Object.Current_Paragraph_String (
+                       1 .. Format_Object.Current_Paragraph_Len);
+       end Paragraph_String;
+
+
+       procedure Check_Paragraph is
+           -- Open a paragraph if needed before outputting any text that needs
+           -- one.
+
+           procedure Set_Format (For_Type : Paragraph_Type) is
+
+               use type ARM_Output.Paragraph_Indent_Type;
+
+               function Enclosing_Format return Paragraph_Type is
+               begin
+                   for I in reverse 1 .. Format_State.Nesting_Stack_Ptr loop
+                       if Format_State.Nesting_Stack(I).Command = Text_Begin 
and then
+                          (Format_State.Nesting_Stack(I).Is_Formatting) then
+                           return 
Format_State.Nesting_Stack(I).Old_Next_Paragraph_Format;
+                       end if;
+                   end loop;
+                   return Plain; -- The default format.
+               end Enclosing_Format;
+
+               function Enclosing_Indent return 
ARM_Output.Paragraph_Indent_Type is
+                   function Nested_Indent (Start_Nesting : in Natural) return 
ARM_Output.Paragraph_Indent_Type is
+                   begin
+                       for I in reverse 1 .. Start_Nesting loop
+                           if Format_State.Nesting_Stack(I).Command = 
Text_Begin and then
+                              (Format_State.Nesting_Stack(I).Is_Formatting) 
then
+                               case 
Format_State.Nesting_Stack(I).Old_Next_Paragraph_Format is
+                                   when Plain | Introduction |
+                                        Resolution |
+                                        Legality |
+                                        Static_Semantics |
+                                        Link_Time |
+                                        Run_Time |
+                                        Bounded_Errors |
+                                        Erroneous |
+                                        Requirements | -- ImplReq
+                                        Documentation | -- DocReq
+                                        Metrics |
+                                        Permissions | -- ImplPerm
+                                        Advice | -- ImplAdvice
+                                        Examples =>
+                                       return 0; -- No indent.
+                                   when Wide_Above =>
+                                       if Is_AARM_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                                           return 2; -- Normal indent for 
annotations.
+                                       else
+                                           return 0; -- No indent.
+                                       end if;
+                                   when Syntax =>
+                                       return 1; -- One unit.
+                                   when Notes | Single_Note => -- Notes (only 
the numbering varies)
+                                       return 1; -- One unit.
+                                   when Element_Ref | Child_Ref | Usage_Note 
=> -- Similar to an AARM note.
+                                       return 2; -- Normal indent for 
annotations.
+                                   when Language_Design | -- "MetaRules"
+                                        Ada83_Inconsistencies | -- 
Inconsistent83
+                                        Ada83_Incompatibilities | -- 
Incompatible83
+                                        Ada83_Extensions | -- Extend83
+                                        Ada83_Wording | -- DiffWord83
+                                        Ada95_Inconsistencies | -- 
Inconsistent95
+                                        Ada95_Incompatibilities | -- 
Incompatible95
+                                        Ada95_Extensions | -- Extend95
+                                        Ada95_Wording | -- DiffWord95
+                                        Ada2005_Inconsistencies | -- 
Inconsistent2005
+                                        Ada2005_Incompatibilities | -- 
Incompatible2005
+                                        Ada2005_Extensions | -- Extend2005
+                                        Ada2005_Wording | -- DiffWord2005
+                                        Ada2012_Inconsistencies | -- 
Inconsistent2012
+                                        Ada2012_Incompatibilities | -- 
Incompatible2012
+                                        Ada2012_Extensions | -- Extend2012
+                                        Ada2012_Wording => -- DiffWord2012
+                                       return 2; -- Normal indent for 
annotations.
+                                   when Reason | Ramification | Proof |
+                                        Imp_Note | Corr_Change | Discussion |
+                                        Honest | Glossary_Marker | 
Bare_Annotation =>
+                                       return 2; -- Normal indent for 
annotations.
+                                   when Example_Text =>
+                                       if Is_AARM_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                                           return 3; -- Three units.
+                                       else
+                                           return 1; -- One unit.
+                                       end if;
+                                   when Child_Example_Text =>
+                                       return 1 + Nested_Indent(I-1); -- 
Depends on enclosing.
+                                   when Indented_Example_Text =>
+                                       if Is_AARM_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                                           return 6; -- Six units.
+                                       else
+                                           return 4; -- Four units.
+                                       end if;
+                                   when Code_Indented =>
+                                       if Is_AARM_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                                           return 4; -- Four units.
+                                       else
+                                           return 2; -- Two units.
+                                       end if;
+                                   when Indent =>
+                                       return 1 + Nested_Indent(I-1); -- 
Depends on enclosing.
+                                   when Bulleted | Nested_Bulleted | 
Nested_X2_Bulleted =>
+                                       return 1 + Nested_Indent(I-1); -- 
Depends on enclosing.
+                                   when Display =>
+                                       return 1 + Nested_Indent(I-1); -- 
Depends on enclosing.
+                                   when Syntax_Display =>
+                                       return 1; -- One unit.
+                                   when Enumerated | Nested_Enumerated =>
+                                       return 1 + Nested_Indent(I-1); -- 
Depends on enclosing.
+                                   when Syntax_Indented =>
+                                       return 1; -- One unit.
+                                   when Syntax_Production =>
+                                       return Nested_Indent(I-1); -- Depends 
on enclosing.
+                                   when Hanging_Indented_1 =>
+                                       return Nested_Indent(I-1) + 1; -- 
Depends on enclosing, at least 1.
+                                   when Hanging_Indented_2 =>
+                                       return Nested_Indent(I-1) + 2; -- 
Depends on enclosing, at least 2.
+                                   when Hanging_Indented_3 =>
+                                       return Nested_Indent(I-1) + 3; -- 
Depends on enclosing, at least 3.
+                                   when Hanging_Indented_4 =>
+                                       return Nested_Indent(I-1) + 4; -- 
Depends on enclosing, at least 4.
+                                   when Small =>
+                                       return Nested_Indent(I-1); -- Depends 
on enclosing, does not change.
+                                   when Title =>
+                                       return 0; -- No indent.
+                                   when In_Table =>
+                                       -- Shouldn't get here.
+                                       return 0; -- No indent.
+                               end case;
+                           end if;
+                       end loop;
+                       return 0; -- No indent.
+                   end Nested_Indent;
+
+               begin
+                   return Nested_Indent (Format_State.Nesting_Stack_Ptr);
+               end Enclosing_Indent;
+
+               function Is_Small_Format_Paragraph (Subhead_Kind : in 
Paragraph_Type) return Boolean is
+                   -- AARM annotations are in the small font, as are user 
notes.
+               begin
+                   if Is_AARM_Paragraph (Subhead_Kind) then
+                       return True; -- AARM paragraphs are always small.
+                   else -- Check the enclosing formatting for "small" or
+                        -- other styles that imply that.
+                       for I in reverse 1 .. Format_State.Nesting_Stack_Ptr 
loop
+                           if Format_State.Nesting_Stack(I).Command = 
Text_Begin and then
+                              (Format_State.Nesting_Stack(I).Is_Formatting) 
then
+                               case 
Format_State.Nesting_Stack(I).Old_Next_Paragraph_Format is
+                                   when Introduction | Syntax | Resolution | 
Legality |
+                                        Static_Semantics | Link_Time |
+                                        Run_Time | Bounded_Errors |
+                                        Erroneous | Requirements | 
Documentation |
+                                        Metrics | Permissions | Advice | 
Examples =>
+                                       return False;
+                                   when Language_Design | 
Ada83_Inconsistencies |
+                                        Ada83_Incompatibilities | 
Ada83_Extensions |
+                                        Ada83_Wording | Ada95_Inconsistencies |
+                                        Ada95_Incompatibilities | 
Ada95_Extensions |
+                                        Ada95_Wording | 
Ada2005_Inconsistencies |
+                                        Ada2005_Incompatibilities | 
Ada2005_Extensions |
+                                        Ada2005_Wording | 
Ada2012_Inconsistencies |
+                                        Ada2012_Incompatibilities | 
Ada2012_Extensions |
+                                        Ada2012_Wording | Reason | 
Ramification | Proof |
+                                        Imp_Note | Corr_Change | Discussion |
+                                        Honest | Glossary_Marker | 
Bare_Annotation |
+                                        Element_Ref | Child_Ref | Usage_Note |
+                                        Notes | Single_Note | Small =>
+                                       return True;
+                                   when Plain | Wide_Above | In_Table | 
Example_Text | Indented_Example_Text |
+                                        Child_Example_Text | Code_Indented | 
Indent |
+                                        Bulleted |
+                                        Nested_Bulleted | Nested_X2_Bulleted |
+                                        Display | Syntax_Display |
+                                        Syntax_Indented | Syntax_Production |
+                                        Enumerated | Nested_Enumerated |
+                                        Hanging_Indented_1 | 
Hanging_Indented_2 |
+                                        Hanging_Indented_3 | 
Hanging_Indented_4 |
+                                        Title =>
+                                       -- This depends on the containing 
paragraph kind,
+                                       -- keep looking.
+                                       null;
+                               end case;
+                           end if;
+                       end loop;
+                       return False; -- Don't know.
+                   end if;
+               end Is_Small_Format_Paragraph;
+
+           begin
+               case For_Type is
+                   when Plain | Introduction |
+                        Resolution |
+                        Legality |
+                        Static_Semantics |
+                        Link_Time |
+                        Run_Time |
+                        Bounded_Errors |
+                        Erroneous |
+                        Requirements | -- ImplReq
+                        Documentation | -- DocReq
+                        Metrics |
+                        Permissions | -- ImplPerm
+                        Advice | -- ImplAdvice
+                        Examples =>
+                       Format_Object.Style := ARM_Output.Normal;
+                       Format_Object.Indent := 0; -- No indent.
+                       Format_Object.No_Breaks := False;
+                   when Wide_Above =>
+                       if Is_AARM_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           Format_Object.Style  := ARM_Output.Small_Wide_Above;
+                           Format_Object.Indent := 2; -- Two units.
+                       elsif Format_Object.Last_Paragraph_Subhead_Type = Notes 
or else
+                             Format_Object.Last_Paragraph_Subhead_Type = 
Single_Note then
+                           Format_Object.Style  := ARM_Output.Small_Wide_Above;
+                           Format_Object.Indent := 1; -- One unit.
+                       else
+                           Format_Object.Style  := ARM_Output.Wide_Above;
+                           Format_Object.Indent := 0; -- No indent.
+                       end if;
+                       Format_Object.No_Breaks := False;
+                   when Syntax =>
+                       Format_Object.Style  := ARM_Output.Normal;
+                       Format_Object.Indent := 1; -- One unit.
+                       Format_Object.No_Breaks := True;
+                   when Notes | Single_Note | Small => -- Notes (only the 
numbering varies)
+                       Format_Object.Style  := ARM_Output.Small;
+                       Format_Object.Indent := 1; -- One unit.
+                       Format_Object.No_Breaks := False;
+                   when Element_Ref | Child_Ref | Usage_Note => -- Similar to 
an AARM note.
+                       Format_Object.Style  := ARM_Output.Small;
+                       Format_Object.Indent := 2; -- Two units.
+                       Format_Object.No_Breaks := False;
+                   when Language_Design | -- "MetaRules"
+                        Ada83_Inconsistencies | -- Inconsistent83
+                        Ada83_Incompatibilities | -- Incompatible83
+                        Ada83_Extensions | -- Extend83
+                        Ada83_Wording | -- DiffWord83
+                        Ada95_Inconsistencies | -- Inconsistent95
+                        Ada95_Incompatibilities | -- Incompatible95
+                        Ada95_Extensions | -- Extend95
+                        Ada95_Wording | -- DiffWord95
+                        Ada2005_Inconsistencies | -- Inconsistent2005
+                        Ada2005_Incompatibilities | -- Incompatible2005
+                        Ada2005_Extensions | -- Extend2005
+                        Ada2005_Wording | -- DiffWord2005
+                        Ada2012_Inconsistencies | -- Inconsistent2012
+                        Ada2012_Incompatibilities | -- Incompatible2012
+                        Ada2012_Extensions | -- Extend2012
+                        Ada2012_Wording => -- DiffWord2012
+                       Format_Object.Style  := ARM_Output.Small;
+                       Format_Object.Indent := 2; -- Two units.
+                       Format_Object.No_Breaks := False;
+                   when Reason | Ramification | Proof |
+                        Imp_Note | Corr_Change | Discussion |
+                        Honest | Glossary_Marker | Bare_Annotation =>
+                       Format_Object.Style  := ARM_Output.Small;
+                       Format_Object.Indent := 2; -- Two units.
+                       Format_Object.No_Breaks := False;
+
+                   when Example_Text | Child_Example_Text |
+                       Indented_Example_Text =>
+                       case Format_Object.Examples_Font is
+                           when ARM_Output.Fixed | ARM_Output.Default =>
+                               if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+--if not Is_AARM_Paragraph (Format_Object.Last_Paragraph_Subhead_Type) and then
+--   Format_Object.Last_Paragraph_Subhead_Type /= Small then
+--   Ada.Text_IO.Put_Line ("$$ Example in notes: size change, line " & 
ARM_Input.Line_String (Input_Object));
+--end if;
+                                  Format_Object.Style := 
ARM_Output.Small_Examples;
+                               else
+                                  Format_Object.Style := ARM_Output.Examples;
+                               end if;
+                           when ARM_Output.Roman =>
+                               if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                                  Format_Object.Style := ARM_Output.Small;
+                               else
+                                  Format_Object.Style := ARM_Output.Normal;
+                               end if;
+                           when ARM_Output.Swiss =>
+                               if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                                  Format_Object.Style := 
ARM_Output.Small_Swiss_Examples;
+                               else
+                                  Format_Object.Style := 
ARM_Output.Swiss_Examples;
+                               end if;
+                       end case;
+                       Format_Object.No_Breaks := True;
+                       if For_Type = Child_Example_Text then
+                           Format_Object.Indent := 1 + Enclosing_Indent;
+--Ada.Text_IO.Put_Line ("&& Child example paragraph, line " & 
ARM_Input.Line_String (Input_Object) & " EF=" & 
Paragraph_Type'Image(Enclosing_Format) & " Indent=" &
+--   ARM_Output.Paragraph_Indent_Type'Image(Format_Object.Indent));
+                       elsif For_Type = Indented_Example_Text then
+                           if Is_AARM_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                               Format_Object.Indent := 6; -- Fixed indent.
+                           elsif Format_Object.Last_Paragraph_Subhead_Type = 
Notes or else
+                                 Format_Object.Last_Paragraph_Subhead_Type = 
Single_Note then
+                               Format_Object.Indent := 5; -- Fixed indent.
+                           else
+                               Format_Object.Indent := 4; -- Fixed indent.
+                           end if;
+                       else
+                           if Is_AARM_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                               Format_Object.Indent := 3; -- Fixed indent.
+                           elsif Format_Object.Last_Paragraph_Subhead_Type = 
Notes or else
+                                 Format_Object.Last_Paragraph_Subhead_Type = 
Single_Note then
+                               Format_Object.Indent := 2; -- Fixed indent.
+                           else
+                               Format_Object.Indent := 1; -- Fixed indent.
+                           end if;
+                       end if;
+
+                   when Code_Indented =>
+                       if Is_AARM_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           Format_Object.Style  := ARM_Output.Small;
+                           Format_Object.Indent := 4; -- Four units.
+                       elsif Format_Object.Last_Paragraph_Subhead_Type = Notes 
or else
+                             Format_Object.Last_Paragraph_Subhead_Type = 
Single_Note then
+                           Format_Object.Style  := ARM_Output.Small;
+                           Format_Object.Indent := 3; -- Three units.
+                       elsif Format_Object.Last_Paragraph_Subhead_Type = Small 
then
+                           Format_Object.Style  := ARM_Output.Small;
+                           Format_Object.Indent := 2; -- Two units.
+                       else
+                           Format_Object.Style  := ARM_Output.Normal;
+                           Format_Object.Indent := 2; -- Two indent.
+                       end if;
+                       Format_Object.No_Breaks := False;
+
+                   when Indent =>
+                       if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           Format_Object.Style  := ARM_Output.Small;
+                       else
+                           Format_Object.Style  := ARM_Output.Normal;
+                       end if;
+                       if Enclosing_Indent = 
Arm_Output.Paragraph_Indent_Type'Last then
+                            raise Program_Error with
+                               "Overindented (indent) text on line " & 
ARM_Input.Line_String (Input_Object);
+                        else
+                           Format_Object.Indent := 1 + Enclosing_Indent;
+                        end if;
+--Ada.Text_IO.Put_Line ("&& Child Indented paragraph, line " & 
ARM_Input.Line_String (Input_Object) & " EF=" & 
Paragraph_Type'Image(Enclosing_Format) & " Indent=" &
+--   ARM_Output.Paragraph_Indent_Type'Image(Format_Object.Indent));
+                       Format_Object.No_Breaks := False;
+
+                   when Bulleted =>
+                       if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           Format_Object.Style  := ARM_Output.Small_Bulleted;
+                       else
+                           Format_Object.Style  := ARM_Output.Bulleted;
+                       end if;
+                       if Enclosing_Indent = 
Arm_Output.Paragraph_Indent_Type'Last then
+                            raise Program_Error with
+                               "Overindented (bullet) text on line " & 
ARM_Input.Line_String (Input_Object);
+                        else
+                           Format_Object.Indent := 1 + Enclosing_Indent;
+                        end if;
+--Ada.Text_IO.Put_Line ("&& Regular bulleted paragraph, line " & 
ARM_Input.Line_String (Input_Object) & " EF=" & 
Paragraph_Type'Image(Enclosing_Format) & " Indent=" &
+--   ARM_Output.Paragraph_Indent_Type'Image(Format_Object.Indent));
+                       Format_Object.Paragraph_Tab_Stops := ARM_Output.NO_TABS;
+                       Format_Object.No_Breaks := False;
+
+                   when Nested_Bulleted =>
+                       if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           Format_Object.Style  := 
ARM_Output.Small_Nested_Bulleted;
+                       else
+                           Format_Object.Style  := ARM_Output.Nested_Bulleted;
+                       end if;
+                       if Enclosing_Indent = 
Arm_Output.Paragraph_Indent_Type'Last then
+                            raise Program_Error with
+                               "Overindented (nestbullet) text on line " & 
ARM_Input.Line_String (Input_Object);
+                        else
+                           Format_Object.Indent := 1 + Enclosing_Indent;
+                        end if;
+--Ada.Text_IO.Put_Line ("&& Nested bulleted paragraph, line " & 
ARM_Input.Line_String (Input_Object) & " EF=" & 
Paragraph_Type'Image(Enclosing_Format) & " Indent=" &
+--   ARM_Output.Paragraph_Indent_Type'Image(Format_Object.Indent));
+                       Format_Object.Paragraph_Tab_Stops := ARM_Output.NO_TABS;
+                       Format_Object.No_Breaks := False;
+
+                   when Nested_X2_Bulleted =>
+                       if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           Format_Object.Style  := 
ARM_Output.Small_Nested_Bulleted;
+                       else
+                           Format_Object.Style  := ARM_Output.Nested_Bulleted;
+                       end if;
+                       Format_Object.Indent := 1 + Enclosing_Indent;
+--Ada.Text_IO.Put_Line ("&& Nested X2 bulleted paragraph, line " & 
ARM_Input.Line_String (Input_Object) & " EF=" & 
Paragraph_Type'Image(Enclosing_Format) & " Indent=" &
+--   ARM_Output.Paragraph_Indent_Type'Image(Format_Object.Indent));
+                       Format_Object.Paragraph_Tab_Stops := ARM_Output.NO_TABS;
+                       Format_Object.No_Breaks := False;
+
+                   when Display =>
+                       if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           Format_Object.Style  := ARM_Output.Small;
+                       else
+                           Format_Object.Style  := ARM_Output.Normal;
+                       end if;
+                       Format_Object.Indent := 1 + Enclosing_Indent;
+--Ada.Text_IO.Put_Line ("&& Display paragraph, line " & ARM_Input.Line_String 
(Input_Object) & " EF=" & Paragraph_Type'Image(Enclosing_Format) & " Indent=" &
+--   ARM_Output.Paragraph_Indent_Type'Image(Format_Object.Indent));
+                       Format_Object.No_Breaks := True;
+
+                   when Syntax_Display =>
+                       Format_Object.Style := ARM_Output.Small;
+                       Format_Object.Indent := 1;
+                       Format_Object.No_Breaks := True;
+
+                   when Enumerated =>
+                       if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           Format_Object.Style  := ARM_Output.Small_Enumerated;
+                       else
+                           Format_Object.Style  := ARM_Output.Enumerated;
+                       end if;
+                       Format_Object.Indent := 1 + Enclosing_Indent;
+--Ada.Text_IO.Put_Line ("&& Regular enumerated paragraph, line " & 
ARM_Input.Line_String (Input_Object) & " EF=" & 
Paragraph_Type'Image(Enclosing_Format) & " Indent=" &
+--   ARM_Output.Paragraph_Indent_Type'Image(Format_Object.Indent));
+                       Format_Object.Paragraph_Tab_Stops := ARM_Output.NO_TABS;
+                       Format_Object.No_Breaks := False;
+
+                   when Nested_Enumerated =>
+                       if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           Format_Object.Style  := ARM_Output.Small_Enumerated;
+                       else
+                           Format_Object.Style  := ARM_Output.Enumerated;
+                       end if;
+                       Format_Object.Indent := 1 + Enclosing_Indent;
+--Ada.Text_IO.Put_Line ("&& Nested enumerated paragraph, line " & 
ARM_Input.Line_String (Input_Object) & " EF=" & 
Paragraph_Type'Image(Enclosing_Format) & " Indent=" &
+--   ARM_Output.Paragraph_Indent_Type'Image(Format_Object.Indent));
+                       -- Note: The difference here is the numbering, not the
+                       -- layout.
+                       Format_Object.Paragraph_Tab_Stops := ARM_Output.NO_TABS;
+                       Format_Object.No_Breaks := False;
+
+                   when Syntax_Indented =>
+                       Format_Object.Style := ARM_Output.Normal;
+                       Format_Object.Indent := 1; -- One unit.
+                       Format_Object.No_Breaks := False;
+                   when Syntax_Production =>
+                       null; -- Leave format alone (but line-breaks are 
preserved).
+                       Format_Object.No_Breaks := True;
+
+                   when Hanging_Indented_1 =>
+                       if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           Format_Object.Style  := 
ARM_Output.Small_Narrow_Hanging;
+                       else -- Normal:
+                           Format_Object.Style  := ARM_Output.Narrow_Hanging;
+                       end if;
+                       Format_Object.Indent := 1 + Enclosing_Indent;
+                       Format_Object.Paragraph_Tab_Stops := ARM_Output.NO_TABS;
+                       Format_Object.No_Breaks := False;
+
+                   when Hanging_Indented_2 =>
+                       if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           if Enclosing_Format = Bulleted or else
+                              Enclosing_Format = Enumerated then
+                               Format_Object.Style  := 
ARM_Output.Small_Hanging_in_Bulleted;
+                               -- The right margin is also adjusted in this 
case.
+                               -- This is a weird special case, used only in
+                               -- RM 11.5.
+                           else
+                               Format_Object.Style  := 
ARM_Output.Small_Medium_Hanging;
+                           end if;
+                       else -- Normal:
+                           if Enclosing_Format = Bulleted or else
+                              Enclosing_Format = Enumerated then
+                               Format_Object.Style  := 
ARM_Output.Hanging_in_Bulleted;
+                               -- The right margin is also adjusted in this 
case.
+                           else
+                               Format_Object.Style  := 
ARM_Output.Medium_Hanging;
+                           end if;
+                       end if;
+                       Format_Object.Indent := 2 + Enclosing_Indent;
+                       Format_Object.Paragraph_Tab_Stops := ARM_Output.NO_TABS;
+                       Format_Object.No_Breaks := False;
+
+                   when Hanging_Indented_3 =>
+                       if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           Format_Object.Style  := 
ARM_Output.Small_Wide_Hanging;
+                       else -- Normal:
+                           Format_Object.Style  := ARM_Output.Wide_Hanging;
+                       end if;
+                       Format_Object.Indent := 3 + Enclosing_Indent;
+                       Format_Object.Paragraph_Tab_Stops := ARM_Output.NO_TABS;
+                       Format_Object.No_Breaks := False;
+
+                   when Hanging_Indented_4 =>
+                       if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           Format_Object.Style  := 
ARM_Output.Small_Giant_Hanging;
+                       else -- Normal:
+                           Format_Object.Style  := ARM_Output.Giant_Hanging;
+                       end if;
+                       Format_Object.Indent := 4 + Enclosing_Indent;
+                       Format_Object.Paragraph_Tab_Stops := ARM_Output.NO_TABS;
+                       Format_Object.No_Breaks := False;
+
+                   when Title =>
+                       Format_Object.Style := ARM_Output.Title;
+                       Format_Object.Indent := 0; -- No indent.
+                       Format_Object.No_Breaks := False;
+                   when In_Table =>
+                        -- Shouldn't get here.
+                       if Is_Small_Format_Paragraph 
(Format_Object.Last_Paragraph_Subhead_Type) then
+                           Format_Object.Style := ARM_Output.Small;
+                       else
+                           Format_Object.Style := ARM_Output.Normal;
+                       end if;
+                       Format_Object.Indent := 0; -- No indent.
+                       Format_Object.No_Breaks := False;
+               end case;
+           end Set_Format;
+
+
+           procedure Make_Subhead (For_Type : Paragraph_Type) is
+           begin
+               case For_Type is
+                   when Syntax |
+                        Resolution |
+                        Legality |
+                        Static_Semantics |
+                        Link_Time |
+                        Run_Time |
+                        Bounded_Errors |
+                        Erroneous |
+                        Requirements | -- ImplReq
+                        Documentation | -- DocReq
+                        Metrics |
+                        Permissions | -- ImplPerm
+                        Advice | -- ImplAdvice
+                        Examples =>
+                       ARM_Output.Category_Header (Output_Object, 
Data.Paragraph_Kind_Title(For_Type).Str(1..Data.Paragraph_Kind_Title(For_Type).Length));
+                       Format_Object.Last_Paragraph_Subhead_Type := For_Type;
+                   when Notes | Single_Note => -- Notes
+                       if not Format_Object.Use_ISO_2004_Note_Format then
+                           -- The Notes header looks different from the others.
+                           ARM_Output.Start_Paragraph (Output_Object,
+                                                       Style  => 
ARM_Output.Small_Header,
+                                                       Indent => 1,
+                                                       Number => "",
+                                                       No_Breaks => True,
+                                                       Keep_with_Next => True);
+                           ARM_Output.Ordinary_Text (Output_Object, 
Data.Paragraph_Kind_Title(For_Type).Str(1..Data.Paragraph_Kind_Title(For_Type).Length));
+                           ARM_Output.End_Paragraph (Output_Object);
+                           Format_Object.Last_Paragraph_Subhead_Type := 
For_Type;
+--!!Debug:
+--Ada.Text_IO.Put_Line ("Write notes header");
+                       else
+                           null; -- No subheader. We don't change the last
+                               -- subheader generated, either.
+                       end if;
+                   when Language_Design | -- "MetaRules"
+                        Ada83_Inconsistencies | -- Inconsistent83
+                        Ada83_Incompatibilities | -- Incompatible83
+                        Ada83_Extensions | -- Extend83
+                        Ada83_Wording | -- DiffWord83
+                        Ada95_Inconsistencies | -- Inconsistent95
+                        Ada95_Incompatibilities | -- Incompatible95
+                        Ada95_Extensions | -- Extend95
+                        Ada95_Wording | -- DiffWord95
+                        Ada2005_Inconsistencies | -- Inconsistent2005
+                        Ada2005_Incompatibilities | -- Incompatible2005
+                        Ada2005_Extensions | -- Extend2005
+                        Ada2005_Wording | -- DiffWord2005
+                        Ada2012_Inconsistencies | -- Inconsistent2012
+                        Ada2012_Incompatibilities | -- Incompatible2012
+                        Ada2012_Extensions | -- Extend2012
+                        Ada2012_Wording => -- DiffWord2012
+                       ARM_Output.Category_Header (Output_Object, 
Paragraph_Kind_Title(For_Type).Str(1..Paragraph_Kind_Title(For_Type).Length));
+                       Format_Object.Last_Paragraph_Subhead_Type := For_Type;
+                   when Plain | Introduction | Element_Ref | Child_Ref | 
Usage_Note =>
+                       null; -- No subheader. We don't change the last
+                           -- subheader generated, either.
+                   when Reason | Ramification | Proof |
+                        Imp_Note | Corr_Change | Discussion |
+                        Honest | Glossary_Marker | Bare_Annotation |
+                        Wide_Above | Example_Text | Child_Example_Text |
+                        Indented_Example_Text | Code_Indented | Indent |
+                        Bulleted | Nested_Bulleted | Nested_X2_Bulleted |
+                        Display |
+                        Syntax_Display | Syntax_Indented | Syntax_Production |
+                        Hanging_Indented_1 | Hanging_Indented_2 |
+                        Hanging_Indented_3 | Hanging_Indented_4 | Title |
+                        Enumerated | Nested_Enumerated | Small |
+                        In_Table =>
+                       null; -- No subheader. We don't change the last
+                           -- subheader generated, either.
+               end case;
+           end Make_Subhead;
+
+
+           procedure Make_Annotation_Preface (For_Type : Paragraph_Type) is
+           begin
+               case For_Type is
+                   when Plain | Introduction |
+                        Syntax |
+                        Resolution |
+                        Legality |
+                        Static_Semantics |
+                        Link_Time |
+                        Run_Time |
+                        Bounded_Errors |
+                        Erroneous |
+                        Requirements | -- ImplReq
+                        Documentation | -- DocReq
+                        Metrics |
+                        Permissions | -- ImplPerm
+                        Advice | -- ImplAdvice
+                        Examples |
+                        Notes | Single_Note |
+                        Language_Design | -- "MetaRules"
+                        Ada83_Inconsistencies | -- Inconsistent83
+                        Ada83_Incompatibilities | -- Incompatible83
+                        Ada83_Extensions | -- Extend83
+                        Ada83_Wording | -- DiffWord83
+                        Ada95_Inconsistencies | -- Inconsistent95
+                        Ada95_Incompatibilities | -- Incompatible95
+                        Ada95_Extensions | -- Extend95
+                        Ada95_Wording | -- DiffWord95
+                        Ada2005_Inconsistencies | -- Inconsistent2005
+                        Ada2005_Incompatibilities | -- Incompatible2005
+                        Ada2005_Extensions | -- Extend2005
+                        Ada2005_Wording | -- DiffWord2005
+                        Ada2012_Inconsistencies | -- Inconsistent2012
+                        Ada2012_Incompatibilities | -- Incompatible2012
+                        Ada2012_Extensions | -- Extend2012
+                        Ada2012_Wording => -- DiffWord2012
+                       null; -- Not an annotation.
+                   when Reason | Ramification | Proof |
+                        Imp_Note | Corr_Change | Discussion |
+                        Honest | Glossary_Marker |
+                        Element_Ref | Child_Ref | Usage_Note =>
+                       declare
+                           Format_Bold : ARM_Output.Format_Type :=
+                               Format_Object.Text_Format;
+                       begin
+                           Format_Bold.Bold := True;
+                           ARM_Output.Text_Format (Output_Object,
+                                                   Format => Format_Bold);
+                       end;
+                       ARM_Output.Ordinary_Text (Output_Object,
+                            Text => Paragraph_Kind_Title(For_Type).Str(
+                                       
1..Paragraph_Kind_Title(For_Type).Length));
+                       ARM_Output.Text_Format (Output_Object,
+                                               Format => 
Format_Object.Text_Format);
+                       Format_Object.Last_Paragraph_Subhead_Type := For_Type;
+                   when Bare_Annotation =>
+                       null; -- Header (if any) is generated elsewhere.
+                   when Wide_Above |
+                        Example_Text | Child_Example_Text | 
Indented_Example_Text |
+                        Code_Indented | Indent |
+                        Bulleted | Nested_Bulleted | Nested_X2_Bulleted |
+                        Display | Syntax_Display |
+                        Syntax_Indented | Syntax_Production |
+                        Hanging_Indented_1 | Hanging_Indented_2 |
+                        Hanging_Indented_3 | Hanging_Indented_4 | Title |
+                        Enumerated | Nested_Enumerated | Small |
+                        In_Table =>
+                       null; -- Just a format.
+               end case;
+           end Make_Annotation_Preface;
+
+
+           function Show_Leading_Text_for_Paragraph return Boolean is
+               -- Returns True if the leading text (note number,
+               -- annotation preface, etc.) should be shown for this paragraph.
+               -- We assume that the current paragraph has a version less than
+               -- or equal to the one that we're displaying.
+               -- ** Note: This is not quite right. If this
+               -- paragraph is deleted, but a following one needs the
+               -- leading item, this will still lead the item out.
+               -- We *do* have enough information for that, at least in the
+               -- case of annotations: they can be marked as deleted, in
+               -- which case we don't need them here. *But* that information
+               -- doesn't get here in the case that we're not showing 
deletions.
+               -- I can't think of a fix right now, and the note numbers need
+               -- fixing ASAP.
+           begin
+--Ada.Text_IO.Put_Line ("Show_Leading_Text, para kind: " &
+--ARM_Database.Paragraph_Change_Kind_Type'Image(Format_Object.Next_Paragraph_Change_Kind)
 &
+--"; version=" & Format_Object.Next_Paragraph_Version & "; on line " & 
Arm_Input.Line_String(Input_Object));
+               if (ARM_Database."/=" 
(Format_Object.Next_Paragraph_Change_Kind, ARM_Database.Deleted) and then
+                   ARM_Database."/=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_Inserted_Number) and then
+                   ARM_Database."/=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_No_Delete_Message) and then
+                   ARM_Database."/=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_Inserted_Number_No_Delete_Message)) then
+                   -- Not a deleted paragraph.
+--Ada.Text_IO.Put_Line ("%% True - Not deleted");
+                   return True;
+               end if;
+               case Format_Object.Changes is
+                   when ARM_Format.Old_Only =>
+                       -- Display only the original version ('0').
+                       if ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_Inserted_Number) or else
+                          ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_Inserted_Number_No_Delete_Message) then
+--Ada.Text_IO.Put_Line ("%% True - Not original");
+                           return False; -- Not in the original document.
+                       else
+--Ada.Text_IO.Put_Line ("%% True - Original");
+                           return True; -- Probably in the original document.
+                               -- (If the paragraph numbers were "new" in a
+                               -- later version, we couldn't tell.)
+                       end if;
+                   when ARM_Format.New_Only =>
+                       -- Display only the version
+                       -- Format_Object.Change_Version, no insertions or 
deletions.
+--Ada.Text_IO.Put_Line ("%% False - New only");
+                       return False; -- This is always deleted.
+                   when ARM_Format.Show_Changes |
+                        ARM_Format.New_Changes =>
+                       -- Display only the the changes for versions
+                       -- Format_Object.Base_Change_Version ..
+                       -- Format_Object.Change_Version, older changes
+                       -- are applied and newer changes are ignored.
+                       -- (New_Changes shows deletions as a single
+                       -- character for older versions of Word, but otherwise
+                       -- is the same.)
+                       if Format_Object.Next_Paragraph_Version <
+                          Format_Object.Base_Change_Version then
+                           -- Change version is older than we're displaying;
+                           -- no text will be shown.
+--Ada.Text_IO.Put_Line ("%% False - show changes, old version");
+                           return False; -- This is always deleted.
+                       else
+                           -- The correct version.
+--Ada.Text_IO.Put_Line ("%% True - show changes, new enough version");
+                           return True; -- Show the item, as the old text
+                                        -- will be shown as deleted.
+                       end if;
+               end case;
+           end Show_Leading_Text_for_Paragraph;
+
+       begin
+           if not Format_Object.In_Paragraph then
+               -- Output subheader, if needed.
+               if Format_Object.Next_Paragraph_Subhead_Type /=
+                  Format_Object.Last_Paragraph_Subhead_Type then
+                   if (ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_No_Delete_Message) or else
+                       ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_Inserted_Number_No_Delete_Message)) and then
+                      ARM_Format."=" (Format_Object.Changes, 
ARM_Format.New_Only) then
+                       -- Nothing at all should be showm.
+                       null;
+if Format_Object.Next_Paragraph_Subhead_Type /= Plain or else
+   Format_Object.Next_Paragraph_Subhead_Type /= Introduction then
+   Ada.Text_IO.Put_Line("    -- No subhead (DelNoMsg); on line " & 
Arm_Input.Line_String(Input_Object));
+end if;
+                   elsif ((not Format_Object.Number_Paragraphs) or else
+                         Format_Object.No_Para_Num) and then
+                      (ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, ARM_Database.Deleted) or else
+                       ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_Inserted_Number)) and then
+                      ARM_Format."=" (Format_Object.Changes, 
ARM_Format.New_Only) then
+                       -- Nothing at all should be showm.
+                       null;
+if Format_Object.Next_Paragraph_Subhead_Type /= Plain or else
+   Format_Object.Next_Paragraph_Subhead_Type /= Introduction then
+   Ada.Text_IO.Put_Line("    -- No subhead (Del-no paranum); on line " & 
Arm_Input.Line_String(Input_Object));
+end if;
+                   else
+                       Make_Subhead 
(Format_Object.Next_Paragraph_Subhead_Type);
+                   end if;
+               end if;
+
+               -- Set the paragraph format:
+               Set_Format (Format_Object.Next_Paragraph_Format_Type);
+
+               if Format_Object.Number_Paragraphs and then
+                  not Format_Object.No_Para_Num then
+
+                   -- Format the paragraph number:
+                   Paragraph_Number_String (Update_Numbers => True);
+
+--Ada.Text_IO.Put_Line ("Check_Paragraph, make number " &
+--Format_Object.Current_Paragraph_String (1 .. 
Format_Object.Current_Paragraph_Len) &
+--": format= " & 
Paragraph_Type'Image(Format_Object.Next_Paragraph_Format_Type));
+                   -- ...and start the paragraph:
+                   if (ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_No_Delete_Message) or else
+                       ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_Inserted_Number_No_Delete_Message)) and then
+                      ARM_Format."=" (Format_Object.Changes, 
ARM_Format.New_Only) then
+                       -- Nothing at all should be showm.
+                       -- ** Warning ** If we lie here, the program will crash!
+                       Format_Object.No_Start_Paragraph := True;
+Ada.Text_IO.Put_Line("    -- No Start Paragraph (DelNoMsg)");
+                   else
+                       ARM_Output.Start_Paragraph (Output_Object,
+                                                   Style     => 
Format_Object.Style,
+                                                   Indent    => 
Format_Object.Indent,
+                                                   Number    => 
Format_Object.Current_Paragraph_String (1 .. 
Format_Object.Current_Paragraph_Len),
+                                                   No_Prefix => 
Format_Object.No_Prefix,
+                                                   Tab_Stops => 
Format_Object.Paragraph_Tab_Stops,
+                                                   No_Breaks => 
Format_Object.No_Breaks or Format_Object.In_Bundle,
+                                                   Keep_with_Next => 
Format_Object.Keep_with_Next or Format_Object.In_Bundle,
+                                                   Space_After => 
Format_Object.Space_After);
+                       Format_Object.No_Start_Paragraph := False;
+                   end if;
+                   if ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, ARM_Database.Deleted) or else
+                      ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_Inserted_Number) then
+                       -- If needed, make the "deleted text" message.
+                       -- We trust that Next_Paragraph_Change_Kind is not
+                       -- set to Deleted if the version number of the change
+                       -- is beyond the document generation version.
+                       -- (Note that Current_Change_Version may not be set,
+                       -- so it is not safe to test here.)
+                       case Format_Object.Changes is
+                           when ARM_Format.New_Only |
+                                ARM_Format.Show_Changes |
+                                ARM_Format.New_Changes =>
+                               -- Note that we include this in the
+                               -- "Show_Changes" version, even when the item
+                               -- is older than the base change version,
+                               -- so that complete paragraph deletions are 
obvious,
+                               -- and also so that we can use revision bars 
rather than
+                               -- displaying the changes in the RM version.
+                               if ARM_Format."=" (Format_Object.Changes, 
ARM_Format.New_Only) and then
+                                   (Format_Object.Next_Paragraph_Format_Type = 
Enumerated or else
+                                    Format_Object.Next_Paragraph_Format_Type = 
Nested_Enumerated or else
+                                    Format_Object.Next_Paragraph_Format_Type = 
Hanging_Indented_1 or else
+                                    Format_Object.Next_Paragraph_Format_Type = 
Hanging_Indented_2 or else
+                                    Format_Object.Next_Paragraph_Format_Type = 
Hanging_Indented_3 or else
+                                    Format_Object.Next_Paragraph_Format_Type = 
Hanging_Indented_4) then
+                                   -- We're in a hanging style, we need to end 
hanging first.
+                                   -- Nothing else will be displayed; if we 
didn't end the hang this
+                                   -- would end up on the same line as the 
next paragraph.
+                                   -- It's possible that we could have a 
problem with
+                                   -- hanging in one of the other cases if no 
text will be
+                                   -- displayed, but there is no way to know 
that here.
+                                   ARM_Output.End_Hang_Item (Output_Object);
+                               end if;
+                               ARM_Output.Text_Format (Output_Object,
+                                   Format => (Bold => 
Format_Object.Text_Format.Bold,
+                                              Italic => True,
+                                              Font => 
Format_Object.Text_Format.Font,
+                                              Color => 
Format_Object.Text_Format.Color,
+                                              Change => ARM_Output.None, -- 
Never mark this as changed!!
+                                              Version => '0', Added_Version => 
'0', -- Not used.
+                                              Size => 
ARM_Output."-"(Format_Object.Text_Format.Size, 1),
+                                              Location => 
Format_Object.Text_Format.Location));
+                               ARM_Output.Ordinary_Text (Output_Object,
+                                    Text => "This paragraph was deleted.");
+                               ARM_Output.Text_Format (Output_Object, -- 
Restore the format.
+                                           Format => 
Format_Object.Text_Format);
+                           when ARM_Format.Old_Only => null; -- Not deleted.
+                       end case;
+                   end if;
+                   Format_Object.In_Paragraph := True;
+                   Format_Object.Last_Non_Space := False;
+
+               else -- No paragraph numbers (or if the paragraph
+                    -- number has been suppressed with @NoParaNum):
+
+--Ada.Text_IO.Put_Line ("Check_Paragraph, no number: format= " & 
Paragraph_Type'Image(Format_Object.Next_Paragraph_Format_Type) &
+--   " output style= " & 
ARM_Output.Paragraph_Style_Type'Image(Format_Object.Style));
+                   -- Start the paragraph:
+                   if (ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_No_Delete_Message) or else
+                       ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_Inserted_Number_No_Delete_Message) or else
+                       ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, ARM_Database.Deleted) or else
+                       ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind, 
ARM_Database.Deleted_Inserted_Number)) and then
+                      ARM_Format."=" (Format_Object.Changes, 
ARM_Format.New_Only) then
+                       -- Nothing at all should be showm.
+                       -- ** Warning ** If we lie here, the program will crash!
+                       Format_Object.No_Start_Paragraph := True;
+Ada.Text_IO.Put_Line("    -- No Start Paragraph (Del-NewOnly)");
+                   else
+                       ARM_Output.Start_Paragraph (Output_Object,
+                                                   Style     => 
Format_Object.Style,
+                                                   Indent    => 
Format_Object.Indent,
+                                                   Number    => "",
+                                                   No_Prefix => 
Format_Object.No_Prefix,
+                                                   Tab_Stops => 
Format_Object.Paragraph_Tab_Stops,
+                                                   No_Breaks => 
Format_Object.No_Breaks or Format_Object.In_Bundle,
+                                                   Keep_with_Next => 
Format_Object.Keep_with_Next or Format_Object.In_Bundle,
+                                                   Space_After => 
Format_Object.Space_After);
+                       Format_Object.In_Paragraph := True;
+                       Format_Object.No_Start_Paragraph := False;
+                       Format_Object.Current_Paragraph_Len := 0; -- Empty 
paragraph number.
+                       Format_Object.No_Para_Num := False;
+                   end if;
+               end if;
+
+               if not Format_Object.No_Prefix then
+                   if Format_Object.Next_Paragraph_Format_Type = Notes and then
+                      Show_Leading_Text_for_Paragraph then
+                       if not Format_Object.Use_ISO_2004_Note_Format then
+                           -- Output the note number (Ada95 format).
+                           declare
+                               NNum : constant String := 
Integer'Image(Format_Object.Next_Note);
+                           begin
+                               ARM_Output.Ordinary_Text (Output_Object,
+                                                         NNum(2..NNum'Last));
+                               ARM_Output.Hard_Space (Output_Object);
+                               ARM_Output.Hard_Space (Output_Object);
+                               Format_Object.Next_Note := 
Format_Object.Next_Note + 1;
+                           end;
+                       else
+                           -- Output the note header (ISO 2004 format).
+                           declare
+                               NNum : constant String := 
Integer'Image(Format_Object.Next_Note);
+                           begin
+                               ARM_Output.Ordinary_Text (Output_Object,
+                                                         "NOTE " & 
NNum(2..NNum'Last));
+                               ARM_Output.Hard_Space (Output_Object);
+                               ARM_Output.Hard_Space (Output_Object);
+                               ARM_Output.Hard_Space (Output_Object);
+                               Format_Object.Next_Note := 
Format_Object.Next_Note + 1;
+                           end;
+                       end if;
+                   elsif Format_Object.Next_Paragraph_Format_Type = 
Single_Note and then
+                      Show_Leading_Text_for_Paragraph then
+                       if not Format_Object.Use_ISO_2004_Note_Format then
+                           -- No note number, and nothing else needed.
+                           null;
+                       else
+                           -- Output the note header (ISO 2004 format)
+                           -- without a number.
+                           ARM_Output.Ordinary_Text (Output_Object,
+                                                     "NOTE");
+                           ARM_Output.Hard_Space (Output_Object);
+                           ARM_Output.Hard_Space (Output_Object);
+                           ARM_Output.Hard_Space (Output_Object);
+                       end if;
+                   elsif (Format_Object.Next_Paragraph_Format_Type = 
Enumerated or else
+                       Format_Object.Next_Paragraph_Format_Type = 
Nested_Enumerated) and then
+                      Show_Leading_Text_for_Paragraph then
+                       -- Output the item number.
+                       if Format_Object.Use_ISO_2004_Note_Format then
+                           if Format_Object.Enumerated_Level <= 1 then -- 
Outer list.
+                               -- Lower case letters for list:
+                               ARM_Output.Ordinary_Text (Output_Object,
+                                  Character'Val 
((Format_Object.Next_Enumerated_Num - 1) +
+                                       Character'Pos ('a'))
+                                                          & ')');
+                               ARM_Output.End_Hang_Item (Output_Object);
+                               Format_Object.Next_Enumerated_Num := 
Format_Object.Next_Enumerated_Num + 1;
+                           else -- numbered.
+                               declare
+                                   NNum : constant String := 
Integer'Image(Format_Object.Next_Enumerated_Num);
+                               begin
+                                   ARM_Output.Ordinary_Text (Output_Object,
+                                                             
NNum(2..NNum'Last) & ')');
+                                   ARM_Output.End_Hang_Item (Output_Object);
+                                   Format_Object.Next_Enumerated_Num := 
Format_Object.Next_Enumerated_Num + 1;
+                               end;
+                           end if;
+                       else -- Ada 95 lists.
+                           declare
+                               NNum : constant String := 
Integer'Image(Format_Object.Next_Enumerated_Num);
+                           begin
+                               ARM_Output.Ordinary_Text (Output_Object,
+                                                         NNum(2..NNum'Last) & 
'.');
+                               ARM_Output.End_Hang_Item (Output_Object);
+                               Format_Object.Next_Enumerated_Num := 
Format_Object.Next_Enumerated_Num + 1;
+                           end;
+                       end if;
+                   end if;
+               else -- No prefix marked, meaning no number.
+                   Format_Object.No_Prefix := False; -- Reset.
+               end if;
+               Format_Object.Last_Non_Space := False;
+
+               Format_Object.Keep_with_Next := False; -- Reset for next 
paragraph.
+
+               Format_Object.Space_After := ARM_Output.Normal; -- Reset for 
next paragraph.
+
+               -- Output the annotation preface, if needed.
+               if Format_Object.Next_Paragraph_Subhead_Type /=
+                  Format_Object.Last_Paragraph_Subhead_Type then
+                   if Show_Leading_Text_for_Paragraph then
+                       Make_Annotation_Preface 
(Format_Object.Next_Paragraph_Subhead_Type);
+                   end if;
+               end if;
+
+               if Format_Object.References /= null then
+                   -- We assume these are only stored here if we want to see
+                   -- them on *this* paragraph. Thus, we just output them if
+                   -- they exist here. Note: This deallocates the references
+                   -- after writing them.
+                   if Format_Object.No_Start_Paragraph then
+                       -- Oh-oh! Can't generate references; there aren't
+                       -- supposed to be any at this point.
+                       Ada.Text_IO.Put_Line ("** References generated for no 
display paragraph; line " & ARM_Input.Line_String (Input_Object));
+                   else
+                       Make_References (Format_Object.References, 
Format_Object, Output_Object);
+                   end if;
+               end if;
+
+               -- Reset the "next" paragraph kind and version (we have to
+               -- wait, so that we can use this to determine whether
+               -- note numbers and things are output):
+               Format_Object.Next_Paragraph_Change_Kind := ARM_Database.None;
+               Format_Object.Next_Paragraph_Version := '0';
+           -- else already in a paragraph.
+           end if;
+       end Check_Paragraph;
+
+
+       procedure Check_End_Paragraph is
+           -- Check for the end of a paragraph; closing it if necessary.
+           -- We will never be in a paragraph after this routine.
+       begin
+           if Format_Object.In_Paragraph then
+               if not Format_Object.No_Start_Paragraph then
+                   ARM_Output.End_Paragraph (Output_Object);
+--else Ada.Text_IO.Put_Line("No Start Paragraph, so no End Paragraph");
+               end if;
+               Format_Object.In_Paragraph := False;
+               Format_Object.No_Start_Paragraph := False;
+               Format_Object.No_Para_Num := False;
+                       -- Make sure any "leftover"
+                       -- NoParaNums are cleared; we don't want this lasting 
into
+                       -- the next paragraph.
+               if Format_Object.In_Change then
+                   Ada.Text_IO.Put_Line ("** Paragraph end while in change; 
line " & ARM_Input.Line_String (Input_Object));
+                   Format_Object.In_Change := False;
+               end if;
+               -- Check command stack for any open formatting commands,
+               -- and complain (these won't be closed properly and chaos
+               -- may result):
+               for I in reverse 1 .. Format_State.Nesting_Stack_Ptr loop
+                   if Format_State.Nesting_Stack (I).Command in Bold .. 
Tab_Set then
+                       -- There is a formatting command active.
+                       -- (Note: not all of these can be on the stack.)
+                       Ada.Text_IO.Put_Line ("** Paragraph end while in 
formatting command " &
+                           Data.Command_Type'Image(Format_State.Nesting_Stack 
(I).Command) &
+                           "; line " & ARM_Input.Line_String (Input_Object));
+                       exit;
+                   end if;
+               end loop;
+           end if;
+       end Check_End_Paragraph;
+
+
+       type DIE_Kind is (None, Is_Root, Is_Partial);
+
+       procedure Display_Index_Entry (Term_Text : in String;
+                                      Special : in DIE_Kind := None) is
+           -- If necessary, display the index entry for Term_Text.
+           Is_AARM : constant Boolean := Is_AARM_Paragraph 
(Format_Object.Next_Paragraph_Subhead_Type);
+            use type ARM_Output.Size_Type;
+       begin
+           if Format_Object.Display_Index_Entries then
+               Check_Paragraph;
+               if not Is_AARM then
+                   ARM_Output.Text_Format (Output_Object,
+                      Format => (Bold => False, Italic => False,
+                                 Font => ARM_Output.Default,
+                                 Color => ARM_Output.Default,
+                                 Size => -1,
+                                 Change => Format_Object.Text_Format.Change,
+                                 Version => Format_Object.Text_Format.Version,
+                                 Added_Version => 
Format_Object.Text_Format.Added_Version,
+                                 Location => ARM_Output.Normal));
+               end if;
+               ARM_Output.Ordinary_Character (Output_Object, '{');
+               if not Is_AARM then
+                   ARM_Output.Text_Format (Output_Object,
+                      Format => (Bold => False, Italic => True,
+                                 Font => ARM_Output.Default,
+                                 Color => ARM_Output.Default,
+                                 Size => -1,
+                                 Change => Format_Object.Text_Format.Change,
+                                 Version => Format_Object.Text_Format.Version,
+                                 Added_Version => 
Format_Object.Text_Format.Added_Version,
+                                 Location => ARM_Output.Normal));
+               else
+                   ARM_Output.Text_Format (Output_Object,
+                      Format => (Bold => False, Italic => True,
+                                 Font => ARM_Output.Default,
+                                 Color => ARM_Output.Default,
+                                 Size => 0,
+                                 Change => Format_Object.Text_Format.Change,
+                                 Version => Format_Object.Text_Format.Version,
+                                 Added_Version => 
Format_Object.Text_Format.Added_Version,
+                                 Location => ARM_Output.Normal));
+               end if;
+               ARM_Output.Ordinary_Text (Output_Object, 
ARM_Index.Clean(Term_Text, Remove_Soft_Hyphens => True));
+               if not Is_AARM then
+                   ARM_Output.Text_Format (Output_Object,
+                      Format => (Bold => False, Italic => False,
+                                 Font => ARM_Output.Default,
+                                 Color => ARM_Output.Default,
+                                 Size => -1,
+                                 Change => Format_Object.Text_Format.Change,
+                                 Version => Format_Object.Text_Format.Version,
+                                 Added_Version => 
Format_Object.Text_Format.Added_Version,
+                                 Location => ARM_Output.Normal));
+               else
+                   ARM_Output.Text_Format (Output_Object,
+                      Format => (Bold => False, Italic => False,
+                                 Font => ARM_Output.Default,
+                                 Color => ARM_Output.Default,
+                                 Size => 0,
+                                 Change => Format_Object.Text_Format.Change,
+                                 Version => Format_Object.Text_Format.Version,
+                                 Added_Version => 
Format_Object.Text_Format.Added_Version,
+                                 Location => ARM_Output.Normal));
+               end if;
+               case Special is
+                   when None => null;
+                   when Is_Root => ARM_Output.Ordinary_Text (Output_Object, " 
[distributed]");
+                   when Is_Partial => ARM_Output.Ordinary_Text (Output_Object, 
" [partial]");
+               end case;
+               ARM_Output.Ordinary_Character (Output_Object, '}');
+               if not Is_AARM then
+                   ARM_Output.Text_Format (Output_Object,
+                      Format => (Bold => False, Italic => False,
+                                 Font => ARM_Output.Default,
+                                 Color => ARM_Output.Default,
+                                 Size => 0,
+                                 Change => Format_Object.Text_Format.Change,
+                                 Version => Format_Object.Text_Format.Version,
+                                 Added_Version => 
Format_Object.Text_Format.Added_Version,
+                                 Location => ARM_Output.Normal));
+               end if;
+               ARM_Output.Ordinary_Character (Output_Object, ' ');
+               Format_Object.Last_Non_Space := False;
+           -- else not displayed.
+           end if;
+       end Display_Index_Entry;
+
+
+       procedure Parse_Tab_Stops (Stops : in String;
+                                  Tabs : in out ARM_Output.Tab_Info) is
+           -- Parse "Stops" as a tab string; store the result in Tabs.
+           Loc : Natural := Stops'First;
+       begin
+           -- Parse tab stops:
+           -- <tab_stop> ::= <modifier><pica_count_literal>
+           -- <modifier> ::= L | P
+           -- <tab_stops> ::= <tab_stop> {, <tab_stop>}
+           while Loc <= Stops'Length loop
+               Tabs.Number := Tabs.Number + 1;
+               if Stops(Loc) = 'l' or Stops(Loc) = 'L' then
+                   Tabs.Stops(Tabs.Number).Kind :=
+                       ARM_Output.Left_Fixed;
+                   Loc := Loc + 1;
+               elsif Stops(Loc) = 'p' or Stops(Loc) = 'P' then
+                   Tabs.Stops(Tabs.Number).Kind :=
+                       ARM_Output.Left_Proportional;
+                   Loc := Loc + 1;
+               else -- Default:
+                   Tabs.Stops(Tabs.Number).Kind :=
+                       ARM_Output.Left_Fixed;
+               end if;
+               while Loc <= Stops'Length loop
+                   if Stops(Loc) in '0' .. '9' then
+                       Tabs.Stops(Tabs.Number).Stop :=
+                           Tabs.Stops(Tabs.Number).Stop * 10 +
+                           Character'Pos(Stops(Loc)) - Character'Pos('0');
+                       Loc := Loc + 1;
+                   else
+                       exit; -- Number ended.
+                   end if;
+               end loop;
+               if Tabs.Stops(Tabs.Number).Stop = 0 then
+                   Tabs.Number := Tabs.Number - 1;
+                   Ada.Text_IO.Put_Line ("  ** Bad tab stop format, position" 
& Natural'Image(Loc) &
+                       " in [" & Stops & "] from line " &
+                       ARM_Input.Line_String (Input_Object));
+                   exit; -- Give up on this tabset.
+               elsif Tabs.Number < 1 and then
+                       Tabs.Stops(Tabs.Number-1).Stop >=
+                       Tabs.Stops(Tabs.Number).Stop then
+                   Tabs.Number := Tabs.Number - 1;
+                   Ada.Text_IO.Put_Line ("  ** Bad tab stop, less than 
previous, at position" & Natural'Image(Loc) &
+                       " in [" & Stops & "] from line " &
+                       ARM_Input.Line_String (Input_Object));
+                   exit; -- Give up on this tabset.
+               end if;
+               if Loc > Stops'Length then
+                   exit; -- Finished.
+               elsif Stops(Loc) = ',' then
+                   Loc := Loc + 1;
+                   if Loc > Stops'Length then
+                       Ada.Text_IO.Put_Line ("  ** Bad tab stop set format, 
ends with comma in [" &
+                           Stops & "] from line " &
+                           ARM_Input.Line_String (Input_Object));
+                       exit; -- Give up on this tabset.
+                   end if;
+               end if;
+               -- Skip any blanks in between.
+               while Loc <= Stops'Length and then Stops(Loc) = ' ' loop
+                   Loc := Loc + 1;
+               end loop;
+           end loop;
+       end Parse_Tab_Stops;
+
+
+        procedure Write_Subindex (
+                           Subindex_Object : in out ARM_Subindex.Subindex_Type;
+                           Format_Object : in out Format_Type;
+                           Output_Object : in out ARM_Output.Output_Type'Class;
+                           Minimize_Lines : in Boolean) is
+           -- Writes a subindex for the document.
+        begin
+           Check_End_Paragraph;
+
+           -- Insert a blank paragraph:
+            ARM_Output.Start_Paragraph (Output_Object, ARM_Output.Normal,
+                                       Indent => 0, Number => "");
+           ARM_Output.Hard_Space (Output_Object);
+            ARM_Output.End_Paragraph (Output_Object);
+
+           ARM_Output.Set_Columns (Output_Object, Number_of_Columns => 2);
+
+           ARM_Subindex.Write_Subindex (
+                   Subindex_Object,
+                   Output_Object,
+                   Use_Paragraphs => Format_Object.Number_Paragraphs,
+                   Minimize_Lines => Minimize_Lines);
+
+           ARM_Output.Set_Columns (Output_Object, Number_of_Columns => 1);
+
+           -- Not in a paragraph here, either.
+        end Write_Subindex;
+
+
+        procedure Simple_Subindex_Item (
+                   Subindex_Object : in out ARM_Subindex.Subindex_Type;
+                   Format_Object : in out Format_Type;
+                   Output_Object : in out ARM_Output.Output_Type'Class;
+                   Entity_Kind_Name : in String) is
+           -- Create a simple subindex item; the command has a single
+           -- parameter <defn>.
+           -- Create an "In_Unit" entry for the item;
+           -- Also create two regular index entries:
+           --    One for <defn> with a secondary entry of "@i{in} <Unit>"
+           --    (where Unit is the unit saved by a previous RootLibUnit or
+           --    ChildUnit.),
+           -- and a Second (only for version < 2 and if the entity name is
+           --    non-null) for
+           --    "Language-Defined <Entity>" with a
+           --     secondary entry of "<defn> @i{in} <Unit>".
+           -- Also outputs the <defn> parameter to the output file.
+           Entity : String(1..80);
+           Len : Natural := 0;
+           Key : ARM_Index.Index_Key := ARM_Index.Get_Key;
+           Disposition : ARM_Output.Change_Type;
+           use type ARM_Output.Change_Type;
+        begin
+           ARM_Input.Copy_to_String_until_Close_Char (
+               Input_Object,
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char,
+               Entity,
+               Len);
+
+           -- Determine what to do with the "Language-Defined" entry:
+           Calc_Change_Disposition (
+               Format_Object => Format_Object,
+               Version => '2',
+               Operation => ARM_Output.Deletion,
+               Text_Kind => Disposition);
+           if Entity_Kind_Name'Length = 0 or else
+               Disposition = Do_Not_Display_Text then
+               null; -- Ignore this.
+           elsif Disposition = ARM_Output.None then
+               -- Normal reference:
+               ARM_Index.Add_Reusing_Key (
+                   Term => "Language-Defined " & Entity_Kind_Name,
+                   Subterm => Entity(1..Len) & " in " &
+                             Format_Object.Unit(1..Format_Object.Unit_Len),
+                   Kind => ARM_Index.SubDeclaration_in_Package,
+                   Clause => Clause_String (Format_Object),
+                   Paragraph => Paragraph_String,
+                   Key => Key);
+                   -- Note that the Subdeclaration type changes the
+                   -- "in" into italics.
+           elsif Disposition = ARM_Output.Deletion then
+               null; -- Ignore this (no change info in the index).
+           else -- Insertion.
+               raise Program_Error; -- An insertion inside of a deletion 
command!
+           end if;
+
+           Check_Paragraph;
+           ARM_Output.Index_Target (Output_Object, Key);
+
+           if Format_Object.Unit_Len = 0 then
+               Ada.Text_IO.Put_Line ("** No unit defined for index entry 
expecting one on line " & ARM_Input.Line_String (Input_Object));
+
+               ARM_Index.Add_Reusing_Key (
+                   Term => Entity(1..Len),
+                   Subterm => "*unknown*",
+                   Kind => ARM_Index.Declaration_in_Package,
+                   Clause => Clause_String (Format_Object),
+                   Paragraph => Paragraph_String,
+                   Key => Key);
+
+               ARM_Subindex.Insert (
+                   Subindex_Object => Subindex_Object,
+                   Entity => Entity(1..Len),
+                   From_Unit => "*unknown*",
+                   Kind => ARM_Subindex.In_Unit,
+                   Clause => Clause_String (Format_Object),
+                   Paragraph => Paragraph_String,
+                   Key => Key);
+           else
+               ARM_Index.Add_Reusing_Key (
+                   Term => Entity(1..Len),
+                   Subterm => Format_Object.Unit(1..Format_Object.Unit_Len),
+                   Kind => ARM_Index.Declaration_in_Package,
+                   Clause => Clause_String (Format_Object),
+                   Paragraph => Paragraph_String,
+                   Key => Key);
+
+               ARM_Subindex.Insert (
+                   Subindex_Object => Subindex_Object,
+                   Entity => Entity(1..Len),
+                   From_Unit => Format_Object.Unit(1..Format_Object.Unit_Len),
+                   Kind => ARM_Subindex.In_Unit,
+                   Clause => Clause_String (Format_Object),
+                   Paragraph => Paragraph_String,
+                   Key => Key);
+           end if;
+
+           ARM_Output.Ordinary_Text (Output_Object, Entity(1..Len));
+           Format_Object.Last_Non_Space := True;
+       end Simple_Subindex_Item;
+
+
+        procedure Child_Unit (
+                   Subindex_Object : in out ARM_Subindex.Subindex_Type;
+                   Format_Object : in out Format_Type;
+                   Output_Object : in out ARM_Output.Output_Type'Class) is
+           -- Generates three index entries: An index entry for <child>, with
+           -- a secondary of "@i{child of} <parent>", an index entry for
+           -- "Language-Defined Library Units" with a secondary entry of
+           -- <parent>.<child>, and an index entry for <parent>.<child>. The
+           -- Unit is set to <parent>.<child>. (For version 2 or later, the
+           -- Language-Defined entry is not generated.) The first entry is
+           -- added to the subindex list as well.
+           Close_Ch : Character;
+           Parent, Child : String(1..80);
+           PLen, CLen : Natural := 0;
+           Key : ARM_Index.Index_Key := ARM_Index.Get_Key;
+            Disposition : ARM_Output.Change_Type;
+            use type ARM_Output.Change_Type;
+        begin
+           ARM_Input.Check_Parameter_Name (Input_Object,
+               Param_Name => "Parent" & (7..ARM_Input.Command_Name_Type'Last 
=> ' '),
+               Is_First => True,
+               Param_Close_Bracket => Close_Ch);
+           if Close_Ch /= ' ' then
+               -- Copy over the term:
+               ARM_Input.Copy_to_String_until_Close_Char (
+                   Input_Object,
+                   Close_Ch,
+                   Parent,
+                   PLen);
+           -- else no parameter. Weird.
+           end if;
+
+           ARM_Input.Check_Parameter_Name (Input_Object,
+               Param_Name => "Child" & (6..ARM_Input.Command_Name_Type'Last => 
' '),
+               Is_First => False,
+               Param_Close_Bracket => Close_Ch);
+           if Close_Ch /= ' ' then
+               -- Copy over the term:
+               ARM_Input.Copy_to_String_until_Close_Char (
+                   Input_Object,
+                   Close_Ch,
+                   Child,
+                   CLen);
+           -- else no parameter. Weird.
+           end if;
+
+           -- Set the current unit for future use:
+           Format_Object.Unit_Len := PLen + CLen + 1;
+           Format_Object.Unit (1..Format_Object.Unit_Len) :=
+               Parent(1..PLen) & '.' & Child(1..CLen);
+
+           ARM_Index.Add_Reusing_Key (
+                   Term => Child(1..CLen),
+                   Subterm => Parent(1..PLen),
+                   Kind => ARM_Index.Child_Unit_Parent,
+                   Clause => Clause_String (Format_Object),
+                   Paragraph => Paragraph_String,
+                   Key => Key);
+
+           Check_Paragraph;
+           ARM_Output.Index_Target (Output_Object, Key);
+
+           -- Determine what to do with the "Language-Defined" entry:
+           Calc_Change_Disposition (
+               Format_Object => Format_Object,
+               Version => '2',
+               Operation => ARM_Output.Deletion,
+               Text_Kind => Disposition);
+           if Disposition = Do_Not_Display_Text then
+               null; -- Ignore this.
+           elsif Disposition = ARM_Output.None then
+               -- Make reference:
+               ARM_Index.Add_Reusing_Key (
+                   Term => "Language-Defined Library Units",
+                   Subterm => Parent(1..PLen) & '.' & Child(1..CLen),
+                   Kind => ARM_Index.Primary_Term_and_Subterm,
+                   Clause => Clause_String (Format_Object),
+                   Paragraph => Paragraph_String,
+                   Key => Key);
+           elsif Disposition = ARM_Output.Deletion then
+               null; -- Ignore this (no change info in the index).
+           else -- Insertion.
+               raise Program_Error; -- An insertion inside of a deletion 
command!
+           end if;
+
+           ARM_Index.Add_Reusing_Key (
+                   Term => Parent(1..PLen) & '.' & Child(1..CLen),
+                   Kind => ARM_Index.Primary_Term,
+                   Clause => Clause_String (Format_Object),
+                   Paragraph => Paragraph_String,
+                   Key => Key);
+
+           ARM_Subindex.Insert (
+                   Subindex_Object => Subindex_Object,
+                   Entity => Child(1..CLen),
+                   From_Unit => Parent(1..PLen),
+                   Kind => ARM_Subindex.Child_of_Parent,
+                   Clause => Clause_String (Format_Object),
+                   Paragraph => Paragraph_String,
+                   Key => Key);
+
+           -- Leave the command end marker, let normal processing
+           -- get rid of it.
+        end Child_Unit;
+
+
+       procedure Process_Begin is
+           -- Process a "begin". The "begin" has been stacked.
+
+           procedure Toss_for_RM (Paragraph_Kind_Name : in String) is
+               -- Call this for AARM-only sections.
+               -- It skips *everything* until the matching end. This includes
+               -- index references, section references, and the like. Anything
+               -- that ought to be in the RM should be moved outside of the
+               -- AARM specific code. Thus, we can use a fairly simple text
+               -- skip.
+               Ch : Character;
+               Close_Ch : Character;
+               Command_Name : ARM_Input.Command_Name_Type;
+           begin
+               -- Skip everything up to the next @end{<Paragraph_Kind_Name...
+               -- then pop the stack and return.
+               loop
+                   ARM_Input.Get_Char (Input_Object, Ch);
+                   while Ch /= '@' loop
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                   end loop;
+                   Arm_Input.Get_Name (Input_Object, Command_Name, 
Null_Name_Allowed => True);
+                       -- Get the command name.
+                   if Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim 
(
+                       Command_Name, Ada.Strings.Right)) /= "end" then
+                       -- Not an "end" command, keep going.
+                       null;
+                   else -- An End command, check if this is the one we want:
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       if ARM_Input.Is_Open_Char (Ch) then -- Start parameter:
+                           Close_Ch := ARM_Input.Get_Close_Char (Ch);
+                           Arm_Input.Get_Name (Input_Object, Command_Name); -- 
Get the end "type".
+                           if Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (
+                               Command_Name, Ada.Strings.Right)) /= 
Paragraph_Kind_Name then
+                               null; -- Wrong end, keep going.
+                           else -- Right end!
+                               -- Skip to the close character:
+                               while Ch /= Close_Ch loop
+                                   ARM_Input.Get_Char (Input_Object, Ch);
+                               end loop;
+                               -- Unstack the "begin".
+                               Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (End AARM-Only)");
+                               -- And we're done with this "begin".
+                               return;
+                           end if;
+                       else -- No parameter, forget it.
+                           null;
+                       end if;
+                   end if;
+               end loop;
+           end Toss_for_RM;
+
+       begin
+           Check_End_Paragraph; -- End any paragraph that we're in.
+           if Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "comment" then
+               Toss_for_RM ("comment");
+           -- Format only:
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "wideabove" then
+               Format_Object.Next_Paragraph_Format_Type := Wide_Above;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "example" then
+               Format_Object.Next_Paragraph_Format_Type := Example_Text;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "childexample" then
+               Format_Object.Next_Paragraph_Format_Type := Child_Example_Text;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "descexample" then
+               Format_Object.Next_Paragraph_Format_Type := 
Indented_Example_Text;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "describecode" then
+               Format_Object.Next_Paragraph_Format_Type := Code_Indented;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "indent" then
+               Format_Object.Next_Paragraph_Format_Type := Indent;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "itemize" then
+               Format_Object.Next_Paragraph_Format_Type := Bulleted;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "inneritemize" then
+               Format_Object.Next_Paragraph_Format_Type := Nested_Bulleted;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "innerinneritemize" then
+               Format_Object.Next_Paragraph_Format_Type := Nested_X2_Bulleted;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "display" then
+               Format_Object.Next_Paragraph_Format_Type := Display;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "syntaxdisplay" then
+               Format_Object.Next_Paragraph_Format_Type := Syntax_Display;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "syntaxtext" then
+               Format_Object.Next_Paragraph_Format_Type := Syntax_Indented;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "description" then
+               Format_Object.Next_Paragraph_Format_Type := Hanging_Indented_3;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "small" then
+               Format_Object.Next_Paragraph_Format_Type := Small;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "enumerate" then
+               Format_Object.Next_Paragraph_Format_Type := Enumerated;
+               Format_Object.Next_Enumerated_Num := 1;
+               Format_Object.Enumerated_Level := 
Format_Object.Enumerated_Level + 1;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "innerenumerate" then
+               Format_Object.Next_Paragraph_Format_Type := Nested_Enumerated;
+               Format_Object.Next_Enumerated_Num := 1;
+               Format_Object.Enumerated_Level := 
Format_Object.Enumerated_Level + 1;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "hang1list" then
+               Format_Object.Next_Paragraph_Format_Type := Hanging_Indented_1;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "hang2list" then
+               Format_Object.Next_Paragraph_Format_Type := Hanging_Indented_2;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "hang3list" then
+               Format_Object.Next_Paragraph_Format_Type := Hanging_Indented_3;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "hang4list" then
+               Format_Object.Next_Paragraph_Format_Type := Hanging_Indented_4;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "title" then
+               Format_Object.Next_Paragraph_Format_Type := Title;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "bundle" then
+               -- Should prevent any page breaks until the "end". Not
+               -- implemented currently.
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Is_Formatting
+                   := False; -- Leave the format alone.
+               Format_Object.In_Bundle := True; -- We don't need to stack this,
+                   -- because once we're in it, we can't leave it until the 
@End.
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "twocol" then
+               -- Two column; no affect on format.
+               ARM_Output.Set_Columns (Output_Object, Number_of_Columns => 2);
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Is_Formatting
+                   := False;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "fourcol" then
+               -- Four column; no affect on format.
+               ARM_Output.Set_Columns (Output_Object, Number_of_Columns => 4);
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Is_Formatting
+                   := False;
+           -- RM groupings:
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "intro" then
+               Format_Object.Next_Paragraph_Format_Type := Introduction;
+               Format_Object.Next_Paragraph_Subhead_Type := Introduction;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "syntax" then
+               Format_Object.Next_Paragraph_Format_Type := Syntax;
+               Format_Object.Next_Paragraph_Subhead_Type := Syntax;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "resolution" then
+               Format_Object.Next_Paragraph_Format_Type := Resolution;
+               Format_Object.Next_Paragraph_Subhead_Type := Resolution;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "legality" then
+               Format_Object.Next_Paragraph_Format_Type := Legality;
+               Format_Object.Next_Paragraph_Subhead_Type := Legality;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "staticsem" then
+               Format_Object.Next_Paragraph_Format_Type := Static_Semantics;
+               Format_Object.Next_Paragraph_Subhead_Type := Static_Semantics;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "linktime" then
+               Format_Object.Next_Paragraph_Format_Type := Link_Time;
+               Format_Object.Next_Paragraph_Subhead_Type := Link_Time;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "runtime" then
+               Format_Object.Next_Paragraph_Format_Type := Run_Time;
+               Format_Object.Next_Paragraph_Subhead_Type := Run_Time;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "bounded" then
+               Format_Object.Next_Paragraph_Format_Type := Bounded_Errors;
+               Format_Object.Next_Paragraph_Subhead_Type := Bounded_Errors;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "erron" then
+               Format_Object.Next_Paragraph_Format_Type := Erroneous;
+               Format_Object.Next_Paragraph_Subhead_Type := Erroneous;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "implreq" then
+               Format_Object.Next_Paragraph_Format_Type := Requirements;
+               Format_Object.Next_Paragraph_Subhead_Type := Requirements;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "docreq" then
+               Format_Object.Next_Paragraph_Format_Type := Documentation;
+               Format_Object.Next_Paragraph_Subhead_Type := Documentation;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "metrics" then
+               Format_Object.Next_Paragraph_Format_Type := Metrics;
+               Format_Object.Next_Paragraph_Subhead_Type := Metrics;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "implperm" then
+               Format_Object.Next_Paragraph_Format_Type := Permissions;
+               Format_Object.Next_Paragraph_Subhead_Type := Permissions;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "impladvice" then
+               Format_Object.Next_Paragraph_Format_Type := Advice;
+               Format_Object.Next_Paragraph_Subhead_Type := Advice;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "examples" then
+               Format_Object.Next_Paragraph_Format_Type := Examples;
+               Format_Object.Next_Paragraph_Subhead_Type := Examples;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "notes" then
+               Format_Object.Next_Paragraph_Format_Type := Notes;
+               Format_Object.Next_Paragraph_Subhead_Type := Notes;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "singlenote" then
+               Format_Object.Next_Paragraph_Format_Type := Single_Note;
+               Format_Object.Next_Paragraph_Subhead_Type := Single_Note;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "rmonly" then
+               if Format_Object.Include_Annotations then -- AARM, but this is 
RM-only.
+                   Toss_for_RM ("rmonly");
+               else
+                   
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Is_Formatting
+                       := False; -- Leave the format alone.
+               end if;
+           -- NotISO text:
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "notiso" then
+               if Format_Object.Include_ISO then
+                   Toss_for_RM ("notiso"); -- This text does not appear in ISO 
documents.
+               else -- not ISO
+                   
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Is_Formatting
+                       := False; -- Leave the format alone.
+               end if;
+--!!Debug:
+---Ada.Text_IO.Put_Line ("Next=" & 
Paragraph_Type'Image(Format_Object.Next_Paragraph_Subhead_Type));
+
+           -- ISOOnly text:
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "isoonly" then
+               if Format_Object.Include_ISO then
+                   
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Is_Formatting
+                       := False; -- Leave the format alone.
+               else -- Not ISO
+                   Toss_for_RM ("isoonly"); -- This text does not appear in 
non-ISO documents.
+               end if;
+           -- AARM groupings:
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "metarules" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Language_Design;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Language_Design;
+               else -- Don't show annotations.
+                   Toss_for_RM ("metarules");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "inconsistent83" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := 
Ada83_Inconsistencies;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada83_Inconsistencies;
+               else -- Don't show annotations.
+                   Toss_for_RM ("inconsistent83");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "incompatible83" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := 
Ada83_Incompatibilities;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada83_Incompatibilities;
+               else -- Don't show annotations.
+                   Toss_for_RM ("incompatible83");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "extend83" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := 
Ada83_Extensions;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada83_Extensions;
+               else -- Don't show annotations.
+                   Toss_for_RM ("extend83");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "diffword83" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Ada83_Wording;
+                   Format_Object.Next_Paragraph_Subhead_Type := Ada83_Wording;
+               else -- Don't show annotations.
+                   Toss_for_RM ("diffword83");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "inconsistent95" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := 
Ada95_Inconsistencies;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada95_Inconsistencies;
+               else -- Don't show annotations.
+                   Toss_for_RM ("inconsistent95");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "incompatible95" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := 
Ada95_Incompatibilities;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada95_Incompatibilities;
+               else -- Don't show annotations.
+                   Toss_for_RM ("incompatible95");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "extend95" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := 
Ada95_Extensions;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada95_Extensions;
+               else -- Don't show annotations.
+                   Toss_for_RM ("extend95");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "diffword95" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Ada95_Wording;
+                   Format_Object.Next_Paragraph_Subhead_Type := Ada95_Wording;
+               else -- Don't show annotations.
+                   Toss_for_RM ("diffword95");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "inconsistent2005" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := 
Ada2005_Inconsistencies;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada2005_Inconsistencies;
+               else -- Don't show annotations.
+                   Toss_for_RM ("inconsistent2005");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "incompatible2005" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := 
Ada2005_Incompatibilities;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada2005_Incompatibilities;
+               else -- Don't show annotations.
+                   Toss_for_RM ("incompatible2005");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "extend2005" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := 
Ada2005_Extensions;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada2005_Extensions;
+               else -- Don't show annotations.
+                   Toss_for_RM ("extend2005");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "diffword2005" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Ada2005_Wording;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada2005_Wording;
+               else -- Don't show annotations.
+                   Toss_for_RM ("diffword2005");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "inconsistent2012" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := 
Ada2012_Inconsistencies;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada2012_Inconsistencies;
+               else -- Don't show annotations.
+                   Toss_for_RM ("inconsistent2012");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "incompatible2012" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := 
Ada2012_Incompatibilities;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada2012_Incompatibilities;
+               else -- Don't show annotations.
+                   Toss_for_RM ("incompatible2012");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "extend2012" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := 
Ada2012_Extensions;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada2012_Extensions;
+               else -- Don't show annotations.
+                   Toss_for_RM ("extend2012");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "diffword2012" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Ada2012_Wording;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Ada2012_Wording;
+               else -- Don't show annotations.
+                   Toss_for_RM ("diffword2012");
+               end if;
+           -- ASIS groupings:
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "elementref" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Element_Ref;
+                   Format_Object.Next_Paragraph_Subhead_Type := Element_Ref;
+               else -- Don't show annotations.
+                   Toss_for_RM ("elementref");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "childref" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Child_Ref;
+                   Format_Object.Next_Paragraph_Subhead_Type := Child_Ref;
+               else -- Don't show annotations.
+                   Toss_for_RM ("childref");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "usagenote" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Usage_Note;
+                   Format_Object.Next_Paragraph_Subhead_Type := Usage_Note;
+               else -- Don't show annotations.
+                   Toss_for_RM ("usagenote");
+               end if;
+           -- AARM annotations:
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "discussion" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Discussion;
+                   Format_Object.Next_Paragraph_Subhead_Type := Discussion;
+               else -- Don't show annotations.
+                   Toss_for_RM ("discussion");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "reason" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Reason;
+                   Format_Object.Next_Paragraph_Subhead_Type := Reason;
+               else -- Don't show annotations.
+                   Toss_for_RM ("reason");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "ramification" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Ramification;
+                   Format_Object.Next_Paragraph_Subhead_Type := Ramification;
+               else -- Don't show annotations.
+                   Toss_for_RM ("ramification");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "theproof" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Proof;
+                   Format_Object.Next_Paragraph_Subhead_Type := Proof;
+               else -- Don't show annotations.
+                   Toss_for_RM ("theproof");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "implnote" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Imp_Note;
+                   Format_Object.Next_Paragraph_Subhead_Type := Imp_Note;
+               else -- Don't show annotations.
+                   Toss_for_RM ("implnote");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "honest" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Honest;
+                   Format_Object.Next_Paragraph_Subhead_Type := Honest;
+               else -- Don't show annotations.
+                   Toss_for_RM ("honest");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "glossarymarker" then
+               if Format_Object.Include_Annotations then
+                   Format_Object.Next_Paragraph_Format_Type := Glossary_Marker;
+                   Format_Object.Next_Paragraph_Subhead_Type := 
Glossary_Marker;
+               else -- Don't show annotations.
+                   Toss_for_RM ("glossarymarker");
+               end if;
+           elsif Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (
+               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right))
+               = "aarmonly" then
+               if Format_Object.Include_Annotations then
+                   null; -- Leave the format alone.
+               else -- Don't show annotations.
+                   Toss_for_RM ("aarmonly");
+               end if;
+           else
+               Ada.Text_IO.Put_Line ("  -- Unknown 'begin' type - " &
+                   Ada.Strings.Fixed.Trim 
(Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right) &
+                   " on line " & ARM_Input.Line_String (Input_Object));
+           end if;
+       end Process_Begin;
+
+
+       procedure Process_Command_with_Parameter is
+           -- Process the start of a command with a parameter.
+           -- The parameter character has been processed, and
+           -- a stack item pushed.
+
+           function Get_NT return String is
+               -- Local routine:
+               -- Return the "current" non-terminal from
+               -- the Syntax_NT string. Handles @Chg.
+           begin
+               return Get_Current_Item (Format_Object, Input_Object,
+                   Format_Object.Syntax_NT (1 .. Format_Object.Syntax_NT_Len));
+           end Get_NT;
+
+
+           function Get_Old_NT return String is
+               -- Local routine:
+               -- Return the "current" non-terminal from
+               -- the Syntax_NT string. Handles @Chg.
+           begin
+               return Get_Old_Item (Format_Object, Input_Object,
+                   Format_Object.Syntax_NT (1 .. Format_Object.Syntax_NT_Len));
+           end Get_Old_NT;
+
+
+           procedure Get_Change_Version (Is_First : in Boolean;
+                                         Version : out Character) is
+               -- Get a parameter named "Version",
+               -- containing a character representing the version number.
+               Ch, Close_Ch : Character;
+           begin
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => "Version" & 
(8..ARM_Input.Command_Name_Type'Last => ' '),
+                   Is_First => Is_First,
+                   Param_Close_Bracket => Close_Ch);
+               if Close_Ch /= ' ' then
+                   -- Get the version character:
+                   ARM_Input.Get_Char (Input_Object, Version);
+                   ARM_Input.Get_Char (Input_Object, Ch);
+                   if Ch /= Close_Ch then
+                       Ada.Text_IO.Put_Line ("  ** Bad close for change 
version on line " & ARM_Input.Line_String (Input_Object));
+                       ARM_Input.Replace_Char (Input_Object);
+                   end if;
+               -- else no parameter. Weird.
+               end if;
+           end Get_Change_Version;
+
+
+           procedure Get_Change_Kind (Kind : out 
ARM_Database.Paragraph_Change_Kind_Type) is
+               -- Get a parameter named "Kind", containing a word representing
+               -- a change kind.
+               Kind_Name : ARM_Input.Command_Name_Type;
+               Ch, Close_Ch : Character;
+           begin
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => "Kind" & (5..ARM_Input.Command_Name_Type'Last 
=> ' '),
+                   Is_First => False,
+                   Param_Close_Bracket => Close_Ch);
+               if Close_Ch /= ' ' then
+                   -- Get the kind word:
+                   Arm_Input.Get_Name (Input_Object, Kind_Name);
+                   ARM_Input.Get_Char (Input_Object, Ch);
+                   if Ch /= Close_Ch then
+                       Ada.Text_IO.Put_Line ("  ** Bad close for change kind 
on line " & ARM_Input.Line_String (Input_Object));
+                       ARM_Input.Replace_Char (Input_Object);
+                   end if;
+                   if Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim 
(Kind_Name, Ada.Strings.Right)) =
+                       "revised" then
+                       Kind := ARM_Database.Revised;
+                   elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Kind_Name, Ada.Strings.Right)) =
+                       "revisedadded" then
+                       Kind := ARM_Database.Revised_Inserted_Number;
+                   elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Kind_Name, Ada.Strings.Right)) =
+                       "added" then
+                       Kind := ARM_Database.Inserted;
+                   elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Kind_Name, Ada.Strings.Right)) =
+                       "addednormal" then
+                       Kind := ARM_Database.Inserted_Normal_Number;
+                   elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Kind_Name, Ada.Strings.Right)) =
+                       "deleted" then
+                       Kind := ARM_Database.Deleted;
+                   elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Kind_Name, Ada.Strings.Right)) =
+                       "deletedadded" then
+                       Kind := ARM_Database.Deleted_Inserted_Number;
+                   elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Kind_Name, Ada.Strings.Right)) =
+                       "deletednodelmsg" then
+                       Kind := ARM_Database.Deleted_No_Delete_Message;
+                   elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Kind_Name, Ada.Strings.Right)) =
+                       "deletedaddednodelmsg" then
+                       Kind := 
ARM_Database.Deleted_Inserted_Number_No_Delete_Message;
+                   else
+                       Ada.Text_IO.Put_Line ("  ** Bad kind for change kind: " 
&
+                               Ada.Strings.Fixed.Trim (Kind_Name, 
Ada.Strings.Right) &
+                               " on line " & ARM_Input.Line_String 
(Input_Object));
+                   end if;
+               -- else no parameter. Weird.
+               end if;
+           end Get_Change_Kind;
+
+
+           procedure Get_Boolean (Param_Name : in ARM_Input.Command_Name_Type;
+                                  Result : out Boolean) is
+               -- Get a boolean value from a parameter named Param_Name.
+               Ch, Close_Ch : Character;
+           begin
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => Param_Name,
+                   Is_First => False,
+                   Param_Close_Bracket => Close_Ch);
+               if Close_Ch /= ' ' then
+                   -- Get the Boolean character:
+                   ARM_Input.Get_Char (Input_Object, Ch);
+                   case Ch is
+                       when 'F' | 'f' | 'N' | 'n' =>
+                           Result := False;
+                       when 'T' | 't' | 'Y' | 'y' =>
+                           Result := True;
+                       when others =>
+                           Ada.Text_IO.Put_Line ("  ** Bad value for boolean 
parameter " &
+                               Ada.Strings.Fixed.Trim (Param_Name, 
Ada.Strings.Right) &
+                               " on line " & ARM_Input.Line_String 
(Input_Object));
+                   end case;
+                   ARM_Input.Get_Char (Input_Object, Ch);
+                   if Ch /= Close_Ch then
+                       Ada.Text_IO.Put_Line ("  ** Bad close for boolean 
parameter " &
+                           Ada.Strings.Fixed.Trim (Param_Name, 
Ada.Strings.Right) &
+                           " on line " & ARM_Input.Line_String (Input_Object));
+                       ARM_Input.Replace_Char (Input_Object);
+                   end if;
+               -- else no parameter. Weird.
+               end if;
+           end Get_Boolean;
+
+
+           procedure Gen_Ref_or_ARef_Parameter (Display_It : Boolean) is
+               -- Generate (and read) a "Ref" or "ARef" parameter, containing
+               -- a DR or AI reference. Generate it into the document only
+               -- if Display_It is True.
+               Ch, Close_Ch : Character;
+               Ref_Name : ARM_Input.Command_Name_Type;
+               Len : Natural;
+               Which_Param : ARM_Input.Param_Num;
+               New_Ref, Cursor : Reference_Ptr;
+           begin
+               ARM_Input.Check_One_of_Parameter_Names (Input_Object,
+                   Param_Name_1 => "Ref" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                   Param_Name_2 => "ARef" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                   Is_First => False,
+                   Param_Found => Which_Param,
+                   Param_Close_Bracket => Close_Ch);
+               if Close_Ch /= ' ' then
+                   -- Get the reference:
+                   Len := 0;
+                   loop
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       if Ch /= Close_Ch then
+                           Len := Len + 1;
+                           if Len > Ref_Name'Last then
+                               Ada.Text_IO.Put_Line ("  ** Reference too long 
on line " & ARM_Input.Line_String (Input_Object));
+                           else
+                               Ref_Name(Len) := Ch;
+                           end if;
+                       else -- End of the reference.
+                           if Len = 0 then
+                               Ada.Text_IO.Put_Line ("  ** Failed to find 
reference on line " & ARM_Input.Line_String (Input_Object));
+                           end if;
+                           exit;
+                       end if;
+                   end loop;
+
+                   if Display_It then
+                       -- Save a reference for outputting on the next
+                       -- paragraph start.
+                       New_Ref := Allocate_Reference;
+                       New_Ref.all := (Ref_Name => Ref_Name,
+                                       Ref_Len => Len,
+                                       Is_DR_Ref => (Which_Param = 1),
+                                          -- DR reference if Param = 1;
+                                          -- AI reference otherwise.
+                                       Next => null);
+                       -- Attach this to the *end* of the list.
+                       if Format_Object.References = null then
+                           Format_Object.References := New_Ref;
+                       else
+                           Cursor := Format_Object.References;
+                           while Cursor.Next /= null loop
+                               Cursor := Cursor.next;
+                           end loop;
+                           Cursor.Next := New_Ref;
+                       end if;
+                   -- else don't display it.
+                   end if;
+               -- else no parameter. Weird.
+               end if;
+           end Gen_Ref_or_ARef_Parameter;
+
+
+           procedure Gen_Chg_xxxx (Param_Cmd   : in Data.Command_Type;
+                                   AARM_Prefix : in String) is
+               -- Implement chgimpdef, chgimpladv, chgdocreq, and
+               -- chgaspectdesc commands.
+               -- The AARM prefix (if needed) is AARM_Prefix, and
+               -- the parameter command is Param_Cmd.
+
+               -- This command is of the form:
+               -- @chgxxxxx{Version=[<version>], Kind=(<kind>),
+               --   Text=(<text>)}}
+               -- where <version> is a single character, <Kind> is one
+               -- of Revised, Added, or Deleted, and this is followed
+               -- by the text. As usual, any of the
+               -- allowed bracketing characters can be used.
+               Close_Ch     : Character;
+               Kind         : ARM_Database.Paragraph_Change_Kind_Type;
+               Version      : ARM_Contents.Change_Version_Type;
+               Display_It   : Boolean;
+               use type ARM_Database.Paragraph_Change_Kind_Type;
+               Local_Change : ARM_Output.Change_Type;
+               Skip_Header  : Boolean := False;
+           begin
+               Get_Change_Version (Is_First => True,
+                   Version => Version);
+                   -- Read a parameter named "Version".
+
+               Get_Change_Kind (Kind);
+                   -- Read a parameter named "Kind".
+
+               if Format_Object.Impdef_Info.Command /= None then
+                   Ada.Text_IO.Put_Line ("  ** Nested impdef entry on line " & 
ARM_Input.Line_String (Input_Object));
+               -- else OK.
+               end if;
+               -- Setup impdef information for this command:
+               case Param_Cmd is
+                   when Change_Impdef_Text_Param =>
+                       Format_Object.Impdef_Info :=
+                           (Command     => Impdef,
+                            Change_Kind => <>,      -- Set below.
+                            Version     => <>,      -- Set below.
+                            Initial_Version =>
+                                         Version,   -- Until we decide 
differently.
+                            Add_to_DB   => True,    -- Until we decide 
differently.
+                            Paragraph_String => <>, -- Set below.
+                            Paragraph_Len    => <>);-- Set below.
+                   when Change_Docreq_Text_Param =>
+                       Format_Object.Impdef_Info :=
+                           (Command     => Docreq,
+                            Change_Kind => <>,      -- Set below.
+                            Version     => <>,      -- Set below.
+                            Initial_Version =>
+                                         Version,   -- Until we decide 
differently.
+                            Add_to_DB   => True,    -- Until we decide 
differently.
+                            Paragraph_String => <>, -- Set below.
+                            Paragraph_Len    => <>);-- Set below.
+                   when Change_Impladv_Text_Param =>
+                       Format_Object.Impdef_Info :=
+                           (Command     => Impladv,
+                            Change_Kind => <>,      -- Set below.
+                            Version     => <>,      -- Set below.
+                            Initial_Version =>
+                                         Version,   -- Until we decide 
differently.
+                            Add_to_DB   => True,    -- Until we decide 
differently.
+                            Paragraph_String => <>, -- Set below.
+                            Paragraph_Len    => <>);-- Set below.
+                   when Change_AspectDesc_Text_Param =>
+                       Format_Object.Impdef_Info :=
+                           (Command     => Aspect,
+                            Change_Kind => <>,      -- Set below.
+                            Version     => <>,      -- Set below.
+                            Initial_Version =>
+                                         Version,   -- Until we decide 
differently.
+                            Add_to_DB   => True,    -- Until we decide 
differently.
+                            Aspect_Name => <>,      -- Set below.
+                            Aspect_Name_Len  => <>, -- Set below.
+                            Paragraph_String => <>, -- Set below.
+                            Paragraph_Len    => <>);-- Set below.
+                   when others =>
+                       raise Program_Error; -- Wrong kind of command passed in.
+               end case;
+               -- Check for the optional "InitialVersion" parameter,
+               -- and the not optional, but only used for some commands
+               -- "Aspect" parameter, stopping when we reach Text:
+
+               -- Note: If there is no InitialVersion command, use the same
+               -- version of the rest of the command (which was set when the
+               -- Info was created).
+               declare
+                   Which_Param : ARM_Input.Param_Num;
+                   Ch          : Character;
+                   Saw_Aspect  : Boolean := False;
+               begin
+                   loop
+                       ARM_Input.Check_One_of_Parameter_Names (Input_Object,
+                           Param_Name_1 => "InitialVersion" & 
(15..ARM_Input.Command_Name_Type'Last => ' '),
+                           Param_Name_2 => "Aspect" & 
(7..ARM_Input.Command_Name_Type'Last => ' '),
+                           Param_Name_3 => "Text" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Found => Which_Param,
+                           Param_Close_Bracket => Close_Ch);
+
+                       if Which_Param = 1 and then Close_Ch /= ' ' then
+                           -- Found InitialVersion
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           Format_Object.Impdef_Info.Initial_Version := Ch;
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           if Ch /= Close_Ch then
+                               Ada.Text_IO.Put_Line ("  ** Bad close for 
InitialVersion parameter on line " &
+                                   ARM_Input.Line_String (Input_Object));
+                               ARM_Input.Replace_Char (Input_Object);
+                           end if;
+                       elsif Which_Param = 2 and then Close_Ch /= ' ' then
+                           -- Found Aspect parameter.
+                           Saw_Aspect := True;
+
+                           -- Save name:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Format_Object.Impdef_Info.Aspect_Name,
+                               Format_Object.Impdef_Info.Aspect_Name_Len);
+
+                       else -- We found "Text" (or an error)
+                           exit; -- Handling of Text is below.
+                       end if;
+                   end loop;
+                   if Format_Object.Impdef_Info.Command = Aspect then
+                       if not Saw_Aspect then
+                           Ada.Text_IO.Put_Line ("  ** Missing Aspect 
parameter on line " &
+                               ARM_Input.Line_String (Input_Object));
+                       -- else OK.
+                       end if;
+                   else -- Not aspect.
+                       if Saw_Aspect then
+                           Ada.Text_IO.Put_Line ("  ** Aspect parameter on 
non-aspect command on line " &
+                               ARM_Input.Line_String (Input_Object));
+                       -- else OK.
+                       end if;
+                   end if;
+               end;
+
+--Ada.Text_IO.Put_Line ("Gen_Chg_xxxx, Kind=" &
+--ARM_Database.Paragraph_Change_Kind_Type'Image(Kind) &
+--"; version=" & Version & "; InitVer=" & 
Format_Object.Impdef_Initial_Version);
+
+               if (Kind = ARM_Database.Inserted or else
+                   Kind = ARM_Database.Inserted_Normal_Number) then
+                   Calc_Change_Disposition
+                       (Format_Object => Format_Object,
+                        Version => Version,
+                        Operation => ARM_Output.Insertion,
+                        Text_Kind => Local_Change);
+--Ada.Text_IO.Put_Line ("  Insert, Local_Change=" &
+--ARM_Output.Change_Type'Image(Local_Change));
+                   case Local_Change is
+                       when Do_Not_Display_Text =>
+                           Display_It := False;
+                           Local_Change := ARM_Output.None;
+                           Format_Object.Impdef_Info.Add_to_DB := False;
+                               -- Do not add to the database, or display 
anything.
+                       when ARM_Output.None|ARM_Output.Insertion =>
+                           Format_Object.Impdef_Info.Version := Version;
+                           Format_Object.Impdef_Info.Change_Kind := Kind;
+                           Display_It := Format_Object.Include_Annotations;
+                               -- Show impdef notes only if we're showing 
annotations.
+                       when ARM_Output.Deletion =>
+                           raise Program_Error;
+                   end case;
+               elsif Kind = ARM_Database.Deleted or else
+                     Kind = ARM_Database.Deleted_Inserted_Number or else
+                     Kind = ARM_Database.Deleted_No_Delete_Message or else
+                     Kind = 
ARM_Database.Deleted_Inserted_Number_No_Delete_Message then
+                   Calc_Change_Disposition
+                       (Format_Object => Format_Object,
+                        Version => Version,
+                        Operation => ARM_Output.Deletion,
+                        Text_Kind => Local_Change);
+--Ada.Text_IO.Put_Line ("  Delete, Local_Change=" &
+--ARM_Output.Change_Type'Image(Local_Change));
+                   case Local_Change is
+                       when Do_Not_Display_Text =>
+                           --Display_It := False;
+                           -- We need to show the paragraph, without its 
header,
+                           -- so that we get a proper "this paragraph is 
deleted"
+                           -- message (if one is needed). Nothing will actually
+                           -- be output in this case.
+                           Local_Change := ARM_Output.None;
+                           Skip_Header := True;
+                           Format_Object.Impdef_Info.Version := Version;
+                           Format_Object.Impdef_Info.Change_Kind := Kind;
+                           Display_It := Format_Object.Include_Annotations;
+                               -- Show impdef notes only if we're showing 
annotations.
+                           Format_Object.Impdef_Info.Add_to_DB := True;
+                               -- This will add deleted text to the database,
+                               -- but there isn't a sensible alternative 
option,
+                               -- as we need to have the deleted paragraph 
numbers.
+                       when ARM_Output.None | ARM_Output.Deletion =>
+                           Format_Object.Impdef_Info.Version := Version;
+                           Format_Object.Impdef_Info.Change_Kind := Kind;
+                           Display_It := Format_Object.Include_Annotations;
+                               -- Show impdef notes only if we're showing 
annotations.
+                           Skip_Header := False;
+                       when ARM_Output.Insertion =>
+                           raise Program_Error;
+                   end case;
+               else -- we always display it.
+--Ada.Text_IO.Put_Line ("  Other");
+                   Format_Object.Impdef_Info.Version := Version;
+                   Format_Object.Impdef_Info.Change_Kind := Kind;
+                   Display_It := Format_Object.Include_Annotations;
+                       -- Show impdef notes only if we're showing annotations.
+                   Local_Change := ARM_Output.None;
+               end if;
+--Ada.Text_IO.Put_Line ("  Display_It=" & Boolean'Image(Display_It));
+
+               -- "Text" parameter name consumed above.
+               if Close_Ch /= ' ' then
+                   -- Stack it so we can process the end:
+                   Set_Nesting_for_Parameter
+                       (Command => Param_Cmd,
+                        Close_Ch => Close_Ch);
+
+                   ARM_Input.Start_Recording (Input_Object);
+
+                   if Format_Object.In_Paragraph then
+                       -- Do this to preserve any inserted paragraph info.
+                       Format_Object.Impdef_Info.Paragraph_String :=
+                           Format_Object.Current_Paragraph_String;
+                       Format_Object.Impdef_Info.Paragraph_Len :=
+                           Format_Object.Current_Paragraph_Len;
+                   else
+                       declare
+                           PNum : constant String := Positive'Image (
+                               Format_Object.Next_Paragraph - 1);
+                       begin
+                           Format_Object.Impdef_Info.Paragraph_Len := 
PNum'Length - 1;
+                           Format_Object.Impdef_Info.Paragraph_String (1 .. 
PNum'Last-1) :=
+                               PNum (2 .. PNum'Last);
+                       end;
+                   end if;
+
+                   if Display_It then
+                       Check_End_Paragraph; -- End any paragraph that we're in.
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Last_Subhead_Paragraph
 := Format_Object.Last_Paragraph_Subhead_Type;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Subhead_Paragraph
 := Format_Object.Next_Paragraph_Subhead_Type;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Paragraph_Format
 := Format_Object.Next_Paragraph_Format_Type;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Tab_Stops := 
Format_Object.Paragraph_Tab_Stops;
+                       Format_Object.Next_Paragraph_Format_Type := 
Bare_Annotation;
+                       Format_Object.Next_Paragraph_Subhead_Type := 
Bare_Annotation;
+                       Format_Object.Next_Paragraph_Version := 
Format_Object.Impdef_Info.Version;
+                       Format_Object.Next_Paragraph_Change_Kind := 
Format_Object.Impdef_Info.Change_Kind;
+                       Format_Object.Paragraph_Tab_Stops := ARM_Output.NO_TABS;
+                       Check_Paragraph;
+
+                       if not Skip_Header then
+                           declare
+                               Local_Format : ARM_Output.Format_Type :=
+                                   Format_Object.Text_Format;
+                           begin
+                               Local_Format.Bold := True;
+                               Local_Format.Version := 
Format_Object.Impdef_Info.Version;
+                               if ARM_Output."/=" (Local_Change, 
ARM_Output.None) then
+                                   Local_Format.Change := Local_Change;
+                                   ARM_Output.Text_Format (Output_Object,
+                                                           Local_Format);
+                               else -- No change from us:
+                                   ARM_Output.Text_Format (Output_Object,
+                                                           Local_Format);
+                               end if;
+                               ARM_Output.Ordinary_Text (Output_Object,
+                                    Text => AARM_Prefix);
+                               Local_Format.Bold := 
Format_Object.Text_Format.Bold;
+                               Local_Format.Change := 
Format_Object.Text_Format.Change;
+                               ARM_Output.Text_Format (Output_Object,
+                                                       Local_Format);
+                           end;
+                       -- else skip the header, do nothing.
+                       end if;
+                       Format_Object.Last_Paragraph_Subhead_Type := 
Bare_Annotation;
+                       Format_Object.Last_Non_Space := False;
+
+                       if Format_Object.Impdef_Info.Command = Aspect then
+                           -- Output the aspect name:
+                           declare
+                               Local_Format : ARM_Output.Format_Type :=
+                                   Format_Object.Text_Format;
+                           begin
+                               Local_Format.Bold := True;
+                               Local_Format.Version := 
Format_Object.Impdef_Info.Version;
+                               if ARM_Output."/=" (Local_Change, 
ARM_Output.None) then
+                                   Local_Format.Change := Local_Change;
+                                   ARM_Output.Text_Format (Output_Object,
+                                                           Local_Format);
+                               else -- No change from us:
+                                   ARM_Output.Text_Format (Output_Object,
+                                                           Local_Format);
+                               end if;
+                               ARM_Output.Ordinary_Text (Output_Object,
+                                    Text => 
Format_Object.Impdef_Info.Aspect_Name(1..Format_Object.Impdef_Info.Aspect_Name_Len));
+                               ARM_Output.Ordinary_Text (Output_Object,
+                                    Text => ": ");
+                               Local_Format.Bold := 
Format_Object.Text_Format.Bold;
+                               Local_Format.Change := 
Format_Object.Text_Format.Change;
+                               ARM_Output.Text_Format (Output_Object,
+                                                       Local_Format);
+                           end;
+                       -- else no additional text.
+                       end if;
+                   else -- Don't display, skip the text:
+                       ARM_Input.Skip_until_Close_Char (Input_Object,
+                           Close_Ch);
+                       ARM_Input.Replace_Char (Input_Object); -- Let the 
normal termination clean this up.
+                   end if;
+
+               -- else no parameter. Weird.
+               end if;
+           end Gen_Chg_xxxx;
+
+
+           procedure Get_Syntax_Parameters (Has_Version : in Boolean;
+                                            RHS_Close_Ch : out Character) is
+               -- Get the parameters for a Syn, AddedSyn, or DeletedSyn
+               -- command. The command has a version parameter (it's not @Syn)
+               -- if Has_Version is True. The results are put into the usual
+               -- places. The RHS parameter's name is evaluated, and its
+               -- closing character is RHS_Close_Ch.
+               -- @Syn{[Tabs=<Tabset>, ]LHS=<Non-terminal>, RHS=<Production>}
+               -- @AddedSyn{Version=[Version],[Tabs=<Tabset>, 
]LHS=<Non-terminal>, RHS=<Production>}
+               -- @DeletedSyn{Version=[Version],[Tabs=<Tabset>, 
]LHS=<Non-terminal>, RHS=<Production>}
+               Close_Ch, Ch : Character;
+               Was_Tabs : Boolean := False;
+           begin
+               if Has_Version then
+                   Get_Change_Version (Is_First => True,
+                                       Version =>
+                                          
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version);
+               end if;
+
+               -- Peek to see if Tabs parmeter is present:
+               ARM_Input.Get_Char (Input_Object, Ch);
+               ARM_Input.Replace_Char (Input_Object);
+               if Ch = 'T' or else Ch = 't' then
+                   Was_Tabs := True;
+                   ARM_Input.Check_Parameter_Name (Input_Object,
+                       Param_Name => "Tabs" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                       Is_First => (not Has_Version),
+                       Param_Close_Bracket => Close_Ch);
+                   if Close_Ch /= ' ' then
+                       -- Grab the tab string:
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           Close_Ch,
+                           Format_Object.Syntax_Tab,
+                           Format_Object.Syntax_Tab_Len);
+                   -- else no parameter. Weird.
+                   end if;
+               else
+                   Format_Object.Syntax_Tab_Len := 0;
+               end if;
+
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => "LHS" & (4..ARM_Input.Command_Name_Type'Last 
=> ' '),
+                   Is_First => (not Was_Tabs) and (not Has_Version),
+                   Param_Close_Bracket => Close_Ch);
+               if Close_Ch /= ' ' then
+                   -- Copy over the non-terminal:
+                   ARM_Input.Copy_to_String_until_Close_Char (
+                       Input_Object,
+                       Close_Ch,
+                       Format_Object.Syntax_NT,
+                       Format_Object.Syntax_NT_Len);
+               -- else no parameter. Weird.
+               end if;
+
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => "RHS" & (4..ARM_Input.Command_Name_Type'Last 
=> ' '),
+                   Is_First => False,
+                   Param_Close_Bracket => RHS_Close_Ch);
+           end Get_Syntax_Parameters;
+
+
+           procedure Gen_Syntax_Rule (Disposition : in ARM_Output.Change_Type;
+                                      RHS_Close_Ch : in Character) is
+               -- Generate a syntax rule with the specified disposition
+               -- for explicitly generated text. All of the parameters have 
been
+               -- read in; the close character for the RHS parameter is
+               -- RHS_Close_Ch.
+               use type ARM_Output.Change_Type;
+               Org_Tabs : ARM_Output.Tab_Info;
+               Key : ARM_Index.Index_Key;
+           begin
+               if Disposition = Do_Not_Display_Text then
+                   if RHS_Close_Ch /= ' ' then
+                       -- Skip the RHS and put nothing in the DB.
+                       ARM_Input.Skip_until_Close_Char (Input_Object, 
RHS_Close_Ch);
+                       ARM_Input.Replace_Char (Input_Object); -- Let the 
normal termination clean this up.
+                       if ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                          ARM_Database.Deleted) or else
+                          ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                          ARM_Database.Deleted_Inserted_Number) or else
+                          ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                          ARM_Database.Deleted_No_Delete_Message) or else
+                          ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                          
ARM_Database.Deleted_Inserted_Number_No_Delete_Message) then
+                           -- In a deleted paragraph, call Check_Paragraph
+                           -- to trigger the "deleted paragraph" message.
+                           -- (Otherwise, this may never happen.)
+                           Check_Paragraph;
+                       -- else null; -- Nothing special to do.
+                       end if;
+                   end if;
+                   -- Stack it so we can process the end:
+                   Set_Nesting_for_Parameter
+                       (Command => Syntax_Rule_RHS,
+                        Close_Ch => RHS_Close_Ch);
+                   -- (We probably don't need to do the above, but consistency
+                   -- is preferred.)
+               else
+                   -- Set up the tabs:
+                   Org_Tabs := Format_Object.Paragraph_Tab_Stops;
+                   Format_Object.Paragraph_Tab_Stops := ARM_Output.NO_TABS;
+                   if Format_Object.Syntax_Tab_Len /= 0 then
+                       Parse_Tab_Stops 
(Format_Object.Syntax_Tab(1..Format_Object.Syntax_Tab_Len),
+                           Format_Object.Paragraph_Tab_Stops);
+                   end if;
+
+                   Check_Paragraph;
+                   ARM_Format.Format (Format_Object,
+                                      "@s{" & 
Format_Object.Syntax_NT(1..Format_Object.Syntax_NT_Len) & "}",
+                                      Output_Object,
+                                      Text_Name => "@Syn(LHS=",
+                                      No_Annotations => False);
+                       -- We use Format here so we can support changes in
+                       -- the non-terminal.
+
+                   -- Index the non-terminal:
+                   ARM_Index.Add (Term => Get_NT,
+                                  Kind => ARM_Index.Primary_Term,
+                                  Clause => Clause_String (Format_Object),
+                                  Paragraph => Paragraph_String,
+                                  Key => Key);
+                   ARM_Output.Index_Target (Output_Object, Key);
+
+                   -- Make an anchor for the non-terminal:
+                   if Format_Object.Link_Non_Terminals then
+                       declare
+                           Lower_NT : constant String :=
+                               Ada.Characters.Handling.To_Lower (Get_NT);
+                           Link_Target : ARM_Syntax.Target_Type :=
+                               ARM_Syntax.Non_Terminal_Link_Target (Lower_NT);
+                           Lower_Old_NT : constant String :=
+                               Ada.Characters.Handling.To_Lower (Get_Old_NT);
+                           Old_Link_Target : ARM_Syntax.Target_Type :=
+                               ARM_Syntax.Non_Terminal_Link_Target 
(Lower_Old_NT);
+                       begin
+                           if Lower_NT /= "" then
+                               if Clause_String (Format_Object) /=
+                                   ARM_Syntax.Non_Terminal_Clause (Lower_NT) 
then
+                                   Ada.Text_IO.Put_Line ("  ** Clause mismatch 
for non-terminal: Is=" &
+                                       Clause_String (Format_Object) & "; 
Was=" & ARM_Syntax.Non_Terminal_Clause (Lower_NT) &
+                                       "; NT=" & Lower_NT & "; on line " & 
ARM_Input.Line_String (Input_Object));
+                               end if;
+                               ARM_Output.Local_Target (Output_Object,
+                                   Text => "",
+                                   Target => Link_Target);
+                           -- else the Non-Terminal was deleted, no
+                           -- anchor is needed.
+                           end if;
+                           if Lower_Old_NT /= "" then
+                               if Clause_String (Format_Object) /=
+                                   ARM_Syntax.Non_Terminal_Clause 
(Lower_Old_NT) then
+                                   -- This can happen if an item is inserted
+                                   -- on one place and deleted in another.
+                                   -- We'll assume this isn't an error and just
+                                   -- do nothing here.
+                                   --Ada.Text_IO.Put_Line ("  %% Clause 
mismatch for old non-terminal: Is=" &
+                                   --    Clause_String (Format_Object) & "; 
Was=" & ARM_Syntax.Non_Terminal_Clause (Lower_Old_NT) &
+                                   --    "; NT=" & Lower_Old_NT & "; on line " 
& ARM_Input.Line_String (Input_Object));
+                                   null;
+                               else
+                                   ARM_Output.Local_Target (Output_Object,
+                                       Text => "",
+                                       Target => Old_Link_Target);
+                               end if;
+                           -- else there was no old Non-Terminal.
+                           end if;
+                       end;
+                   end if;
+
+                   -- Set the font for the "::=". Note that we use @s{}
+                   -- above, so that any font changes in the Non-Terminal
+                   -- (as in a @Chg command) are respected.
+                   -- This command includes any needed insertion or deletion.
+
+                   declare
+                       Swiss_Format : ARM_Output.Format_Type :=
+                           Format_Object.Text_Format;
+                   begin
+                       Swiss_Format.Font := ARM_Output.Swiss;
+                       if Disposition = ARM_Output.None then
+                           null;
+                       else
+                           Swiss_Format.Change := Disposition;
+                           Swiss_Format.Version := 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version;
+                       end if;
+                       ARM_Output.Text_Format (Output_Object,
+                                               Swiss_Format);
+                   end;
+                   ARM_Output.Ordinary_Text (Output_Object, " ::= ");
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format_Object.Text_Format); -- 
Reset format.
+                   Format_Object.Last_Non_Space := False;
+
+                   if RHS_Close_Ch /= ' ' then
+                       -- Now, handle the parameter:
+                       -- Stack it so we can process the end:
+                       Set_Nesting_for_Parameter
+                           (Command => Syntax_Rule_RHS,
+                            Close_Ch => RHS_Close_Ch);
+
+                       ARM_Input.Start_Recording (Input_Object);
+
+                       -- Set the format to preserve line breaks.
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Last_Subhead_Paragraph
 := Format_Object.Last_Paragraph_Subhead_Type;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Subhead_Paragraph
 := Format_Object.Next_Paragraph_Subhead_Type;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Paragraph_Format
 := Format_Object.Next_Paragraph_Format_Type;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Tab_Stops := 
Org_Tabs;
+                       Format_Object.Next_Paragraph_Format_Type := 
Syntax_Production;
+                       -- Tab stops are already set.
+                   -- else no parameter, weird.
+                   end if;
+               end if;
+           end Gen_Syntax_Rule;
+
+
+           procedure Format_Text (Text : in String;
+                                  Text_Name : in String) is
+               -- Note: We use the state of the surrounding call.
+               Input_Object : Arm_String.String_Input_Type;
+               Real_Include_Annotations : Boolean := 
Format_Object.Include_Annotations;
+           begin
+               -- Don't show annotations here:
+                Format_Object.Include_Annotations := False;
+               Arm_String.Open (Input_Object, Text, Text_Name);
+                    -- Open the input object using a string for input.
+               Real_Process (Format_Object, Format_State, Input_Object, 
Output_Object);
+               Arm_String.Close (Input_Object);
+               Format_Object.Include_Annotations := Real_Include_Annotations;
+           end Format_Text;
+
+           procedure DB_Report is new ARM_Database.Report (Format_Text);
+
+       begin
+           case 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command is
+
+               -- Basic text commands:
+
+               when Redundant =>
+                   if Format_Object.Include_Annotations then
+                       Check_Paragraph;
+                       ARM_Output.Ordinary_Character (Output_Object, '[');
+                       Format_Object.Last_Non_Space := True;
+                   -- else ignored.
+                   end if;
+
+               when Comment | Part =>
+                   -- Skip the contents of this command.
+                   -- For Part, we don't use the information contained,
+                   -- but it would help a human reader.
+                   ARM_Input.Skip_until_Close_Char (Input_Object,
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char);
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                       -- Remove the "comment" or "part" record.
+
+               when Bold =>
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Bold := True;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Italic =>
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Italic := True;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Roman =>
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Font := ARM_Output.Roman;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Swiss =>
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Font := ARM_Output.Swiss;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Fixed =>
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Font := ARM_Output.Fixed;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Roman_Italic =>
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Italic := True;
+                   Format_Object.Text_Format.Font := ARM_Output.Roman;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+               when Shrink =>
+                   declare
+                       use type ARM_Output.Size_Type;
+                   begin
+                       Check_Paragraph;
+                       Format_Object.Text_Format.Size :=
+                           Format_Object.Text_Format.Size - 1;
+                       ARM_Output.Text_Format (Output_Object,
+                                               Format => 
Format_Object.Text_Format);
+                   end;
+
+               when Grow =>
+                   declare
+                       use type ARM_Output.Size_Type;
+                   begin
+                       Check_Paragraph;
+                       Format_Object.Text_Format.Size :=
+                           Format_Object.Text_Format.Size + 1;
+                       ARM_Output.Text_Format (Output_Object,
+                                               Format => 
Format_Object.Text_Format);
+                   end;
+
+               when Black =>
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Color := ARM_Output.Black;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Red =>
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Color := ARM_Output.Red;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Green =>
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Color := ARM_Output.Green;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Blue =>
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Color := ARM_Output.Blue;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Keyword =>
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Bold := True;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Non_Terminal_Format =>
+                   -- No linking here.
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Font := ARM_Output.Swiss;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Example_Text =>
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Font := 
Format_Object.Examples_Font;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Example_Comment =>
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Font := ARM_Output.Roman;
+                   Format_Object.Text_Format.Italic := True;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Tab_Clear =>
+                   Format_Object.Paragraph_Tab_Stops := ARM_Output.NO_TABS;
+
+               when Tab_Set =>
+                   if Format_Object.Next_Paragraph_Format_Type = Bulleted or 
else
+                      Format_Object.Next_Paragraph_Format_Type = 
Nested_Bulleted or else
+                      Format_Object.Next_Paragraph_Format_Type = 
Nested_X2_Bulleted or else
+                      Format_Object.Next_Paragraph_Format_Type = Enumerated or 
else
+                      Format_Object.Next_Paragraph_Format_Type = 
Nested_Enumerated or else
+                      Format_Object.Next_Paragraph_Format_Type = 
Hanging_Indented_1 or else
+                      Format_Object.Next_Paragraph_Format_Type = 
Hanging_Indented_2 or else
+                      Format_Object.Next_Paragraph_Format_Type = 
Hanging_Indented_3 or else
+                      Format_Object.Next_Paragraph_Format_Type = 
Hanging_Indented_4 then
+                       Ada.Text_IO.Put_Line ("  ** Tab set in hang or bulleted 
format: " &
+                           
Paragraph_Type'Image(Format_Object.Next_Paragraph_Format_Type) &
+                           ", line " & ARM_Input.Line_String (Input_Object));
+                   elsif ARM_Output."/=" (Format_Object.Paragraph_Tab_Stops, 
ARM_Output.NO_TABS) then
+                       Ada.Text_IO.Put_Line ("  ** Setting tabs when they are 
not clear on line "
+                               & ARM_Input.Line_String (Input_Object));
+                   else
+                       declare
+                           My_Tabs : ARM_Output.Tab_Info := ARM_Output.NO_TABS;
+                           Stops : String(1..80);
+                           Len : Natural;
+                       begin
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char,
+                               Stops, Len);
+                           Parse_Tab_Stops (Stops(1..Len), My_Tabs);
+
+                           Format_Object.Paragraph_Tab_Stops := My_Tabs;
+                           Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Tabstop)");
+                       end;
+                   end if;
+
+               when Non_Terminal =>
+                   -- @nt{text}
+                   -- This *was* simple, until we added linking.
+                   declare
+                       Name : String(1..120);
+                       Len : Natural;
+                       Swiss_Format : ARM_Output.Format_Type :=
+                           Format_Object.Text_Format;
+                   begin
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char,
+                           Name, Len);
+
+                       -- Set the appropriate style:
+                       Check_Paragraph;
+
+                       Swiss_Format.Font := ARM_Output.Swiss;
+                       ARM_Output.Text_Format (Output_Object,
+                                               Format => Swiss_Format);
+                       if Format_Object.Link_Non_Terminals then
+                           if Ada.Strings.Fixed.Index (Name(1..Len), "@") /= 0 
then
+                               -- Embedded commands. We have to clean the
+                               -- string of the commands (if we can) before
+                               -- making a link.
+                               declare
+                                   Lower_NT : String :=
+                                       Ada.Characters.Handling.To_Lower 
(Name(1..Len));
+                                   Lower_NT_Len : Natural := Lower_NT'Length;
+                                   Loc : Natural := Lower_NT'First;
+                               begin
+                                   while Loc <= Lower_NT_Len loop
+                                       -- Check for simple commands and remove 
them:
+                                       if Lower_NT(Loc) = '@' then -- Start of 
a command.
+                                           if Loc < Lower_NT_Len and then
+                                               (Lower_NT(Loc+1) = '!' or else
+                                                Lower_NT(Loc+1) = ';') then
+                                               -- Soft hyphen or no-op, remove.
+                                               Lower_NT(Loc .. Lower_NT_Len-2) 
:=
+                                                   Lower_NT(Loc+2 .. 
Lower_NT_Len);
+                                               Lower_NT_Len := Lower_NT_Len - 
2;
+                                           else -- Unknown.
+                                               exit;
+                                           end if;
+                                       else -- nothing to do, move to next 
character
+                                           Loc := Loc + 1;
+                                       end if;
+                                   end loop;
+
+                                   declare
+                                       Clause : constant String :=
+                                           ARM_Syntax.Non_Terminal_Clause 
(Lower_NT(1..Lower_NT_Len));
+                                       Target : constant 
ARM_Syntax.Target_Type :=
+                                           ARM_Syntax.Non_Terminal_Link_Target 
(Lower_NT(1..Lower_NT_Len));
+                                       Org_Font : ARM_Output.Font_Family_Type 
:=
+                                           Format_Object.Text_Format.Font;
+                                   begin
+                                       Format_Object.Text_Format.Font := 
ARM_Output.Swiss;
+                                       if Clause = "" then -- Not found. No 
link, but error message:
+                                           if Ada.Strings.Fixed.Index 
(Lower_NT(1..Lower_NT_Len), "@") /= 0 then
+                                               Ada.Text_IO.Put_Line ("  %% 
Non-terminal with complex embedded commands " &
+                                                   Lower_NT(1..Lower_NT_Len) & 
" on line " & ARM_Input.Line_String (Input_Object));
+                                           else
+                                               Ada.Text_IO.Put_Line ("  ?? 
Unknown non-terminal " &
+                                                   Lower_NT(1..Lower_NT_Len) & 
" on line " & ARM_Input.Line_String (Input_Object));
+                                           end if;
+                                           ARM_Format.Format (Format_Object,
+                                                              Name(1..Len),
+                                                              Output_Object,
+                                                              Text_Name => 
"@nt{}",
+                                                              No_Annotations 
=> False);
+                                       else
+                                           ARM_Output.Local_Link_Start 
(Output_Object,
+                                               Target => Target, Clause_Number 
=> Clause);
+                                           ARM_Format.Format (Format_Object,
+                                                              Name(1..Len),
+                                                              Output_Object,
+                                                              Text_Name => 
"@nt{}",
+                                                              No_Annotations 
=> False);
+                                           ARM_Output.Local_Link_End 
(Output_Object,
+                                               Target => Target, Clause_Number 
=> Clause);
+                                       end if;
+                                       Format_Object.Text_Format.Font := 
Org_Font;
+                                   end;
+                               end;
+                           else -- Ordinary link.
+                               declare
+                                   Lower_NT : constant String :=
+                                       Ada.Characters.Handling.To_Lower 
(Name(1..Len));
+                                   Clause : constant String :=
+                                       ARM_Syntax.Non_Terminal_Clause 
(Lower_NT);
+                                   Target : constant ARM_Syntax.Target_Type :=
+                                       ARM_Syntax.Non_Terminal_Link_Target 
(Lower_NT);
+                               begin
+                                   if Clause = "" then -- Not found. No link, 
but error message:
+                                       Ada.Text_IO.Put_Line ("  ?? Unknown 
non-terminal " &
+                                           Name(1..Len) & " on line " & 
ARM_Input.Line_String (Input_Object));
+                                       ARM_Output.Ordinary_Text 
(Output_Object, Name(1..Len));
+                                   else
+                                       ARM_Output.Local_Link (Output_Object, 
Text => Name(1..Len),
+                                           Target => Target, Clause_Number => 
Clause);
+                                   end if;
+                               end;
+                           end if;
+                       else
+                           if Ada.Strings.Fixed.Index (Name(1..Len), "@") /= 0 
then
+                               -- Embedded commands, better execute them.
+                               declare
+                                   Org_Font : ARM_Output.Font_Family_Type :=
+                                       Format_Object.Text_Format.Font;
+                               begin
+                                   Format_Object.Text_Format.Font := 
ARM_Output.Swiss;
+                                   ARM_Format.Format (Format_Object,
+                                                      Name(1..Len),
+                                                      Output_Object,
+                                                      Text_Name => "@nt{}",
+                                                      No_Annotations => False);
+                                   Format_Object.Text_Format.Font := Org_Font;
+                               end;
+                           else
+                               ARM_Output.Ordinary_Text (Output_Object, 
Name(1..Len));
+                           end if;
+                       end if;
+                       ARM_Output.Text_Format (Output_Object,
+                                               Format => 
Format_Object.Text_Format);
+                       Format_Object.Last_Non_Space := True;
+                   end;
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Nonterminal)");
+
+               -- Versioned breaking:
+               when New_Page_for_Version | RM_New_Page_for_Version |
+                    New_Column_for_Version |
+                    Not_ISO_RM_New_Page_for_Version |
+                    ISO_Only_RM_New_Page_for_Version =>
+                   declare
+                       Version : ARM_Contents.Change_Version_Type;
+                   begin
+                       Get_Change_Version (Is_First => True,
+                           Version => Version);
+                           -- Read a parameter named "Version".
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version := 
Version;
+                   end;
+
+               -- Tables:
+               when Table =>
+                       -- @table(Columns=<number>,
+                       --       
Alignment=<AllLeft|AllCenter|CenterExceptFirst>,
+                       --       FirstColWidth=<number>,
+                       --       LastColWidth=<number>,
+                       --       NoBreak=<T|F>,
+                       --       Border=<T|F>,
+                       --       SmallSize=<T|F>,
+                       --       Caption=<text>,
+                       --       Headers=<text>,
+                       --       Body=<row_text>)
+                       -- Columns must be a single digit (2-9).
+                       -- Caption defines the table caption.
+                       -- Headers defines the table headers.
+                       -- Body defines the table body.
+
+                   Check_End_Paragraph; -- End any paragraph we're in.
+                   declare
+                       Close_Ch, Ch : Character;
+                       Align_Name : ARM_Input.Command_Name_Type;
+                       Cols, FirstWidth, LastWidth : Character;
+                       No_Page_Break : Boolean;
+                       Has_Border : Boolean;
+                       Small_Text : Boolean;
+                       Alignment : ARM_Output.Column_Text_Alignment;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Columns" & 
(8..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => True,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           ARM_Input.Get_Char (Input_Object, Cols);
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           if Ch /= Close_Ch then
+                               Ada.Text_IO.Put_Line ("  ** Bad close for Table 
Columns on line " & ARM_Input.Line_String (Input_Object));
+                               ARM_Input.Replace_Char (Input_Object);
+                           end if;
+                           if Cols not in '2'..'9' then
+                               Ada.Text_IO.Put_Line ("  ** Bad table column 
count on line " & ARM_Input.Line_String (Input_Object));
+                           end if;
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Alignment" & 
(10..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Get the alignment word:
+                           Arm_Input.Get_Name (Input_Object, Align_Name);
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           if Ch /= Close_Ch then
+                               Ada.Text_IO.Put_Line ("  ** Bad close for Table 
Alignment on line " & ARM_Input.Line_String (Input_Object));
+                               ARM_Input.Replace_Char (Input_Object);
+                           end if;
+
+                           if Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Align_Name, Ada.Strings.Right)) =
+                               "allleft" then
+                               Alignment := ARM_Output.Left_All;
+                           elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Align_Name, Ada.Strings.Right)) =
+                               "allcenter" then
+                               Alignment := ARM_Output.Center_All;
+                           elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Align_Name, Ada.Strings.Right)) =
+                               "centerexceptfirst" then
+                               Alignment := ARM_Output.Center_Except_First;
+                           else
+                               Ada.Text_IO.Put_Line ("  ** Bad column 
alignment: " &
+                                       Ada.Strings.Fixed.Trim (Align_Name, 
Ada.Strings.Right) &
+                                       " on line " & ARM_Input.Line_String 
(Input_Object));
+                           end if;
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "FirstColWidth" & 
(14..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           ARM_Input.Get_Char (Input_Object, FirstWidth);
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           if Ch /= Close_Ch then
+                               Ada.Text_IO.Put_Line ("  ** Bad close for Table 
FirstColWidth on line " & ARM_Input.Line_String (Input_Object));
+                               ARM_Input.Replace_Char (Input_Object);
+                           end if;
+                           if FirstWidth not in '1'..'9' then
+                               Ada.Text_IO.Put_Line ("  ** Bad table 1st 
column width on line " & ARM_Input.Line_String (Input_Object));
+                           end if;
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "LastColWidth" & 
(13..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           ARM_Input.Get_Char (Input_Object, LastWidth);
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           if Ch /= Close_Ch then
+                               Ada.Text_IO.Put_Line ("  ** Bad close for Table 
FirstColWidth on line " & ARM_Input.Line_String (Input_Object));
+                               ARM_Input.Replace_Char (Input_Object);
+                           end if;
+                           if FirstWidth not in '1'..'9' then
+                               Ada.Text_IO.Put_Line ("  ** Bad table last 
column width on line " & ARM_Input.Line_String (Input_Object));
+                           end if;
+                       end if;
+
+                       Get_Boolean ("NoBreak" & 
(8..ARM_Input.Command_Name_Type'Last => ' '), No_Page_Break);
+                       Get_Boolean ("Border" & 
(7..ARM_Input.Command_Name_Type'Last => ' '), Has_Border);
+                       Get_Boolean ("SmallSize" & 
(10..ARM_Input.Command_Name_Type'Last => ' '), Small_Text);
+
+                       -- Set to the table format:
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Last_Subhead_Paragraph
 := Format_Object.Last_Paragraph_Subhead_Type;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Subhead_Paragraph
 := Format_Object.Next_Paragraph_Subhead_Type;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Paragraph_Format
 := Format_Object.Next_Paragraph_Format_Type;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Tab_Stops := 
Format_Object.Paragraph_Tab_Stops;
+                       Format_Object.Next_Paragraph_Format_Type := In_Table;
+                       Format_Object.In_Paragraph := True; -- A fake, but we 
cannot have any format.
+                       Format_Object.No_Start_Paragraph := False; -- For most 
purposes, being in a table is like being in a paragraph.
+
+                       -- OK, we've started the table. Now, get the caption:
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Caption" & 
(8..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Check if the parameter is empty:
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           if Ch /= Close_Ch then
+                               -- There is a caption:
+                               ARM_Input.Replace_Char (Input_Object);
+
+                               -- Create the table.
+                               Arm_Output.Start_Table (
+                                       Output_Object,
+                                       Columns => Character'Pos(Cols) - 
Character'Pos('0'),
+                                       First_Column_Width => 
Character'Pos(FirstWidth) - Character'Pos('0'),
+                                       Last_Column_Width => 
Character'Pos(LastWidth) - Character'Pos('0'),
+                                       Alignment => Alignment,
+                                       No_Page_Break => No_Page_Break,
+                                       Has_Border => Has_Border,
+                                       Small_Text_Size => Small_Text,
+                                       Header_Kind => 
ARM_Output.Both_Caption_and_Header);
+
+                               -- Now, handle the parameter:
+                               -- Stack it so we can process the end:
+                               Set_Nesting_for_Parameter
+                                   (Command => Table_Param_Caption,
+                                    Close_Ch => Close_Ch);
+
+                           else -- Empty Caption. Move on to the Headers
+                                -- command.
+                               ARM_Input.Check_Parameter_Name (Input_Object,
+                                   Param_Name => "Headers" & 
(8..ARM_Input.Command_Name_Type'Last => ' '),
+                                   Is_First => False,
+                                   Param_Close_Bracket => Close_Ch);
+
+                               if Close_Ch /= ' ' then
+                                   -- Check if the parameter is empty:
+                                   ARM_Input.Get_Char (Input_Object, Ch);
+                                   if Ch /= Close_Ch then
+                                       -- There is a header:
+                                       ARM_Input.Replace_Char (Input_Object);
+
+                                       -- Create the table.
+                                       Arm_Output.Start_Table (
+                                               Output_Object,
+                                               Columns => Character'Pos(Cols) 
- Character'Pos('0'),
+                                               First_Column_Width => 
Character'Pos(FirstWidth) - Character'Pos('0'),
+                                               Last_Column_Width => 
Character'Pos(LastWidth) - Character'Pos('0'),
+                                               Alignment => Alignment,
+                                               No_Page_Break => No_Page_Break,
+                                               Has_Border => Has_Border,
+                                               Small_Text_Size => Small_Text,
+                                               Header_Kind => 
ARM_Output.Header_Only);
+
+                                       -- Now, handle the parameter:
+                                       -- Stack it so we can process the end:
+                                       Set_Nesting_for_Parameter
+                                           (Command => Table_Param_Header,
+                                            Close_Ch => Close_Ch);
+
+                                   else -- Empty Headers, too. Move on to the
+                                        -- Body command.
+                                       ARM_Input.Check_Parameter_Name 
(Input_Object,
+                                           Param_Name => "Body" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                                           Is_First => False,
+                                           Param_Close_Bracket => Close_Ch);
+
+                                       if Close_Ch /= ' ' then
+                                           -- Create the table.
+                                           Arm_Output.Start_Table (
+                                                   Output_Object,
+                                                   Columns => 
Character'Pos(Cols) - Character'Pos('0'),
+                                                   First_Column_Width => 
Character'Pos(FirstWidth) - Character'Pos('0'),
+                                                   Last_Column_Width => 
Character'Pos(LastWidth) - Character'Pos('0'),
+                                                   Alignment => Alignment,
+                                                   No_Page_Break => 
No_Page_Break,
+                                                   Has_Border => Has_Border,
+                                                   Small_Text_Size => 
Small_Text,
+                                                   Header_Kind => 
ARM_Output.No_Headers);
+
+                                           -- Now, handle the parameter:
+                                           -- Stack it so we can process the 
end:
+                                           Set_Nesting_for_Parameter
+                                               (Command => Table_Param_Body,
+                                                Close_Ch => Close_Ch);
+
+                                       -- else no parameter, weird.
+                                       end if;
+
+                                   end if;
+
+                               -- else no parameter, weird.
+                               end if;
+
+                            end if;
+
+                       -- else no parameter, weird.
+                       end if;
+                   end;
+
+               -- Pictures:
+               when Picture_Alone | Picture_Inline =>
+                   -- @PictureInline(Alignment=<Inline|FloatLeft|FloatRight>,
+                   --               Border=<None|Thin|Thick>,
+                   --               Height=<nnn>,
+                   --               Width=<nnn>,
+                   --               Name=<name>,
+                   --               Descr=<descr>)
+                   -- @PictureAlone(Alignment=<Left|Right|Center>,
+                   --               Border=<None|Thin|Thick>,
+                   --               Height=<nnn>,
+                   --               Width=<nnn>,
+                   --               Name=<name>,
+                   --               Descr=<descr>)
+                   declare
+                       Close_Ch, Ch : Character;
+                       Align_Name : ARM_Input.Command_Name_Type;
+                       Alignment : ARM_Output.Picture_Alignment;
+                       Border : ARM_Output.Border_Kind;
+                       Height : Natural := 0;
+                       Width : Natural := 0;
+                       Name, Descr : String(1..120);
+                       NLen, DLen : Natural := 0;
+                   begin
+                       if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command =
+                           Picture_Alone then
+                           Check_End_Paragraph; -- End any paragraph that 
we're in.
+
+                           ARM_Input.Check_Parameter_Name (Input_Object,
+                               Param_Name => "Alignment" & 
(10..ARM_Input.Command_Name_Type'Last => ' '),
+                               Is_First => True,
+                               Param_Close_Bracket => Close_Ch);
+                           if Close_Ch /= ' ' then
+                               -- Get the alignment word:
+                               Arm_Input.Get_Name (Input_Object, Align_Name);
+                               ARM_Input.Get_Char (Input_Object, Ch);
+                               if Ch /= Close_Ch then
+                                   Ada.Text_IO.Put_Line ("  ** Bad close for 
Picture Alignment on line " & ARM_Input.Line_String (Input_Object));
+                                   ARM_Input.Replace_Char (Input_Object);
+                               end if;
+
+                               if Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Align_Name, Ada.Strings.Right)) =
+                                   "left" then
+                                   Alignment := ARM_Output.Alone_Left;
+                               elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Align_Name, Ada.Strings.Right)) =
+                                   "right" then
+                                   Alignment := ARM_Output.Alone_Right;
+                               elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Align_Name, Ada.Strings.Right)) =
+                                   "center" then
+                                   Alignment := ARM_Output.Alone_Center;
+                               else
+                                   Ada.Text_IO.Put_Line ("  ** Bad stand-alone 
picture alignment: " &
+                                           Ada.Strings.Fixed.Trim (Align_Name, 
Ada.Strings.Right) &
+                                           " on line " & ARM_Input.Line_String 
(Input_Object));
+                               end if;
+                           -- else no parameter. Weird.
+                           end if;
+
+                       else -- Picture_Inline.
+                           Check_Paragraph; -- Make sure we're in a paragraph.
+
+                           ARM_Input.Check_Parameter_Name (Input_Object,
+                               Param_Name => "Alignment" & 
(10..ARM_Input.Command_Name_Type'Last => ' '),
+                               Is_First => True,
+                               Param_Close_Bracket => Close_Ch);
+                           if Close_Ch /= ' ' then
+                               -- Get the alignment word:
+                               Arm_Input.Get_Name (Input_Object, Align_Name);
+                               ARM_Input.Get_Char (Input_Object, Ch);
+                               if Ch /= Close_Ch then
+                                   Ada.Text_IO.Put_Line ("  ** Bad close for 
Picture Alignment on line " & ARM_Input.Line_String (Input_Object));
+                                   ARM_Input.Replace_Char (Input_Object);
+                               end if;
+
+                               if Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Align_Name, Ada.Strings.Right)) =
+                                   "inline" then
+                                   Alignment := ARM_Output.Inline;
+                               elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Align_Name, Ada.Strings.Right)) =
+                                   "floatleft" then
+                                   Alignment := ARM_Output.Float_Left;
+                               elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Align_Name, Ada.Strings.Right)) =
+                                   "floatright" then
+                                   Alignment := ARM_Output.Float_Right;
+                               else
+                                   Ada.Text_IO.Put_Line ("  ** Bad inline 
picture alignment: " &
+                                           Ada.Strings.Fixed.Trim (Align_Name, 
Ada.Strings.Right) &
+                                           " on line " & ARM_Input.Line_String 
(Input_Object));
+                               end if;
+                           -- else no parameter. Weird.
+                           end if;
+
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Border" & 
(7..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Get the alignment word:
+                           Arm_Input.Get_Name (Input_Object, Align_Name);
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           if Ch /= Close_Ch then
+                               Ada.Text_IO.Put_Line ("  ** Bad close for 
Picture Border on line " & ARM_Input.Line_String (Input_Object));
+                               ARM_Input.Replace_Char (Input_Object);
+                           end if;
+
+                           if Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Align_Name, Ada.Strings.Right)) =
+                               "none" then
+                               Border := ARM_Output.None;
+                           elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Align_Name, Ada.Strings.Right)) =
+                               "thin" then
+                               Border := ARM_Output.Thin;
+                           elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Align_Name, Ada.Strings.Right)) =
+                               "thick" then
+                               Border := ARM_Output.Thick;
+                           else
+                               Ada.Text_IO.Put_Line ("  ** Bad picture border: 
" &
+                                       Ada.Strings.Fixed.Trim (Align_Name, 
Ada.Strings.Right) &
+                                       " on line " & ARM_Input.Line_String 
(Input_Object));
+                           end if;
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                                   Param_Name => "Height" & 
(7..ARM_Input.Command_Name_Type'Last => ' '),
+                                   Is_First => False,
+                                   Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Name,
+                               NLen);
+                           begin
+                               Height := Natural'Value(Name(1..NLen));
+                           exception
+                               when Constraint_Error =>
+                                   Ada.Text_IO.Put_Line ("  ** Bad picture 
height: " &
+                                           Name(1..NLen) & " on line " & 
ARM_Input.Line_String (Input_Object));
+                           end;
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                                   Param_Name => "Width" & 
(6..ARM_Input.Command_Name_Type'Last => ' '),
+                                   Is_First => False,
+                                   Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Name,
+                               NLen);
+                           begin
+                               Width := Natural'Value(Name(1..NLen));
+                           exception
+                               when Constraint_Error =>
+                                   Ada.Text_IO.Put_Line ("  ** Bad picture 
width: " &
+                                           Name(1..NLen) & " on line " & 
ARM_Input.Line_String (Input_Object));
+                           end;
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                                   Param_Name => "Name" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                                   Is_First => False,
+                                   Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Name,
+                               NLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Descr" & 
(6..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Descr,
+                               DLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Output.Picture (
+                           Output_Object,
+                           Alignment => Alignment,
+                           Border => Border,
+                           Height => Height,
+                           Width => Width,
+                           Name => Name(1..NLen),
+                           Descr => Descr(1..DLen));
+                   end;
+                   -- Normal processing should remove the command end marker.
+
+               -- Paragraph kind commands:
+
+               when Text_Begin =>
+                   declare
+                       Type_Name : ARM_Input.Command_Name_Type;
+                       Ch : Character;
+                   begin
+                       -- OK, now read the begin "type":
+                       Arm_Input.Get_Name (Input_Object, Type_Name);
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       if Ch = ',' then
+                           -- Multiple parameters. The remaining
+                           -- parameters appear to be format instructions,
+                           -- which we ought to replace or remove.
+                           Ada.Text_IO.Put_Line ("  -- Multi-parameter begin, 
line " & ARM_Input.Line_String (Input_Object));
+
+                           -- We ignore everything until the end of the
+                           -- parameter.
+                           while Ch /= 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char loop
+                               -- Ignore everything until the end character
+                               -- turns up.
+                               ARM_Input.Get_Char (Input_Object, Ch);
+                           end loop;
+                        end if;
+
+                       if Format_State.Nesting_Stack 
(Format_State.Nesting_Stack_Ptr).Close_Char = Ch then
+                           -- Found the end of the parameter.
+                           -- Replace the top of stack with the appropriate 
begin record:
+                           Format_State.Nesting_Stack 
(Format_State.Nesting_Stack_Ptr) :=
+                               (Name => Ada.Characters.Handling.To_Lower 
(Type_Name),
+                                Kind => Begin_Word,
+                                Command => Text_Begin,
+                                Close_Char => ' ',-- No close character.
+                                Text_Format => Format_Object.Text_Format,
+                                       -- Save the current format.
+                                Old_Last_Subhead_Paragraph => 
Format_Object.Last_Paragraph_Subhead_Type,
+                                Old_Next_Subhead_Paragraph => 
Format_Object.Next_Paragraph_Subhead_Type,
+                                Old_Next_Paragraph_Format => 
Format_Object.Next_Paragraph_Format_Type,
+                                Old_Tab_Stops => 
Format_Object.Paragraph_Tab_Stops,
+                                Old_Next_Enum_Num => 
Format_Object.Next_Enumerated_Num,
+                                Is_Formatting => True, -- Reset if needed 
later.
+                                Change_Version => '0', -- Not used.
+                                Was_Text => False, -- Not used.
+                                Prev_Change => ARM_Output.None, -- Not used.
+                                Prev_Change_Version => '0', -- Not used.
+                                Prev_Added_Change_Version => '0'); -- Not used.
+
+                           Process_Begin;
+
+                       else
+                           ARM_Input.Replace_Char (Input_Object);
+                           Ada.Text_IO.Put_Line ("  ** Failed to find close 
for parameter to begin, line " & ARM_Input.Line_String (Input_Object));
+                           --Bracket_Check := 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Bracket_State;
+                           Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Bad Begin)");
+                       end if;
+                   end;
+
+               when Text_End =>
+                   declare
+                       Type_Name : ARM_Input.Command_Name_Type;
+                       Ch : Character;
+                   begin
+                       Arm_Input.Get_Name (Input_Object, Type_Name); -- Get 
the end "type".
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       if Format_State.Nesting_Stack 
(Format_State.Nesting_Stack_Ptr).Close_Char = Ch then
+                           -- Found end of parameter:
+                           Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                               -- Remove the "End" record.
+                           -- Check for the matching begin, and remove it.
+                           if Format_State.Nesting_Stack_Ptr = 0 then
+                               Ada.Text_IO.Put_Line ("  ** No begin for end, 
line " & ARM_Input.Line_String (Input_Object));
+                           elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name /=
+                               Ada.Characters.Handling.To_Lower (Type_Name) 
then
+                               Ada.Text_IO.Put_Line ("  ** Names of begin and 
end mismatch, line " & ARM_Input.Line_String (Input_Object));
+                               Ada.Text_IO.Put_Line ("     Begin name: " & 
Ada.Strings.Fixed.Trim(Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name,
 Ada.Strings.Right) &
+                                                     "  End name: " & 
Ada.Strings.Fixed.Trim(Type_Name, Ada.Strings.Right));
+--Ada.Text_IO.Put_Line (" &Stack name is " & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name);
+                           else
+                               if Format_Object.Next_Paragraph_Subhead_Type /= 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Subhead_Paragraph
 then
+                                   Format_Object.Last_Paragraph_Subhead_Type 
:= 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Last_Subhead_Paragraph;
+                               -- else still in same subhead, leave alone. (If
+                               -- we didn't do this, we'd output the subhead
+                               -- multiple times).
+                               end if;
+                               Format_Object.Next_Paragraph_Subhead_Type := 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Subhead_Paragraph;
+                               Format_Object.Next_Paragraph_Format_Type := 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Paragraph_Format;
+                               Format_Object.Paragraph_Tab_Stops := 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Tab_Stops;
+                               Format_Object.Next_Enumerated_Num := 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Enum_Num;
+                               Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (End)");
+--!!Debug:
+--Ada.Text_IO.Put_Line ("(End) Next=" & 
Paragraph_Type'Image(Format_Object.Next_Paragraph_Subhead_Type));
+                           end if;
+
+                           Check_End_Paragraph; -- End any paragraph that 
we're in.
+
+                           declare
+                               Lower_Type_Name : constant String :=
+                                   Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (
+                                       Type_Name, Ada.Strings.Right));
+                           begin
+                               -- Check if number of columns is changing:
+                               if Lower_Type_Name = "twocol" then
+                                   -- Leaving two column region, reset to one:
+                                   ARM_Output.Set_Columns (Output_Object, 
Number_of_Columns => 1);
+                               elsif Lower_Type_Name = "fourcol" then
+                                   -- Leaving four column region, reset to one:
+                                   ARM_Output.Set_Columns (Output_Object, 
Number_of_Columns => 1);
+                               end if;
+                               -- Check if we're leaving a bundle:
+                               if Lower_Type_Name = "bundle" then
+                                   Format_Object.In_Bundle := False;
+                               end if;
+                               -- Check if we're leaving an enumerated list:
+                               if Lower_Type_Name = "enumerate" or else
+                                  Lower_Type_Name = "innerenumerate" then
+                                   Format_Object.Enumerated_Level :=
+                                       Format_Object.Enumerated_Level - 1;
+                               end if;
+                           end;
+                       else
+                           ARM_Input.Replace_Char (Input_Object);
+                           Ada.Text_IO.Put_Line ("  ** Failed to find close 
for parameter to end, line " & ARM_Input.Line_String (Input_Object));
+                           Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Bad End)");
+                       end if;
+                   end;
+
+               -- Indexing commands:
+
+               when Defn | RootDefn =>
+                   -- @Defn{term} or @RootDefn{term}. Index the term.
+                   -- Note that there is no difference between these in terms
+                   -- of the index, so we do them together.
+                   declare
+                       Term : String(1..80);
+                       Len : Natural := 0;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char,
+                           Term,
+                           Len);
+                       ARM_Index.Add (Term => Term(1..Len),
+                                      Kind => ARM_Index.Primary_Term,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+
+                       Check_Paragraph;
+                       if Format_Object.Display_Index_Entries then
+                           if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = Defn then
+                               Display_Index_Entry (Term(1..Len));
+                           else -- RootDefn
+                               Display_Index_Entry (Term(1..Len), Special => 
Is_Root);
+                           end if;
+                       end if;
+                       ARM_Output.Index_Target (Output_Object, Key);
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                           -- Remove the "(Root)Defn" record.
+                   end;
+
+               when PDefn =>
+                   -- @PDefn{term} ot @RootDefn{term}. Index the term as a 
partial
+                   -- definition.
+                   declare
+                       Term : String(1..80);
+                       Len : Natural := 0;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char,
+                           Term,
+                           Len);
+                       ARM_Index.Add (Term => Term(1..Len),
+                                      Kind => ARM_Index.Partial_Term,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+
+                       Check_Paragraph;
+                       if Format_Object.Display_Index_Entries then
+                           Display_Index_Entry (Term(1..Len), Special => 
Is_Partial);
+                       end if;
+                       ARM_Output.Index_Target (Output_Object, Key);
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                           -- Remove the "PDefn" record.
+                   end;
+
+               when Defn2 | RootDefn2 =>
+                   -- @Defn2[Term={term}, Sec={sec}]
+                   -- @RootDefn[Term={term}, Sec={sec}]. Index the term and 
subterm.
+                   -- Note that there is no difference between these in terms
+                   -- of the index, so we do them together.
+                   declare
+                       Close_Ch : Character;
+                       Term, Subterm : String(1..90);
+                       TLen, SLen : Natural := 0;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Term" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => True,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Term,
+                               TLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Sec" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Subterm,
+                               SLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Index.Add (Term => Term(1..TLen),
+                                      Subterm => Subterm(1..SLen),
+                                      Kind => 
ARM_Index.Primary_Term_and_Subterm,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+
+                       Check_Paragraph;
+                       if Format_Object.Display_Index_Entries then
+                           if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = Defn2 then
+                               Display_Index_Entry (Term(1..TLen) & " (" & 
Subterm(1..SLen) & ')');
+                           else -- RootDefn
+                               Display_Index_Entry (Term(1..TLen) & " (" & 
Subterm(1..SLen) & ')', Special => Is_Root);
+                           end if;
+                       end if;
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       -- Leave the command end marker, let normal processing
+                       -- get rid of it.
+                   end;
+
+               when PDefn2 =>
+                   -- @PDefn2[Term={term}, Sec={sec}]. Index the term and 
subterm.
+                   -- Note that there is no difference between these in terms
+                   -- of the index, so we do them together.
+                   declare
+                       Close_Ch : Character;
+                       Term, Subterm : String(1..90);
+                       TLen, SLen : Natural := 0;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Term" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => True,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Term,
+                               TLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Sec" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Subterm,
+                               SLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Index.Add (Term => Term(1..TLen),
+                                      Subterm => Subterm(1..SLen),
+                                      Kind => 
ARM_Index.Partial_Term_with_Subterm,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+
+                       Check_Paragraph;
+                       if Format_Object.Display_Index_Entries then
+                           Display_Index_Entry (Term(1..TLen) & " (" & 
Subterm(1..SLen) & ')',
+                               Special => Is_Partial);
+                       end if;
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       -- Leave the command end marker, let normal processing
+                       -- get rid of it.
+                   end;
+
+               when Index_See =>
+                   -- @IndexSee[Term={term}, See={see}]. Index a See item.
+                   declare
+                       Close_Ch : Character;
+                       Term, See : String(1..80);
+                       TLen, SLen : Natural := 0;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Term" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => True,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Term,
+                               TLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "See" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               See,
+                               SLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Index.Add (Term => Term(1..TLen),
+                                      Subterm => See(1..SLen),
+                                      Kind => ARM_Index.See_Term,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+
+                       Check_Paragraph;
+                       if Format_Object.Display_Index_Entries then
+                           Display_Index_Entry (Term(1..TLen) & ": See " & 
See(1..SLen));
+                       end if;
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       -- Leave the command end marker, let normal processing
+                       -- get rid of it.
+                   end;
+
+               when Index_See_Also =>
+                   -- @IndexSeeAlso[Term={term}, See={see}]. Index a See Also 
item.
+                   declare
+                       Close_Ch : Character;
+                       Term, See : String(1..80);
+                       TLen, SLen : Natural := 0;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Term" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => True,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Term,
+                               TLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "See" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               See,
+                               SLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Index.Add (Term => Term(1..TLen),
+                                      Subterm => See(1..SLen),
+                                      Kind => ARM_Index.See_Also_Term,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+
+                       Check_Paragraph;
+                       if Format_Object.Display_Index_Entries then
+                           Display_Index_Entry (Term(1..TLen) & ": See also " 
& See(1..SLen));
+                       end if;
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       -- Leave the command end marker, let normal processing
+                       -- get rid of it.
+                   end;
+
+               when See_Other =>
+                   -- @SeeOther[Primary={term}, Other={see}]. Generate a
+                   -- See {see} in the index, but no reference.
+                   declare
+                       Close_Ch : Character;
+                       Term, See : String(1..80);
+                       TLen, SLen : Natural := 0;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Primary" & 
(8..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => True,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Term,
+                               TLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Other" & 
(6..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               See,
+                               SLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Index.Add (Term => Term(1..TLen),
+                                      Subterm => See(1..SLen),
+                                      Kind => ARM_Index.See_Other_Term,
+                                      Clause => "",
+                                      Paragraph => "",
+                                      Key => Key);
+
+                       Check_Paragraph;
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       -- Leave the command end marker, let normal processing
+                       -- get rid of it.
+                   end;
+
+               when See_Also =>
+                   -- @SeeAlso[Primary={term}, Other={see}]. Generate a
+                   -- See also {see} in the index, but no reference.
+                   declare
+                       Close_Ch : Character;
+                       Term, See : String(1..80);
+                       TLen, SLen : Natural := 0;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Primary" & 
(8..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => True,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Term,
+                               TLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Other" & 
(6..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               See,
+                               SLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Index.Add (Term => Term(1..TLen),
+                                      Subterm => See(1..SLen),
+                                      Kind => ARM_Index.See_Also_Other_Term,
+                                      Clause => "",
+                                      Paragraph => "",
+                                      Key => Key);
+
+                       Check_Paragraph;
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       -- Leave the command end marker, let normal processing
+                       -- get rid of it.
+                   end;
+
+               when Index_Root_Unit =>
+                   -- @RootLibUnit{<unit>}
+                   -- Generates two index entries: An index entry for
+                   -- "Language-Defined Library Units" with a secondary
+                   -- entry of <unit>, and an index entry for <unit>.
+                   declare
+                       Term : String(1..80);
+                       Len : Natural := 0;
+                       Key : ARM_Index.Index_Key := ARM_Index.Get_Key;
+                       Disposition : ARM_Output.Change_Type;
+                       use type ARM_Output.Change_Type;
+                   begin
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char,
+                           Term,
+                           Len);
+
+                       -- Set the current unit for future use:
+                       Format_Object.Unit (1..Len) := Term(1..Len);
+                       Format_Object.Unit_Len := Len;
+
+                       -- Determine what to do with the "Language-Defined" 
entry:
+                       Calc_Change_Disposition (
+                           Format_Object => Format_Object,
+                           Version => '2',
+                           Operation => ARM_Output.Deletion,
+                           Text_Kind => Disposition);
+                       if Disposition = Do_Not_Display_Text then
+                           null; -- Ignore this.
+                       elsif Disposition = ARM_Output.None then
+                           -- Make reference:
+                           ARM_Index.Add_Reusing_Key (
+                               Term => "Language-Defined Library Units",
+                               Subterm => Term(1..Len),
+                               Kind => ARM_Index.Primary_Term_and_Subterm,
+                               Clause => Clause_String (Format_Object),
+                               Paragraph => Paragraph_String,
+                               Key => Key);
+                       elsif Disposition = ARM_Output.Deletion then
+                           null; -- Ignore this (no change info in the index).
+                       else -- Insertion.
+                           raise Program_Error; -- An insertion inside of a 
deletion command!
+                       end if;
+
+                       Check_Paragraph;
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       ARM_Index.Add_Reusing_Key (
+                               Term => Term(1..Len),
+                               Kind => ARM_Index.Primary_Term,
+                               Clause => Clause_String (Format_Object),
+                               Paragraph => Paragraph_String,
+                               Key => Key);
+
+                       ARM_Subindex.Insert (
+                               Subindex_Object => Format_Object.Package_Index,
+                               Entity => Term(1..Len),
+                               Kind => ARM_Subindex.Top_Level,
+                               Clause => Clause_String (Format_Object),
+                               Paragraph => Paragraph_String,
+                               Key => Key);
+
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                           -- Remove the "RootLibUnit" record.
+                   end;
+
+               when Index_Child_Unit =>
+                   -- @ChildUnit{Parent=[<parent>],Child=[<child>]}
+                   -- Generates three index entries: An index entry for 
<child>, with a secondary
+                   -- of "@i{child of} <parent>", an index entry for 
"Language-Defined
+                   -- Library Units" with a secondary entry of 
<parent>.<child>,
+                   -- and an index entry for <parent>.<child>.
+                   Child_Unit (Format_Object.Package_Index,
+                       Format_Object,
+                       Output_Object);
+
+
+               when Index_Subprogram_Child_Unit =>
+                   -- @ChildUnit{Parent=[<parent>],Child=[<child>]}
+                   -- Generates three index entries: An index entry for 
<child>, with a secondary
+                   -- of "@i{child of} <parent>", an index entry for 
"Language-Defined
+                   -- Library Units" with a secondary entry of 
<parent>.<child>,
+                   -- and an index entry for <parent>.<child>.
+                   Child_Unit (Format_Object.Subprogram_Index,
+                       Format_Object,
+                       Output_Object);
+
+               when Index_Type =>
+                   -- @AdaTypeDefn{<defn>}
+                   -- Generates two index entries: one for <defn> with a
+                   -- secondary entry of "@i{in} <Unit>" (where Unit is
+                   -- the unit saved by a previous RootLibUnit or ChildUnit.),
+                   -- adds a similar entry to the exception list,
+                   -- and second for "Language-Defined Type" with a
+                   -- secondary entry of "<defn> @i{in} <Unit>".
+                   -- Also outputs the <defn> to the output file.
+
+                   Simple_Subindex_Item (
+                       Format_Object.Type_Index,
+                       Format_Object,
+                       Output_Object,
+                       Entity_Kind_Name => "Type");
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                       -- Remove the "AdaTypeDefn" record.
+
+               when Index_Subtype =>
+                   -- @AdaSubTypeDefn{Name=<defn>,Of=<type>}
+                   -- Generates an index entry of "<defn> @i{subtype of}
+                   -- <type>" with a secondary entry of "@i{in} <Unit>" (where
+                   -- Unit is the unit saved by a previous RootLibUnit or
+                   -- ChildUnit.) The entry is added to the type list as well.
+                   -- Also outputs the <defn> to the output file.
+                   declare
+                       Subtype_Name, Type_Name : String(1..80);
+                       SLen, TLen : Natural := 0;
+                       Key : ARM_Index.Index_Key := ARM_Index.Get_Key;
+                       Close_Ch : Character;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                                   Param_Name => "Name" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                                   Is_First => True,
+                                   Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Subtype_Name,
+                               SLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Of" & 
(3..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy over the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Type_Name,
+                               TLen);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       Check_Paragraph;
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       if Format_Object.Unit_Len = 0 then
+                           Ada.Text_IO.Put_Line ("** No unit defined for index 
entry expecting one on line " & ARM_Input.Line_String (Input_Object));
+
+                           ARM_Index.Add_Reusing_Key (
+                               Term => Subtype_Name(1..SLen) & " subtype of " &
+                                   Type_Name(1..TLen),
+                               Subterm => "*unknown*",
+                               Kind => 
ARM_Index.Subtype_Declaration_in_Package,
+                               Clause => Clause_String (Format_Object),
+                               Paragraph => Paragraph_String,
+                               Key => Key);
+
+                           ARM_Subindex.Insert (
+                               Subindex_Object => Format_Object.Type_Index,
+                               Entity => Subtype_Name(1..SLen) & " subtype of 
" &
+                                   Type_Name(1..TLen),
+                               From_Unit => "*unknown*",
+                               Kind => ARM_Subindex.Subtype_In_Unit,
+                               Clause => Clause_String (Format_Object),
+                               Paragraph => Paragraph_String,
+                               Key => Key);
+                       else
+                           ARM_Index.Add_Reusing_Key (
+                               Term => Subtype_Name(1..SLen) & " subtype of " &
+                                   Type_Name(1..TLen),
+                               Subterm => 
Format_Object.Unit(1..Format_Object.Unit_Len),
+                               Kind => 
ARM_Index.Subtype_Declaration_in_Package,
+                               Clause => Clause_String (Format_Object),
+                               Paragraph => Paragraph_String,
+                               Key => Key);
+
+                           ARM_Subindex.Insert (
+                               Subindex_Object => Format_Object.Type_Index,
+                               Entity => Subtype_Name(1..SLen) & " subtype of 
" &
+                                   Type_Name(1..TLen),
+                               From_Unit => 
Format_Object.Unit(1..Format_Object.Unit_Len),
+                               Kind => ARM_Subindex.Subtype_In_Unit,
+                               Clause => Clause_String (Format_Object),
+                               Paragraph => Paragraph_String,
+                               Key => Key);
+                       end if;
+                       ARM_Output.Ordinary_Text (Output_Object, 
Subtype_Name(1..SLen));
+                       Format_Object.Last_Non_Space := True;
+                       -- Leave the command end marker, let normal processing
+                       -- get rid of it.
+                   end;
+
+               when Index_Subprogram =>
+                   -- @AdaSubDefn{<defn>}
+                   -- Generates two index entries: one for <defn> with a
+                   -- secondary entry of "@i{in} <Unit>" (where Unit is
+                   -- the unit saved by a previous RootLibUnit or ChildUnit.),
+                   -- adds a similar entry to the exception list,
+                   -- and second for "Language-Defined Subprogram" with a
+                   -- secondary entry of "<defn> @i{in} <Unit>".
+                   -- Also outputs the <defn> to the output file.
+                   Simple_Subindex_Item (
+                       Format_Object.Subprogram_Index,
+                       Format_Object,
+                       Output_Object,
+                       Entity_Kind_Name => "Subprogram");
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                       -- Remove the "AdaSubDefn" record.
+
+               when Index_Exception =>
+                   -- @AdaExcDefn{<defn>}
+                   -- Generates and index entries for <defn> with a
+                   -- secondary entry of "@i{in} <Unit>" (where Unit is
+                   -- the unit saved by a previous RootLibUnit or ChildUnit.),
+                   -- and adds a similar entry to the exception list.
+                   -- Also outputs the <defn> to the output file.
+                   Simple_Subindex_Item (
+                       Format_Object.Exception_Index,
+                       Format_Object,
+                       Output_Object,
+                       Entity_Kind_Name => "");
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                       -- Remove the "AdaExcDefn" record.
+
+               when Index_Object =>
+                   -- @AdaObjDefn{<defn>}
+                   -- Generates and index entries for <defn> with a
+                   -- secondary entry of "@i{in} <Unit>" (where Unit is
+                   -- the unit saved by a previous RootLibUnit or ChildUnit.),
+                   -- and adds a similar entry to the exception list.
+                   -- Also outputs the <defn> to the output file.
+                   Simple_Subindex_Item (
+                       Format_Object.Object_Index,
+                       Format_Object,
+                       Output_Object,
+                       Entity_Kind_Name => "");
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                       -- Remove the "AdaObjDefn" record.
+
+               when Index_Package =>
+                   -- @AdaObjDefn{<defn>}
+                   -- Generates and index entries for <defn> with a
+                   -- secondary entry of "@i{in} <Unit>" (where Unit is
+                   -- the unit saved by a previous RootLibUnit or ChildUnit.),
+                   -- and adds a similar entry to the package list.
+                   -- Also outputs the <defn> to the output file.
+                   Simple_Subindex_Item (
+                       Format_Object.Package_Index,
+                       Format_Object,
+                       Output_Object,
+                       Entity_Kind_Name => "");
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                       -- Remove the "AdaPackDefn" record.
+
+               when Index_Other =>
+                   -- @AdaDefn{<defn>}
+                   -- Generate an index entries for <defn> with a
+                   -- secondary entry of "@i{in} <Unit>" (where Unit is
+                   -- the unit saved by a previous RootLibUnit or ChildUnit.).
+                   -- Also outputs the <defn> to the output file.
+                   declare
+                       Item : String(1..80);
+                       Len : Natural := 0;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char,
+                           Item,
+                           Len);
+
+                       ARM_Index.Add (Term => Item(1..Len),
+                                      Subterm => 
Format_Object.Unit(1..Format_Object.Unit_Len),
+                                      Kind => ARM_Index.Declaration_in_Package,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+                       Check_Paragraph;
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       ARM_Output.Ordinary_Text (Output_Object, Item(1..Len));
+                       Format_Object.Last_Non_Space := True;
+
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                           -- Remove the "AdaDefn" record.
+                   end;
+
+               when Index_Check =>
+                   -- @Indexcheck{<check>}
+                   -- Generates index items for
+                   -- "check, language-defined", <check>,
+                   -- and <check> [partial].
+                   declare
+                       Term : String(1..80);
+                       Len : Natural := 0;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char,
+                           Term,
+                           Len);
+
+                       ARM_Index.Add (Term => Term(1..Len),
+                                      Kind => ARM_Index.Partial_Term,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+                       Check_Paragraph;
+                       if Format_Object.Display_Index_Entries then
+                           Display_Index_Entry (Term(1..Len), Special => 
Is_Partial);
+                       end if;
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       ARM_Index.Add (Term => "check, language-defined",
+                                      Subterm => Term(1..Len),
+                                      Kind => 
ARM_Index.Primary_Term_and_Subterm,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+                       if Format_Object.Display_Index_Entries then
+                           Display_Index_Entry ("check, language-defined (" & 
Term(1..Len) & ")");
+                       end if;
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                           -- Remove the "Indexcheck" record.
+                   end;
+
+               when Index_Attr =>
+                   -- This command indexes an attribute name.
+                   -- This calls Defn2("attributes", <param>), and
+                   -- also writes <param> to output.
+                   declare
+                       Param : String(1..20);
+                       Len : Natural := 0;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char,
+                           Param,
+                           Len);
+
+                       Check_Paragraph;
+
+                       ARM_Index.Add (Term => "attributes",
+                                      Subterm => Param(1..Len),
+                                      Kind => 
ARM_Index.Primary_Term_and_Subterm,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       ARM_Index.Add (Term => Param(1..Len) & " attribute",
+                                      Kind => ARM_Index.Primary_Term,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       ARM_Output.Ordinary_Text (Output_Object,
+                           Param(1..Len));
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                           -- Remove the "Index_Attr" record.
+                   end;
+
+               when Index_Pragma =>
+                   -- This command indexes a pragma name.
+                   -- This calls Defn2("pragmas", <param>), and
+                   -- also writes <param> to output.
+                   declare
+                       Param : String(1..30);
+                       Len : Natural := 0;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char,
+                           Param,
+                           Len);
+                       Check_Paragraph;
+                       ARM_Index.Add (Term => "pragmas",
+                                      Subterm => Param(1..Len),
+                                      Kind => 
ARM_Index.Primary_Term_and_Subterm,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       ARM_Index.Add (Term => Param(1..Len) & " pragma",
+                                      Kind => ARM_Index.Primary_Term,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       ARM_Output.Ordinary_Text (Output_Object,
+                           Param(1..Len));
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                           -- Remove the "Index_Pragma" record.
+                   end;
+
+               when Index_Aspect =>
+                   -- This command indexes an aspect name.
+                   -- This calls Defn2("aspects", <param>), and
+                   -- Defn(<param> "aspect")
+                   declare
+                       Param : String(1..30);
+                       Len : Natural := 0;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char,
+                           Param,
+                           Len);
+                       Check_Paragraph;
+                       ARM_Index.Add (Term => "aspects",
+                                      Subterm => Param(1..Len),
+                                      Kind => 
ARM_Index.Primary_Term_and_Subterm,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       ARM_Index.Add (Term => Param(1..Len) & " aspect",
+                                      Kind => ARM_Index.Primary_Term,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                           -- Remove the "Index_Aspect" record.
+                   end;
+
+               when Syntax_Rule =>
+                   -- @syn{[Tabs=<Tabset>, ]LHS=<Non-terminal>, 
RHS=<Production>}
+                   -- Marks a syntax production of the form:
+                   --    @nt<Non-Terminal> ::= <Production>
+                   -- <Tabset> defines any tabs needed by the syntax 
production.
+                   --
+                   -- Also, the <Non-terminal> is indexed. The <Non-Terminal>
+                   -- and <Production> (and the clause number) are sent to the
+                   -- syntax manager. Also, saves <Non-terminal> for any
+                   -- following Syntax_Term (@Syn2) to use.
+
+                   declare
+                       RHS_Close_Ch : Character;
+                   begin
+                       Get_Syntax_Parameters (Has_Version => False,
+                                              RHS_Close_Ch => RHS_Close_Ch);
+
+                       Gen_Syntax_Rule (ARM_Output.None, RHS_Close_Ch);
+                   end;
+
+               when Added_Syntax_Rule =>
+                   -- @AddedSyn{Version=[Version],[Tabs=<Tabset>, 
]LHS=<Non-terminal>, RHS=<Production>}
+                   -- Marks an added syntax production of the form:
+                   --    @nt<Non-Terminal> ::= <Production>
+                   -- See Syntax_Rule for the details.
+                   declare
+                       RHS_Close_Ch : Character;
+                       Disposition : ARM_Output.Change_Type;
+                   begin
+                       Get_Syntax_Parameters (Has_Version => True,
+                                              RHS_Close_Ch => RHS_Close_Ch);
+                       if Format_Object.In_Change then
+                           Ada.Text_IO.Put_Line ("  ** In change for AddedSyn 
on line " & ARM_Input.Line_String (Input_Object));
+                           raise Program_Error;
+                       end if;
+
+                       Calc_Change_Disposition (
+                           Format_Object => Format_Object,
+                           Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version,
+                           Operation => ARM_Output.Insertion,
+                           Text_Kind => Disposition);
+
+                       Gen_Syntax_Rule (Disposition, RHS_Close_Ch);
+                   end;
+
+               when Deleted_Syntax_Rule =>
+                   -- @DeletedSyn{Version=[Version],[Tabs=<Tabset>, 
]LHS=<Non-terminal>, RHS=<Production>}
+                   -- Marks a deleted syntax production of the form:
+                   --    @nt<Non-Terminal> ::= <Production>
+                   -- See Syntax_Rule for the details.
+                   declare
+                       RHS_Close_Ch : Character;
+                       Disposition : ARM_Output.Change_Type;
+                   begin
+                       Get_Syntax_Parameters (Has_Version => True,
+                                              RHS_Close_Ch => RHS_Close_Ch);
+                       if Format_Object.In_Change then
+                           Ada.Text_IO.Put_Line ("  ** In change for 
DeletedSyn on line " & ARM_Input.Line_String (Input_Object));
+                           raise Program_Error;
+                       end if;
+
+                       Calc_Change_Disposition (
+                           Format_Object => Format_Object,
+                           Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version,
+                           Operation => ARM_Output.Deletion,
+                           Text_Kind => Disposition);
+
+                       Gen_Syntax_Rule (Disposition, RHS_Close_Ch);
+                   end;
+
+               when Syntax_Term | Syntax_Term_Undefined =>
+                   -- Marks a non-terminal name in the production of a syntax
+                   -- rule. Generates the term in the same style as
+                   -- @nt (Non_Terminal). "Undefined" means the term is
+                   -- not formally defined (like the character class names in
+                   -- the Ada standard).
+                   -- If the current LHS non-terminal is not null, generates
+                   -- a syntax cross reference entry:
+                   -- <Name> in <Non-Terminal> at <ClauseNum>. Also,
+                   -- generate an index entry for the item:
+                   -- @Defn2(Term=<Name>,address@hidden
+                   -- Note: We assume no internal formatting in <Name>.
+                   declare
+                       Name : String(1..40);
+                       Len : Natural;
+                       Key : ARM_Index.Index_Key;
+                       Defined : constant Boolean :=
+                          
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command =
+                              Syntax_Term;
+                   begin
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char,
+                           Name, Len);
+                       if Format_Object.Syntax_NT_Len /= 0 then
+                           -- Generate a syntax cross-reference entry.
+                           declare
+                               NT : constant String := Get_NT;
+                           begin
+                               if NT /= "" then
+                                   ARM_Syntax.Add_Xref (
+                                        Name => Name(1..Len),
+                                        Used_In => Get_NT,
+                                        Clause => Clause_String 
(Format_Object),
+                                        Defined => Defined);
+                               -- else this is a deleted production that is
+                               -- still displayed; forget the XRef.
+                               end if;
+                           end;
+                       end if;
+
+                       -- Index the non-terminal:
+                       ARM_Index.Add (Term => Name(1..Len),
+                                      Kind => ARM_Index.Syntax_NT_Used,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       -- Set the appropriate style:
+                       Check_Paragraph;
+                       declare
+                           Swiss_Format : ARM_Output.Format_Type :=
+                               Format_Object.Text_Format;
+                       begin
+                           Swiss_Format.Font := ARM_Output.Swiss;
+                           ARM_Output.Text_Format (Output_Object,
+                                                   Swiss_Format);
+                       end;
+                       if not Defined then
+                           -- No linking to do.
+                           ARM_Output.Ordinary_Text (Output_Object, 
Name(1..Len));
+                       elsif Format_Object.Link_Non_Terminals then
+                           declare
+                               Lower_NT : constant String :=
+                                   Ada.Characters.Handling.To_Lower 
(Name(1..Len));
+                               Clause : constant String :=
+                                   ARM_Syntax.Non_Terminal_Clause (Lower_NT);
+                               Target : constant ARM_Syntax.Target_Type :=
+                                   ARM_Syntax.Non_Terminal_Link_Target 
(Lower_NT);
+                           begin
+                               if Clause = "" then -- Not found. No link, but 
error message:
+                                   Ada.Text_IO.Put_Line ("  ** Unknown 
non-terminal in syntax production " &
+                                       Name(1..Len) & " on line " & 
ARM_Input.Line_String (Input_Object));
+                                   ARM_Output.Ordinary_Text (Output_Object, 
Name(1..Len));
+                               else
+                                   ARM_Output.Local_Link (Output_Object, Text 
=> Name(1..Len),
+                                       Target => Target, Clause_Number => 
Clause);
+                               end if;
+                           end;
+                       else
+                           ARM_Output.Ordinary_Text (Output_Object, 
Name(1..Len));
+                       end if;
+                       ARM_Output.Text_Format (Output_Object,
+                                               Format_Object.Text_Format); -- 
Reset the format.
+                       Format_Object.Last_Non_Space := True;
+                   end;
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Syntax Term)");
+
+               when Syntax_Prefix =>
+                   -- Marks the prefix of a non-terminal. Writes italized
+                   -- text in the current font.
+                   -- Set the appropriate style:
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Italic := True;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format_Object.Text_Format);
+
+               when To_Glossary | To_Glossary_Also =>
+                   -- This is a glossary command.
+                   -- It is of the form @ToGlossary(Term=[<term>], 
Text=[<text>])
+                   -- We will store the term and definition in the glossary
+                   -- database. We also have to pass through the Text
+                   -- parameter, either to the regular text (for
+                   -- ToGlossaryAlso) or the AARM (for ToGlossary).
+
+                   declare
+                       Close_Ch : Character;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       if Format_Object.Glossary_Info.Active then
+                           Ada.Text_IO.Put_Line ("  ** Nested glossary entry 
on line " & ARM_Input.Line_String (Input_Object));
+                       -- else OK.
+                       end if;
+                       -- Setup glossary information for this command:
+                       Format_Object.Glossary_Info :=
+                           (Active      => True,
+                            Change_Kind => ARM_Database.None,
+                               -- No change for this command.
+                            Term        => <>, -- Set below.
+                            Term_Len    => <>, -- Set below.
+                            Add_to_Glossary => True, -- Always add it.
+                            Displayed   => False); -- Until we decide 
differently.
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Term" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => True,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Format_Object.Glossary_Info.Term,
+                               Format_Object.Glossary_Info.Term_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Text" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Now, handle the parameter:
+                           -- Stack it so we can process the end:
+                           Set_Nesting_for_Parameter
+                               (Command => Glossary_Text_Param,
+                                Close_Ch => Close_Ch);
+
+                           ARM_Input.Start_Recording (Input_Object);
+
+                           if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Command = 
To_Glossary_Also then
+                               -- The text just goes straight to the file.
+                               if Format_Object.Display_Index_Entries then
+                                   Display_Index_Entry 
(Format_Object.Glossary_Info.Term (1..Format_Object.Glossary_Info.Term_Len)); 
-- Includes Check_Paragraph.
+                                   ARM_Output.Ordinary_Text (Output_Object,
+                                       "[Glossary Entry]");
+                                   Format_Object.Last_Non_Space := True;
+                               -- else no marker.
+                               end if;
+
+                               -- Index the term (because it does appear here):
+                               Check_Paragraph; -- We've got to be in a 
paragraph to write this.
+                               ARM_Index.Add (Term => 
Format_Object.Glossary_Info.Term (1..Format_Object.Glossary_Info.Term_Len),
+                                              Kind => ARM_Index.Primary_Term,
+                                              Clause => Clause_String 
(Format_Object),
+                                              Paragraph => Paragraph_String,
+                                              Key => Key);
+                               ARM_Output.Index_Target (Output_Object, Key);
+                               Format_Object.Glossary_Info.Displayed := True;
+                           elsif Format_Object.Include_Annotations then
+                               Check_End_Paragraph; -- End any paragraph that 
we're in.
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Last_Subhead_Paragraph
 := Format_Object.Last_Paragraph_Subhead_Type;
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Subhead_Paragraph
 := Format_Object.Next_Paragraph_Subhead_Type;
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Paragraph_Format
 := Format_Object.Next_Paragraph_Format_Type;
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Tab_Stops := 
Format_Object.Paragraph_Tab_Stops;
+                               Format_Object.Next_Paragraph_Format_Type := 
Glossary_Marker;
+                               Format_Object.Next_Paragraph_Subhead_Type := 
Glossary_Marker;
+                               Format_Object.Paragraph_Tab_Stops := 
ARM_Output.NO_TABS;
+                               Display_Index_Entry 
(Format_Object.Glossary_Info.Term (1..Format_Object.Glossary_Info.Term_Len)); 
-- Includes Check_Paragraph.
+                               Format_Object.Glossary_Info.Displayed := True;
+                               -- Note: The term is indexed in the glossary,
+                               -- but not here.
+                           else -- No annotations, "To_Glossary"
+                               if Format_Object.Display_Index_Entries then
+                                   Display_Index_Entry 
(Format_Object.Glossary_Info.Term (1..Format_Object.Glossary_Info.Term_Len)); 
-- Includes Check_Paragraph.
+                                   ARM_Output.Ordinary_Text (Output_Object,
+                                       "[Glossary Entry]");
+                                   Format_Object.Last_Non_Space := True;
+                               -- else no marker.
+                               end if;
+                               -- Skip the text:
+                               ARM_Input.Skip_until_Close_Char (Input_Object,
+                                   
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char);
+                               ARM_Input.Replace_Char (Input_Object); -- Let 
the normal termination clean this up.
+                               Format_Object.Glossary_Info.Displayed := False;
+                               -- Note: The term is indexed in the glossary,
+                               -- but not here.
+                           end if;
+                       end if;
+                   end;
+
+               when Change_To_Glossary | Change_To_Glossary_Also =>
+                   -- This is a change glossary command.
+                   -- It is of the form
+                   -- 
@ChgToGlossary(Version=[<version>],Kind=(<kind>),Term=[<term>], Text=[<text>])
+                   -- We will store the term and definition in the glossary
+                   -- database. We also have to pass through the Text
+                   -- parameter, either to the regular text (for
+                   -- ChgToGlossaryAlso) or the AARM (for ChgToGlossary).
+
+                   declare
+                       Close_Ch : Character;
+                       Key : ARM_Index.Index_Key;
+                       Kind : ARM_Database.Paragraph_Change_Kind_Type;
+                       Our_Version : ARM_Contents.Change_Version_Type;
+                       use type ARM_Database.Paragraph_Change_Kind_Type;
+                       Local_Change  : ARM_Output.Change_Type;
+                   begin
+                       if Format_Object.Glossary_Info.Active then
+                           Ada.Text_IO.Put_Line ("  ** Nested glossary entry 
on line " & ARM_Input.Line_String (Input_Object));
+                       -- else OK.
+                       end if;
+
+                       Get_Change_Version (Is_First => True,
+                           Version => Our_Version);
+                           -- Read a parameter named "Version".
+
+                       Get_Change_Kind (Kind);
+                           -- Read a parameter named "Kind".
+
+                       -- Setup glossary information for this command (now
+                       -- that we know the above):
+                       -- Note: Discriminants need to be static, so we have
+                       -- to use the following brain-damaged initialization.
+                       -- At least this lets us strip the number and message
+                       -- information from Inserted and Deleted (which we
+                       -- would have to do anyway).
+                       case Kind is
+                           when ARM_Database.Inserted |
+                                ARM_Database.Inserted_Normal_Number =>
+                               Format_Object.Glossary_Info :=
+                                   (Active      => True,
+                                    Change_Kind => ARM_Database.Inserted,
+                                    Version     => Our_Version,
+                                    Term        => <>, -- Set below.
+                                    Term_Len    => <>, -- Set below.
+                                    Add_to_Glossary => <>, -- Set below.
+                                    Displayed   => <>); -- Set below.
+                           when ARM_Database.Deleted |
+                                ARM_Database.Deleted_Inserted_Number |
+                                ARM_Database.Deleted_No_Delete_Message |
+                                
ARM_Database.Deleted_Inserted_Number_No_Delete_Message =>
+                               Format_Object.Glossary_Info :=
+                                   (Active      => True,
+                                    Change_Kind => ARM_Database.Deleted,
+                                    Version     => Our_Version,
+                                    Term        => <>, -- Set below.
+                                    Term_Len    => <>, -- Set below.
+                                    Add_to_Glossary => <>, -- Set below.
+                                    Displayed   => <>); -- Set below.
+                           when ARM_Database.Revised =>
+                               Format_Object.Glossary_Info :=
+                                   (Active      => True,
+                                    Change_Kind => ARM_Database.Revised,
+                                    Version     => Our_Version,
+                                    Term        => <>, -- Set below.
+                                    Term_Len    => <>, -- Set below.
+                                    Add_to_Glossary => <>, -- Set below.
+                                    Displayed   => <>); -- Set below.
+                           when ARM_Database.Revised_Inserted_Number =>
+                               Format_Object.Glossary_Info :=
+                                   (Active      => True,
+                                    Change_Kind => 
ARM_Database.Revised_Inserted_Number,
+                                    Version     => Our_Version,
+                                    Term        => <>, -- Set below.
+                                    Term_Len    => <>, -- Set below.
+                                    Add_to_Glossary => <>, -- Set below.
+                                    Displayed   => <>); -- Set below.
+                           when ARM_Database.None =>
+                               raise Program_Error; -- Can't happen.
+                       end case;
+
+                       if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Change_To_Glossary_Also then
+                           -- The text just goes straight to the file. It will
+                           -- get formatted appropriately. So we only need to
+                           -- figure out whether it will get indexed and 
displayed
+                           -- in the Glossary.
+                           Format_Object.Glossary_Info.Displayed := True;
+                           Local_Change := ARM_Output.None;
+                           if Format_Object.Changes = ARM_Format.Old_Only and 
then
+                               Format_Object.Glossary_Info.Version > '0' then
+                               -- Old only, don't display it (and it won't be
+                               -- inserted, either).
+                               Format_Object.Glossary_Info.Add_to_Glossary := 
False;
+                           elsif Format_Object.Glossary_Info.Change_Kind = 
ARM_Database.Inserted then
+                               if Format_Object.Glossary_Info.Version <= 
Format_Object.Change_Version then
+                                   Format_Object.Glossary_Info.Add_to_Glossary 
:= True;
+                               else --This reference is too new, ignore it.
+                                   Format_Object.Glossary_Info.Displayed := 
False;
+                                   Format_Object.Glossary_Info.Add_to_Glossary 
:= False;
+                               end if;
+                           elsif Format_Object.Glossary_Info.Change_Kind = 
ARM_Database.Deleted then
+                               Format_Object.Glossary_Info.Add_to_Glossary := 
True;
+                           else -- we always display it.
+                               Format_Object.Glossary_Info.Add_to_Glossary := 
True;
+                           end if;
+                       else
+                           if Format_Object.Glossary_Info.Change_Kind = 
ARM_Database.Inserted then
+                               Calc_Change_Disposition
+                                   (Format_Object => Format_Object,
+                                    Version => 
Format_Object.Glossary_Info.Version,
+                                    Operation => ARM_Output.Insertion,
+                                    Text_Kind => Local_Change);
+                               case Local_Change is
+                                   when Do_Not_Display_Text =>
+                                       Format_Object.Glossary_Info.Displayed 
:= False;
+                                       
Format_Object.Glossary_Info.Add_to_Glossary := False;
+                                       Local_Change := ARM_Output.None;
+                                   when ARM_Output.None|ARM_Output.Insertion =>
+                                       Format_Object.Glossary_Info.Displayed :=
+                                           Format_Object.Include_Annotations;
+                                       
Format_Object.Glossary_Info.Add_to_Glossary := True;
+                                   when ARM_Output.Deletion =>
+                                       raise Program_Error;
+                               end case;
+                           elsif Format_Object.Glossary_Info.Change_Kind = 
ARM_Database.Deleted then
+                               -- Note: other forms of delete removed 
previously.
+                               Calc_Change_Disposition
+                                   (Format_Object => Format_Object,
+                                    Version => 
Format_Object.Glossary_Info.Version,
+                                    Operation => ARM_Output.Deletion,
+                                    Text_Kind => Local_Change);
+                               case Local_Change is
+                                   when Do_Not_Display_Text =>
+                                       Format_Object.Glossary_Info.Displayed 
:= False;
+                                       
Format_Object.Glossary_Info.Add_to_Glossary := True;
+                                       -- We still add this to the glossary so 
that
+                                       -- the deleted paragraph message can be 
displayed for it.
+                                       Local_Change := ARM_Output.None;
+                                   when ARM_Output.None|ARM_Output.Deletion =>
+                                       Format_Object.Glossary_Info.Displayed :=
+                                           Format_Object.Include_Annotations;
+                                       
Format_Object.Glossary_Info.Add_to_Glossary := True;
+                                   when ARM_Output.Insertion =>
+                                       raise Program_Error;
+                               end case;
+                           else -- we always display it.
+                               Format_Object.Glossary_Info.Displayed :=
+                                   Format_Object.Include_Annotations;
+                               Format_Object.Glossary_Info.Add_to_Glossary := 
True;
+                               Local_Change := ARM_Output.None;
+                           end if;
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Term" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Copy the term:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Format_Object.Glossary_Info.Term,
+                               Format_Object.Glossary_Info.Term_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Text" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Now, handle the parameter:
+                           -- Stack it so we can process the end:
+                           Set_Nesting_for_Parameter
+                               (Command => Glossary_Text_Param,
+                                Close_Ch => Close_Ch);
+
+                           ARM_Input.Start_Recording (Input_Object);
+
+                           if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Command = 
Change_To_Glossary_Also then
+                               -- The text just goes straight to the file.
+                               if Format_Object.Glossary_Info.Add_to_Glossary 
then
+                                   if Format_Object.Display_Index_Entries then
+                                       Display_Index_Entry 
(Format_Object.Glossary_Info.Term (1..Format_Object.Glossary_Info.Term_Len)); 
-- Includes Check_Paragraph.
+                                       ARM_Output.Ordinary_Text (Output_Object,
+                                           "[Glossary Entry]");
+                                       Format_Object.Last_Non_Space := True;
+                                   -- else no marker.
+                                   end if;
+
+                                   -- Index the term (because it does appear 
here):
+                                   Check_Paragraph; -- We've got to be in a 
paragraph to write this.
+                                   ARM_Index.Add (Term => 
Format_Object.Glossary_Info.Term (1..Format_Object.Glossary_Info.Term_Len),
+                                                  Kind => 
ARM_Index.Primary_Term,
+                                                  Clause => Clause_String 
(Format_Object),
+                                                  Paragraph => 
Paragraph_String,
+                                                  Key => Key);
+                                   ARM_Output.Index_Target (Output_Object, 
Key);
+                               -- else no indexing.
+                               end if;
+                           elsif Format_Object.Glossary_Info.Displayed then -- 
Change_To_Glossary
+                               -- Create the AARM annotation:
+                               Check_End_Paragraph; -- End any paragraph that 
we're in.
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Last_Subhead_Paragraph
 := Format_Object.Last_Paragraph_Subhead_Type;
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Subhead_Paragraph
 := Format_Object.Next_Paragraph_Subhead_Type;
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Paragraph_Format
 := Format_Object.Next_Paragraph_Format_Type;
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Tab_Stops := 
Format_Object.Paragraph_Tab_Stops;
+                               Format_Object.Next_Paragraph_Format_Type := 
Glossary_Marker;
+                               Format_Object.Next_Paragraph_Subhead_Type := 
Glossary_Marker;
+                               Format_Object.Paragraph_Tab_Stops := 
ARM_Output.NO_TABS;
+                               Format_Object.Next_Paragraph_Version := 
Format_Object.Glossary_Info.Version;
+                               Format_Object.Next_Paragraph_Change_Kind := 
Kind;
+
+                                -- We assume no outer changes;
+                               -- set new change state:
+                               Format_Object.Text_Format.Change := 
Local_Change;
+                               Format_Object.Text_Format.Version :=
+                                  Format_Object.Glossary_Info.Version;
+                               Format_Object.Text_Format.Added_Version := '0';
+                                   -- Change the state *before* outputting the
+                                   -- paragraph header, so the AARM prefix is 
included.
+                               Display_Index_Entry 
(Format_Object.Glossary_Info.Term (1..Format_Object.Glossary_Info.Term_Len)); 
-- Includes Check_Paragraph.
+
+                               Format_Object.Text_Format.Change := 
ARM_Output.None; -- Undo (header) change.
+                               Format_Object.Text_Format.Version := '0';
+
+                           elsif Format_Object.Glossary_Info.Add_to_Glossary 
then -- Change_To_Glossary
+                               -- No AARM annotation:
+                               if Format_Object.Display_Index_Entries then
+                                   Display_Index_Entry 
(Format_Object.Glossary_Info.Term (1..Format_Object.Glossary_Info.Term_Len)); 
-- Includes Check_Paragraph.
+                                   ARM_Output.Ordinary_Text (Output_Object,
+                                       "[Glossary Entry]");
+                                   Format_Object.Last_Non_Space := True;
+                               -- else no marker.
+                               end if;
+                               -- Skip the text:
+                               ARM_Input.Skip_until_Close_Char (Input_Object,
+                                   
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char);
+                               ARM_Input.Replace_Char (Input_Object); -- Let 
the normal termination clean this up.
+
+                               -- Note: The term is indexed in the glossary,
+                               -- but not here.
+                           else
+                               -- Skip the text (it won't be used at all):
+                               ARM_Input.Skip_until_Close_Char (Input_Object,
+                                   
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char);
+                               ARM_Input.Replace_Char (Input_Object); -- Let 
the normal termination clean this up.
+                           end if;
+                       end if;
+                   end;
+
+               when Implementation_Defined =>
+                   -- Store an "implementation-defined" entry for the 
parameter;
+                   -- also save the clause and paragraph reference.
+
+                   ARM_Input.Start_Recording (Input_Object);
+
+                   if Format_Object.Impdef_Info.Command /= None then
+                       Ada.Text_IO.Put_Line ("  ** Nested impdef entry on line 
" & ARM_Input.Line_String (Input_Object));
+                   -- else OK.
+                   end if;
+                   -- Setup impdef information for this command:
+                   Format_Object.Impdef_Info :=
+                       (Command     => Impdef,
+                        Change_Kind => ARM_Database.None,
+                        Version     => '0',
+                        Initial_Version => '0',
+                        Add_to_DB   => True,    -- Until we decide differently.
+                        Paragraph_String => <>, -- Set below.
+                        Paragraph_Len    => <>);-- Set below.
+
+                   if Format_Object.In_Paragraph then
+                       -- Do this to preserve any inserted paragraph info.
+                       Format_Object.Impdef_Info.Paragraph_String :=
+                           Format_Object.Current_Paragraph_String;
+                       Format_Object.Impdef_Info.Paragraph_Len :=
+                           Format_Object.Current_Paragraph_Len;
+                   else
+                       declare
+                           PNum : constant String := Positive'Image (
+                               Format_Object.Next_Paragraph - 1);
+                       begin
+                           Format_Object.Impdef_Info.Paragraph_Len := 
PNum'Length - 1;
+                           Format_Object.Impdef_Info.Paragraph_String (1 .. 
PNum'Last-1) :=
+                               PNum (2 .. PNum'Last);
+                       end;
+                   end if;
+
+                   if Format_Object.Include_Annotations then
+                       Check_End_Paragraph; -- End any paragraph that we're in.
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Last_Subhead_Paragraph
 := Format_Object.Last_Paragraph_Subhead_Type;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Subhead_Paragraph
 := Format_Object.Next_Paragraph_Subhead_Type;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Paragraph_Format
 := Format_Object.Next_Paragraph_Format_Type;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Tab_Stops := 
Format_Object.Paragraph_Tab_Stops;
+                       Format_Object.Next_Paragraph_Format_Type := 
Bare_Annotation;
+                       Format_Object.Next_Paragraph_Subhead_Type := 
Bare_Annotation;
+                       Format_Object.Paragraph_Tab_Stops := ARM_Output.NO_TABS;
+                       Check_Paragraph;
+                       declare
+                           Bold_Format : ARM_Output.Format_Type :=
+                               Format_Object.Text_Format;
+                       begin
+                           Bold_Format.Bold := True; -- Change only the 
boldface.
+                           ARM_Output.Text_Format (Output_Object,
+                                                   Bold_Format);
+                       end;
+                       ARM_Output.Ordinary_Text (Output_Object,
+                            Text => "Implementation defined: ");
+                       ARM_Output.Text_Format (Output_Object,
+                                               Format_Object.Text_Format); -- 
Reset style.
+                       Format_Object.Last_Paragraph_Subhead_Type := 
Bare_Annotation;
+                       Format_Object.Last_Non_Space := False;
+                   else -- No annotations
+                       -- Skip the text:
+                       ARM_Input.Skip_until_Close_Char (Input_Object,
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char);
+                       ARM_Input.Replace_Char (Input_Object); -- Let the 
normal termination clean this up.
+                   end if;
+
+               when Prefix_Type =>
+                   -- Copy the text into the Format_Object.Prefix_Text string.
+                   Check_Paragraph;
+                   ARM_Input.Start_Recording (Input_Object);
+                   -- No changes in this version (use ChgAttribute if you need 
that).
+                   Format_Object.Attr_Prefix_Change_Kind := ARM_Database.None;
+                   Format_Object.Attr_Prefix_Version := '0';
+
+               when Reset_Prefix_Type =>
+                   -- Set Format_Object.Prefix_Text string to the default.
+                   Format_Object.Prefix_Text := "@b{NONE!}" & (10..200 => ' ');
+                   Format_Object.Prefix_Text_Len := 9;
+
+               when Attribute | Attribute_Leading =>
+                    -- @Attribute{Prefix=<Prefix>,AttrName=<Name>,Text=<Text>}
+                    -- Defines an attribute. Creates a hanging text item 
<Prefix>'<Name>,
+                    -- with the specified text. The text can contain arbitrary 
commands;
+                    -- it will be run through the full evaluation code.
+                    -- The attribute and text is also sent to a database used 
to later create
+                    -- Annex K. (This uses the current value of PrefixType.) 
Finally, the
+                    -- attribute <Name> is indexed as by calling 
@Defn2{Term=[Attribute],
+                    -- Sec=<Name>}, and as by calling @Defn{<Name> attribute}.
+                   declare
+                       Close_Ch : Character;
+                       Key : ARM_Index.Index_Key;
+                   begin
+                       Check_End_Paragraph; -- This is always a paragraph end.
+
+                       -- No changes in this version (use ChgAttribute if you 
need that).
+                       Format_Object.Attr_Change_Kind := ARM_Database.None;
+                       Format_Object.Attr_Version := '0';
+                       Format_Object.Attr_Initial_Version := '0';
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Prefix" & 
(7..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => True,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Save prefix:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Format_Object.Attr_Prefix,
+                               Format_Object.Attr_Prefix_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "AttrName" & 
(9..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Save name:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Format_Object.Attr_Name,
+                               Format_Object.Attr_Name_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       -- Output <Prefix>'<Name> as the hanging text.
+                       if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Attribute_Leading then
+                           Format_Object.Space_After := ARM_Output.Narrow;
+                           Format_Object.Attr_Leading := True;
+                       else
+                           Format_Object.Space_After := ARM_Output.Normal;
+                           Format_Object.Attr_Leading := False;
+                       end if;
+                       Check_Paragraph;
+                       ARM_Output.Ordinary_Text (Output_Object,
+                               Format_Object.Attr_Prefix (1 .. 
Format_Object.Attr_Prefix_Len));
+                       ARM_Output.Ordinary_Character (Output_Object, ''');
+                       ARM_Output.Ordinary_Text (Output_Object,
+                               Format_Object.Attr_Name (1 .. 
Format_Object.Attr_Name_Len));
+                       ARM_Output.End_Hang_Item (Output_Object);
+                       Format_Object.Last_Non_Space := False; -- Treat like 
start of a line.
+
+                       ARM_Index.Add (Term => "attributes",
+                                      Subterm => Format_Object.Attr_Name (1 .. 
Format_Object.Attr_Name_Len),
+                                      Kind => 
ARM_Index.Primary_Term_and_Subterm,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       ARM_Index.Add (Term => Format_Object.Attr_Name (1 .. 
Format_Object.Attr_Name_Len) & " attribute",
+                                      Kind => ARM_Index.Primary_Term,
+                                      Clause => Clause_String (Format_Object),
+                                      Paragraph => Paragraph_String,
+                                      Key => Key);
+                       ARM_Output.Index_Target (Output_Object, Key);
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Text" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Now, handle the parameter:
+                           -- The text goes to the file *and* is recorded.
+                           Arm_Input.Start_Recording (Input_Object);
+                           -- Stack the parameter so we can process the end:
+                           Set_Nesting_for_Parameter
+                               (Command => Attribute_Text_Param,
+                                Close_Ch => Close_Ch);
+                       end if;
+                   end;
+
+               when Pragma_Syntax =>
+                    -- @PragmaSyntax{<Text>}
+                    -- Defines a pragma. The text can contain arbitrary 
commands;
+                    -- it will be run through the full evaluation code.
+                    -- The text is also sent to a database used to later create
+                    -- Annex L.
+                    -- Note that these are indented slightly more than regular
+                    -- syntax text. We handle that by adding a couple of
+                    -- spaces before the text.
+
+--Ada.Text_IO.Put_Line ("%% Pragma - normal initialization.");
+                    -- All we have to do here is output a couple of
+                    -- hard spaces and then start recording.
+                    Check_Paragraph;
+                    ARM_Output.Hard_Space (Output_Object);
+                    ARM_Output.Hard_Space (Output_Object);
+                    ARM_Input.Start_Recording (Input_Object);
+                    -- Just handle the text normally.
+
+               when Added_Pragma_Syntax =>
+                    -- @AddedPragmaSyntax{Version=[<Version>],<Text>}
+                    -- Defines a pragma. The text can contain arbitrary 
commands;
+                    -- it will be run through the full evaluation code.
+                    -- The text is also sent to a database used to later create
+                    -- Annex L.
+                    -- Note that these are indented slightly more than regular
+                    -- syntax text. We handle that by adding a couple of
+                    -- spaces before the text.
+
+                    declare
+                       Ch : Character;
+                       Version : ARM_Contents.Change_Version_Type := '0';
+
+                       Disposition : ARM_Output.Change_Type;
+                       use type ARM_Output.Change_Type;
+                    begin
+                       Get_Change_Version (Is_First => True,
+                                           Version => Version);
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       if Ch /= ',' then
+                           Ada.Text_IO.Put_Line ("  ** Missing comma for 
AddedPragmaSyn on line " & ARM_Input.Line_String (Input_Object));
+                           ARM_Input.Replace_Char (Input_Object);
+                       end if;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version := 
Version;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Prev_Change_Version 
:= Version; -- Don't have or need an InitialVersion parameter.
+
+                       Calc_Change_Disposition (
+                           Format_Object => Format_Object,
+                           Version => Version,
+                           Operation => ARM_Output.Insertion,
+                           Text_Kind => Disposition);
+
+                       -- All we have to do here is output a couple of
+                       -- hard spaces (if anything will be displayed) and then
+                       -- start recording. The inner @Chg will handle the
+                       -- formatting for this.
+--Ada.Text_IO.Put_Line ("%% Added pragma.");
+                       Check_Paragraph;
+                       if Disposition /= Do_Not_Display_Text then
+                           ARM_Output.Hard_Space (Output_Object);
+                           ARM_Output.Hard_Space (Output_Object);
+                       -- else nothing to display.
+                       end if;
+                       ARM_Input.Start_Recording (Input_Object);
+                       -- Just handle the text normally.
+                   end;
+
+               when Deleted_Pragma_Syntax =>
+                    -- 
@DeletedPragmaSyntax{Version=[<Version>],InitialVersion=[<InitialVersion>],<Text>}
+                    -- Defines a pragma. The text can contain arbitrary 
commands;
+                    -- it will be run through the full evaluation code.
+                    -- The text is also sent to a database used to later create
+                    -- Annex L.
+                    -- Note that these are indented slightly more than regular
+                    -- syntax text. We handle that by adding a couple of
+                    -- spaces before the text.
+
+                    declare
+                       Close_Ch, Ch : Character;
+                       Version : ARM_Contents.Change_Version_Type := '0';
+                       Initial_Version : ARM_Contents.Change_Version_Type := 
'0';
+
+                       Disposition : ARM_Output.Change_Type;
+                       use type ARM_Output.Change_Type;
+                    begin
+                       Get_Change_Version (Is_First => True,
+                                           Version => Version);
+
+                       -- Now, get InitialVersion.
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "InitialVersion" & 
(15..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+
+                       ARM_Input.Get_Char (Input_Object, Initial_Version);
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       if Ch /= Close_Ch then
+                           Ada.Text_IO.Put_Line ("  ** Bad close for 
InitialVersion parameter on line " &
+                               ARM_Input.Line_String (Input_Object));
+                           ARM_Input.Replace_Char (Input_Object);
+                       end if;
+
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       if Ch /= ',' then
+                           Ada.Text_IO.Put_Line ("  ** Missing comma for 
AddedPragmaSyn on line " & ARM_Input.Line_String (Input_Object));
+                           ARM_Input.Replace_Char (Input_Object);
+                       end if;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version := 
Version;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Prev_Change_Version 
:= Initial_Version;
+
+                       Calc_Change_Disposition (
+                           Format_Object => Format_Object,
+                           Version => Version,
+                           Operation => ARM_Output.Deletion,
+                           Text_Kind => Disposition);
+
+--Ada.Text_IO.Put_Line ("%% Deleted pragma.");
+                       -- All we have to do here is output a couple of
+                       -- hard spaces (if anything will be displayed) and then
+                       -- start recording. The inner @Chg will handle the
+                       -- formatting for this.
+                       Check_Paragraph;
+                       if Disposition /= Do_Not_Display_Text then
+                           ARM_Output.Hard_Space (Output_Object);
+                           ARM_Output.Hard_Space (Output_Object);
+                       -- else nothing to display.
+                       end if;
+                       ARM_Input.Start_Recording (Input_Object);
+                       -- Just handle the text normally.
+                   end;
+
+               -- Clause title and reference commands:
+
+               when Labeled_Section | Labeled_Section_No_Break |
+                    Labeled_Annex | Labeled_Informative_Annex |
+                    Labeled_Normative_Annex | Labeled_Clause |
+                    Labeled_Subclause | Labeled_Subsubclause |
+                    Unnumbered_Section =>
+                   -- Load the title into the Title string:
+                   declare
+                       Title : ARM_Contents.Title_Type;
+                       Title_Length : Natural;
+                       Level : ARM_Contents.Level_Type;
+                   begin
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char,
+                           Title, Title_Length);
+                       if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Subclause then
+                           Format_Object.Clause_Number :=
+                               (Section   => 
Format_Object.Clause_Number.Section,
+                                Clause    => 
Format_Object.Clause_Number.Clause,
+                                Subclause => 
Format_Object.Clause_Number.Subclause + 1,
+                                Subsubclause => 0);
+                           Level := ARM_Contents.Subclause;
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Subsubclause then
+                           Format_Object.Clause_Number.Subsubclause :=
+                               Format_Object.Clause_Number.Subsubclause + 1;
+                           Level := ARM_Contents.Subsubclause;
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Clause then
+                           Format_Object.Clause_Number :=
+                               (Section   => 
Format_Object.Clause_Number.Section,
+                                Clause    => 
Format_Object.Clause_Number.Clause + 1,
+                                Subclause => 0, Subsubclause => 0);
+                           Level := ARM_Contents.Clause;
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Unnumbered_Section then
+                           Format_Object.Unnumbered_Section :=
+                               Format_Object.Unnumbered_Section + 1;
+                           Format_Object.Clause_Number :=
+                               (Section   => 0,
+                                Clause    => Format_Object.Unnumbered_Section,
+                                Subclause => 0, Subsubclause => 0);
+                           Level := ARM_Contents.Unnumbered_Section;
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Section or else
+                             
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Section_No_Break then
+                           Format_Object.Clause_Number :=
+                               (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                Clause    => 0,
+                                Subclause => 0, Subsubclause => 0);
+                           Level := ARM_Contents.Section;
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Annex then
+                           Format_Object.Clause_Number :=
+                               (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                Clause    => 0,
+                                Subclause => 0, Subsubclause => 0);
+                           Level := ARM_Contents.Plain_Annex;
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Normative_Annex then
+                           Format_Object.Clause_Number :=
+                               (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                Clause    => 0,
+                                Subclause => 0, Subsubclause => 0);
+                           Level := ARM_Contents.Normative_Annex;
+                       else -- 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Informative_Annex then
+                           Format_Object.Clause_Number :=
+                               (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                Clause    => 0,
+                                Subclause => 0, Subsubclause => 0);
+                           Level := ARM_Contents.Informative_Annex;
+                       end if;
+                       Title(Title_Length+1 .. Title'Last) :=
+                           (others => ' ');
+
+                       begin
+                           declare
+                               Clause_Number : constant String :=
+                                   ARM_Contents.Lookup_Clause_Number (Title);
+                           begin
+                               Check_End_Paragraph; -- End any paragraph that 
we're in.
+                               if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Section_No_Break then
+                                   ARM_Output.Clause_Header (Output_Object,
+                                       Title(1..Title_Length),
+                                       Level => ARM_Contents.Section,
+                                       Clause_Number => Clause_Number,
+                                       No_Page_Break => True,
+                                       Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+
+                               else -- Other cases:
+                                   ARM_Output.Clause_Header (Output_Object,
+                                       Title(1..Title_Length),
+                                       Level => Level,
+                                       Clause_Number => Clause_Number,
+                                       Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+                               end if;
+                               -- Check that the section numbers match the 
title:
+                               if Ada.Characters.Handling.To_Lower (Title) /=
+                                  Ada.Characters.Handling.To_Lower 
(ARM_Contents.Lookup_Title (
+                                     Level, Format_Object.Clause_Number)) then
+                                   Ada.Text_IO.Put_Line ("** Unable to match 
title with section numbers, line " & ARM_Input.Line_String (Input_Object));
+                               end if;
+--!!Debug:
+--Ada.Text_IO.Put_Line ("Start clause " & Clause_Number & " -- " & 
Title(1..Title_Length));
+
+                           end;
+                       exception
+                           when ARM_Contents.Not_Found_Error =>
+                               Ada.Text_IO.Put_Line ("** Unable to find header 
reference, line " & ARM_Input.Line_String (Input_Object));
+                               Ada.Text_IO.Put_Line ("   Looking for " & 
Title(1..Title_Length));
+                       end;
+                   end;
+                   -- Reset the paragraph numbers:
+                   Format_Object.Next_Paragraph := 1;
+                   Format_Object.Next_Insert_Para := 1;
+                   Format_Object.Next_AARM_Sub := 'a';
+                   if Format_Object.Use_ISO_2004_Note_Format then
+                       -- Reset the note number:
+                       Format_Object.Next_Note := 1;
+                   elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Section or else
+                         
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Section_No_Break or else
+                         
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Annex or else
+                         
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Informative_Annex or else
+                         
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Normative_Annex then
+                       -- Reset the note number, only for sections:
+                       Format_Object.Next_Note := 1;
+                   end if;
+                   -- Reset the subhead:
+                   Format_Object.Last_Paragraph_Subhead_Type := Plain;
+                   Format_Object.Next_Paragraph_Format_Type := Plain;
+
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Header)");
+
+               when Labeled_Revised_Annex |
+                    Labeled_Revised_Informative_Annex |
+                    Labeled_Revised_Normative_Annex |
+                    Labeled_Revised_Section |
+                    Labeled_Revised_Clause |
+                    Labeled_Revised_Subclause |
+                    Labeled_Revised_Subsubclause =>
+                   -- Load the title into the Title string:
+                   declare
+                       New_Title : ARM_Contents.Title_Type;
+                       New_Title_Length : Natural;
+                       Old_Title : ARM_Contents.Title_Type;
+                       Old_Title_Length : Natural;
+                       Close_Ch  : Character;
+                       Version   : ARM_Contents.Change_Version_Type := '0';
+                       Initial_Version : ARM_Contents.Change_Version_Type := 
'0';
+                       Level     : ARM_Contents.Level_Type;
+                   begin
+                       Get_Change_Version (Is_First => True,
+                                           Version => Version);
+
+                       -- Check for the optional "InitialVersion" parameter,
+                       -- stopping when we reach "New":
+                       declare
+                           Which_Param : ARM_Input.Param_Num;
+                           Ch          : Character;
+                       begin
+                           -- If there is no InitialVersion command, use the 
same
+                           -- version of the rest of the command.
+                           loop
+                               ARM_Input.Check_One_of_Parameter_Names 
(Input_Object,
+                                   Param_Name_1 => "InitialVersion" & 
(15..ARM_Input.Command_Name_Type'Last => ' '),
+                                   Param_Name_2 => "New" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                                   Is_First => False,
+                                   Param_Found => Which_Param,
+                                   Param_Close_Bracket => Close_Ch);
+
+                               if Which_Param = 1 and then Close_Ch /= ' ' then
+                                   -- Found InitialVersion
+                                   ARM_Input.Get_Char (Input_Object, Ch);
+                                   Initial_Version := Ch;
+                                   ARM_Input.Get_Char (Input_Object, Ch);
+                                   if Ch /= Close_Ch then
+                                       Ada.Text_IO.Put_Line ("  ** Bad close 
for InitialVersion parameter on line " &
+                                           ARM_Input.Line_String 
(Input_Object));
+                                       ARM_Input.Replace_Char (Input_Object);
+                                   end if;
+                               else -- We found "New" (or an error)
+                                   exit; -- Handling of New is below.
+                               end if;
+                           end loop;
+                       end;
+
+                       if Close_Ch /= ' ' then
+                           -- There is a parameter:
+                           -- Load the new title into the Title string:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               New_Title, New_Title_Length);
+                           New_Title(New_Title_Length+1 .. New_Title'Last) :=
+                               (others => ' ');
+                           ARM_Input.Check_Parameter_Name (Input_Object,
+                               Param_Name => "Old" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                               Is_First => False,
+                               Param_Close_Bracket => Close_Ch);
+                           if Close_Ch /= ' ' then
+                               -- There is a parameter:
+                               -- Load the new title into the Title string:
+                               ARM_Input.Copy_to_String_until_Close_Char (
+                                   Input_Object,
+                                   Close_Ch,
+                                   Old_Title, Old_Title_Length);
+                               Old_Title(Old_Title_Length+1 .. Old_Title'Last) 
:=
+                                   (others => ' ');
+                           end if;
+                       end if;
+                       ARM_Input.Get_Char (Input_Object, Close_Ch);
+                       if Close_Ch /= 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char then
+                           Ada.Text_IO.Put_Line ("  ** Bad close for 
Labeled_Revised_(SubClause|Annex) on line " & ARM_Input.Line_String 
(Input_Object));
+                           ARM_Input.Replace_Char (Input_Object);
+                       end if;
+
+                       if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Revised_Subclause then
+                           Format_Object.Clause_Number :=
+                               (Section   => 
Format_Object.Clause_Number.Section,
+                                Clause    => 
Format_Object.Clause_Number.Clause,
+                                Subclause => 
Format_Object.Clause_Number.Subclause + 1,
+                                Subsubclause => 0);
+                           Level := ARM_Contents.Subclause;
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Revised_Subsubclause then
+                           Format_Object.Clause_Number.Subsubclause :=
+                               Format_Object.Clause_Number.Subsubclause + 1;
+                           Level := ARM_Contents.Subsubclause;
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Revised_Clause then
+                           Format_Object.Clause_Number :=
+                               (Section   => 
Format_Object.Clause_Number.Section,
+                                Clause    => 
Format_Object.Clause_Number.Clause + 1,
+                                Subclause => 0, Subsubclause => 0);
+                           Level := ARM_Contents.Clause;
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Revised_Section then
+                           Format_Object.Clause_Number :=
+                               (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                Clause    => 0,
+                                Subclause => 0, Subsubclause => 0);
+                           Level := ARM_Contents.Section;
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Revised_Annex then
+                           Format_Object.Clause_Number :=
+                               (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                Clause    => 0,
+                                Subclause => 0, Subsubclause => 0);
+                           Level := ARM_Contents.Plain_Annex;
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Revised_Normative_Annex then
+                           Format_Object.Clause_Number :=
+                               (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                Clause    => 0,
+                                Subclause => 0, Subsubclause => 0);
+                           Level := ARM_Contents.Normative_Annex;
+                       else -- 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Revised_Informative_Annex then
+                           Format_Object.Clause_Number :=
+                               (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                Clause    => 0,
+                                Subclause => 0, Subsubclause => 0);
+                           Level := ARM_Contents.Informative_Annex;
+                       end if;
+
+                       begin
+                           declare
+                               Clause_Number : constant String :=
+                                   ARM_Contents.Lookup_Clause_Number 
(New_Title);
+
+                               New_Disposition : ARM_Output.Change_Type;
+                               Old_Disposition : ARM_Output.Change_Type;
+                               use type ARM_Output.Change_Type;
+                           begin
+                               Check_End_Paragraph; -- End any paragraph that 
we're in.
+                               -- Check that the section numbers match the 
title:
+                               if Ada.Characters.Handling.To_Lower (New_Title) 
/=
+                                  Ada.Characters.Handling.To_Lower 
(ARM_Contents.Lookup_Title (
+                                     Level, Format_Object.Clause_Number)) then
+                                   Ada.Text_IO.Put_Line ("** Unable to match 
title with section numbers, line " & ARM_Input.Line_String (Input_Object));
+                               end if;
+
+                               Calc_Change_Disposition (
+                                   Format_Object => Format_Object,
+                                   Version => Version,
+                                   Operation => ARM_Output.Insertion,
+                                   Text_Kind => New_Disposition);
+                                   -- Note: We use insertion here because
+                                   -- we want to decide what to do with
+                                   -- the New part.
+                               Calc_Change_Disposition (
+                                   Format_Object => Format_Object,
+                                   Version => Initial_Version,
+                                   Operation => ARM_Output.Insertion,
+                                   Text_Kind => Old_Disposition);
+
+                               if New_Disposition = Do_Not_Display_Text then
+                                   if Old_Disposition = Do_Not_Display_Text 
then
+                                       null; -- Show nothing.
+                                   elsif Old_Disposition = ARM_Output.None then
+                                       -- Use the old only:
+                                       ARM_Output.Clause_Header (Output_Object,
+                                           Old_Title(1..Old_Title_Length),
+                                           Level => Level,
+                                           Clause_Number => Clause_Number,
+                                           Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+                                   elsif Old_Disposition = ARM_Output.Deletion 
then
+                                       raise Program_Error; -- A deletion 
inside of an insertion command!
+                                   else -- an insertion of the Old. Show this 
like an added item:
+                                       ARM_Output.Revised_Clause_Header 
(Output_Object,
+                                           New_Header_Text => 
Old_Title(1..Old_Title_Length),
+                                           Old_Header_Text => "",
+                                           Level => Level,
+                                           Version => Initial_Version,
+                                           Old_Version => '0',
+                                           Clause_Number => Clause_Number,
+                                           Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+                                   end if;
+                               elsif New_Disposition = ARM_Output.None then
+                                   -- Use the new only:
+                                   ARM_Output.Clause_Header (Output_Object,
+                                       New_Title(1..New_Title_Length),
+                                       Level => Level,
+                                       Clause_Number => Clause_Number,
+                                       Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+                                       -- In this case, we have no sane
+                                       -- way to show the old, so we hope that
+                                       -- isn't expected.
+--!!Debug:
+--Ada.Text_IO.Put_Line ("Start clause " & Clause_Number & " -- " & 
New_Title(1..New_Title_Length));
+                               elsif New_Disposition = ARM_Output.Deletion then
+                                   raise Program_Error; -- A deletion inside 
of an insertion command!
+                               else -- Insertion.
+                                   if Format_Object.Changes = 
ARM_Format.New_Changes or else
+                                       Old_Disposition = Do_Not_Display_Text 
then
+                                       ARM_Output.Revised_Clause_Header 
(Output_Object,
+                                           New_Header_Text => 
New_Title(1..New_Title_Length),
+                                           Old_Header_Text => " ",
+                                           Level => Level,
+                                           Version => Version,
+                                           Old_Version => '0',
+                                           Clause_Number => Clause_Number,
+                                           Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+                                   elsif Old_Disposition = ARM_Output.None then
+                                       -- Show old without any insertion marks:
+                                       ARM_Output.Revised_Clause_Header 
(Output_Object,
+                                           New_Header_Text => 
New_Title(1..New_Title_Length),
+                                           Old_Header_Text => 
Old_Title(1..Old_Title_Length),
+                                           Level => Level,
+                                           Version => Version,
+                                           Old_Version => '0',
+                                           Clause_Number => Clause_Number,
+                                           Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+                                   elsif Old_Disposition = ARM_Output.Deletion 
then
+                                       raise Program_Error; -- A deletion 
inside of an insertion command!
+                                   else -- An insertion of the Old item:
+                                       ARM_Output.Revised_Clause_Header 
(Output_Object,
+                                           New_Header_Text => 
New_Title(1..New_Title_Length),
+                                           Old_Header_Text => 
Old_Title(1..Old_Title_Length),
+                                           Level => Level,
+                                           Version => Version,
+                                           Old_Version => Initial_Version,
+                                           Clause_Number => Clause_Number,
+                                           Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+                                   end if;
+--!!Debug:
+--Ada.Text_IO.Put_Line ("Start clause " & Clause_Number & " -- " & 
New_Title(1..New_Title_Length));
+                               end if;
+                           end;
+                       exception
+                           when ARM_Contents.Not_Found_Error =>
+                               Ada.Text_IO.Put_Line ("** Unable to find header 
reference, line " & ARM_Input.Line_String (Input_Object));
+                               Ada.Text_IO.Put_Line ("   Looking for " & 
New_Title(1..New_Title_Length));
+                       end;
+                       -- Reset the paragraph numbers:
+                       Format_Object.Next_Paragraph := 1;
+                       Format_Object.Next_Insert_Para := 1;
+                       Format_Object.Next_AARM_Sub := 'a';
+                       if Format_Object.Use_ISO_2004_Note_Format then
+                           -- Reset the note number:
+                           Format_Object.Next_Note := 1;
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Revised_Section or else
+                             
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Revised_Annex or else
+                             
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Revised_Informative_Annex or else
+                             
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Revised_Normative_Annex then
+                           -- Reset the note number, only for sections:
+                           Format_Object.Next_Note := 1;
+                       end if;
+                       -- Reset the subhead:
+                       Format_Object.Last_Paragraph_Subhead_Type := Plain;
+                       Format_Object.Next_Paragraph_Format_Type := Plain;
+
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Header)");
+                   end;
+
+               when Labeled_Added_Annex |
+                    Labeled_Added_Informative_Annex |
+                    Labeled_Added_Normative_Annex |
+                    Labeled_Added_Section |
+                    Labeled_Added_Clause |
+                    Labeled_Added_Subclause |
+                    Labeled_Added_Subsubclause =>
+                   -- Load the title into the Title string:
+                   declare
+                       New_Title : ARM_Contents.Title_Type;
+                       New_Title_Length : Natural;
+                       Ch : Character;
+                       Version : ARM_Contents.Change_Version_Type := '0';
+                       Level : ARM_Contents.Level_Type;
+                       Disposition : ARM_Output.Change_Type;
+                       use type ARM_Output.Change_Type;
+                   begin
+                       Get_Change_Version (Is_First => True,
+                                           Version => Version);
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Name" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Ch);
+                       if Ch /= ' ' then
+                           -- There is a parameter:
+                           -- Load the new title into the Title string:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Ch,
+                               New_Title, New_Title_Length);
+                           New_Title(New_Title_Length+1 .. New_Title'Last) :=
+                               (others => ' ');
+                       end if;
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       if Ch /= 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char then
+                           Ada.Text_IO.Put_Line ("  ** Bad close for 
Labeled_Added_(Sub)Clause on line " & ARM_Input.Line_String (Input_Object));
+                           ARM_Input.Replace_Char (Input_Object);
+                       end if;
+
+                       Calc_Change_Disposition (
+                           Format_Object => Format_Object,
+                           Version => Version,
+                           Operation => ARM_Output.Insertion,
+                           Text_Kind => Disposition);
+
+                       if Disposition = Do_Not_Display_Text then
+                           null; -- Ignore this; it isn't numbered or anything.
+                       elsif Disposition = ARM_Output.Deletion then
+                           raise Program_Error; -- A deletion inside of an 
insertion command!
+                       else
+                           if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Added_Subclause then
+                               Format_Object.Clause_Number :=
+                                   (Section   => 
Format_Object.Clause_Number.Section,
+                                    Clause    => 
Format_Object.Clause_Number.Clause,
+                                    Subclause => 
Format_Object.Clause_Number.Subclause + 1,
+                                    Subsubclause => 0);
+                               Level := ARM_Contents.Subclause;
+                           elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Added_Subsubclause then
+                               Format_Object.Clause_Number.Subsubclause :=
+                                   Format_Object.Clause_Number.Subsubclause + 
1;
+                               Level := ARM_Contents.Subsubclause;
+                           elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Added_Clause then
+                               Format_Object.Clause_Number :=
+                                   (Section   => 
Format_Object.Clause_Number.Section,
+                                    Clause    => 
Format_Object.Clause_Number.Clause + 1,
+                                    Subclause => 0, Subsubclause => 0);
+                               Level := ARM_Contents.Clause;
+                           elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Added_Section then
+                               Format_Object.Clause_Number :=
+                                   (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                    Clause    => 0,
+                                    Subclause => 0, Subsubclause => 0);
+                               Level := ARM_Contents.Section;
+                           elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Added_Annex then
+                               Format_Object.Clause_Number :=
+                                   (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                    Clause    => 0,
+                                    Subclause => 0, Subsubclause => 0);
+                               Level := ARM_Contents.Plain_Annex;
+                           elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Added_Normative_Annex then
+                               Format_Object.Clause_Number :=
+                                   (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                    Clause    => 0,
+                                    Subclause => 0, Subsubclause => 0);
+                               Level := ARM_Contents.Normative_Annex;
+                           else -- 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Added_Informative_Annex then
+                               Format_Object.Clause_Number :=
+                                   (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                    Clause    => 0,
+                                    Subclause => 0, Subsubclause => 0);
+                               Level := ARM_Contents.Informative_Annex;
+                           end if;
+
+                           begin
+                               declare
+                                   Clause_Number : constant String :=
+                                       ARM_Contents.Lookup_Clause_Number 
(New_Title);
+
+                               begin
+                                   if Disposition = ARM_Output.None then
+                                       -- Normal reference:
+                                       Check_End_Paragraph; -- End any 
paragraph that we're in.
+                                       ARM_Output.Clause_Header (Output_Object,
+                                           New_Title(1..New_Title_Length),
+                                           Level => Level,
+                                           Clause_Number => Clause_Number,
+                                           Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+                                   else -- Insertion.
+                                       Check_End_Paragraph; -- End any 
paragraph that we're in.
+                                       ARM_Output.Revised_Clause_Header 
(Output_Object,
+                                           New_Header_Text => 
New_Title(1..New_Title_Length),
+                                           Old_Header_Text => "",
+                                           Level => Level,
+                                           Version => Version,
+                                           Old_Version => '0',
+                                           Clause_Number => Clause_Number,
+                                           Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+                                   end if;
+
+                                   -- Check that the section numbers match the 
title:
+                                   if Ada.Characters.Handling.To_Lower 
(New_Title) /=
+                                      Ada.Characters.Handling.To_Lower 
(ARM_Contents.Lookup_Title (
+                                         Level, Format_Object.Clause_Number)) 
then
+                                       Ada.Text_IO.Put_Line ("** Unable to 
match title with section numbers, line " & ARM_Input.Line_String 
(Input_Object));
+                                   end if;
+--!!Debug:
+--Ada.Text_IO.Put_Line ("Start clause " & Clause_Number & " -- " & 
New_Title(1..New_Title_Length));
+                               end;
+                           exception
+                               when ARM_Contents.Not_Found_Error =>
+                                   Ada.Text_IO.Put_Line ("** Unable to find 
header reference, line " & ARM_Input.Line_String (Input_Object));
+                                   Ada.Text_IO.Put_Line ("   Looking for " & 
New_Title(1..New_Title_Length));
+                           end;
+                           -- Reset the paragraph numbers:
+                           Format_Object.Next_Paragraph := 1;
+                           Format_Object.Next_Insert_Para := 1;
+                           Format_Object.Next_AARM_Sub := 'a';
+                           if Format_Object.Use_ISO_2004_Note_Format then
+                               -- Reset the note number:
+                               Format_Object.Next_Note := 1;
+                           elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Added_Section or else
+                                 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Added_Annex or else
+                                 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Added_Informative_Annex or else
+                                 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Added_Normative_Annex then
+                               -- Reset the note number, only for sections:
+                               Format_Object.Next_Note := 1;
+                           end if;
+                           -- Reset the subhead:
+                           Format_Object.Last_Paragraph_Subhead_Type := Plain;
+                           Format_Object.Next_Paragraph_Format_Type := Plain;
+                       end if;
+
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Header)");
+                   end;
+
+               when Labeled_Deleted_Clause |
+                    Labeled_Deleted_Subclause |
+                    Labeled_Deleted_Subsubclause =>
+                   -- Load the title into the Title string:
+                   declare
+                       Old_Title : ARM_Contents.Title_Type;
+                       Old_Title_Length : Natural;
+                       Ch : Character;
+                       Version : ARM_Contents.Change_Version_Type := '0';
+                       Level : ARM_Contents.Level_Type;
+                       Disposition : ARM_Output.Change_Type;
+                       use type ARM_Output.Change_Type;
+                   begin
+                       Get_Change_Version (Is_First => True,
+                                           Version => Version);
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Name" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Ch);
+                       if Ch /= ' ' then
+                           -- There is a parameter:
+                           -- Load the new title into the Title string:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Ch,
+                               Old_Title, Old_Title_Length);
+                           Old_Title(Old_Title_Length+1 .. Old_Title'Last) :=
+                               (others => ' ');
+                       end if;
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       if Ch /= 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char then
+                           Ada.Text_IO.Put_Line ("  ** Bad close for 
Labeled_Deleted_(Sub)Clause on line " & ARM_Input.Line_String (Input_Object));
+                           ARM_Input.Replace_Char (Input_Object);
+                       end if;
+
+                       Calc_Change_Disposition (
+                           Format_Object => Format_Object,
+                           Version => Version,
+                           Operation => ARM_Output.Deletion,
+                           Text_Kind => Disposition);
+
+--Ada.Text_IO.Put_Line ("Labeled_Deleted disp: " & 
ARM_Output.Change_Type'Image(Disposition));
+--Ada.Text_IO.Put_Line ("  Version:" & Version);
+                       if Disposition = Do_Not_Display_Text then
+                           null; -- Ignore this; it isn't numbered or anything.
+                       elsif Disposition = ARM_Output.Insertion then
+                           raise Program_Error; -- An insertion inside of a 
deletion command!
+                       elsif Disposition = ARM_Output.Deletion then
+                           -- Format the text as a deletion, but not as a 
header.
+                           Check_End_Paragraph; -- End any paragraph that 
we're in.
+
+                           ARM_Output.Start_Paragraph (Output_Object,
+                               Style => ARM_Output.Title,
+                               Indent => 0,
+                               Number => "");
+                           ARM_Output.Text_Format (Output_Object,
+                               Format => (Bold => True,
+                                          Italic => False,
+                                          Font => ARM_Output.Default,
+                                          Size => ARM_Output.Size_Type(-2),
+                                          Color => ARM_Output.Default,
+                                          Change => ARM_Output.Deletion,
+                                          Version => Version,
+                                          Added_Version => '0',
+                                          Location => ARM_Output.Normal));
+                           ARM_Output.Ordinary_Text (Output_Object,
+                               Old_Title(1..Old_Title_Length));
+                           ARM_Output.Text_Format (Output_Object,
+                               ARM_Output.NORMAL_FORMAT);
+                           ARM_Output.End_Paragraph (Output_Object);
+
+                           -- Reset the paragraph numbers: (for the following 
deleted text, presumably also shown).
+                           Format_Object.Next_Paragraph := 1;
+                           Format_Object.Next_Insert_Para := 1;
+                           Format_Object.Next_AARM_Sub := 'a';
+                           if Format_Object.Use_ISO_2004_Note_Format then
+                               -- Reset the note number:
+                               Format_Object.Next_Note := 1;
+                           --elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Deleted_Section or else
+                           --      
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Deleted_Annex or else
+                           --      
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Deleted_Informative_Annex or else
+                           --      
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Deleted_Normative_Annex then
+                           --    -- Reset the note number, only for sections: 
(no sections yet)
+                           --    Format_Object.Next_Note := 1;
+                           end if;
+                           -- Reset the subhead:
+                           Format_Object.Last_Paragraph_Subhead_Type := Plain;
+                           Format_Object.Next_Paragraph_Format_Type := Plain;
+                       else -- Disposition = ARM_Output.None then
+                           if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Deleted_Subclause then
+                               Format_Object.Clause_Number :=
+                                   (Section   => 
Format_Object.Clause_Number.Section,
+                                    Clause    => 
Format_Object.Clause_Number.Clause,
+                                    Subclause => 
Format_Object.Clause_Number.Subclause + 1,
+                                    Subsubclause => 0);
+                               Level := ARM_Contents.Subclause;
+                           elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Deleted_Subsubclause then
+                               Format_Object.Clause_Number.Subsubclause :=
+                                   Format_Object.Clause_Number.Subsubclause + 
1;
+                               Level := ARM_Contents.Subsubclause;
+                           else 
--Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Labeled_Deleted_Clause then
+                               Format_Object.Clause_Number :=
+                                   (Section   => 
Format_Object.Clause_Number.Section,
+                                    Clause    => 
Format_Object.Clause_Number.Clause + 1,
+                                    Subclause => 0, Subsubclause => 0);
+                               Level := ARM_Contents.Clause;
+                           end if;
+
+                           begin
+                               declare
+                                   Clause_Number : constant String :=
+                                       ARM_Contents.Lookup_Clause_Number 
(Old_Title);
+                               begin
+                                   -- Normal reference:
+                                   Check_End_Paragraph; -- End any paragraph 
that we're in.
+                                   ARM_Output.Clause_Header (Output_Object,
+                                       Old_Title(1..Old_Title_Length),
+                                       Level => Level,
+                                       Clause_Number => Clause_Number,
+                                       Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+                               end;
+
+                               -- Check that the section numbers match the 
title:
+                               if Ada.Characters.Handling.To_Lower (Old_Title) 
/=
+                                  Ada.Characters.Handling.To_Lower 
(ARM_Contents.Lookup_Title (
+                                     Level, Format_Object.Clause_Number)) then
+                                   Ada.Text_IO.Put_Line ("** Unable to match 
title with section numbers, line " & ARM_Input.Line_String (Input_Object));
+                               end if;
+                           exception
+                               when ARM_Contents.Not_Found_Error =>
+                                   Ada.Text_IO.Put_Line ("** Unable to find 
header reference, line " & ARM_Input.Line_String (Input_Object));
+                                   Ada.Text_IO.Put_Line ("   Looking for " & 
Old_Title(1..Old_Title_Length));
+                           end;
+                           -- Reset the paragraph numbers:
+                           Format_Object.Next_Paragraph := 1;
+                           Format_Object.Next_Insert_Para := 1;
+                           Format_Object.Next_AARM_Sub := 'a';
+                           -- Reset the subhead:
+                           Format_Object.Last_Paragraph_Subhead_Type := Plain;
+                           Format_Object.Next_Paragraph_Format_Type := Plain;
+                       end if;
+
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Header)");
+                   end;
+
+               when Preface_Section =>
+                   Check_End_Paragraph; -- End any paragraph that we're in.
+                   --ARM_Output.New_Page (Output_Object, 
ARM_Output.Odd_Page_Only);
+                   ARM_Output.Clause_Header (Output_Object,
+                                             Header_Text => "",
+                                             Level => 
ARM_Contents.Unnumbered_Section,
+                                             Clause_Number => "0.99",
+                                             Top_Level_Subdivision_Name => 
Format_Object.Top_Level_Subdivision_Name);
+
+               when Subheading =>
+                   -- This is used in preface sections where no numbers or
+                   -- contents are desired.
+                   Check_End_Paragraph; -- End any paragraph that we're in.
+                   ARM_Output.Start_Paragraph (Output_Object,
+                            Style     => ARM_Output.Wide_Above,
+                            Indent    => 0,
+                            Number    => "",
+                            No_Breaks => True, Keep_with_Next => True);
+                   Format_Object.In_Paragraph := True;
+                   Format_Object.No_Start_Paragraph := False;
+
+                   Format_Object.Text_Format := ARM_Output.NORMAL_FORMAT;
+                   Format_Object.Text_Format.Bold := True;
+                   Format_Object.Text_Format.Font := ARM_Output.Swiss;
+                   Format_Object.Text_Format.Size := 2;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format_Object.Text_Format);
+
+               when Added_Subheading =>
+                   -- This is used in preface sections where no numbers or
+                   -- contents are desired.
+                   declare
+                       Ch : Character;
+                       Version : ARM_Contents.Change_Version_Type := '0';
+
+                       Disposition : ARM_Output.Change_Type;
+                       use type ARM_Output.Change_Type;
+                   begin
+                       Get_Change_Version (Is_First => True,
+                                           Version => Version);
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       if Ch /= ',' then
+                           Ada.Text_IO.Put_Line ("  ** Missing comma for 
AddedSubheading on line " & ARM_Input.Line_String (Input_Object));
+                           ARM_Input.Replace_Char (Input_Object);
+                       end if;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version := 
Version;
+
+                       Calc_Change_Disposition (
+                           Format_Object => Format_Object,
+                           Version => Version,
+                           Operation => ARM_Output.Insertion,
+                           Text_Kind => Disposition);
+
+                       if Disposition = Do_Not_Display_Text then
+                           -- Skip the text:
+                           ARM_Input.Skip_until_Close_Char (Input_Object,
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char);
+                           ARM_Input.Replace_Char (Input_Object); -- Let the 
normal termination clean this up.
+                       elsif Disposition = ARM_Output.None then
+                           -- Normal text:
+                           ARM_Output.Start_Paragraph (Output_Object,
+                                Style  => ARM_Output.Wide_Above,
+                                Indent => 0,
+                                Number => "",
+                                No_Breaks => True, Keep_with_Next => True);
+                           Format_Object.In_Paragraph := True;
+                           Format_Object.No_Start_Paragraph := False;
+
+                           Format_Object.Text_Format := 
ARM_Output.NORMAL_FORMAT;
+                           Format_Object.Text_Format.Bold := True;
+                           Format_Object.Text_Format.Font := ARM_Output.Swiss;
+                           Format_Object.Text_Format.Size := 2;
+                           ARM_Output.Text_Format (Output_Object,
+                                                   Format_Object.Text_Format);
+                       elsif Disposition = ARM_Output.Deletion then
+                           raise Program_Error; -- A deletion inside of an 
insertion command!
+                       else -- Insertion.
+                           ARM_Output.Start_Paragraph (Output_Object,
+                                Style  => ARM_Output.Wide_Above,
+                                Indent => 0,
+                                Number => "",
+                                No_Breaks => True, Keep_with_Next => True);
+                           Format_Object.In_Paragraph := True;
+                           Format_Object.No_Start_Paragraph := False;
+
+                           Format_Object.Text_Format := 
ARM_Output.NORMAL_FORMAT;
+                           Format_Object.Text_Format.Bold := True;
+                           Format_Object.Text_Format.Font := ARM_Output.Swiss;
+                           Format_Object.Text_Format.Size := 2;
+                           Format_Object.Text_Format.Change := 
ARM_Output.Insertion;
+                           Format_Object.Text_Format.Version := Version;
+                           ARM_Output.Text_Format (Output_Object,
+                                           Format_Object.Text_Format);
+                       end if;
+                   end;
+
+               when Heading =>
+                   -- This is used in preface sections where no numbers or
+                   -- contents are desired.
+                   Check_End_Paragraph; -- End any paragraph that we're in.
+                   ARM_Output.Start_Paragraph (Output_Object,
+                            Style  => ARM_Output.Title,
+                            Indent => 0,
+                            Number => "",
+                            No_Breaks => True, Keep_with_Next => True,
+                            Justification => ARM_Output.Center);
+                   Format_Object.In_Paragraph := True;
+                   Format_Object.No_Start_Paragraph := False;
+
+                   Format_Object.Text_Format := ARM_Output.NORMAL_FORMAT;
+                   Format_Object.Text_Format.Bold := True;
+                   Format_Object.Text_Format.Font := ARM_Output.Swiss;
+                   Format_Object.Text_Format.Size := 0;
+                       -- Note that the size is +3 from the Title format.
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format_Object.Text_Format);
+
+               when Center =>
+                   Check_End_Paragraph; -- End any paragraph that we're in.
+                   ARM_Output.Start_Paragraph (Output_Object,
+                            Style  => ARM_Output.Normal,
+                            Indent => 0,
+                            Number => "",
+                            No_Breaks => True, Keep_with_Next => False,
+                            Justification => ARM_Output.Center);
+                   Format_Object.In_Paragraph := True;
+                   Format_Object.No_Start_Paragraph := False;
+
+               when Right =>
+                   Check_End_Paragraph; -- End any paragraph that we're in.
+                   ARM_Output.Start_Paragraph (Output_Object,
+                            Style  => ARM_Output.Normal,
+                            Indent => 0,
+                            Number => "",
+                            No_Breaks => True, Keep_with_Next => False,
+                            Justification => ARM_Output.Right);
+                   Format_Object.In_Paragraph := True;
+                   Format_Object.No_Start_Paragraph := False;
+
+               when Ref_Section | Ref_Section_Number =>
+                   -- Load the title into the Title string:
+                   declare
+                       Ch : Character;
+                       Title : ARM_Contents.Title_Type;
+                       Title_Length : Natural;
+                   begin
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       Title_Length := 0;
+                       while Ch /= 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char loop
+                           Title_Length := Title_Length + 1;
+                           Title(Title_Length) := Ch;
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                       end loop;
+                       Title(Title_Length+1 .. Title'Last) :=
+                           (others => ' ');
+
+                       begin
+                           declare
+                               Clause_Number_Text : constant String :=
+                                   ARM_Contents.Lookup_Clause_Number (Title);
+                           begin
+                               if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Ref_Section then
+                                   Check_Paragraph;
+                                   ARM_Output.Clause_Reference (Output_Object,
+                                       Text => Clause_Number_Text,
+                                       Clause_Number => Clause_Number_Text);
+                                   ARM_Output.Ordinary_Text (Output_Object, ", 
");
+                                   -- Was: (To match the Ada 95 Standard)
+                                   --ARM_Output.Special_Character 
(Output_Object, ARM_Output.Left_Quote);
+                                   --ARM_Output.Special_Character 
(Output_Object, ARM_Output.Left_Quote);
+                                   ARM_Output.Special_Character 
(Output_Object, ARM_Output.Left_Double_Quote);
+                                   if Format_Object.Change_Version < '1' or 
else
+                                      Format_Object.Changes = 
ARM_Format.Old_Only then
+                                       -- Use original version:
+                                       declare
+                                           Clause_Number : 
ARM_Contents.Clause_Number_Type;
+                                       begin
+                                           ARM_Contents.Make_Clause 
(Clause_Number_Text,
+                                               Clause_Number);
+                                           ARM_Output.Clause_Reference 
(Output_Object,
+                                               Text => Ada.Strings.Fixed.Trim (
+                                                   
ARM_Contents.Lookup_Old_Title (
+                                                           
ARM_Contents.Lookup_Level (Title),
+                                                           Clause_Number),
+                                                           Ada.Strings.Right),
+                                               Clause_Number => 
Clause_Number_Text);
+                                       end;
+                                   else
+                                       -- Use new version. We don't have 
version numbers for these yet.
+                                       ARM_Output.Clause_Reference 
(Output_Object,
+                                           Text => Title(1..Title_Length),
+                                           Clause_Number => 
Clause_Number_Text);
+                                   end if;
+                                   -- Was: (To match the Ada 95 Standard)
+                                   --ARM_Output.Special_Character 
(Output_Object, ARM_Output.Right_Quote);
+                                   --ARM_Output.Special_Character 
(Output_Object, ARM_Output.Right_Quote);
+                                   ARM_Output.Special_Character 
(Output_Object, ARM_Output.Right_Double_Quote);
+                               else -- 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Ref_Section_Number then
+                                   Check_Paragraph;
+                                   ARM_Output.Clause_Reference (Output_Object,
+                                       Text => Clause_Number_Text,
+                                       Clause_Number => Clause_Number_Text);
+                               end if;
+                               Format_Object.Last_Non_Space := True;
+                           end;
+                       exception
+                           when ARM_Contents.Not_Found_Error =>
+                               Ada.Text_IO.Put_Line ("** Unable to find 
section reference, line " & ARM_Input.Line_String (Input_Object));
+                               Ada.Text_IO.Put_Line ("   Looking for " & 
Title(1..Title_Length));
+                       end;
+                   end;
+
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Section Reference)");
+
+               when Ref_Section_by_Number =>
+                   -- Load the number into the Number string:
+                   declare
+                       Ch : Character;
+                       Number : String(1..20);
+                       Number_Length : Natural;
+                   begin
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       Number_Length := 0;
+                       while Ch /= 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char loop
+                           Number_Length := Number_Length + 1;
+                           Number(Number_Length) := Ch;
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                       end loop;
+                       Number(Number_Length+1 .. Number'Last) :=
+                           (others => ' ');
+
+                       Check_Paragraph;
+                       ARM_Output.Clause_Reference (Output_Object,
+                           Text => Number(1..Number_Length),
+                           Clause_Number => Number(1..Number_Length));
+                       Format_Object.Last_Non_Space := True;
+                       -- No checking here.
+                   end;
+
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Section Num Reference)");
+
+               -- Link commands:
+               when Local_Target =>
+                   -- @LocalTarget{Target=[<target-text>],Text=[<text>]}
+                   declare
+                       Close_Ch : Character;
+                       Target : String(1..40);
+                       Target_Len : Natural;
+                       Text : String(1..100);
+                       Text_Len : Natural;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Target" & 
(7..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => True,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Save URL:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Target,
+                               Target_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Text" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Save name:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Text,
+                               Text_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       Check_Paragraph;
+                       ARM_Output.Local_Target (Output_Object,
+                           Text => Text(1..Text_Len),
+                           Target => Target(1..Target_Len));
+                       if Text_Len /= 0 and then Text(Text_Len) /= ' ' then
+                           Format_Object.Last_Non_Space := True;
+                       end if;
+                   end;
+                   -- Leave the command end marker, let normal processing
+                   -- get rid of it.
+
+               when Local_Link =>
+                   -- 
@LocalLink{Target=[<target-text>],Sec=[<title>],Text=[<text>]}
+                   declare
+                       Close_Ch : Character;
+                       Target : String(1..40);
+                       Target_Len : Natural;
+                       Text : String(1..100);
+                       Text_Len : Natural;
+                       Title : ARM_Contents.Title_Type;
+                       Title_Length : Natural;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Target" & 
(7..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => True,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Save URL:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Target,
+                               Target_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Sec" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Save URL:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Title,
+                               Title_Length);
+                           Title(Title_Length+1 .. Title'Last) :=
+                               (others => ' ');
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Text" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Save name:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Text,
+                               Text_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       begin
+                           declare
+                               Clause_Number_Text : constant String :=
+                                   ARM_Contents.Lookup_Clause_Number (Title);
+                           begin
+                               Check_Paragraph;
+                               ARM_Output.Local_Link (Output_Object,
+                                   Text => Text(1..Text_Len),
+                                   Target => Target(1..Target_Len),
+                                   Clause_Number => Clause_Number_Text);
+                               if Text_Len /= 0 and then Text(Text_Len) /= ' ' 
then
+                                   Format_Object.Last_Non_Space := True;
+                               end if;
+                           end;
+                       exception
+                           when ARM_Contents.Not_Found_Error =>
+                               Ada.Text_IO.Put_Line ("** Unable to find 
section in local link, line " & ARM_Input.Line_String (Input_Object));
+                               Ada.Text_IO.Put_Line ("   Looking for " & 
Title(1..Title_Length));
+                       end;
+                   end;
+                   -- Leave the command end marker, let normal processing
+                   -- get rid of it.
+
+               when URL_Link =>
+                   -- @URLLink{URL=[<URL>],Text=[<text>]}
+                   declare
+                       Close_Ch : Character;
+                       URL : String(1..80);
+                       URL_Len : Natural;
+                       Text : String(1..100);
+                       Text_Len : Natural;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "URL" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => True,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Save URL:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               URL,
+                               URL_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Text" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Save name:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Text,
+                               Text_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       Check_Paragraph;
+                       ARM_Output.URL_Link (Output_Object,
+                           Text => Text(1..Text_Len),
+                           URL => URL(1..URL_Len));
+                       if Text_Len /= 0 and then Text(Text_Len) /= ' ' then
+                           Format_Object.Last_Non_Space := True;
+                       end if;
+                   end;
+                   -- Leave the command end marker, let normal processing
+                   -- get rid of it.
+
+               when AI_Link =>
+                   -- @AILink{AI=[<AI>],Text=[<text>]}
+                   declare
+                       Close_Ch : Character;
+                       AI : String(1..30);
+                       AI_Len : Natural;
+                       Text : String(1..100);
+                       Text_Len : Natural;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "AI" & 
(3..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => True,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Save AI:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               AI,
+                               AI_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Text" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Save name:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Text,
+                               Text_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       Check_Paragraph;
+                       ARM_Output.AI_Reference (Output_Object,
+                           Text => Text(1..Text_Len),
+                           AI_Number => AI(1..AI_Len));
+                       if Text_Len /= 0 and then Text(Text_Len) /= ' ' then
+                           Format_Object.Last_Non_Space := True;
+                       end if;
+                   end;
+                   -- Leave the command end marker, let normal processing
+                   -- get rid of it.
+
+               -- Change commands:
+
+               when Change =>
+                   -- This command is of the form:
+                   -- @chg{[version=<Version>],new=[<new text>],old=[<old 
text>]}.
+                   -- where the parameter names (other than version) are
+                   -- optional (but highly recommended), and the curly and
+                   -- square brackets can be any of the allowed bracketing 
characters.
+                   -- We have to process this in parts, in order that the
+                   -- text can be handled normally.
+
+                   declare
+                       Ch : Character;
+                       Saw_Version : Boolean;
+                   begin
+                       -- Check for the optional "Version" parameter:
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       ARM_Input.Replace_Char (Input_Object);
+                       if Ch = 'V' or else Ch = 'v' then
+                           -- There is a Version parameter, grab it.
+                           Get_Change_Version (Is_First => True,
+                               Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version);
+                               -- Read a parameter named "Version".
+                           Saw_Version := True;
+                       else
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version := 
'1';
+                           Saw_Version := False;
+                       end if;
+
+                       -- Save the current state:
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Prev_Change :=
+                           Format_Object.Text_Format.Change;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Prev_Change_Version 
:=
+                           Format_Object.Text_Format.Version;
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Prev_Added_Change_Version
 :=
+                           Format_Object.Text_Format.Added_Version;
+
+                       -- Check and handle the "New" parameter:
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "New" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => not Saw_Version,
+                           Param_Close_Bracket => Ch);
+                       if Ch /= ' ' then
+                           -- There is a parameter:
+
+                           -- Stack the parameter so we can process the end:
+                           Set_Nesting_for_Parameter
+                               (Command => Change_Param_New,
+                                Close_Ch => Ch);
+
+                           Format_Object.In_Change := True;
+
+                           -- Note: We can't use Calc_Change_Disposition here,
+                           -- because it isn't intended to work on possibly
+                           -- nested calls like these.
+
+                           -- Now, handle the parameter:
+                           if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version >
+                              Format_Object.Change_Version then
+                               -- Ignore any changes with version numbers 
higher than
+                               -- the current maximum.
+                               -- Skip the text:
+                               ARM_Input.Skip_until_Close_Char (Input_Object,
+                                   
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char);
+                               ARM_Input.Replace_Char (Input_Object); -- Let 
the normal termination clean this up.
+                           else
+                               case Format_Object.Changes is
+                                   when ARM_Format.Old_Only =>
+                                       -- Skip the text:
+                                       ARM_Input.Skip_until_Close_Char 
(Input_Object,
+                                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char);
+                                       ARM_Input.Replace_Char (Input_Object); 
-- Let the normal termination clean this up.
+                                   when ARM_Format.New_Only =>
+                                       if ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                                          ARM_Database.Deleted) or else
+                                          ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                                          
ARM_Database.Deleted_Inserted_Number) or else
+                                          ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                                          
ARM_Database.Deleted_No_Delete_Message) or else
+                                          ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                                          
ARM_Database.Deleted_Inserted_Number_No_Delete_Message) then
+                                           -- In a deleted paragraph, call 
Check_Paragraph
+                                           -- to trigger the "deleted 
paragraph" message.
+                                           -- (Otherwise, this never happens.)
+                                           Check_Paragraph;
+                                       -- else null; -- Nothing special to do.
+                                       end if;
+                                   when ARM_Format.Show_Changes |
+                                        ARM_Format.New_Changes =>
+                                       if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version <
+                                           Format_Object.Base_Change_Version 
then
+                                           -- Just normal output text.
+                                           if ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                                              ARM_Database.Deleted) or else
+                                              ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                                              
ARM_Database.Deleted_Inserted_Number) or else
+                                              ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                                              
ARM_Database.Deleted_No_Delete_Message) or else
+                                              ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                                              
ARM_Database.Deleted_Inserted_Number_No_Delete_Message) then
+                                               -- In a deleted paragraph, call 
Check_Paragraph
+                                               -- to trigger the "deleted 
paragraph" message.
+                                               -- (Otherwise, this never 
happens.)
+                                               Check_Paragraph;
+                                           -- else null; -- Nothing special to 
do.
+                                           end if;
+                                       else
+                                           ARM_Input.Get_Char (Input_Object, 
Ch);
+                                           ARM_Input.Replace_Char 
(Input_Object);
+                                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Was_Text :=
+                                               Ch /= 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char;
+                                           if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Was_Text then
+                                               -- Non-empty text; Calculate 
new change state (current is insertion):
+                                               Check_Paragraph; -- Change the 
state *after* outputting the paragraph header.
+                                               case 
Format_Object.Text_Format.Change is
+                                                   when ARM_Output.Insertion | 
ARM_Output.None =>
+                                                       
Format_Object.Text_Format.Change := ARM_Output.Insertion;
+                                                       
Format_Object.Text_Format.Version :=
+                                                          
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version;
+                                                       
Format_Object.Text_Format.Added_Version := '0';
+                                                   when ARM_Output.Deletion =>
+                                                       
Format_Object.Text_Format.Change := ARM_Output.Both;
+                                                       
Format_Object.Text_Format.Added_Version := -- The insertion should be older.
+                                                          
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version;
+                                                       -- .Text_Format.Version 
is unchanged.
+                                                   when ARM_Output.Both =>
+                                                       
Format_Object.Text_Format.Change := ARM_Output.Both;
+                                                       
Format_Object.Text_Format.Added_Version := -- The insertion should be older.
+                                                          
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version;
+                                                       -- .Text_Format.Version 
is unchanged.
+                                               end case;
+                                               ARM_Output.Text_Format 
(Output_Object,
+                                                                       
Format_Object.Text_Format); -- Set style.
+                                           -- else no text, so don't bother.
+                                           end if;
+                                       end if;
+                               end case;
+                           end if;
+                       -- else no parameter. Weird.
+                       end if;
+                   end;
+
+               when Change_Param_Old | Change_Param_New =>
+                   -- These can't get here; they represent the parameters of
+                   -- "Change" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Change parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Change_Added | Change_Deleted =>
+                   -- 
@ChgAdded{Version=[<Version>],[NoPrefix=[T|F],][NoParanum=[T|F],]
+                   --     
[Type=[Leading|Trailing|Normal],][Keepnext=[T|F],]Text=[text]}
+                   -- 
@ChgDeleted{Version=[<Version>],[NoPrefix=[T|F],][NoParanum=[T|F],]
+                   --     
[Type=[Leading|Trailing|Normal],][Keepnext=[T|F],]Text=[text]}
+                   -- Whole paragraph change. These let us modify the AARM 
prefix
+                   -- (like "Reason:" or "Discussion:", and also let us
+                   -- conditionally handle paragraph formatting (which
+                   -- otherwise would come too late).
+                   declare
+                       Which_Param : ARM_Input.Param_Num;
+                       Close_Ch : Character;
+
+                       NoPrefix, Noparanum, Keepnext : Boolean := False;
+                       Space_After : ARM_Output.Space_After_Type := 
ARM_Output.Normal;
+
+                       Disposition : ARM_Output.Change_Type;
+                       use type ARM_Output.Change_Type;
+
+                       function Read_Boolean (Close_Ch : in Character;
+                                              Name : in String) return Boolean 
is
+                           -- Read a Boolean parameter for a parameter already
+                           -- opened and ending with Close_Ch.
+                           -- Name is the name of the parameter; for error 
messages only.
+                           Ch : Character;
+                           Result : Boolean;
+                       begin
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           case Ch is
+                               when 'F' | 'f' | 'N' | 'n' =>
+                                   Result := False;
+                               when 'T' | 't' | 'Y' | 'y' =>
+                                   Result := True;
+                               when others =>
+                                   Ada.Text_IO.Put_Line ("  ** Bad value for 
boolean parameter " &
+                                       Name & " on line " & 
ARM_Input.Line_String (Input_Object));
+                           end case;
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           if Ch /= Close_Ch then
+                               Ada.Text_IO.Put_Line ("  ** Bad close for 
boolean parameter " &
+                                   Name & " on line " & ARM_Input.Line_String 
(Input_Object));
+                               ARM_Input.Replace_Char (Input_Object);
+                           end if;
+                           return Result;
+                       end Read_Boolean;
+
+                       function Read_Type (Close_Ch : in Character) return 
ARM_Output.Space_After_Type is
+                           -- Read the Type parameter.
+                           Type_Name : ARM_Input.Command_Name_Type;
+                           Ch : Character;
+                           Result : ARM_Output.Space_After_Type := 
ARM_Output.Normal;
+                       begin
+                           -- Get the type word:
+                           Arm_Input.Get_Name (Input_Object, Type_Name);
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           if Ch /= Close_Ch then
+                               Ada.Text_IO.Put_Line ("  ** Bad close for Type 
on line " & ARM_Input.Line_String (Input_Object));
+                               ARM_Input.Replace_Char (Input_Object);
+                           end if;
+                           if Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Type_Name, Ada.Strings.Right)) =
+                               "leading" then
+                               Result := ARM_Output.Narrow;
+                           elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Type_Name, Ada.Strings.Right)) =
+                               "trailing" then
+                               Result := ARM_Output.Wide;
+                           elsif Ada.Characters.Handling.To_Lower 
(Ada.Strings.Fixed.Trim (Type_Name, Ada.Strings.Right)) =
+                               "normal" then
+                               Result := ARM_Output.Normal;
+                           else
+                               Ada.Text_IO.Put_Line ("  ** Bad type for 
paragraph type: " &
+                                   Ada.Strings.Fixed.Trim (Type_Name, 
Ada.Strings.Right) &
+                                   " on line " & ARM_Input.Line_String 
(Input_Object));
+                           end if;
+                           return Result;
+                       end Read_Type;
+
+                   begin
+                       -- These are not allowed in other @Chg commands.
+                       if Format_Object.In_Change then
+                           Ada.Text_IO.Put_Line ("** ChgAdded/ChgDeleted 
nested in other Chg, line " & ARM_Input.Line_String (Input_Object));
+                       end if;
+
+                       Get_Change_Version (Is_First => True,
+                           Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version);
+                           -- Read a parameter named "Version".
+
+                       loop
+                           -- Handle the optional parameters; stop on Text.
+                           ARM_Input.Check_One_of_Parameter_Names 
(Input_Object,
+                               Param_Name_1 => "NoPrefix" & 
(9..ARM_Input.Command_Name_Type'Last => ' '),
+                               Param_Name_2 => "NoParanum" & 
(10..ARM_Input.Command_Name_Type'Last => ' '),
+                               Param_Name_3 => "Type" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                               Param_Name_4 => "Keepnext" & 
(9..ARM_Input.Command_Name_Type'Last => ' '),
+                               Param_Name_5 => "Text" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                               Is_First => False,
+                               Param_Found => Which_Param,
+                               Param_Close_Bracket => Close_Ch);
+
+                           if Which_Param = 1 and then Close_Ch /= ' ' then
+                               NoPrefix := Read_Boolean (Close_Ch, "NoPrefix");
+                           elsif Which_Param = 2 and then Close_Ch /= ' ' then
+                               NoParanum := Read_Boolean (Close_Ch, 
"NoParanum");
+                           elsif Which_Param = 3 and then Close_Ch /= ' ' then
+                               Space_After := Read_Type (Close_Ch);
+                           elsif Which_Param = 4 and then Close_Ch /= ' ' then
+                               Keepnext := Read_Boolean (Close_Ch, "KeepNext");
+                           else
+                               exit; -- We found "Text" (or an error)
+                           end if;
+                       end loop;
+
+                       if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Change_Added and then
+                          Close_Ch /= ' ' then
+                           -- Generate an insertion, there is a Text parameter.
+
+                           Calc_Change_Disposition (
+                               Format_Object => Format_Object,
+                               Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version,
+                               Operation => ARM_Output.Insertion,
+                               Text_Kind => Disposition);
+
+                           -- Stack the parameter so we can process the end:
+                           Set_Nesting_for_Parameter
+                               (Command => Change_Added_Param,
+                                Close_Ch => Close_Ch);
+
+                           Format_Object.In_Change := True;
+
+                           if Disposition = Do_Not_Display_Text then
+                               -- Skip the text:
+                               ARM_Input.Skip_until_Close_Char (Input_Object,
+                                   
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char);
+                               ARM_Input.Replace_Char (Input_Object); -- Let 
the normal termination clean this up.
+                           elsif Disposition = ARM_Output.None then
+                               -- Display the text normally.
+                               Format_Object.No_Prefix := NoPrefix;
+                               Format_Object.No_Para_Num := NoParanum;
+                               Format_Object.Keep_with_Next := KeepNext;
+                               Format_Object.Space_After := Space_After;
+                           elsif Disposition = ARM_Output.Deletion then
+                               raise Program_Error; -- A deletion inside of an 
insertion command!
+                           else -- Insertion.
+                               Format_Object.No_Prefix := NoPrefix;
+                               Format_Object.No_Para_Num := NoParanum;
+                               Format_Object.Keep_with_Next := KeepNext;
+                               Format_Object.Space_After := Space_After;
+                               -- We assume non-empty text and no outer 
changes;
+                               -- set new change state:
+                               Format_Object.Text_Format.Change := 
ARM_Output.Insertion;
+                               Format_Object.Text_Format.Version :=
+                                  
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version;
+                               Format_Object.Text_Format.Added_Version := '0';
+                               Check_Paragraph; -- Change the state *before* 
outputting the
+                                                -- paragraph header, so the 
AARM prefix is included.
+                               ARM_Output.Text_Format (Output_Object,
+                                                       
Format_Object.Text_Format); -- Reset style.
+                           end if;
+
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Change_Deleted and then
+                          Close_Ch /= ' ' then
+                           -- Generate a deletion.
+
+                           Calc_Change_Disposition (
+                               Format_Object => Format_Object,
+                               Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version,
+                               Operation => ARM_Output.Deletion,
+                               Text_Kind => Disposition);
+
+                           -- Stack the parameter so we can process the end:
+                           Set_Nesting_for_Parameter
+                               (Command => Change_Deleted_Param,
+                                Close_Ch => Close_Ch);
+
+                           Format_Object.In_Change := True;
+
+                           if Disposition = Do_Not_Display_Text then
+                               -- Skip the text:
+                               ARM_Input.Skip_until_Close_Char (Input_Object,
+                                   
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char);
+                               ARM_Input.Replace_Char (Input_Object); -- Let 
the normal termination clean this up.
+                               if ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                                  ARM_Database.Deleted) or else
+                                  ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                                  ARM_Database.Deleted_Inserted_Number) or else
+                                  ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                                  ARM_Database.Deleted_No_Delete_Message) or 
else
+                                  ARM_Database."=" 
(Format_Object.Next_Paragraph_Change_Kind,
+                                  
ARM_Database.Deleted_Inserted_Number_No_Delete_Message) then
+                                   -- In a deleted paragraph, call 
Check_Paragraph
+                                   -- to trigger the "deleted paragraph" 
message and
+                                   -- increment the paragraph number.
+                                   -- (Otherwise, this may never happen.)
+                                   Format_Object.No_Para_Num := NoParanum;
+                                   Check_Paragraph;
+                               -- else null; -- Nothing special to do.
+                               end if;
+                           elsif Disposition = ARM_Output.None then
+                               -- Display the text normally.
+                               Format_Object.No_Prefix := NoPrefix;
+                               Format_Object.No_Para_Num := NoParanum;
+                               Format_Object.Keep_with_Next := KeepNext;
+                               Format_Object.Space_After := Space_After;
+                           elsif Disposition = ARM_Output.Insertion then
+                               raise Program_Error; -- An insertion inside of 
a deletion command!
+                           else -- Deletion.
+                               if Format_Object.Changes = 
ARM_Format.New_Changes then
+                                   -- Special case: we ignore the deleted 
text, but mark its presence.
+                                   -- We assume that the text is non-empty;
+                                   -- set the new change state.
+                                   -- Note: We ignore the formatting here!
+                                   Format_Object.No_Prefix := True;
+                                   Format_Object.No_Para_Num := NoParanum;
+                                   Format_Object.Text_Format.Change := 
ARM_Output.Deletion;
+                                   Format_Object.Text_Format.Version :=
+                                      
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version;
+                                   Format_Object.Text_Format.Added_Version := 
'0';
+                                   Check_Paragraph; -- Output the paragraph 
headers *after* changing the state,
+                                       -- so that AARM headers are marked.
+                                   ARM_Output.Text_Format (Output_Object,
+                                                           
Format_Object.Text_Format); -- Reset style.
+
+                                   ARM_Output.Ordinary_Character 
(Output_Object, ' ');
+                                   -- Skip the text (we're not going to output 
it):
+                                   ARM_Input.Skip_until_Close_Char 
(Input_Object, Close_Ch);
+                                   ARM_Input.Replace_Char (Input_Object); -- 
Let the normal termination clean this up.
+
+                               else -- Normal.
+                                   -- We assume that the text is non-empty;
+                                   -- set the new change state and formatting.
+                                   Format_Object.No_Prefix := NoPrefix;
+                                   Format_Object.No_Para_Num := NoParanum;
+                                   Format_Object.Keep_with_Next := KeepNext;
+                                   Format_Object.Space_After := Space_After;
+
+                                   Format_Object.Text_Format.Change := 
ARM_Output.Deletion;
+                                   Format_Object.Text_Format.Version :=
+                                      
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version;
+                                   Format_Object.Text_Format.Added_Version := 
'0';
+                                   Check_Paragraph; -- Output the paragraph 
headers *after* changing the state,
+                                       -- so that AARM headers are marked.
+                                   ARM_Output.Text_Format (Output_Object,
+                                                           
Format_Object.Text_Format); -- Reset style.
+                               end if;
+                           end if;
+                       -- else no parameter; previous error.
+                       end if;
+                   end;
+
+               when Change_Added_Param | Change_Deleted_Param =>
+                   -- These can't get here; they represent the parameter of
+                   -- "Change_Added" and "Change_Deleted" and can't be 
generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Change_xxx parameter command?? 
on line " & ARM_Input.Line_String (Input_Object));
+
+               when Table_Param_Caption | Table_Param_Header | 
Table_Param_Body =>
+                   -- These can't get here; they represent the parameters of
+                   -- "Table" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Table parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Syntax_Rule_RHS =>
+                   -- This can't get here; it represents the second parameter 
of
+                   -- "Syn" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Syntax parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Glossary_Text_Param =>
+                   -- This can't get here; it represents the second parameter 
of
+                   -- "ToGlossary" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Glossary parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Attribute_Text_Param =>
+                   -- This can't get here; it represents the third parameter of
+                   -- "Attribute" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Attribute parameter command?? 
on line " & ARM_Input.Line_String (Input_Object));
+
+               when Change_Impdef_Text_Param =>
+                   -- This can't get here; it represents the third parameter of
+                   -- "ChgImpldef" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Impdef parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Change_Impladv_Text_Param =>
+                   -- This can't get here; it represents the third parameter of
+                   -- "ChgImpladvice" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Impladv parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Change_Docreq_Text_Param =>
+                   -- This can't get here; it represents the third parameter of
+                   -- "ChgDocReq" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Docreq parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Change_AspectDesc_Text_Param =>
+                   -- This can't get here; it represents the fourth parameter 
of
+                   -- "ChgAspectDesc" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** AspectDesc parameter command?? 
on line " & ARM_Input.Line_String (Input_Object));
+
+               when Change_Prefix_Text_Param =>
+                   -- This can't get here; it represents the second parameter 
of
+                   -- "ChgPrefixType" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** ChgPrefix parameter command?? 
on line " & ARM_Input.Line_String (Input_Object));
+
+               when Change_Reference =>
+                   -- This command is of the form:
+                   -- @chgref{Version=[<version>], Kind=(<kind>)
+                   --   {,Ref=(<DR_Number>)}{,ARef=(<AI_Number>)}}
+                   -- where <version> is a single character, <Kind> is one
+                   -- of Revised, Added, or Deleted, followed by zero or more
+                   -- DR references, and finally zero or more AI references.
+                   -- As usual, any of the allowed bracketing characters can
+                   -- be used.
+
+                   declare
+                       Ch : Character;
+                       Kind : ARM_Database.Paragraph_Change_Kind_Type;
+                       Version : ARM_Contents.Change_Version_Type;
+                       Display_It : Boolean;
+                   begin
+                       Get_Change_Version (Is_First => True,
+                           Version => Version);
+                           -- Read a parameter named "Version".
+
+                       Get_Change_Kind (Kind);
+                           -- Read a parameter named "Kind".
+
+                       if Version <= Format_Object.Change_Version then
+                           Format_Object.Next_Paragraph_Version := Version;
+                           Format_Object.Next_Paragraph_Change_Kind := Kind;
+                           if (ARM_Database."=" (Kind, 
ARM_Database.Deleted_No_Delete_Message) or else
+                               ARM_Database."=" (Kind, 
ARM_Database.Deleted_Inserted_Number_No_Delete_Message)) and then
+                              ARM_Format."=" (Format_Object.Changes, 
ARM_Format.New_Only) then
+                               -- In this case, display nothing, period.
+                               Display_It := False;
+                               -- Check if any Ref's already exist; remove them
+                               -- if they do. %% Ugly: This is needed if
+                               -- a paragraph is first revised, then deleted,
+                               -- as in 4.6. There ought to be a better way
+                               -- of handling this, not sure what it is.
+                               Dump_References (Format_Object.References);
+                           elsif (ARM_Database."=" (Kind, 
ARM_Database.Deleted) or else
+                               ARM_Database."=" (Kind, 
ARM_Database.Deleted_Inserted_Number)) and then
+                              ARM_Format."=" (Format_Object.Changes, 
ARM_Format.New_Only) and then
+                               (not Format_Object.Number_Paragraphs) then
+                               -- No delete messages ever in this case, so
+                               -- display nothing, period.
+                               Display_It := False;
+                               -- Check if any Ref's already exist; see above.
+                               Dump_References (Format_Object.References);
+                           else
+                               Display_It := Format_Object.Include_Annotations;
+                           end if;
+                       else --This reference is too new, ignore it.
+                           Display_It := False;
+                       end if;
+
+                       -- Handle zero or more "Ref" parameters.
+                       loop
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           if Ch /= ',' then
+                               exit; -- No more commands.
+                           else
+                               ARM_Input.Replace_Char (Input_Object);
+                           end if;
+                           Gen_Ref_or_ARef_Parameter (Display_It);
+                               -- Read (and possibly generate) a "Ref" or 
"ARef" parameter.
+                       end loop;
+
+                       -- Now, close the command.
+                       -- Ch was read when checking for commas, above.
+                       if Ch /= 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char then
+                           Ada.Text_IO.Put_Line ("  ** Bad close for Chgref on 
line " & ARM_Input.Line_String (Input_Object));
+                           ARM_Input.Replace_Char (Input_Object);
+                       end if;
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                           -- Remove the "Change_Reference" record.
+                   end;
+
+               when Change_Note =>
+                   -- Skip the contents of this command.
+                   ARM_Input.Skip_until_Close_Char (Input_Object,
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char);
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                       -- Remove the "Change_Note" record.
+
+               when Change_Implementation_Defined =>
+                   -- This command is of the form:
+                   -- @chgimpldef{Version=[<version>], Kind=(<kind>),
+                   --   Text=(<text>)}}
+                   -- where <version> is a single character, <Kind> is one
+                   -- of Revised, Added, or Deleted, and this is followed
+                   -- by the text. As usual, any of the
+                   -- allowed bracketing characters can be used.
+                   Gen_Chg_xxxx (Param_Cmd => Change_Impdef_Text_Param,
+                                 AARM_Prefix => "Implementation defined: ");
+
+               when Change_Implementation_Advice =>
+                   -- This command is of the form:
+                   -- @chgimpladvice{Version=[<version>], Kind=(<kind>),
+                   --   Text=(<text>)}}
+                   -- where <version> is a single character, <Kind> is one
+                   -- of Revised, Added, or Deleted, and this is followed
+                   -- by the text. As usual, any of the
+                   -- allowed bracketing characters can be used.
+                   Gen_Chg_xxxx (Param_Cmd => Change_Impladv_Text_Param,
+                                 AARM_Prefix => "Implementation Advice: ");
+
+               when Change_Documentation_Requirement =>
+                   -- This command is of the form:
+                   -- @chgdocreq{Version=[<version>], Kind=(<kind>),
+                   --   Text=(<text>)}}
+                   -- where <version> is a single character, <Kind> is one
+                   -- of Revised, Added, or Deleted, and this is followed
+                   -- by the text. As usual, any of the
+                   -- allowed bracketing characters can be used.
+                   Gen_Chg_xxxx (Param_Cmd => Change_Docreq_Text_Param,
+                                 AARM_Prefix => "Documentation Requirement: ");
+
+               when Change_Aspect_Description =>
+                   -- This command is of the form:
+                   -- @chgaspectdesc{Version=[<version>], Kind=(<kind>),
+                   --   Aspect=[<name>],Text=(<text>)}}
+                   -- where <version> is a single character, <Kind> is one
+                   -- of Revised, Added, or Deleted, <Name> is the aspect
+                   -- name, and this is followed
+                   -- by the text. As usual, any of the
+                   -- allowed bracketing characters can be used.
+                   Gen_Chg_xxxx (Param_Cmd => Change_AspectDesc_Text_Param,
+                                 AARM_Prefix => "Aspect Description for ");
+
+               when Change_Attribute =>
+                    -- @ChgAttribute{Version=[<version>], Kind=(<kind>),
+                    --    Chginannex=[T|F],Leading=[T|F],
+                    --    Prefix=<Prefix>,AttrName=<Name>,
+                    --    {[A]Ref=[<DR_Number>]},Text=<Text>}
+                    -- Defines a changed attribute.
+                   declare
+                       Close_Ch : Character;
+                       Key : ARM_Index.Index_Key;
+                       Chg_in_Annex : Boolean;
+                       Is_Leading : Boolean;
+                       Kind : ARM_Database.Paragraph_Change_Kind_Type;
+                       Version : ARM_Contents.Change_Version_Type;
+                       InitialVersion : ARM_Contents.Change_Version_Type;
+                       Display_Ref : Boolean;
+                       References : Reference_Ptr := null;
+
+
+                       procedure Make_Attribute_Text is
+                           -- Generate the attribute text.
+                           -- Output <Prefix>'<Name> as the hanging text.
+                           -- Generate the needed index entries.
+                       begin
+                           Check_Paragraph;
+                           ARM_Output.Ordinary_Text (Output_Object,
+                                   Format_Object.Attr_Prefix (1 .. 
Format_Object.Attr_Prefix_Len));
+                           ARM_Output.Ordinary_Character (Output_Object, ''');
+                           ARM_Output.Ordinary_Text (Output_Object,
+                                   Format_Object.Attr_Name (1 .. 
Format_Object.Attr_Name_Len));
+                           ARM_Output.End_Hang_Item (Output_Object);
+                           Format_Object.Last_Non_Space := False; -- Treat 
like start of a line.
+
+                           ARM_Index.Add (Term => "attributes",
+                                          Subterm => Format_Object.Attr_Name 
(1 .. Format_Object.Attr_Name_Len),
+                                          Kind => 
ARM_Index.Primary_Term_and_Subterm,
+                                          Clause => Clause_String 
(Format_Object),
+                                          Paragraph => Paragraph_String,
+                                          Key => Key);
+                           ARM_Output.Index_Target (Output_Object, Key);
+
+                           ARM_Index.Add (Term => Format_Object.Attr_Name (1 
.. Format_Object.Attr_Name_Len) & " attribute",
+                                          Kind => ARM_Index.Primary_Term,
+                                          Clause => Clause_String 
(Format_Object),
+                                          Paragraph => Paragraph_String,
+                                          Key => Key);
+                           ARM_Output.Index_Target (Output_Object, Key);
+
+                           Make_References (References, Format_Object, 
Output_Object);
+
+                       end Make_Attribute_Text;
+
+                   begin
+                       Check_End_Paragraph; -- This is always a paragraph end.
+
+                       Get_Change_Version (Is_First => True,
+                           Version => Version);
+                           -- Read a parameter named "Version".
+
+                       Get_Change_Kind (Kind);
+                           -- Read a parameter named "Kind".
+
+                       if Version <= Format_Object.Change_Version then
+                           Format_Object.Next_Paragraph_Version := Version;
+                           Format_Object.Next_Paragraph_Change_Kind := Kind;
+                           if (ARM_Database."=" (Kind, 
ARM_Database.Deleted_No_Delete_Message) or else
+                               ARM_Database."=" (Kind, 
ARM_Database.Deleted_Inserted_Number_No_Delete_Message)) and then
+                              ARM_Format."=" (Format_Object.Changes, 
ARM_Format.New_Only) then
+                               -- In this case, display nothing, period.
+                               Display_Ref := False;
+                           else
+                               Display_Ref := 
Format_Object.Include_Annotations;
+                           end if;
+                       else --This reference is too new, ignore it.
+                           Display_Ref := False;
+                       end if;
+
+                       Get_Boolean ("ChginAnnex" & 
(11..ARM_Input.Command_Name_Type'Last => ' '),
+                                    Chg_in_Annex);
+                           -- Read a boolean parameter.
+
+                       if Chg_in_Annex then
+                           Format_Object.Attr_Change_Kind := Kind;
+                           Format_Object.Attr_Version := Version;
+                       else -- don't save the change info.; it only applies 
here.
+                           Format_Object.Attr_Change_Kind := ARM_Database.None;
+                           Format_Object.Attr_Version := '0';
+                           Format_Object.Attr_Initial_Version := '0';
+                       end if;
+
+                       Get_Boolean ("Leading" & 
(8..ARM_Input.Command_Name_Type'Last => ' '),
+                                    Is_Leading);
+                           -- Read a boolean parameter.
+
+                       if Is_Leading then
+                           Format_Object.Space_After := ARM_Output.Narrow;
+                           Format_Object.Attr_Leading := True;
+                       else
+                           Format_Object.Space_After := ARM_Output.Normal;
+                           Format_Object.Attr_Leading := False;
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Prefix" & 
(7..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Save prefix:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Format_Object.Attr_Prefix,
+                               Format_Object.Attr_Prefix_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "AttrName" & 
(9..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Save name:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Format_Object.Attr_Name,
+                               Format_Object.Attr_Name_Len);
+                       -- else no parameter. Weird.
+                       end if;
+
+                       -- Handle the Ref, ARef, and InitialVersion parameters,
+                       -- until the Text parameter shows up.
+
+                       -- Note: If there is no InitialVersion command, use the
+                       -- value of Version.
+                       InitialVersion := Version;
+                       declare
+                           Which_Param : ARM_Input.Param_Num;
+                           Ch          : Character;
+                       begin
+                           loop
+                               ARM_Input.Check_One_of_Parameter_Names 
(Input_Object,
+                                   Param_Name_1 => "Ref" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                                   Param_Name_2 => "ARef" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                                   Param_Name_3 => "InitialVersion" & 
(15..ARM_Input.Command_Name_Type'Last => ' '),
+                                   Param_Name_4 => "Text" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                                   Is_First => False,
+                                   Param_Found => Which_Param,
+                                   Param_Close_Bracket => Close_Ch);
+                               if (Which_Param = 1 or else Which_Param = 2) 
and then
+                                   Close_Ch /= ' ' then
+                                   declare
+                                       Ref_Name : ARM_Input.Command_Name_Type;
+                                       Len : Natural := 0;
+                                       New_Ref, Cursor : Reference_Ptr;
+                                       Ch : Character;
+                                   begin
+                                       -- Get the reference:
+                                       loop
+                                           ARM_Input.Get_Char (Input_Object, 
Ch);
+                                           if Ch /= Close_Ch then
+                                               Len := Len + 1;
+                                               if Len > Ref_Name'Last then
+                                                   Ada.Text_IO.Put_Line ("  ** 
Reference too long on line " & ARM_Input.Line_String (Input_Object));
+                                               else
+                                                   Ref_Name(Len) := Ch;
+                                               end if;
+                                           else -- End of the reference.
+                                               if Len = 0 then
+                                                   Ada.Text_IO.Put_Line ("  ** 
Failed to find reference on line " & ARM_Input.Line_String (Input_Object));
+                                               end if;
+                                               exit;
+                                           end if;
+                                       end loop;
+
+                                       if Display_Ref then
+                                           -- Save a reference for outputting
+                                           -- later.
+                                           New_Ref := Allocate_Reference;
+                                           New_Ref.all := (Ref_Name => 
Ref_Name,
+                                                           Ref_Len => Len,
+                                                           Is_DR_Ref => 
(Which_Param = 1),
+                                                              -- DR reference 
if Param = 1;
+                                                              -- AI reference 
otherwise.
+                                                           Next => null);
+                                           -- Attach this to the *end* of the 
list.
+                                           if References = null then
+                                               References := New_Ref;
+                                           else
+                                               Cursor := References;
+                                               while Cursor.Next /= null loop
+                                                   Cursor := Cursor.next;
+                                               end loop;
+                                               Cursor.Next := New_Ref;
+                                           end if;
+                                       -- else don't display it.
+                                       end if;
+                                   end;
+                               elsif Which_Param = 3 and then Close_Ch /= ' ' 
then
+                                   -- Found InitialVersion
+                                   ARM_Input.Get_Char (Input_Object, Ch);
+                                   InitialVersion := Ch;
+                                   ARM_Input.Get_Char (Input_Object, Ch);
+                                   if Ch /= Close_Ch then
+                                       Ada.Text_IO.Put_Line ("  ** Bad close 
for InitialVersion parameter on line " &
+                                           ARM_Input.Line_String 
(Input_Object));
+                                       ARM_Input.Replace_Char (Input_Object);
+                                   end if;
+                               else
+                                   exit; -- We found "Text" (or an error)
+                               end if;
+                           end loop;
+                       end;
+
+--**Debug:
+--Ada.Text_IO.Put_Line ("ChgAttr on line " & ARM_Input.Line_String 
(Input_Object) &
+--   "; Vers=" & Version & "; InitVer=" & InitialVersion & "; Kind=" & 
ARM_Database.Paragraph_Change_Kind_Type'Image(Format_Object.Attr_Change_Kind));
+                       if ARM_Database."/=" (Format_Object.Attr_Change_Kind, 
ARM_Database.None) then
+                           Format_Object.Attr_Initial_Version := 
InitialVersion;
+                       -- else ChginAnnex is False, don't care about this.
+                       end if;
+
+                       -- How the prefix (attribute name) is handled depends
+                       -- only on the InitialVersion and its relationship
+                       -- to the version we're generating. It does *not*
+                       -- depend on the (current) change kind.
+
+                       if InitialVersion = '0' then
+                           -- Original version, never an insertion.
+                           Make_Attribute_Text;
+                           if Close_Ch /= ' ' then
+                               -- Now, handle the parameter:
+                               -- The text goes to the file *and* is recorded.
+                               Arm_Input.Start_Recording (Input_Object);
+                               -- Stack the parameter so we can process the 
end:
+                               Set_Nesting_for_Parameter
+                                   (Command => Attribute_Text_Param,
+                                    Close_Ch => Close_Ch);
+                           end if;
+
+                       elsif Close_Ch /= ' ' then -- All other cases.
+
+                           -- Stack the parameter so we can process the end:
+                           Set_Nesting_for_Parameter
+                               (Command => Attribute_Text_Param,
+                                Close_Ch => Close_Ch);
+
+                           declare
+                               Disposition : ARM_Output.Change_Type;
+                               use type ARM_Output.Change_Type;
+                           begin
+
+                               Calc_Change_Disposition (
+                                   Format_Object => Format_Object,
+                                   Version   => InitialVersion,
+                                   Operation => ARM_Output.Insertion,
+                                   Text_Kind => Disposition);
+
+                               if Disposition = Do_Not_Display_Text then
+                                   -- Skip the text:
+                                   ARM_Input.Skip_until_Close_Char 
(Input_Object, Close_Ch);
+                                   ARM_Input.Replace_Char (Input_Object); -- 
Let the normal termination clean this up.
+--Ada.Text_IO.Put_Line("--Skip text");
+
+                               elsif Disposition = ARM_Output.None then
+                                   -- Display the text normally.
+                                   Make_Attribute_Text;
+                                   -- Nothing special to do (normal text).
+--Ada.Text_IO.Put_Line("--Normal text");
+
+                               elsif Disposition = ARM_Output.Deletion then
+                                   raise Program_Error; -- A deletion inside 
of an insertion command!
+
+                               else -- Insertion.
+--Ada.Text_IO.Put_Line("--Insertion");
+                                   -- We assume non-empty text and no outer 
changes;
+                                   -- set new change state:
+                                   Format_Object.Text_Format.Change := 
ARM_Output.Insertion;
+                                   Format_Object.Text_Format.Version := 
InitialVersion;
+                                   Format_Object.Text_Format.Added_Version := 
'0';
+                                   Check_Paragraph; -- Change the state 
*before* outputting the
+                                                    -- paragraph header, so 
the AARM prefix is included.
+                                   ARM_Output.Text_Format (Output_Object,
+                                                           
Format_Object.Text_Format);
+                                   Make_Attribute_Text;
+
+                                   -- Reset the state to normal:
+                                   Format_Object.Text_Format.Change := 
ARM_Output.None;
+                                   Format_Object.Text_Format.Version := '0';
+                                   Format_Object.Text_Format.Added_Version := 
'0';
+                                   ARM_Output.Text_Format (Output_Object,
+                                                           
Format_Object.Text_Format);
+                               end if;
+                           end;
+
+                           -- The text goes to the file *and* is recorded.
+                           Arm_Input.Start_Recording (Input_Object);
+
+                       -- else no parameter. Do nothing.
+                       end if;
+                   end;
+
+               when Change_Prefix_Type =>
+                   -- This command is of the form:
+                   -- @chgprefixtype{Version=[<version>], Kind=(<kind>),
+                   --   Text=(<text>)}}
+                   -- where <version> is a single character, <Kind> is one
+                   -- of Revised, Added, or Deleted, and this is followed
+                   -- by the text. As usual, any of the
+                   -- allowed bracketing characters can be used.
+                   declare
+                       Close_Ch : Character;
+                   begin
+                       Get_Change_Version (Is_First => True,
+                                           Version => 
Format_Object.Attr_Prefix_Version);
+                           -- Read a parameter named "Version".
+
+                       Get_Change_Kind (Format_Object.Attr_Prefix_Change_Kind);
+                           -- Read a parameter named "Kind".
+
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Text" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- Stack it so we can process the end:
+                           Set_Nesting_for_Parameter
+                               (Command => Change_Prefix_Text_Param,
+                                Close_Ch => Close_Ch);
+
+                           ARM_Input.Start_Recording (Input_Object);
+                       -- else no parameter. Weird.
+                       end if;
+                   end;
+
+               when Added_Implementation_Advice_List =>
+                   -- This command is of the form:
+                   -- @AddedImplAdvice{Version=[v]}
+                   declare
+                       Version : ARM_Contents.Change_Version_Type;
+                   begin
+                       Get_Change_Version (Is_First => True,
+                           Version => Version);
+                           -- Read a parameter named "Version".
+                       DB_Report  (Format_Object.ImplAdv_DB,
+                                   ARM_Database.Bullet_List,
+                                   Sorted => True,
+                                   Added_Version => Version);
+                   end;
+
+               when Added_Documentation_Requirements_List =>
+                   -- This command is of the form:
+                   -- @AddedDocReq{Version=[v]}
+                   declare
+                       Version : ARM_Contents.Change_Version_Type;
+                   begin
+                       Get_Change_Version (Is_First => True,
+                           Version => Version);
+                           -- Read a parameter named "Version".
+                       DB_Report  (Format_Object.Docreq_DB,
+                                   ARM_Database.Bullet_List,
+                                   Sorted => True,
+                                   Added_Version => Version);
+                   end;
+
+               when Added_Aspect_Description_List =>
+                   -- This command is of the form:
+                   -- @AddedAspectList{Version=[v]}
+                   declare
+                       Version : ARM_Contents.Change_Version_Type;
+                   begin
+                       Get_Change_Version (Is_First => True,
+                           Version => Version);
+                           -- Read a parameter named "Version".
+                       DB_Report  (Format_Object.Aspect_DB,
+                                   ARM_Database.Hanging_List,
+                                   Sorted => True,
+                                   Added_Version => Version);
+                   end;
+
+               when Latin_1 =>
+                   -- The parameter is the decimal code for the Latin-1
+                   -- character to generate.
+                   declare
+                       Value : String (1..5);
+                       Len : Natural := 0;
+                       Ch : Character;
+                   begin
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       while Ch /= 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char loop
+                           Len := Len + 1;
+                           if Len > Value'Last then
+                               Ada.Text_IO.Put_Line ("  ** Latin-1 value too 
long on line " &
+                                                           
ARM_Input.Line_String (Input_Object));
+                               exit;
+                           end if;
+                           Value(Len) := Ch;
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                       end loop;
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                           -- Remove the "Latin-1" record.
+                       Check_Paragraph;
+                       ARM_Output.Ordinary_Character (Output_Object,
+                           Character'Val(Natural'Value(Value(1..Len))));
+                       Format_Object.Last_Non_Space := True;
+                   exception
+                       when Constraint_Error =>
+                           Ada.Text_IO.Put_Line ("  ** Bad Latin-1 value [" &
+                                                 Value(1..Len) & "] on line " &
+                                                       ARM_Input.Line_String 
(Input_Object));
+                   end;
+
+               when Unicode =>
+                   -- The parameter is the decimal code for the Uncode
+                   -- character to generate.
+                   declare
+                       Value : String (1..11);
+                       Len : Natural := 0;
+                       Ch : Character;
+                   begin
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       while Ch /= 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Close_Char loop
+                           Len := Len + 1;
+                           if Len > Value'Last then
+                               Ada.Text_IO.Put_Line ("  ** Unicode value too 
long on line " &
+                                                           
ARM_Input.Line_String (Input_Object));
+                               exit;
+                           end if;
+                           Value(Len) := Ch;
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                       end loop;
+                       Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                           -- Remove the "Unicode" record.
+                       Check_Paragraph;
+                       ARM_Output.Unicode_Character (Output_Object,
+                           ARM_Output.Unicode_Type'Value(Value(1..Len)));
+                       Format_Object.Last_Non_Space := True;
+                   exception
+                       when Constraint_Error =>
+                           Ada.Text_IO.Put_Line ("  ** Bad Unicode value [" &
+                                                 Value(1..Len) & "] on line " &
+                                                       ARM_Input.Line_String 
(Input_Object));
+                   end;
+
+               when Ceiling =>
+                    Check_Paragraph;
+                    ARM_Output.Special_Character (Output_Object, 
ARM_Output.Left_Ceiling);
+                    Format_Object.Last_Non_Space := True;
+
+               when Floor =>
+                    Check_Paragraph;
+                    ARM_Output.Special_Character (Output_Object, 
ARM_Output.Left_Floor);
+                    Format_Object.Last_Non_Space := True;
+
+               when Absolute =>
+                    Check_Paragraph;
+                    ARM_Output.Ordinary_Character (Output_Object, '|');
+                    Format_Object.Last_Non_Space := True;
+
+               when Log =>
+                    Check_Paragraph;
+                    ARM_Output.Ordinary_Text (Output_Object, "log(");
+                    Format_Object.Last_Non_Space := True;
+
+               when Down | Up =>
+                   Ada.Text_IO.Put_Line ("  ** Su(b|per)script can't occur 
directly, line " &
+                       ARM_Input.Line_String (Input_Object));
+
+               when New_Column | New_Page | RM_New_Page | Soft_Page |
+                    No_Prefix | No_Para_Num | Keep_with_Next | Leading | 
Trailing |
+                    Thin_Line | Thick_Line | Table_Last |
+                    Index_List |
+                    Syntax_Summary | Syntax_XRef | Glossary_List |
+                    Attribute_List | Pragma_List | Implementation_Defined_List 
|
+                    Package_List | Type_List | Subprogram_List |
+                    Exception_List | Object_List |
+                    Intro_Name | Syntax_Name | Resolution_Name |
+                    Legality_Name | Static_Name | Link_Name | Run_Name |
+                    Bounded_Name | Erroneous_Name | Req_Name |
+                    Doc_Name | Metrics_Name | Permission_Name | Advice_Name |
+                    Notes_Name | Single_Note_Name | Examples_Name |
+                    Meta_Name | Inconsistent83_Name |
+                    Incompatible83_Name | Extend83_Name | Wording83_Name |
+                    Inconsistent95_Name |
+                    Incompatible95_Name | Extend95_Name | Wording95_Name |
+                    Inconsistent2005_Name |
+                    Incompatible2005_Name | Extend2005_Name | Wording2005_Name 
|
+                    Inconsistent2012_Name |
+                    Incompatible2012_Name | Extend2012_Name | Wording2012_Name 
|
+                    Syntax_Title | Resolution_Title | Legality_Title |
+                    Static_Title | Link_Title | Run_Title | Bounded_Title |
+                    Erroneous_Title | Req_Title | Doc_Title | Metrics_Title |
+                    Permission_Title | Advice_Title | Notes_Title |
+                    Single_Note_Title |
+                    Examples_Title | Meta_Title | Inconsistent83_Title |
+                    Incompatible83_Title | Extend83_Title | Wording83_Title |
+                    Inconsistent95_Title |
+                    Incompatible95_Title | Extend95_Title | Wording95_Title |
+                    Inconsistent2005_Title |
+                    Incompatible2005_Title | Extend2005_Title | 
Wording2005_Title |
+                    Inconsistent2012_Title |
+                    Incompatible2012_Title | Extend2012_Title | 
Wording2012_Title |
+                    EM_Dash | EN_Dash | LT | LE | GT | GE | NE | PI |
+                    Times | PorM | Single_Quote | Thin_Space | Left_Quote |
+                    Right_Quote | Left_Double_Quote | Right_Double_Quote |
+                    Left_Quote_Pair | Right_Quote_Pair | Small_Dotless_I |
+                    Capital_Dotted_I =>
+
+                   -- These commands must not have a parameter.
+                   Ada.Text_IO.Put_Line ("  ** Parameter for " &
+                       Ada.Strings.Fixed.Trim 
(Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right) &
+                       ", line " & ARM_Input.Line_String (Input_Object));
+
+               when Unknown =>
+                   Ada.Text_IO.Put_Line ("  ?? Unknown command (skipped) - " &
+                       Ada.Strings.Fixed.Trim 
(Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Name, 
Ada.Strings.Right) &
+                       " on line " & ARM_Input.Line_String (Input_Object));
+           end case;
+       end Process_Command_with_Parameter;
+
+
+       procedure Process_Command_without_Parameter (Name : in 
ARM_Input.Command_Name_Type) is
+           -- Process the start of a command without a parameter. The name
+           -- of the command is Name.
+           procedure Put_Name (Kind : Paragraph_Type) is
+           begin
+               Check_Paragraph;
+               ARM_Output.Ordinary_Text (Output_Object,
+                   
Data.Paragraph_Kind_Name(Kind).Str(1..Data.Paragraph_Kind_Name(Kind).Length));
+               Format_Object.Last_Non_Space := True;
+           end Put_Name;
+
+           procedure Put_Title (Kind : Paragraph_Type) is
+           begin
+               Check_Paragraph;
+               ARM_Output.Ordinary_Text (Output_Object,
+                   
Paragraph_Kind_Title(Kind).Str(1..Paragraph_Kind_Title(Kind).Length));
+               Format_Object.Last_Non_Space := True;
+           end Put_Title;
+
+           procedure Format_Text (Text : in String;
+                                  Text_Name : in String) is
+               -- Note: We use the state of the surrounding call.
+               Input_Object : Arm_String.String_Input_Type;
+               Real_Include_Annotations : Boolean := 
Format_Object.Include_Annotations;
+           begin
+               -- Don't show annotations here:
+                Format_Object.Include_Annotations := False;
+               Arm_String.Open (Input_Object, Text, Text_Name);
+                    -- Open the input object using a string for input.
+               Real_Process (Format_Object, Format_State, Input_Object, 
Output_Object);
+               Arm_String.Close (Input_Object);
+               Format_Object.Include_Annotations := Real_Include_Annotations;
+           end Format_Text;
+
+           procedure DB_Report is new ARM_Database.Report (Format_Text);
+
+           procedure Syn_Report is new ARM_Syntax.Report (Format_Text);
+
+           procedure Syn_XRef is new ARM_Syntax.XRef (Format_Text);
+
+       begin
+           case Command (Name) is
+               when Comment =>
+                   null; -- Harmless, but still junk.
+
+               when No_Prefix =>
+                   Format_Object.No_Prefix := True;
+
+               when No_Para_Num =>
+                   Format_Object.No_Para_Num := True;
+
+               when Keep_with_Next =>
+                   Format_Object.Keep_with_Next := True;
+
+               when Leading =>
+                   Format_Object.Space_After := ARM_Output.Narrow;
+
+               when Trailing =>
+                   Format_Object.Space_After := ARM_Output.Wide;
+
+               when New_Page =>
+                   Check_End_Paragraph; -- End any paragraph that we're in.
+                   ARM_Output.New_Page (Output_Object, ARM_Output.Any_Page);
+
+               when RM_New_Page =>
+                   if not Format_Object.Include_Annotations then
+                       Check_End_Paragraph; -- End any paragraph that we're in.
+                       ARM_Output.New_Page (Output_Object, 
ARM_Output.Any_Page);
+                   -- else do nothing.
+                   end if;
+
+               when Soft_Page =>
+                   Check_Paragraph;
+                   ARM_Output.New_Page (Output_Object, ARM_Output.Soft_Page);
+
+               when New_Column =>
+                   Check_End_Paragraph; -- End any paragraph that we're in.
+                   ARM_Output.New_Column (Output_Object);
+
+               when Thin_Line =>
+                   Check_End_Paragraph;
+                   ARM_Output.Separator_Line (Output_Object, Is_Thin => True);
+
+               when Thick_Line =>
+                   Check_End_Paragraph;
+                   ARM_Output.Separator_Line (Output_Object, Is_Thin => False);
+
+               when Table_Last =>
+                   if Format_Object.Next_Paragraph_Format_Type = In_Table then
+                       -- If in a table, ends the second last row.
+                       ARM_Output.Table_Marker (Output_Object, 
ARM_Output.End_Row_Next_is_Last);
+                       -- Eat the following LF, if any, to avoid confusing
+                       -- row ends:
+                       declare
+                           Ch : Character;
+                       begin
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           if Ch /= Ascii.LF then
+                               ARM_Input.Replace_Char (Input_Object);
+                           end if;
+                       end;
+                   else
+                       Ada.Text_IO.Put_Line ("  ** @Last command not in table, 
line " & ARM_Input.Line_String (Input_Object));
+                   end if;
+
+               when Index_List =>
+                   -- Generate the index body.
+                   Check_End_Paragraph;
+
+                   ARM_Output.Set_Columns (Output_Object, Number_of_Columns => 
3);
+
+                   ARM_Index.Generate_Index_Body (Output_Object,
+                       Use_Paragraphs => Format_Object.Number_Paragraphs);
+
+                   ARM_Output.Set_Columns (Output_Object, Number_of_Columns => 
1);
+
+               when Syntax_Summary =>
+--Ada.Text_IO.Put_Line ("%% Generate Syntax summary");
+                   Syn_Report;
+
+               when Syntax_XRef =>
+--Ada.Text_IO.Put_Line ("%% Generate Syntax xref");
+                   Syn_XRef;
+
+               when Glossary_List =>
+                   DB_Report  (Format_Object.Glossary_DB,
+                               ARM_Database.Normal_Indexed_List,
+                               Sorted => True);
+
+               when Attribute_List =>
+                   DB_Report  (Format_Object.Attr_DB,
+                               ARM_Database.Hanging_List,
+                               Sorted => True,
+                               No_Deleted_Paragraph_Messages => True);
+
+               when Pragma_List =>
+                   DB_Report  (Format_Object.Pragma_DB,
+                               ARM_Database.Normal_List,
+                               Sorted => True);
+
+               when Implementation_Defined_List =>
+                   DB_Report  (Format_Object.Impdef_DB,
+                               ARM_Database.Bullet_List,
+                               Sorted => True);
+
+               when Package_List =>
+                   Write_Subindex (Format_Object.Package_Index,
+                                   Format_Object,
+                                   Output_Object,
+                                   Minimize_Lines => False);
+
+               when Type_List =>
+                   Write_Subindex (Format_Object.Type_Index,
+                                   Format_Object,
+                                   Output_Object,
+                                   Minimize_Lines => False);
+
+               when Subprogram_List =>
+                   Write_Subindex (Format_Object.Subprogram_Index,
+                                   Format_Object,
+                                   Output_Object,
+                                   Minimize_Lines => True);
+
+               when Exception_List =>
+                   Write_Subindex (Format_Object.Exception_Index,
+                                   Format_Object,
+                                   Output_Object,
+                                   Minimize_Lines => False);
+
+               when Object_List =>
+                   Write_Subindex (Format_Object.Object_Index,
+                                   Format_Object,
+                                   Output_Object,
+                                   Minimize_Lines => True);
+
+               when Text_Begin | Text_End | Redundant | Part | Bold | Italic |
+                    Roman | Swiss | Fixed | Roman_Italic | Shrink | Grow |
+                    Black | Red | Green | Blue |
+                    Keyword | Non_Terminal | Non_Terminal_Format |
+                    Example_Text | Example_Comment |
+                    Up | Down | Tab_Clear | Tab_Set |
+                    New_Page_for_Version | RM_New_Page_for_Version |
+                    Not_ISO_RM_New_Page_for_Version |
+                    ISO_Only_RM_New_Page_for_Version |
+                    New_Column_for_Version |
+                    Table | Picture_Alone | Picture_Inline |
+                    Defn | RootDefn | PDefn | Defn2 | RootDefn2 | PDefn2 |
+                    Index_See | Index_See_Also | See_Other | See_Also |
+                    Index_Root_Unit | Index_Child_Unit | 
Index_Subprogram_Child_Unit |
+                    Index_Type | Index_Subtype |
+                    Index_Subprogram | Index_Exception | Index_Object |
+                    Index_Package | Index_Other | Index_Check |
+                    Index_Attr | Index_Pragma | Index_Aspect |
+                    Syntax_Rule | Syntax_Term | Syntax_Term_Undefined | 
Syntax_Prefix |
+                    Added_Syntax_Rule | Deleted_Syntax_Rule |
+                    To_Glossary | To_Glossary_Also |
+                    Change_To_Glossary | Change_To_Glossary_Also |
+                    Implementation_Defined |
+                    Prefix_Type | Reset_Prefix_Type | Attribute | 
Attribute_Leading |
+                    Pragma_Syntax | Added_Pragma_Syntax | 
Deleted_Pragma_Syntax |
+                    Labeled_Section | Labeled_Section_No_Break |
+                    Labeled_Clause | Labeled_Subclause | Labeled_Subsubclause |
+                    Labeled_Revised_Section | Labeled_Revised_Clause |
+                    Labeled_Revised_Subclause | Labeled_Revised_Subsubclause |
+                    Labeled_Added_Section | Labeled_Added_Clause |
+                    Labeled_Added_Subclause | Labeled_Added_Subsubclause |
+                    Labeled_Deleted_Clause |
+                    Labeled_Deleted_Subclause | Labeled_Deleted_Subsubclause |
+                    Labeled_Annex | Labeled_Revised_Annex | 
Labeled_Added_Annex |
+                    Labeled_Informative_Annex | 
Labeled_Revised_Informative_Annex |
+                    Labeled_Added_Informative_Annex |
+                    Labeled_Normative_Annex | Labeled_Revised_Normative_Annex |
+                    Labeled_Added_Normative_Annex |
+                    Unnumbered_Section | Subheading | Added_Subheading | 
Heading |
+                    Center | Right |
+                    Preface_Section | Ref_Section | Ref_Section_Number | 
Ref_Section_by_Number |
+                    Local_Target | Local_Link | URL_Link | AI_Link |
+                    Change | Change_Reference | Change_Note |
+                    Change_Added | Change_Deleted |
+                    Change_Implementation_Defined |
+                    Change_Implementation_Advice |
+                    Change_Documentation_Requirement |
+                    Change_Aspect_Description |
+                    Added_Implementation_Advice_List |
+                    Added_Documentation_Requirements_List |
+                    Added_Aspect_Description_List |
+                    Change_Attribute |
+                    Change_Prefix_Type |
+                    Latin_1 | Unicode | Ceiling | Floor | Absolute | Log =>
+                   -- These commands must have a parameter.
+                   Ada.Text_IO.Put_Line ("  ** Failed to find parameter for " &
+                       Ada.Strings.Fixed.Trim (Name, Ada.Strings.Right) &
+                       ", line " & ARM_Input.Line_String (Input_Object));
+
+               when Change_Param_Old | Change_Param_New | Change_Added_Param | 
Change_Deleted_Param =>
+                   -- These can't get here; they represent the parameters of
+                   -- "Change" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Change parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Table_Param_Caption | Table_Param_Header | 
Table_Param_Body =>
+                   -- These can't get here; they represent the parameters of
+                   -- "Table" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Table parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Syntax_Rule_RHS =>
+                   -- This can't get here; it represents the second parameter 
of
+                   -- "Syn" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Syntax parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Glossary_Text_Param =>
+                   -- This can't get here; it represents a parameter of
+                   -- "ToGlossary" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Glossary parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Attribute_Text_Param =>
+                   -- This can't get here; it represents a parameter of
+                   -- "Attribute" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Attribute parameter command?? 
on line " & ARM_Input.Line_String (Input_Object));
+
+               when Change_Impdef_Text_Param =>
+                   -- This can't get here; it represents a parameter of
+                   -- "ChgImpldef" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Impdef parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Change_Impladv_Text_Param =>
+                   -- This can't get here; it represents a parameter of
+                   -- "ChgImpladv" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** Impladv parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Change_Docreq_Text_Param =>
+                   -- This can't get here; it represents a parameter of
+                   -- "ChgDocreq" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** DocReq parameter command?? on 
line " & ARM_Input.Line_String (Input_Object));
+
+               when Change_AspectDesc_Text_Param =>
+                   -- This can't get here; it represents a parameter of
+                   -- "ChgAspectDesc" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** AspectDesc parameter command?? 
on line " & ARM_Input.Line_String (Input_Object));
+
+               when Change_Prefix_Text_Param =>
+                   -- This can't get here; it represents a parameter of
+                   -- "ChgPrefixType" and can't be generated explicitly.
+                   Ada.Text_IO.Put_Line ("  ** ChgPrefix parameter command?? 
on line " & ARM_Input.Line_String (Input_Object));
+
+               when Intro_Name =>
+                   Put_Name(Introduction);
+               when Syntax_Name =>
+                   Put_Name(Syntax);
+               when Resolution_Name =>
+                   Put_Name(Resolution);
+               when Legality_Name =>
+                   Put_Name(Legality);
+               when Static_Name =>
+                   Put_Name(Static_Semantics);
+               when Link_Name =>
+                   Put_Name(Link_Time);
+               when Run_Name =>
+                   Put_Name(Run_Time);
+               when Bounded_Name =>
+                   Put_Name(Bounded_Errors);
+               when Erroneous_Name =>
+                   Put_Name(Erroneous);
+               when Req_Name =>
+                   Put_Name(Requirements);
+               when Doc_Name =>
+                   Put_Name(Documentation);
+               when Metrics_Name =>
+                   Put_Name(Metrics);
+               when Permission_Name =>
+                   Put_Name(Permissions);
+               when Advice_Name =>
+                   Put_Name(Advice);
+               when Notes_Name =>
+                   Put_Name(Notes);
+               when Single_Note_Name =>
+                   Put_Name(Single_Note);
+               when Examples_Name =>
+                   Put_Name(Examples);
+               when Meta_Name =>
+                   Put_Name(Language_Design);
+               when Inconsistent83_Name =>
+                   Put_Name(Ada83_Inconsistencies);
+               when Incompatible83_Name =>
+                   Put_Name(Ada83_Incompatibilities);
+               when Extend83_Name =>
+                   Put_Name(Ada83_Extensions);
+               when Wording83_Name =>
+                   Put_Name(Ada83_Wording);
+               when Inconsistent95_Name =>
+                   Put_Name(Ada95_Inconsistencies);
+               when Incompatible95_Name =>
+                   Put_Name(Ada95_Incompatibilities);
+               when Extend95_Name =>
+                   Put_Name(Ada95_Extensions);
+               when Wording95_Name =>
+                   Put_Name(Ada95_Wording);
+               when Inconsistent2005_Name =>
+                   Put_Name(Ada2005_Inconsistencies);
+               when Incompatible2005_Name =>
+                   Put_Name(Ada2005_Incompatibilities);
+               when Extend2005_Name =>
+                   Put_Name(Ada2005_Extensions);
+               when Wording2005_Name =>
+                   Put_Name(Ada2005_Wording);
+               when Inconsistent2012_Name =>
+                   Put_Name(Ada2012_Inconsistencies);
+               when Incompatible2012_Name =>
+                   Put_Name(Ada2012_Incompatibilities);
+               when Extend2012_Name =>
+                   Put_Name(Ada2012_Extensions);
+               when Wording2012_Name =>
+                   Put_Name(Ada2012_Wording);
+
+               when Syntax_Title =>
+                   Put_Title(Syntax);
+               when Resolution_Title =>
+                   Put_Title(Resolution);
+               when Legality_Title =>
+                   Put_Title(Legality);
+               when Static_Title =>
+                   Put_Title(Static_Semantics);
+               when Link_Title =>
+                   Put_Title(Link_Time);
+               when Run_Title =>
+                   Put_Title(Run_Time);
+               when Bounded_Title =>
+                   Put_Title(Bounded_Errors);
+               when Erroneous_Title =>
+                   Put_Title(Erroneous);
+               when Req_Title =>
+                   Put_Title(Requirements);
+               when Doc_Title =>
+                   Put_Title(Documentation);
+               when Metrics_Title =>
+                   Put_Title(Metrics);
+               when Permission_Title =>
+                   Put_Title(Permissions);
+               when Advice_Title =>
+                   Put_Title(Advice);
+               when Notes_Title =>
+                   Put_Title(Notes);
+               when Single_Note_Title =>
+                   Put_Title(Single_Note);
+               when Examples_Title =>
+                   Put_Title(Examples);
+               when Meta_Title =>
+                   Put_Title(Language_Design);
+               when Inconsistent83_Title =>
+                   Put_Title(Ada83_Inconsistencies);
+               when Incompatible83_Title =>
+                   Put_Title(Ada83_Incompatibilities);
+               when Extend83_Title =>
+                   Put_Title(Ada83_Extensions);
+               when Wording83_Title =>
+                   Put_Title(Ada83_Wording);
+               when Inconsistent95_Title =>
+                   Put_Title(Ada95_Inconsistencies);
+               when Incompatible95_Title =>
+                   Put_Title(Ada95_Incompatibilities);
+               when Extend95_Title =>
+                   Put_Title(Ada95_Extensions);
+               when Wording95_Title =>
+                   Put_Title(Ada95_Wording);
+               when Inconsistent2005_Title =>
+                   Put_Title(Ada2005_Inconsistencies);
+               when Incompatible2005_Title =>
+                   Put_Title(Ada2005_Incompatibilities);
+               when Extend2005_Title =>
+                   Put_Title(Ada2005_Extensions);
+               when Wording2005_Title =>
+                   Put_Title(Ada2005_Wording);
+               when Inconsistent2012_Title =>
+                   Put_Title(Ada2012_Inconsistencies);
+               when Incompatible2012_Title =>
+                   Put_Title(Ada2012_Incompatibilities);
+               when Extend2012_Title =>
+                   Put_Title(Ada2012_Extensions);
+               when Wording2012_Title =>
+                   Put_Title(Ada2012_Wording);
+
+               when EM_Dash =>
+                   Check_Paragraph;
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.EM_Dash);
+                   Format_Object.Last_Non_Space := True;
+               when EN_Dash =>
+                   Check_Paragraph;
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.EN_Dash);
+                   Format_Object.Last_Non_Space := True;
+               when LE =>
+                   Check_Paragraph;
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.LEQ);
+                   Format_Object.Last_Non_Space := True;
+               when LT =>
+                   Check_Paragraph;
+                   ARM_Output.Ordinary_Character (Output_Object, '<');
+                   Format_Object.Last_Non_Space := True;
+               when GE =>
+                   Check_Paragraph;
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.GEQ);
+                   Format_Object.Last_Non_Space := True;
+               when GT =>
+                   Check_Paragraph;
+                   ARM_Output.Ordinary_Character (Output_Object, '>');
+                   Format_Object.Last_Non_Space := True;
+               when NE =>
+                   Check_Paragraph;
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.NEQ);
+                   Format_Object.Last_Non_Space := True;
+               when PI =>
+                   Check_Paragraph;
+                   ARM_Output.Special_Character (Output_Object, ARM_Output.PI);
+                   Format_Object.Last_Non_Space := True;
+               when Times =>
+                   Check_Paragraph;
+                   ARM_Output.Ordinary_Character (Output_Object, 
Character'Val(183)); -- Middle Dot.
+                   Format_Object.Last_Non_Space := True;
+               when PorM =>
+                   Check_Paragraph;
+                   ARM_Output.Ordinary_Character (Output_Object, 
Character'Val(177)); -- Plus or Minus character.
+                   Format_Object.Last_Non_Space := True;
+               when Single_Quote =>
+                   Check_Paragraph;
+                   ARM_Output.Ordinary_Character (Output_Object, '''); -- 
Single quote.
+                   Format_Object.Last_Non_Space := True;
+               when Thin_Space =>
+                   Check_Paragraph;
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.Thin_Space);
+                   Format_Object.Last_Non_Space := True;
+               when Small_Dotless_I =>
+                   Check_Paragraph;
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.Small_Dotless_I);
+                   Format_Object.Last_Non_Space := True;
+               when Capital_Dotted_I =>
+                   Check_Paragraph;
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.Capital_Dotted_I);
+                   Format_Object.Last_Non_Space := True;
+               when Left_Quote =>
+                   Check_Paragraph;
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.Left_Quote);
+                   Format_Object.Last_Non_Space := True;
+               when Right_Quote =>
+                   Check_Paragraph;
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.Right_Quote);
+                   Format_Object.Last_Non_Space := True;
+               when Left_Double_Quote =>
+                   Check_Paragraph;
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.Left_Double_Quote);
+                   Format_Object.Last_Non_Space := True;
+               when Right_Double_Quote =>
+                   Check_Paragraph;
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.Right_Double_Quote);
+                   Format_Object.Last_Non_Space := True;
+               when Left_Quote_Pair =>
+                   Check_Paragraph;
+                   -- Was: To match the Ada 95 standard:
+                   --ARM_Output.Special_Character (Output_Object, 
ARM_Output.Left_Quote);
+                   --ARM_Output.Special_Character (Output_Object, 
ARM_Output.Left_Quote);
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.Left_Double_Quote);
+                   Format_Object.Last_Non_Space := True;
+               when Right_Quote_Pair =>
+                   Check_Paragraph;
+                   -- Was: To match the Ada 95 standard:
+                   --ARM_Output.Special_Character (Output_Object, 
ARM_Output.Right_Quote);
+                   --ARM_Output.Special_Character (Output_Object, 
ARM_Output.Right_Quote);
+                   ARM_Output.Special_Character (Output_Object, 
ARM_Output.Right_Double_Quote);
+                   Format_Object.Last_Non_Space := True;
+
+               when Unknown =>
+                   Ada.Text_IO.Put_Line ("  ?? Unknown command (skipped) - " &
+                       Ada.Strings.Fixed.Trim (Name, Ada.Strings.Right) &
+                       " on line " & ARM_Input.Line_String (Input_Object));
+           end case;
+       end Process_Command_without_Parameter;
+
+
+       procedure Handle_End_of_Command is
+           -- Unstack and handle the end of Commands.
+
+           procedure Finish_and_DB_Entry (DB : in out 
ARM_Database.Database_Type) is
+               -- Close the text parameter for a number of commands
+               -- (impdef, chgimpdef, chgimpladv, chgdocreg)
+               -- and insert the resulting string into the appropriate DB.
+               Text_Buffer : String (1..ARM_Input.MAX_RECORDING_SIZE);
+               Text_Buffer_Len : Natural;
+
+               function DB_Clause_String return String is
+                   use type ARM_Contents.Section_Number_Type;
+               begin
+                   if Format_Object.Clause_Number.Clause = 0 then
+                       if Format_Object.Clause_Number.Section in 0 .. 9 then
+                           return
+                               Character'Val(Character'Pos('0') +
+                                  Format_Object.Clause_Number.Section) & "";
+                       elsif Format_Object.Clause_Number.Section in 10 .. 19 
then
+                           return "1" &
+                               Character'Val(Character'Pos('0') +
+                                  Format_Object.Clause_Number.Section - 10);
+                       elsif Format_Object.Clause_Number.Section in 20 .. 29 
then
+                           return "2" &
+                               Character'Val(Character'Pos('0') +
+                                  Format_Object.Clause_Number.Section - 20);
+                       elsif Format_Object.Clause_Number.Section = 30 then
+                           return "30";
+                       else --if Format_Object.Clause_Number.Section >= 
ARM_Contents.ANNEX_START then
+                           return Character'Val (Character'Pos('A') +
+                                (Format_Object.Clause_Number.Section -
+                                   ARM_Contents.ANNEX_START)) & "";
+                       end if;
+                   elsif Format_Object.Clause_Number.Subclause = 0 then
+                       return ARM_Contents.Make_Clause_Number (
+                               ARM_Contents.Clause,
+                               Format_Object.Clause_Number);
+                   elsif Format_Object.Clause_Number.Subsubclause = 0 then
+                       return ARM_Contents.Make_Clause_Number (
+                               ARM_Contents.SubClause,
+                               Format_Object.Clause_Number);
+                   else
+                       return ARM_Contents.Make_Clause_Number (
+                               ARM_Contents.SubsubClause,
+                               Format_Object.Clause_Number);
+                   end if;
+               end DB_Clause_String;
+
+               function Sort_Clause_String return String is
+                   Res : String(1..13);
+                   -- Always use the paragraph for sorting:
+               begin
+                   -- The funny encoding to insure proper sorting.
+                   -- (Otherwise "10" sorts before "2".
+                   Res(1) := Character'Val 
(Natural(Format_Object.Clause_Number.Section) + 16#30#);
+                   Res(2) := '.';
+                   Res(3) := Character'Val (Format_Object.Clause_Number.Clause 
+ 16#30#);
+                   Res(4) := '.';
+                   Res(5) := Character'Val 
(Format_Object.Clause_Number.Subclause + 16#30#);
+                   Res(6) := '.';
+                   Res(7) := Character'Val 
(Format_Object.Clause_Number.Subsubclause + 16#30#);
+                   Res(8) := '(';
+                   Res(9) := Character'Val ((Format_Object.Next_Paragraph / 
10) + 16#30#);
+                   Res(10) := Character'Val ((Format_Object.Next_Paragraph mod 
10) + 16#30#);
+                   Res(11) := '.';
+                   Res(12) := Character'Val ((Format_Object.Next_Insert_Para 
mod 10) + 16#30#);
+                   Res(13) := ')';
+                   return Res;
+               end Sort_Clause_String;
+
+               function See_String return String is
+               begin
+                   case Format_Object.Impdef_Info.Change_Kind is
+                       when ARM_Database.None | ARM_Database.Revised |
+                            ARM_Database.Revised_Inserted_Number =>
+                           if Format_Object.Number_Paragraphs and then
+                                Format_Object.Impdef_Info.Command /= Aspect 
then
+                               return " See @RefSecbyNum{" & DB_Clause_String 
& "}(" &
+                                   Format_Object.Impdef_Info.Paragraph_String 
(1..Format_Object.Impdef_Info.Paragraph_Len) &
+                                   ").";
+                           else -- No paragraph numbers.
+                               return " See @RefSecbyNum{" & DB_Clause_String 
& "}.";
+                           end if;
+                       when ARM_Database.Inserted | 
ARM_Database.Inserted_Normal_Number =>
+                           if Format_Object.Number_Paragraphs and then
+                                Format_Object.Impdef_Info.Command /= Aspect 
then
+                               return "@Chg{Version=[" & 
Format_Object.Impdef_Info.Version &
+                                   "], New=[ See @RefSecbyNum{" & 
DB_Clause_String & "}(" &
+                                   Format_Object.Impdef_Info.Paragraph_String 
(1..Format_Object.Impdef_Info.Paragraph_Len) &
+                                   ").],Old=[]}";
+                           else -- No paragraph numbers.
+                               return "@Chg{Version=[" & 
Format_Object.Impdef_Info.Version &
+                                   "], New=[ See @RefSecbyNum{" & 
DB_Clause_String & "}.],Old=[]}";
+                           end if;
+                       when ARM_Database.Deleted |
+                            ARM_Database.Deleted_Inserted_Number |
+                            ARM_Database.Deleted_No_Delete_Message |
+                            
ARM_Database.Deleted_Inserted_Number_No_Delete_Message =>
+                           if Format_Object.Number_Paragraphs and then
+                                Format_Object.Impdef_Info.Command /= Aspect 
then
+                               return "@Chg{Version=[" & 
Format_Object.Impdef_Info.Version &
+                                   "], New=[],Old=[ See @RefSecbyNum{" & 
DB_Clause_String & "}(" &
+                                   Format_Object.Impdef_Info.Paragraph_String 
(1..Format_Object.Impdef_Info.Paragraph_Len) &
+                                   ").]}";
+                           else -- No paragraph numbers.
+                               return "@Chg{Version=[" & 
Format_Object.Impdef_Info.Version &
+                                   "], New=[],Old=[ See @RefSecbyNum{" & 
DB_Clause_String & "}.]}";
+                           end if;
+                   end case;
+               end See_String;
+
+           begin
+               Arm_Input.Stop_Recording_and_Read_Result
+                   (Input_Object, Text_Buffer, Text_Buffer_Len);
+               Text_Buffer_Len := Text_Buffer_Len - 1; -- Remove command close 
character.
+               if not Format_Object.Impdef_Info.Add_to_DB then
+                   null; -- Don't add to the DB
+               elsif Format_Object.Impdef_Info.Command = Aspect then
+                   if Format_Object.Impdef_Info.Initial_Version >= '4' then
+                       -- ** Horrible hack: We treat the aspect as inserted
+                       -- if the initial version is greater than 4 (this is
+                       -- what we need in the RM and AARM). This
+                       -- should depend on other parameters, and ideally
+                       -- be determined inside of the DB_Report code.
+                       ARM_Database.Insert (DB,
+                           Sort_Key => 
Format_Object.Impdef_Info.Aspect_Name(1..Format_Object.Impdef_Info.Aspect_Name_Len),
+                           Hang_Item => "@Chg{Version=[" & 
Format_Object.Impdef_Info.Initial_Version &
+                               "],New=[" & 
Format_Object.Impdef_Info.Aspect_Name(1..Format_Object.Impdef_Info.Aspect_Name_Len)
 &
+                               "],Old=[]}",
+                           Text => Text_Buffer(1..Text_Buffer_Len) &
+                              See_String,
+                           Change_Kind => 
Format_Object.Impdef_Info.Change_Kind,
+                           Version => Format_Object.Impdef_Info.Version,
+                           Initial_Version => 
Format_Object.Impdef_Info.Initial_Version);
+                   else -- Normal
+                       ARM_Database.Insert (DB,
+                           Sort_Key => 
Format_Object.Impdef_Info.Aspect_Name(1..Format_Object.Impdef_Info.Aspect_Name_Len),
+                           Hang_Item => 
Format_Object.Impdef_Info.Aspect_Name(1..Format_Object.Impdef_Info.Aspect_Name_Len),
+                           Text => Text_Buffer(1..Text_Buffer_Len) &
+                              See_String,
+                           Change_Kind => 
Format_Object.Impdef_Info.Change_Kind,
+                           Version => Format_Object.Impdef_Info.Version,
+                           Initial_Version => 
Format_Object.Impdef_Info.Initial_Version);
+                   end if;
+               else
+                   ARM_Database.Insert (DB,
+                       Sort_Key => Sort_Clause_String,
+                       Hang_Item => "",
+                       Text => Text_Buffer(1..Text_Buffer_Len) &
+                          See_String,
+                       Change_Kind => Format_Object.Impdef_Info.Change_Kind,
+                       Version => Format_Object.Impdef_Info.Version,
+                       Initial_Version => 
Format_Object.Impdef_Info.Initial_Version);
+               end if;
+               -- Finish the text processing:
+               if Format_Object.Impdef_Info.Add_to_DB and
+                  Format_Object.Include_Annotations then
+                   -- End the annotation:
+                   Check_End_Paragraph;
+                   if Format_Object.Next_Paragraph_Subhead_Type /=
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Subhead_Paragraph
 then
+                       Format_Object.Last_Paragraph_Subhead_Type :=
+                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Last_Subhead_Paragraph;
+                   -- else still in same subhead, leave alone. (If
+                   -- we didn't do this, we'd output the subhead
+                   -- multiple times).
+                   end if;
+                   Format_Object.Next_Paragraph_Subhead_Type :=
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Subhead_Paragraph;
+                   Format_Object.Next_Paragraph_Format_Type :=
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Paragraph_Format;
+                   Format_Object.Paragraph_Tab_Stops :=
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Tab_Stops;
+               -- else nothing started, nothing to finish.
+               end if;
+               -- Clear the Impdef information:
+               Format_Object.Impdef_Info := (Command => None);
+           end Finish_and_DB_Entry;
+
+       begin
+           case 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command is
+               when Redundant =>
+                   if Format_Object.Include_Annotations then
+                       Check_Paragraph;
+                       ARM_Output.Ordinary_Character (Output_Object, ']');
+                   -- else ignored.
+                   end if;
+
+               when Bold | Italic | Roman | Swiss | Fixed | Roman_Italic |
+                    Shrink | Grow | Up | Down |
+                    Black | Red | Green | Blue |
+                    Keyword | Non_Terminal | Non_Terminal_Format |
+                    Example_Text | Example_Comment =>
+                   -- Formatting commands; revert to the previous (saved)
+                   -- version:
+                   Check_Paragraph;
+                   Format_Object.Text_Format :=
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Text_Format;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => 
Format_Object.Text_Format);
+
+               when Subheading | Heading =>
+                   -- Restore the format.
+                   Check_Paragraph;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format => ARM_Output.NORMAL_FORMAT);
+                   Format_Object.Text_Format := ARM_Output.NORMAL_FORMAT;
+                   Check_End_Paragraph;
+
+               when Added_Subheading =>
+                   -- Restore the format.
+                   declare
+                       Disposition : ARM_Output.Change_Type;
+                       use type ARM_Output.Change_Type;
+                   begin
+                       Calc_Change_Disposition (
+                           Format_Object => Format_Object,
+                           Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version,
+                           Operation => ARM_Output.Insertion,
+                           Text_Kind => Disposition);
+
+                       if Disposition = Do_Not_Display_Text then
+                           -- The new text was ignored.
+                           null; -- Nothing to do (we nulled out the text 
before we got here).
+                       elsif Disposition = ARM_Output.None then
+                           -- Display the text normally.
+                           Check_Paragraph;
+                           ARM_Output.Text_Format (Output_Object,
+                                                   Format => 
ARM_Output.NORMAL_FORMAT);
+                           Format_Object.Text_Format := 
ARM_Output.NORMAL_FORMAT;
+                           Check_End_Paragraph;
+                       elsif Disposition = ARM_Output.Deletion then
+                           raise Program_Error; -- A deletion inside of an 
insertion command!
+                       else -- Insertion.
+                           Check_Paragraph;
+                           ARM_Output.Text_Format (Output_Object,
+                                                   Format => 
ARM_Output.NORMAL_FORMAT);
+                           Format_Object.Text_Format := 
ARM_Output.NORMAL_FORMAT;
+                           Check_End_Paragraph;
+                       end if;
+                   end;
+
+               when Center | Right =>
+                   -- Close the paragraph.
+                   Check_End_Paragraph;
+
+               when New_Page_for_Version =>
+                   -- The version parameter is stored in Change_Version on
+                   -- the stack.
+                   if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version
+                       = Format_Object.Change_Version then
+                       Check_End_Paragraph; -- End any paragraph that we're in.
+                       ARM_Output.New_Page (Output_Object, 
ARM_Output.Any_Page);
+                   -- else do nothing.
+                   end if;
+
+               when RM_New_Page_for_Version =>
+                   -- The version parameter is stored in Change_Version on
+                   -- the stack.
+                   if not Format_Object.Include_Annotations and then
+                      
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version
+                       = Format_Object.Change_Version then
+                       Check_End_Paragraph; -- End any paragraph that we're in.
+                       ARM_Output.New_Page (Output_Object, 
ARM_Output.Any_Page);
+                   -- else do nothing.
+                   end if;
+
+               when Not_ISO_RM_New_Page_for_Version =>
+                   -- The version parameter is stored in Change_Version on
+                   -- the stack.
+                   if not Format_Object.Include_Annotations and then
+                      not Format_Object.Include_ISO and then
+                      
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version
+                       = Format_Object.Change_Version then
+                       Check_End_Paragraph; -- End any paragraph that we're in.
+                       ARM_Output.New_Page (Output_Object, 
ARM_Output.Any_Page);
+                   -- else do nothing.
+                   end if;
+
+               when ISO_Only_RM_New_Page_for_Version =>
+                   -- The version parameter is stored in Change_Version on
+                   -- the stack.
+                   if not Format_Object.Include_Annotations and then
+                      Format_Object.Include_ISO and then
+                      
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version
+                       = Format_Object.Change_Version then
+                       Check_End_Paragraph; -- End any paragraph that we're in.
+                       ARM_Output.New_Page (Output_Object, 
ARM_Output.Any_Page);
+                   -- else do nothing.
+                   end if;
+
+               when New_Column_for_Version =>
+                   -- The version parameter is stored in Change_Version on
+                   -- the stack.
+                   if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version
+                       = Format_Object.Change_Version then
+                       Check_End_Paragraph; -- End any paragraph that we're in.
+                       ARM_Output.New_Column (Output_Object);
+                   -- else do nothing.
+                   end if;
+
+               when Table_Param_Caption =>
+                   ARM_Output.Table_Marker (Output_Object,
+                                            ARM_Output.End_Caption);
+                   Format_Object.Last_Non_Space := False;
+
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                       -- Unstack the "Caption" parameter.
+--Ada.Text_IO.Put_Line (" &Unstack (Tab Cap)");
+
+                   -- Check and handle the following "Headers" parameter:
+                   declare
+                       Ch : Character;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Headers" & 
(8..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Ch);
+                       if Ch /= ' ' then -- There is a parameter.
+                           -- Stack the parameter so we can process the end:
+                           Set_Nesting_for_Parameter
+                               (Command => Table_Param_Header,
+                                Close_Ch => Ch);
+
+                           -- No processing needed here.
+
+                       -- else no parameter. Weird.
+                       end if;
+                       return; -- We've already done the unstacking.
+                   end;
+
+               when Table_Param_Header =>
+                   ARM_Output.Table_Marker (Output_Object,
+                                            ARM_Output.End_Header);
+                   Format_Object.Last_Non_Space := False;
+
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                       -- Unstack the "Header" parameter.
+--Ada.Text_IO.Put_Line (" &Unstack (Tab Head)");
+
+                   -- Check and handle the following "Body" parameter:
+                   declare
+                       Ch : Character;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Body" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Ch);
+                       if Ch /= ' ' then -- There is a parameter.
+                           -- Stack the parameter so we can process the end:
+                           Set_Nesting_for_Parameter
+                               (Command => Table_Param_Body,
+                                Close_Ch => Ch);
+
+                           -- No processing needed here.
+
+                       -- else no parameter. Weird.
+                       end if;
+                       return; -- We've already done the unstacking.
+                   end;
+
+               when Table_Param_Body =>
+                   -- Close the table:
+                   ARM_Output.Table_Marker (Output_Object,
+                                            ARM_Output.End_Table);
+                   Format_Object.Last_Non_Space := False;
+
+                   -- Reset the paragraph format (and skip over the parameter 
records):
+                   Format_Object.Last_Paragraph_Subhead_Type :=
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Old_Last_Subhead_Paragraph;
+                   Format_Object.Next_Paragraph_Subhead_Type :=
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Old_Next_Subhead_Paragraph;
+                   Format_Object.Next_Paragraph_Format_Type :=
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Old_Next_Paragraph_Format;
+                   Format_Object.Paragraph_Tab_Stops :=
+                       
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Old_Tab_Stops;
+                   Format_Object.In_Paragraph := False; -- End fake paragraph.
+                   Format_Object.No_Start_Paragraph := False;
+
+               when Syntax_Rule_RHS =>
+                   -- Send the production to the syntax manager.
+                   -- Other processing has already been handled.
+                   declare
+                       Text_Buffer : String (1..ARM_Input.MAX_RECORDING_SIZE);
+                       Text_Buffer_Len : Natural;
+                       Disposition : ARM_Output.Change_Type;
+                       use type ARM_Output.Change_Type;
+                   begin
+                       -- Calculate Disposition:
+                       if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Command = 
Syntax_Rule then
+                           Disposition := ARM_Output.None; -- Normal text.
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Command = 
Added_Syntax_Rule then
+                           Calc_Change_Disposition (
+                               Format_Object => Format_Object,
+                               Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version,
+                               Operation => ARM_Output.Insertion,
+                               Text_Kind => Disposition);
+                       else -- Deleted_Syntax_Rule
+                           Calc_Change_Disposition (
+                               Format_Object => Format_Object,
+                               Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version,
+                               Operation => ARM_Output.Deletion,
+                               Text_Kind => Disposition);
+                       end if;
+
+                       if Disposition = Do_Not_Display_Text then
+                           -- The text was ignored and skipped.
+                           -- Set the Non-terminal to empty:
+                           Format_Object.Syntax_NT_Len := 0;
+                           Format_Object.Syntax_Tab_Len := 0;
+                       else
+                           Arm_Input.Stop_Recording_and_Read_Result
+                               (Input_Object, Text_Buffer, Text_Buffer_Len);
+                           Text_Buffer_Len := Text_Buffer_Len - 1; -- Remove 
command close character.
+                           if Disposition = ARM_Output.None then
+                               -- Display the text normally.
+                               ARM_Syntax.Insert_Rule (For_Clause => 
Clause_String (Format_Object),
+                                   Rule => "@ntf{" & 
Format_Object.Syntax_NT(1..Format_Object.Syntax_NT_Len) &
+                                       " ::=} " & 
Text_Buffer(1..Text_Buffer_Len),
+                                   Tabset => 
Format_Object.Syntax_Tab(1..Format_Object.Syntax_Tab_Len));
+                           elsif Disposition = ARM_Output.Deletion then
+                               ARM_Syntax.Insert_Rule (For_Clause => 
Clause_String (Format_Object),
+                                   Rule => "@ntf{" & 
Format_Object.Syntax_NT(1..Format_Object.Syntax_NT_Len) &
+                                       "@Chg{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version &
+                                       "],New=[],Old=[ ::=]}} " & 
Text_Buffer(1..Text_Buffer_Len),
+                                   Tabset => 
Format_Object.Syntax_Tab(1..Format_Object.Syntax_Tab_Len));
+                           else -- Insertion.
+                               ARM_Syntax.Insert_Rule (For_Clause => 
Clause_String (Format_Object),
+                                   Rule => "@ntf{" & 
Format_Object.Syntax_NT(1..Format_Object.Syntax_NT_Len) &
+                                       "@Chg{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version &
+                                       "],New=[ ::=],Old=[]}} " & 
Text_Buffer(1..Text_Buffer_Len),
+                                   Tabset => 
Format_Object.Syntax_Tab(1..Format_Object.Syntax_Tab_Len));
+                           end if;
+                           -- Note: The LHS non-terminals aren't linked as 
usual.
+
+                           Check_End_Paragraph; -- End the paragraph, so the
+                                                -- next rule gets its own.
+
+                           -- Reset the paragraph format:
+                           Format_Object.Last_Paragraph_Subhead_Type :=
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Last_Subhead_Paragraph;
+                           Format_Object.Next_Paragraph_Subhead_Type :=
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Subhead_Paragraph;
+                           Format_Object.Next_Paragraph_Format_Type :=
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Paragraph_Format;
+                           Format_Object.Paragraph_Tab_Stops :=
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Tab_Stops;
+
+                           -- Set the Non-terminal to empty:
+                           Format_Object.Syntax_NT_Len := 0;
+                           Format_Object.Syntax_Tab_Len := 0;
+                       end if;
+                   end;
+
+               when Syntax_Prefix =>
+                   -- Reset the style:
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Italic := False;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format_Object.Text_Format);
+
+               when Glossary_Text_Param =>
+                   -- Save the glossary entry in the Glossary database.
+                   if not Format_Object.Glossary_Info.Active then
+                       Ada.Text_IO.Put_Line ("  ** Not in glossary command at 
end of glossary command!? on line " & ARM_Input.Line_String (Input_Object));
+                   -- else OK.
+                   end if;
+                   declare
+                       use type ARM_Database.Paragraph_Change_Kind_Type;
+                       Text_Buffer : String (1..ARM_Input.MAX_RECORDING_SIZE);
+                       Text_Buffer_Len : Natural;
+                   begin
+                       Arm_Input.Stop_Recording_and_Read_Result
+                           (Input_Object, Text_Buffer, Text_Buffer_Len);
+                       Text_Buffer_Len := Text_Buffer_Len - 1; -- Remove 
command close character.
+                       if Format_Object.Glossary_Info.Add_to_Glossary then
+                           if Format_Object.Glossary_Info.Change_Kind = 
ARM_Database.Inserted then
+                               ARM_Database.Insert (Format_Object.Glossary_DB,
+                                   Sort_Key => 
Format_Object.Glossary_Info.Term(1..Format_Object.Glossary_Info.Term_Len),
+                                   Hang_Item => "",
+                                   Text => "@chg{Version=[" & 
Format_Object.Glossary_Info.Version & "],address@hidden" &
+                                       
Format_Object.Glossary_Info.Term(1..Format_Object.Glossary_Info.Term_Len) &
+                                       ".}],Old=[]} " & 
Text_Buffer(1..Text_Buffer_Len),
+                                   Change_Kind => 
Format_Object.Glossary_Info.Change_Kind,
+                                   Version => 
Format_Object.Glossary_Info.Version,
+                                   Initial_Version => 
Format_Object.Glossary_Info.Version);
+
+                           elsif Format_Object.Glossary_Info.Change_Kind = 
ARM_Database.Deleted then
+                               ARM_Database.Insert (Format_Object.Glossary_DB,
+                                   Sort_Key => 
Format_Object.Glossary_Info.Term(1..Format_Object.Glossary_Info.Term_Len),
+                                   Hang_Item => "",
+                                   Text => "@chg{Version=[" & 
Format_Object.Glossary_Info.Version & "],New=[],address@hidden" &
+                                       
Format_Object.Glossary_Info.Term(1..Format_Object.Glossary_Info.Term_Len) &
+                                       ".}]} " & 
Text_Buffer(1..Text_Buffer_Len),
+                                   Change_Kind => 
Format_Object.Glossary_Info.Change_Kind,
+                                   Version => 
Format_Object.Glossary_Info.Version);
+
+                           elsif Format_Object.Glossary_Info.Change_Kind = 
ARM_Database.None then
+                               ARM_Database.Insert (Format_Object.Glossary_DB,
+                                   Sort_Key => 
Format_Object.Glossary_Info.Term(1..Format_Object.Glossary_Info.Term_Len),
+                                   Hang_Item => "",
+                                   Text => "@b{" & 
Format_Object.Glossary_Info.Term(1..Format_Object.Glossary_Info.Term_Len) &
+                                       ".} " & Text_Buffer(1..Text_Buffer_Len),
+                                   Change_Kind => ARM_Database.None);
+
+                           else
+                               ARM_Database.Insert (Format_Object.Glossary_DB,
+                                   Sort_Key => 
Format_Object.Glossary_Info.Term(1..Format_Object.Glossary_Info.Term_Len),
+                                   Hang_Item => "",
+                                   Text => "@b{" & 
Format_Object.Glossary_Info.Term(1..Format_Object.Glossary_Info.Term_Len) &
+                                       ".} " & Text_Buffer(1..Text_Buffer_Len),
+                                   Change_Kind => 
Format_Object.Glossary_Info.Change_Kind,
+                                   Version => 
Format_Object.Glossary_Info.Version);
+                           end if;
+                       end if;
+                   end;
+
+                   -- Finish the text processing:
+                   if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Command = 
To_Glossary_Also or else
+                      
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Command = 
Change_To_Glossary_Also then
+                       null; -- Normal text, no special handling needed.
+                   else
+                       if Format_Object.Glossary_Info.Displayed then
+                           -- End the annotation.
+                           Check_End_Paragraph;
+                           Format_Object.Last_Paragraph_Subhead_Type :=
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Last_Subhead_Paragraph;
+                           Format_Object.Next_Paragraph_Subhead_Type :=
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Subhead_Paragraph;
+                           Format_Object.Next_Paragraph_Format_Type :=
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Next_Paragraph_Format;
+                           Format_Object.Paragraph_Tab_Stops :=
+                               
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Old_Tab_Stops;
+                       else
+                           null; -- No text, no special handling needed.
+                       end if;
+                   end if;
+                   -- Remove glossary information as the command is finished:
+                   Format_Object.Glossary_Info :=
+                       (Active => False,
+                        Change_Kind => ARM_Database.None);
+
+               when Attribute_Text_Param =>
+                   declare
+                       Text_Buffer : String (1..ARM_Input.MAX_RECORDING_SIZE);
+                       Text_Buffer_Len : Natural;
+
+                       function Sort_Key return String is
+                           -- Generate a Sort Key so that these sort
+                           -- as they did in Ada 95.
+                       begin
+                           if Format_Object.Attr_Prefix_Len > 2 and then
+                                   Format_Object.Attr_Prefix(2) = ''' then
+                               -- Class-wide prefix. For some reason, this
+                               -- sorts before the main item in the Ada 95 RM.
+                               -- (And this continues in later RMs.)
+                               return 
Format_Object.Attr_Name(1..Format_Object.Attr_Name_Len) &
+                                   ''' & 
Character'Pred(Format_Object.Attr_Prefix(1)) &
+                                   "'Class";
+                                       -- Sort by name, then by prefix.
+                           else
+                               return 
Format_Object.Attr_Name(1..Format_Object.Attr_Name_Len) &
+                                   ''' & 
Format_Object.Attr_Prefix(1..Format_Object.Attr_Prefix_Len);
+                                       -- Sort by name, then by prefix.
+                           end if;
+                           -- Note: Ada 2005 sorted E'Identity and T'Identity
+                           -- backwards from Ada 95. This will fix that.
+                       end Sort_Key;
+
+                       function ChgRef_Command (Kind : in 
ARM_Database.Paragraph_Change_Kind_Type;
+                                                Version : in Character;
+                                                Initial_Version : in 
Character) return String is
+                           -- Careful: This assumes this is being used for
+                           -- the attribute index, which has always existed.
+                           -- Use the annex initial version rather than '0'
+                           -- to determine whether it is inserted or not for
+                           -- other listings.
+                       begin
+                           case Kind is
+                               when ARM_Database.None =>
+                                   return "";
+                               when ARM_Database.Inserted | 
ARM_Database.Inserted_Normal_Number =>
+                                   if Initial_Version > '0' then -- Not 
original.
+                                       return "@Chgref{Version=[" & Version &
+                                           "],Kind=[Added]}";
+                                   else
+                                       return "@Chgref{Version=[" & Version &
+                                           "],Kind=[AddedNormal]}";
+                                   end if;
+                               when ARM_Database.Deleted |
+                                    ARM_Database.Deleted_Inserted_Number |
+                                    ARM_Database.Deleted_No_Delete_Message |
+                                    
ARM_Database.Deleted_Inserted_Number_No_Delete_Message =>
+                                   if Initial_Version > '0' then -- Not 
original.
+                                       return "@Chgref{Version=[" & Version &
+                                           "],Kind=[DeletedAdded]}";
+                                   else
+                                       return "@Chgref{Version=[" & Version &
+                                           "],Kind=[Deleted]}";
+                                   end if;
+                               when ARM_Database.Revised | 
ARM_Database.Revised_Inserted_Number =>
+                                   if Initial_Version > '0' then -- Not 
original.
+                                       return "@Chgref{Version=[" & Version &
+                                           "],Kind=[RevisedAdded]}";
+                                   else
+                                       return "@Chgref{Version=[" & Version &
+                                           "],Kind=[Revised]}";
+                                   end if;
+                           end case;
+                       end ChgRef_Command;
+
+                       procedure Write_to_DB (Prefix_Kind, Text_Kind :
+                               in ARM_Database.Paragraph_Change_Kind_Type;
+                               Prefix_Version, Text_Version,
+                               Initial_Version : in Character) is
+                           -- Write the item to the DB; use Prefix_Kind and
+                           -- Text_Kind for the change kind.
+                       begin
+                           if Format_Object.Attr_Leading then
+                               ARM_Database.Insert (Format_Object.Attr_DB,
+                                   Sort_Key => Sort_Key,
+                                   Hang_Item =>
+                                       
Format_Object.Attr_Prefix(1..Format_Object.Attr_Prefix_Len) &
+                                          ''' & 
Format_Object.Attr_Name(1..Format_Object.Attr_Name_Len),
+                                   Text => "For " & 
Format_Object.Prefix_Text(1..Format_Object.Prefix_Text_Len) &
+                                       ":" & Ascii.LF & Ascii.LF &
+                                       ChgRef_Command (Text_Kind, 
Text_Version, Initial_Version) &
+                                       "@address@hidden@;" & 
Text_Buffer(1..Text_Buffer_Len) &
+                                       " See @RefSecbyNum{" & 
Clause_String(Format_Object) & "}.",
+                                   Change_Kind => Prefix_Kind,
+                                   Version => Prefix_Version,
+                                   Initial_Version => Initial_Version);
+                           else -- not leading:
+                               ARM_Database.Insert (Format_Object.Attr_DB,
+                                   Sort_Key => Sort_Key,
+                                   Hang_Item =>
+                                       
Format_Object.Attr_Prefix(1..Format_Object.Attr_Prefix_Len) &
+                                          ''' & 
Format_Object.Attr_Name(1..Format_Object.Attr_Name_Len),
+                                   Text => "For " & 
Format_Object.Prefix_Text(1..Format_Object.Prefix_Text_Len) &
+                                       ":" & Ascii.LF & Ascii.LF &
+                                       ChgRef_Command (Text_Kind, 
Text_Version, Initial_Version) &
+                                       "@noprefix@;" & 
Text_Buffer(1..Text_Buffer_Len) &
+                                       " See @RefSecbyNum{" & 
Clause_String(Format_Object) & "}.",
+                                   Change_Kind => Prefix_Kind,
+                                   Version => Prefix_Version,
+                                   Initial_Version => Initial_Version);
+                           end if;
+                       end Write_to_DB;
+
+                       use type ARM_Database.Paragraph_Change_Kind_Type;
+
+                   begin
+                       Arm_Input.Stop_Recording_and_Read_Result
+                           (Input_Object, Text_Buffer, Text_Buffer_Len);
+                       Text_Buffer_Len := Text_Buffer_Len - 1; -- Remove 
command close character.
+--Ada.Text_IO.Put_Line ("&& Attr: " & 
Format_Object.Attr_Name(1..Format_Object.Attr_Name_Len) &
+--   "; Prefix kind=" & 
ARM_Database.Paragraph_Change_Kind_Type'Image(Format_Object.Attr_Prefix_Change_Kind)
 &
+--   "; Attr chg kind=" & 
ARM_Database.Paragraph_Change_Kind_Type'Image(Format_Object.Attr_Change_Kind) &
+--   "; Attr Prefix Vers=" & Format_Object.Attr_Prefix_Version & "; Attr Text 
Vers=" & Format_Object.Attr_Version &
+--   "; Attr Init Vers=" & Format_Object.Attr_Initial_Version);
+
+                       -- How the prefix text is handled depends only on
+                       -- the Initial_Version and what version we're 
generating.
+                       -- The Kind and Version of the prefix or item is
+                       -- irrelevant (it's needed mainly for the paragraph
+                       -- revision number). We assume that all attributes
+                       -- are inserted for their Initial_Version (since it's
+                       -- unlikely that we'd delete an attribute).
+
+                       if Format_Object.Attr_Initial_Version = '0' then
+                           -- Initial version, not inserted.
+--Ada.Text_IO.Put_Line ("   Attr: Normal initial version");
+                               -- Normal reference:
+                           Write_to_DB (Prefix_Kind     => 
Format_Object.Attr_Prefix_Change_Kind,
+                                        Text_Kind       => 
Format_Object.Attr_Change_Kind,
+                                        Prefix_Version  => 
Format_Object.Attr_Prefix_Version,
+                                        Text_Version    => 
Format_Object.Attr_Version,
+                                        Initial_Version => '0');
+                       else
+                           declare
+                               Disposition : ARM_Output.Change_Type;
+                               use type ARM_Output.Change_Type;
+                               PVersion : Character := 
Format_Object.Attr_Prefix_Version;
+                               PKind    : 
ARM_Database.Paragraph_Change_Kind_Type :=
+                                               
Format_Object.Attr_Prefix_Change_Kind;
+                           begin
+                               if PVersion < 
Format_Object.Attr_Initial_Version then
+                                   -- This usually happens when the prefix used
+                                   -- @PrefixType; in that case, the
+                                   -- Initial_Version is really want we want.
+                                   -- And in that case, the prefix paragraph 
number
+                                   -- is always inserted (since we can't get 
here
+                                   -- if the Initial_Version is '0').
+                                   PVersion := 
Format_Object.Attr_Initial_Version;
+                                   PKind    := ARM_Database.Inserted;
+                               end if;
+
+                               Calc_Change_Disposition (
+                                   Format_Object => Format_Object,
+                                   Version => 
Format_Object.Attr_Initial_Version,
+                                   Operation => ARM_Output.Insertion,
+                                   Text_Kind => Disposition);
+
+                               if Disposition = Do_Not_Display_Text then
+                                   null; -- Do *not* put this into the DB.
+--Ada.Text_IO.Put_Line ("   Attr: Ignore");
+                               elsif Disposition = ARM_Output.None then
+--Ada.Text_IO.Put_Line ("   Attr: Normal");
+                                   -- Normal reference:
+                                   Write_to_DB (Prefix_Kind     => PKind,
+                                                Text_Kind       => 
Format_Object.Attr_Change_Kind,
+                                                Prefix_Version  => PVersion,
+                                                Text_Version    => 
Format_Object.Attr_Version,
+                                                Initial_Version => 
Format_Object.Attr_Initial_Version);
+                               elsif Disposition = ARM_Output.Deletion then
+                                   raise Program_Error; -- A deletion inside 
of an insertion command!
+                               else -- Insertion.
+                                   -- Write inserted text:
+                                   -- We need to mark everything with
+                                   -- the kind and version of the *entire* 
insertion,
+                                   -- because the entire thing is an
+                                   -- insertion. (So we ignore the prefix kind 
and version).
+--Ada.Text_IO.Put_Line ("   Attr: Inserted version:" & 
Format_Object.Attr_Initial_Version);
+                                   if Format_Object.Attr_Leading then
+                                       ARM_Database.Insert 
(Format_Object.Attr_DB,
+                                           Sort_Key => Sort_Key,
+                                           Hang_Item =>
+                                               "@ChgAdded{Version=[" & 
Format_Object.Attr_Initial_Version & "],Text=[" &
+                                               
Format_Object.Attr_Prefix(1..Format_Object.Attr_Prefix_Len) &
+                                                  ''' & 
Format_Object.Attr_Name(1..Format_Object.Attr_Name_Len) & "]}",
+                                           Text =>
+                                               "@ChgAdded{Version=[" & 
Format_Object.Attr_Initial_Version & "],Text=[" &
+                                               "For " & 
Format_Object.Prefix_Text(1..Format_Object.Prefix_Text_Len) &
+                                               ":]}" & Ascii.LF & Ascii.LF &
+                                               ChgRef_Command 
(Format_Object.Attr_Change_Kind, Format_Object.Attr_Version, 
Format_Object.Attr_Initial_Version) &
+                                               "@address@hidden@;" & 
Text_Buffer(1..Text_Buffer_Len) &
+                                               " See @RefSecbyNum{" & 
Clause_String(Format_Object) & "}.",
+                                           Change_Kind => PKind,
+                                           Version => PVersion,
+                                           Initial_Version => 
Format_Object.Attr_Initial_Version);
+                                   else -- not leading:
+                                       ARM_Database.Insert 
(Format_Object.Attr_DB,
+                                           Sort_Key => Sort_Key,
+                                           Hang_Item =>
+                                               "@ChgAdded{Version=[" & 
Format_Object.Attr_Initial_Version & "],Text=[" &
+                                               
Format_Object.Attr_Prefix(1..Format_Object.Attr_Prefix_Len) &
+                                                  ''' & 
Format_Object.Attr_Name(1..Format_Object.Attr_Name_Len) & "]}",
+                                           Text =>
+                                               "@ChgAdded{Version=[" & 
Format_Object.Attr_Initial_Version & "],Text=[" &
+                                               "For " & 
Format_Object.Prefix_Text(1..Format_Object.Prefix_Text_Len) &
+                                               ":]}" & Ascii.LF & Ascii.LF &
+                                               ChgRef_Command 
(Format_Object.Attr_Change_Kind, Format_Object.Attr_Version, 
Format_Object.Attr_Initial_Version) &
+                                               "@noprefix@;" & 
Text_Buffer(1..Text_Buffer_Len) &
+                                               " See @RefSecbyNum{" & 
Clause_String(Format_Object) & "}.",
+                                           Change_Kind => PKind,
+                                           Version => PVersion,
+                                           Initial_Version => 
Format_Object.Attr_Initial_Version);
+                                   end if;
+                               end if;
+                           end;
+                       end if;
+                   end;
+
+               when Pragma_Syntax | Added_Pragma_Syntax | 
Deleted_Pragma_Syntax =>
+                   -- Note: Pragma_Syntax is not recorded in the syntax 
summary.
+                   declare
+                       Text_Buffer : String (1..ARM_Input.MAX_RECORDING_SIZE);
+                       Text_Buffer_Len : Natural;
+
+                       function My_Sort return String is
+                           -- Find and return the @prag argument.
+                       begin
+                           for I in 1 .. Text_Buffer_Len - 7 loop
+                               if Text_Buffer(I) = '@' and then
+                               (Text_Buffer(I+1) = 'p' or else 
Text_Buffer(I+1) = 'P') and then
+                               (Text_Buffer(I+2) = 'r' or else 
Text_Buffer(I+2) = 'R') and then
+                               (Text_Buffer(I+3) = 'a' or else 
Text_Buffer(I+3) = 'A') and then
+                               (Text_Buffer(I+4) = 'g' or else 
Text_Buffer(I+4) = 'G') and then
+                               ARM_Input.Is_Open_Char (Text_Buffer(I+5)) then
+                                   -- Found @prag.
+                                   for J in I+6 .. Text_Buffer_Len loop
+                                       if Text_Buffer(J) = 
ARM_Input.Get_Close_Char (Text_Buffer(I+5)) then
+                                           return Text_Buffer(I+6 .. J-1);
+                                       end if;
+                                   end loop;
+                                   Ada.Text_IO.Put_Line ("** Can't find 
argument for @prag: " & Text_Buffer(1..Text_Buffer_Len) &
+                                       " on line " & ARM_Input.Line_String 
(Input_Object));
+                                   return ""; -- Never found the end of the 
argument.
+                               -- else not @prag, keep looking.
+                               end if;
+                           end loop;
+                           -- If we get here, we never found "@prag"
+                           Ada.Text_IO.Put_Line ("** Funny pragma format: " & 
Text_Buffer(1..Text_Buffer_Len) &
+                               " on line " & ARM_Input.Line_String 
(Input_Object));
+                           return ""; -- Gotta return something.
+                       end My_Sort;
+
+                   begin
+                       Arm_Input.Stop_Recording_and_Read_Result
+                           (Input_Object, Text_Buffer, Text_Buffer_Len);
+                       Text_Buffer_Len := Text_Buffer_Len - 1; -- Remove 
command close character.
+                       -- Ordinary text processing is fine for the local text.
+                       if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Pragma_Syntax then
+                           ARM_Database.Insert (Format_Object.Pragma_DB,
+                               Sort_Key => My_Sort,
+                               Hang_Item => "",
+                               Text => Text_Buffer(1..Text_Buffer_Len) &
+                                   " @em See @RefSecbyNum{" & 
Clause_String(Format_Object) & "}.");
+                       elsif 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Added_Pragma_Syntax then
+                           declare
+                               Disposition : ARM_Output.Change_Type;
+                               use type ARM_Output.Change_Type;
+                           begin
+                               Calc_Change_Disposition (
+                                   Format_Object => Format_Object,
+                                   Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version,
+                                   Operation => ARM_Output.Insertion,
+                                   Text_Kind => Disposition);
+
+                               if Disposition = Do_Not_Display_Text then
+                                   null; -- Not in old versions, omit from 
Annex.
+                               elsif Disposition = ARM_Output.None then
+                                   -- Normal reference:
+                                   ARM_Database.Insert 
(Format_Object.Pragma_DB,
+                                       Sort_Key => My_Sort,
+                                       Hang_Item => "",
+                                       Text => "@ChgRef{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version &
+                                           "],Kind=[Added]}" &
+                                           Text_Buffer(1..Text_Buffer_Len) &
+                                           " @em See @RefSecbyNum{" & 
Clause_String(Format_Object) & "}.");
+                                   -- Note: We still need the @ChgRef in order
+                                   -- to get the paragraph numbers right.
+                               elsif Disposition = ARM_Output.Deletion then
+                                   raise Program_Error; -- A deletion inside 
of an insertion command!
+                               else -- Insertion.
+                                   ARM_Database.Insert 
(Format_Object.Pragma_DB,
+                                       Sort_Key => My_Sort,
+                                       Hang_Item => "",
+                                       Text => "@ChgRef{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version &
+                                           "],Kind=[Added]}" &
+                                           Text_Buffer(1..Text_Buffer_Len) &
+                                           "@Chg{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version &
+                                           "],New=[" &
+                                           " @em See @RefSecbyNum<" & 
Clause_String(Format_Object) & ">.],Old=[]}");
+                                   -- Note: Text includes any needed @Chg 
commands.
+                               end if;
+                           end;
+                       else --if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Command = 
Deleted_Pragma_Syntax then
+                           declare
+                               Add_Disposition : ARM_Output.Change_Type;
+                               Del_Disposition : ARM_Output.Change_Type;
+                               use type ARM_Output.Change_Type;
+
+                               function Para_Kind return String is
+                               begin
+                                   if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Prev_Change_Version 
= '0' and then
+                                       Add_Disposition /= ARM_Output.Insertion 
then
+                                       return "Deleted";
+                                   else
+                                       return "DeletedAdded";
+                                   end if;
+                               end Para_Kind;
+
+                           begin
+                               Calc_Change_Disposition (
+                                   Format_Object => Format_Object,
+                                   Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version,
+                                   Operation => ARM_Output.Deletion,
+                                   Text_Kind => Del_Disposition);
+                               if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Prev_Change_Version 
= '0' then
+                                   Add_Disposition := ARM_Output.None;
+                               else
+                                   Calc_Change_Disposition (
+                                       Format_Object => Format_Object,
+                                       Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Prev_Change_Version,
+                                       Operation => ARM_Output.Insertion,
+                                       Text_Kind => Add_Disposition);
+                               end if;
+
+                               if Del_Disposition = Do_Not_Display_Text then
+--Ada.Text_IO.Put_Line ("%% Deleted pragma completely omitted");
+                                   if Add_Disposition /= Do_Not_Display_Text
+                                       and then 
Format_Object.Number_Paragraphs then
+                                       -- If this was in older editions, then
+                                       -- we need a deletion message (and also
+                                       -- to get the paragraph numbers right).
+                                       -- But don't need this if there are no
+                                       -- paragraph numbers (then there is no
+                                       -- deleted message).
+--Ada.Text_IO.Put_Line ("   ... but need a deletion message");
+                                       ARM_Database.Insert 
(Format_Object.Pragma_DB,
+                                           Sort_Key => My_Sort,
+                                           Hang_Item => "",
+                                           Text => "@ChgRef{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version &
+                                               "],Kind=[" & Para_Kind & "]}@ 
");
+                                    else
+                                       null; -- Not at all in this version, 
omit from Annex.
+                                   end if;
+                               elsif Del_Disposition = ARM_Output.None then
+--Ada.Text_IO.Put_Line ("%% Deleted pragma normal format");
+                                   -- Is the initial item inserted or normal?
+                                   if Add_Disposition = ARM_Output.Insertion 
then
+--Ada.Text_IO.Put_Line ("... but inserted");
+                                       -- Inserted reference:
+                                       ARM_Database.Insert 
(Format_Object.Pragma_DB,
+                                           Sort_Key => My_Sort,
+                                           Hang_Item => "",
+                                           Text => "@ChgRef{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Prev_Change_Version &
+                                               "],Kind=[Added]}" &
+                                               Text_Buffer(1..Text_Buffer_Len) 
&
+                                               "@Chg{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Prev_Change_Version &
+                                               "],New=[" &
+                                               " @em See @RefSecbyNum<" & 
Clause_String(Format_Object) & ">.],Old=[]}");
+                                   else -- Anything else.
+                                       -- Normal reference:
+                                       if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Prev_Change_Version 
= '0' then
+                                           ARM_Database.Insert 
(Format_Object.Pragma_DB,
+                                               Sort_Key => My_Sort,
+                                               Hang_Item => "",
+                                               Text => 
Text_Buffer(1..Text_Buffer_Len) &
+                                                   " @em See @RefSecbyNum{" & 
Clause_String(Format_Object) & "}.");
+                                       else
+                                           ARM_Database.Insert 
(Format_Object.Pragma_DB,
+                                               Sort_Key => My_Sort,
+                                               Hang_Item => "",
+                                               Text => "@ChgRef{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Prev_Change_Version &
+                                                   "],Kind=[Added]}" &
+                                                   
Text_Buffer(1..Text_Buffer_Len) &
+                                                   " @em See @RefSecbyNum{" & 
Clause_String(Format_Object) & "}.");
+                                           -- Note: We still need the @ChgRef 
in order
+                                           -- to get the paragraph numbers 
right.
+                                       end if;
+                                   end if;
+                               elsif Del_Disposition = ARM_Output.Insertion 
then
+                                   raise Program_Error; -- An insertion inside 
of a deletion command!
+                               else -- Deletion.
+--Ada.Text_IO.Put_Line ("%% Deleted pragma deleted text");
+                                   -- Is the initial item inserted or normal?
+                                   if Add_Disposition = ARM_Output.Insertion 
then
+                                       ARM_Database.Insert 
(Format_Object.Pragma_DB,
+                                           Sort_Key => My_Sort,
+                                           Hang_Item => "",
+                                           Text => "@ChgRef{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version &
+                                               "],Kind=[DeletedAdded]}" &
+                                               Text_Buffer(1..Text_Buffer_Len) 
&
+                                               "@Chg{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Prev_Change_Version &
+                                               "],New=[" &
+                                               "@Chg{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version &
+                                               "],New=[],Old=[" &
+                                               " @em See @RefSecbyNum<" & 
Clause_String(Format_Object) & ">.]}],Old=[]}");
+                                   else -- Anything else.
+                                       -- Just a deleted reference:
+                                       ARM_Database.Insert 
(Format_Object.Pragma_DB,
+                                           Sort_Key => My_Sort,
+                                           Hang_Item => "",
+                                           Text => "@ChgRef{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version &
+                                               "],Kind=[" & Para_Kind & "]}" &
+                                               Text_Buffer(1..Text_Buffer_Len) 
&
+                                               "@Chg{Version=[" & 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr).Change_Version &
+                                               "],New=[],Old=[" &
+                                               " @em See @RefSecbyNum<" & 
Clause_String(Format_Object) & ">.]}");
+                                       -- Note: We still need the @ChgRef in 
order
+                                       -- to get the paragraph numbers right 
and for the deleted paragraph message.
+                                   end if;
+                               end if;
+                           end;
+
+                       end if;
+                   end;
+
+               when Implementation_Defined | Change_Impdef_Text_Param =>
+                   -- Save the implementation-defined entry in the database.
+                   Finish_and_DB_Entry (Format_Object.Impdef_DB);
+
+               when Change_Impladv_Text_Param =>
+                   -- Save the implementation advice entry in the database.
+                   Finish_and_DB_Entry (Format_Object.Impladv_DB);
+
+               when Change_Docreq_Text_Param =>
+                   -- Save the documentation requirement entry in the database.
+                   Finish_and_DB_Entry (Format_Object.Docreq_DB);
+
+               when Change_AspectDesc_Text_Param =>
+                   -- Save the documentation requirement entry in the database.
+                   Finish_and_DB_Entry (Format_Object.Aspect_DB);
+
+               when Prefix_Type | Change_Prefix_Text_Param =>
+                   -- Copy the text into the Format_Object.Prefix_Text string.
+                   ARM_Input.Stop_Recording_and_Read_Result (
+                       Input_Object,
+                       Format_Object.Prefix_Text,
+                       Format_Object.Prefix_Text_Len);
+                   Format_Object.Prefix_Text_Len :=
+                       Format_Object.Prefix_Text_Len - 1; -- Remove command 
close character.
+
+               when Change_Param_Old =>
+                   if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version >
+                       Format_Object.Change_Version then
+                       -- The new text was ignored, use the old only.
+                       null; -- Nothing special to do.
+                   else
+                       case Format_Object.Changes is
+                           when ARM_Format.Old_Only =>
+                               null; -- Nothing special to do.
+                           when ARM_Format.New_Only =>
+                               null; -- Nothing to do (we nulled out the text 
before we got here).
+                           when ARM_Format.Show_Changes |
+                                ARM_Format.New_Changes =>
+                               if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version <
+                                   Format_Object.Base_Change_Version then
+                                   -- Old enough that only the new text is 
shown.
+                                   null; -- Nothing to do (we nulled out the 
text before we got here).
+                               else
+                                   if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Was_Text then
+                                       -- Non-empty text. Restore the previous
+                                       -- insertion state.
+                                       Format_Object.Text_Format.Change :=
+                                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Prev_Change;
+                                       Format_Object.Text_Format.Version :=
+                                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Prev_Change_Version;
+                                       Format_Object.Text_Format.Added_Version 
:=
+                                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Prev_Added_Change_Version;
+
+                                       Check_Paragraph; -- We have to be in a 
paragraph
+                                           -- in correct code, but this could 
happen
+                                           -- if the user ended the paragraph 
by mistake
+                                           -- (we've already generated an 
error in that case).
+                                       ARM_Output.Text_Format (Output_Object,
+                                                               
Format_Object.Text_Format);
+                                   -- else no text.
+                                   end if;
+                               end if;
+                       end case;
+                   end if;
+                   Format_Object.In_Change :=
+                       Arm_Output."/=" (Format_Object.Text_Format.Change, 
ARM_Output.None);
+
+               when Change_Param_New =>
+                   if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version >
+                      Format_Object.Change_Version then
+                       -- The new text was ignored.
+                       null; -- Nothing to do (we nulled out the text before 
we got here).
+                   else
+                       case Format_Object.Changes is
+                           when ARM_Format.Old_Only =>
+                               null; -- Nothing to do (we nulled out the text 
before we got here).
+                           when ARM_Format.New_Only =>
+                               null; -- Nothing special to do.
+                           when ARM_Format.Show_Changes |
+                                ARM_Format.New_Changes =>
+                               if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version <
+                                   Format_Object.Base_Change_Version then
+                                   -- Old enough that only the new text is 
shown.
+                                   null; -- Nothing special to do.
+                               else
+                                   if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Was_Text then
+                                       -- Non-empty text. Restore the previous
+                                       -- insertion state.
+                                       Format_Object.Text_Format.Change :=
+                                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Prev_Change;
+                                       Format_Object.Text_Format.Version :=
+                                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Prev_Change_Version;
+                                       Format_Object.Text_Format.Added_Version 
:=
+                                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Prev_Added_Change_Version;
+
+                                       Check_Paragraph; -- We have to be in a 
paragraph
+                                           -- in correct code, but this could 
happen
+                                           -- if the user ended the paragraph 
by mistake
+                                           -- (we've already generated an 
error in that case).
+                                       ARM_Output.Text_Format (Output_Object,
+                                                               
Format_Object.Text_Format);
+                                   -- else no text.
+                                   end if;
+                               end if;
+                       end case;
+                   end if;
+
+                   Format_State.Nesting_Stack_Ptr := 
Format_State.Nesting_Stack_Ptr - 1;
+                   -- Unstack the "New" parameter.
+--Ada.Text_IO.Put_Line (" &Unstack (Chg New)");
+
+                   -- Check and handle the following "Old" parameter:
+                   declare
+                       Ch, Ch2 : Character;
+                   begin
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Old" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Ch);
+                       if Ch /= ' ' then -- There is a parameter.
+                           -- Stack the parameter so we can process the end:
+                           Set_Nesting_for_Parameter
+                               (Command => Change_Param_Old,
+                                Close_Ch => Ch);
+
+                           -- Now, handle the parameter:
+                           if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version >
+                               Format_Object.Change_Version then
+                               -- The new text was ignored, show the old only.
+                               null; -- Nothing special to do.
+                           else
+                               case Format_Object.Changes is
+                                   when ARM_Format.Old_Only =>
+                                       null; -- Nothing special to do.
+                                   when ARM_Format.New_Only =>
+                                       -- Skip the text:
+                                       ARM_Input.Skip_until_Close_Char 
(Input_Object, Ch);
+                                       ARM_Input.Replace_Char (Input_Object); 
-- Let the normal termination clean this up.
+                                   when ARM_Format.Show_Changes |
+                                        ARM_Format.New_Changes =>
+                                       if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version <
+                                           Format_Object.Base_Change_Version 
then
+                                           -- Old enough that only the new 
text is shown.
+                                           -- Skip the text:
+                                           ARM_Input.Skip_until_Close_Char 
(Input_Object, Ch);
+                                           ARM_Input.Replace_Char 
(Input_Object); -- Let the normal termination clean this up.
+                                       else
+                                           ARM_Input.Get_Char (Input_Object, 
Ch2);
+                                           ARM_Input.Replace_Char 
(Input_Object);
+                                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Was_Text :=
+                                               Ch /= Ch2;
+                                           if 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Was_Text then
+                                               -- Non-empty text; calculate 
new change state: (current is deletion)
+                                               Check_Paragraph; -- Output the 
paragraph headers before changing the state.
+                                                   -- This can only matter for 
a deletion without
+                                                   -- an insertion; otherwise, 
we're already in a paragraph.
+                                               case 
Format_Object.Text_Format.Change is
+                                                   when ARM_Output.Deletion | 
ARM_Output.None =>
+                                                       
Format_Object.Text_Format.Change := ARM_Output.Deletion;
+                                                       
Format_Object.Text_Format.Version :=
+                                                           
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version;
+                                                       
Format_Object.Text_Format.Added_Version := '0';
+                                                   when ARM_Output.Insertion =>
+                                                       
Format_Object.Text_Format.Change := ARM_Output.Both;
+                                                       
Format_Object.Text_Format.Added_Version :=
+                                                           
Format_Object.Text_Format.Version;
+                                                       
Format_Object.Text_Format.Version :=
+                                                          
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version;
+                                                   when ARM_Output.Both =>
+                                                       
Format_Object.Text_Format.Change := ARM_Output.Both;
+                                                       -- Added_Version is 
unchanged.
+                                                       
Format_Object.Text_Format.Version :=
+                                                          
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version;
+                                               end case;
+                                               ARM_Output.Text_Format 
(Output_Object,
+                                                                       
Format_Object.Text_Format);
+                                               if Format_Object.Changes = 
ARM_Format.New_Changes then
+                                                   
ARM_Output.Ordinary_Character (Output_Object, ' ');
+                                                   -- Skip the text (we're not 
going to output it):
+                                                   
ARM_Input.Skip_until_Close_Char (Input_Object, Ch);
+                                                   ARM_Input.Replace_Char 
(Input_Object); -- Let the normal termination clean this up.
+                                               -- else if 
Format_Object.Changes = ARM_Format.Show_Changes then
+                                               --    Nothing else needed.
+                                               end if;
+                                           -- else no text, so don't emit a 
change area.
+                                           end if;
+                                       end if;
+                               end case;
+                           end if;
+                           Format_Object.In_Change := True;
+
+                       -- else no parameter. Weird.
+                       end if;
+                       return; -- We've already done the unstacking.
+                   end;
+
+               when Change_Added_Param =>
+                   declare
+                       Disposition : ARM_Output.Change_Type;
+                       use type ARM_Output.Change_Type;
+                   begin
+                       Format_Object.In_Change := False;
+
+                       Calc_Change_Disposition (
+                           Format_Object => Format_Object,
+                           Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version,
+                           Operation => ARM_Output.Insertion,
+                           Text_Kind => Disposition);
+
+                       if Disposition = Do_Not_Display_Text then
+                           -- The new text was ignored.
+                           null; -- Nothing to do (we nulled out the text 
before we got here).
+                       elsif Disposition = ARM_Output.None then
+                           -- Display the text normally.
+                           null; -- Nothing special to do.
+                       elsif Disposition = ARM_Output.Deletion then
+                           raise Program_Error; -- A deletion inside of an 
insertion command!
+                       else -- Insertion.
+                           -- Reset the state to normal:
+                           Format_Object.Text_Format.Change := ARM_Output.None;
+                           Format_Object.Text_Format.Version := '0';
+                           Format_Object.Text_Format.Added_Version := '0';
+
+                           Check_Paragraph; -- We have to be in a paragraph
+                               -- in correct code, but this could happen
+                               -- if the user ended the paragraph by mistake
+                               -- (we've already generated an error in that 
case).
+                           ARM_Output.Text_Format (Output_Object,
+                                                   Format_Object.Text_Format);
+                       end if;
+                   end;
+
+               when Change_Deleted_Param =>
+                   declare
+                       Disposition : ARM_Output.Change_Type;
+                       use type ARM_Output.Change_Type;
+                   begin
+                       Format_Object.In_Change := False;
+
+                       Calc_Change_Disposition (
+                           Format_Object => Format_Object,
+                           Version => 
Format_State.Nesting_Stack(Format_State.Nesting_Stack_Ptr-1).Change_Version,
+                           Operation => ARM_Output.Deletion,
+                           Text_Kind => Disposition);
+
+                       if Disposition = Do_Not_Display_Text then
+                           -- The old text was ignored.
+                           null; -- Nothing to do (we nulled out the text 
before we got here).
+                       elsif Disposition = ARM_Output.None then
+                           -- Display the text normally.
+                           null; -- Nothing special to do.
+                       elsif Disposition = ARM_Output.Insertion then
+                           raise Program_Error; -- An insertion inside of a 
deletion command!
+                       else -- Insertion.
+                           -- Reset the state to normal:
+                           Format_Object.Text_Format.Change := ARM_Output.None;
+                           Format_Object.Text_Format.Version := '0';
+                           Format_Object.Text_Format.Added_Version := '0';
+
+                           Check_Paragraph; -- We have to be in a paragraph
+                               -- in correct code, but this could happen
+                               -- if the user ended the paragraph by mistake
+                               -- (we've already generated an error in that 
case).
+                           ARM_Output.Text_Format (Output_Object,
+                                                   Format_Object.Text_Format);
+                       end if;
+                   end;
+
+               when Ceiling =>
+                    Check_Paragraph;
+                    ARM_Output.Special_Character (Output_Object, 
ARM_Output.Right_Ceiling);
+                    Format_Object.Last_Non_Space := True;
+
+               when Floor =>
+                    Check_Paragraph;
+                    ARM_Output.Special_Character (Output_Object, 
ARM_Output.Right_Floor);
+                    Format_Object.Last_Non_Space := True;
+
+               when Absolute =>
+                    Check_Paragraph;
+                    ARM_Output.Ordinary_Character (Output_Object, '|');
+                    Format_Object.Last_Non_Space := True;
+
+               when Log =>
+                    Check_Paragraph;
+                    ARM_Output.Ordinary_Character (Output_Object, ')');
+                    Format_Object.Last_Non_Space := True;
+
+               when others =>
+                   -- No special handling needed.
+                   null;
+           end case;
+--Ada.Text_IO.Put_Line (" &Unstack (Normal)");
+           Format_State.Nesting_Stack_Ptr := Format_State.Nesting_Stack_Ptr - 
1;
+       end Handle_End_of_Command;
+
+
+       procedure Process_Special is
+           -- Process a special command/macro/tab.
+           -- These all start with '@'.
+           -- @xxxx is a command. It may have parameters delimited by
+           -- (), {}, [], or <>. There does not appear to be an escape, so
+           -- we don't have to worry about '}' being used in {} brackets,
+           -- for example. (Must be a pain to write, though.)
+           Command_Name : ARM_Input.Command_Name_Type;
+           Ch : Character;
+           use type ARM_Output.Size_Type;
+       begin
+           ARM_Input.Get_Char (Input_Object, Ch);
+           if Ch = '\' then
+               -- This represents a tab, or the end of centered text.
+               -- (According to Bob Duff, from the Scribe manual).
+               if Format_Object.Next_Paragraph_Format_Type = 
Hanging_Indented_1 or else
+                  Format_Object.Next_Paragraph_Format_Type = 
Hanging_Indented_2 or else
+                  Format_Object.Next_Paragraph_Format_Type = 
Hanging_Indented_3 or else
+                  Format_Object.Next_Paragraph_Format_Type = 
Hanging_Indented_4 then
+                   -- Instead of a tab, just use this to mark the end
+                   -- of the hanging portion:
+                   Check_Paragraph;
+                   if Format_Object.In_Change then
+                       -- Close all formatting:
+                       declare
+                           Closed_Formatting : ARM_Output.Format_Type :=
+                               ARM_Output.NORMAL_FORMAT;
+                       begin
+                           Closed_Formatting.Font := 
Format_Object.Text_Format.Font; -- No clear default for these.
+                           Closed_Formatting.Size := 
Format_Object.Text_Format.Size;
+
+                           ARM_Output.Text_Format (Output_Object,
+                                                   Closed_Formatting);
+                       end;
+                   end if;
+                   ARM_Output.End_Hang_Item (Output_Object);
+                   if Format_Object.In_Change then
+                       -- Reset to the normal case:
+                       ARM_Output.Text_Format (Output_Object,
+                                               Format_Object.Text_Format);
+                   end if;
+               elsif Format_Object.Next_Paragraph_Format_Type = In_Table then
+                   -- If in a table, ends a item.
+                   ARM_Output.Table_Marker (Output_Object, 
ARM_Output.End_Item);
+               -- elsif centered text: TBD.
+               elsif ARM_Output."="(Format_Object.Paragraph_Tab_Stops, 
ARM_Output.NO_TABS) then
+                   Ada.Text_IO.Put_Line ("  ** Tab, but no tab stops set on 
line " &
+                        ARM_Input.Line_String (Input_Object));
+               else
+                   Check_Paragraph;
+                   ARM_Output.Tab (Output_Object);
+               end if;
+               return; -- We're done here.
+           elsif Ch = '=' then
+               -- This marks the start of centered text.
+               -- (According to Bob Duff, from the Scribe manual).
+               -- We're not implementing this; we're just going to replace
+               -- the handful of uses.
+               -- We're done here.
+               Ada.Text_IO.Put_Line ("  ** Centered text unimplemented 
(skipped) on line " &
+                    ARM_Input.Line_String (Input_Object));
+               return;
+           elsif Ch = '^' then
+               -- This represents setting at tab stop at the current location.
+               -- Neither HTML nor RTF supports such a thing, so these should
+               -- all have been replaced by conventional tab stops.
+               Ada.Text_IO.Put_Line ("  && Cursor tab stop unimplemented 
(skipped) on line " &
+                    ARM_Input.Line_String (Input_Object));
+               return;
+           elsif Ch = '@' then
+               -- This represents @ in the text. We're done here.
+               Check_Paragraph;
+               ARM_Output.Ordinary_Character (Output_Object, '@');
+               return;
+           elsif Ch = ' ' then
+               -- This represents a hard space in the text. We're done here.
+               Check_Paragraph;
+               ARM_Output.Hard_Space (Output_Object);
+               return;
+           elsif Ch = ';' then
+               -- This seems to be an end of command (or substitution) marker.
+               -- For instance, it is used in Section 1:
+               -- .. the distinction between @ResolutionName@;s and ...
+               -- This converts to:
+               -- .. the distinction between Name Resolution Rules and ...
+               -- Without it, the 's' would append to the command name, and
+               -- we would get the wrong command. Thus, it itself does nothing
+               -- at all, so we're done here.
+               return;
+           elsif Ch = '-' then
+               -- This represents a subscript. It has an argument.
+               ARM_Input.Get_Char (Input_Object, Ch);
+               if ARM_Input.Is_Open_Char (Ch) then -- Start parameter:
+                   Set_Nesting_for_Command
+                       (Name => '-' & (2..ARM_Input.Command_Name_Type'Last => 
' '),
+                        Kind => Normal,
+                        Param_Ch => Ch);
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Size :=
+                       Format_Object.Text_Format.Size - 2;
+                   Format_Object.Text_Format.Location := ARM_Output.Subscript;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format_Object.Text_Format);
+               else -- No parameter. Weird.
+                   ARM_Input.Replace_Char (Input_Object);
+                   Ada.Text_IO.Put_Line ("  ** Failed to find parameter for 
subscript, line " & ARM_Input.Line_String (Input_Object));
+               end if;
+               return;
+           elsif Ch = '+' then
+               -- This represents a superscript. It has an argument.
+               ARM_Input.Get_Char (Input_Object, Ch);
+               if ARM_Input.Is_Open_Char (Ch) then -- Start parameter:
+                   Set_Nesting_for_Command
+                       (Name => '+' & (2..ARM_Input.Command_Name_Type'Last => 
' '),
+                        Kind => Normal,
+                        Param_Ch => Ch);
+                   Check_Paragraph;
+                   Format_Object.Text_Format.Size :=
+                       Format_Object.Text_Format.Size - 2;
+                   Format_Object.Text_Format.Location := 
ARM_Output.Superscript;
+                   ARM_Output.Text_Format (Output_Object,
+                                           Format_Object.Text_Format);
+               else -- No parameter. Weird.
+                   ARM_Input.Replace_Char (Input_Object);
+                   Ada.Text_IO.Put_Line ("  ** Failed to find parameter for 
superscript, line " & ARM_Input.Line_String (Input_Object));
+               end if;
+               return;
+           elsif Ch = ':' then
+               -- According to Tucker, the Scribe manual says:
+               -- @:  After a ".", it forces the "." to be interpreted as a
+               --     sentence-ending period rather than as an initial-ending
+               --     period.  E.g.: You are better than I.@:  F. Stone is
+               --     even better. Without the @:, the period after "I"
+               --     would be interpreted as the period signifying an
+               --     initial.
+               --
+               -- Besides not making much sense, this certainly does nothing
+               -- for us.
+               return;
+           elsif Ch = '*' then
+               -- According to Tucker, the Scribe manual says:
+               -- @*  This forces a line break, without starting a new
+               --     paragraph.
+               -- Tucker thinks this is "<BR>" in HTML.
+               if Format_Object.In_Paragraph then
+                   ARM_Output.Line_Break (Output_Object);
+                   Format_Object.Last_Non_Space := False;
+               -- else why start a paragraph with a line break??
+               end if;
+               return;
+           elsif Ch = '|' then
+               -- According to Tucker, the Scribe manual says:
+               -- @|  This marks a place within a word where a line break
+               --     may be inserted, *without* inserting a hyphen.  It is
+               --     effectively a zero-length "word".  You can use it to add
+               --     spaces between words that disappear if the line gets
+               --     broken there.  For example:
+               --        This is @| a sentence with two spaces between "is" 
and "a".
+               --     The extra space will disappear if the line is broken
+               --     between "is" and "a".
+               --
+               -- However, this appears to be used mainly to insert potential
+               -- line breaks into large words, and we use and implement it
+               -- that way.
+               if Format_Object.In_Paragraph then
+                   ARM_Output.Soft_Line_Break (Output_Object);
+                   Format_Object.Last_Non_Space := False;
+               -- else don't care about non-required breaks between paragraphs.
+               end if;
+               return;
+           elsif Ch = '!' then
+               -- This marks a place within a word where a line break
+               -- may be inserted, inserting a hyphen.
+               if Format_Object.In_Paragraph then
+                   ARM_Output.Soft_Hyphen_Break (Output_Object);
+                   Format_Object.Last_Non_Space := False;
+               -- else don't care about non-required breaks between paragraphs.
+               end if;
+               return;
+           elsif Ch = Ascii.LF then
+               -- Stand alone '@'.
+               -- I now believe this is an error, perhaps a hard space where
+               -- the trailing blank was dropped. It originally appeared in
+               -- Infosys.MSS.
+               Ada.Text_IO.Put_Line("** Stand-alone '@' on line " & 
ARM_Input.Line_String (Input_Object));
+               return;
+           end if;
+           ARM_Input.Replace_Char (Input_Object);
+           ARM_Input.Get_Name (Input_Object, Command_Name);
+--Ada.Text_IO.Put_Line("!!Command=" & Ada.Strings.Fixed.Trim(Command_Name, 
Ada.Strings.Both));
+
+           ARM_Input.Get_Char (Input_Object, Ch);
+           if ARM_Input.Is_Open_Char (Ch) then -- Start parameter:
+               Set_Nesting_for_Command
+                   (Name => Ada.Characters.Handling.To_Lower (Command_Name),
+                    Kind => Normal,
+                    Param_Ch => Ch);
+               Process_Command_with_Parameter;
+           else
+               ARM_Input.Replace_Char (Input_Object);
+               Process_Command_without_Parameter (Command_Name);
+           end if;
+       end Process_Special;
+
+
+       procedure Lookahead_for_End_of_Paragraph is
+           -- Look at the command following to see if it would
+           -- end the paragraph. If not, generate a Line_Break.
+           -- In any case, process the command (we don't allow more than
+           -- one call to Replace_Char).
+           -- We can assume that we are in a paragraph.
+           Command_Name : ARM_Input.Command_Name_Type;
+           Ch : Character;
+       begin
+           ARM_Input.Get_Char (Input_Object, Ch);
+           if Ch not in 'A' .. 'Z' and then Ch not in 'a' .. 'z' then
+               -- Not a named command, these never end a paragraph:
+               ARM_Input.Replace_Char (Input_Object);
+               ARM_Output.Line_Break (Output_Object);
+               Format_Object.Last_Non_Space := False;
+               Process_Special;
+           else -- Named command.
+               ARM_Input.Replace_Char (Input_Object);
+               ARM_Input.Get_Name (Input_Object, Command_Name);
+
+               case Command (Command_Name) is
+                   when Text_Begin | Text_End | New_Page | New_Column | 
RM_New_Page |
+                       Thin_Line | Thick_Line | Table | Picture_Alone |
+                       To_Glossary | Change_To_Glossary |
+                       Implementation_Defined |
+                       Change_Implementation_Defined |
+                       Change_Implementation_Advice |
+                       Change_Documentation_Requirement |
+                       Labeled_Section |
+                       Labeled_Section_No_Break |
+                       Labeled_Clause | Labeled_Subclause | 
Labeled_Subsubclause |
+                       Labeled_Revised_Section | Labeled_Revised_Clause |
+                       Labeled_Revised_Subclause | 
Labeled_Revised_Subsubclause |
+                       Labeled_Added_Section | Labeled_Added_Clause |
+                       Labeled_Added_Subclause | Labeled_Added_Subsubclause |
+                       Labeled_Deleted_Clause |
+                       Labeled_Deleted_Subclause | 
Labeled_Deleted_Subsubclause |
+                       Preface_Section |
+                       Labeled_Annex | Labeled_Revised_Annex | 
Labeled_Added_Annex |
+                       Labeled_Informative_Annex |
+                       Labeled_Revised_Informative_Annex | 
Labeled_Added_Informative_Annex |
+                       Labeled_Normative_Annex |
+                       Labeled_Revised_Normative_Annex | 
Labeled_Added_Normative_Annex |
+                       Unnumbered_Section | Subheading | Heading | Center | 
Right =>
+                       -- Ends a paragraph. No line break needed here (or
+                       -- we'd end up with two).
+                       null;
+                   when others =>
+                       -- Does not end a paragraph. Put in the soft break.
+                       ARM_Output.Line_Break (Output_Object);
+                       Format_Object.Last_Non_Space := False;
+               end case;
+
+               -- Now, process the command:
+               ARM_Input.Get_Char (Input_Object, Ch);
+               if ARM_Input.Is_Open_Char (Ch) then -- Start parameter:
+                   Set_Nesting_for_Command
+                       (Name => Ada.Characters.Handling.To_Lower 
(Command_Name),
+                        Kind => Normal,
+                        Param_Ch => Ch);
+                   Process_Command_with_Parameter;
+               else
+                   ARM_Input.Replace_Char (Input_Object);
+                   Process_Command_without_Parameter (Command_Name);
+               end if;
+           end if;
+       end Lookahead_for_End_of_Paragraph;
+
+    begin
+        Reading_Loop: loop
+           declare
+               Char : Character;
+           begin
+               ARM_Input.Get_Char (Input_Object, Char);
+--Ada.Text_IO.Put_Line("!!Char=" & Char & " Nesting=" & 
Natural'Image(Format_State.Nesting_Stack_Ptr));
+               case Char is
+                   when '@' =>
+                       Process_Special;
+                   when Ascii.LF =>
+                       ARM_Input.Get_Char (Input_Object, Char);
+                       if Char /= Ascii.LF then
+                           -- Soft line break.
+                           if Format_Object.Next_Paragraph_Format_Type = 
Example_Text or else
+                              Format_Object.Next_Paragraph_Format_Type = 
Child_Example_Text or else
+                              Format_Object.Next_Paragraph_Format_Type = 
Indented_Example_Text or else
+                              Format_Object.Next_Paragraph_Format_Type = 
Display or else
+                              Format_Object.Next_Paragraph_Format_Type = 
Syntax_Display or else
+                              Format_Object.Next_Paragraph_Format_Type = 
Syntax_Production then
+                               -- These formats preserves all line breaks, but 
a
+                               -- "soft" break does not end a paragraph.
+                               if Char /= '@' or else (not 
Format_Object.In_Paragraph) then
+                                   -- Not a paragraph end coming up:
+                                   if Format_Object.In_Paragraph then
+                                       ARM_Output.Line_Break (Output_Object);
+                                       Format_Object.Last_Non_Space := False;
+                                   -- else not in paragraph, we don't need to 
preserve
+                                   -- the break.
+                                   end if;
+                                   ARM_Input.Replace_Char (Input_Object);
+                               else
+                                   -- A command following, and we're in a 
paragraph.
+                                   -- If that command ends the paragraph, then
+                                   -- we don't want a soft break here (else 
we'd
+                                   -- end up with an extra blank line at the 
end).
+                                   -- Otherwise, we do.
+                                   Lookahead_for_End_of_Paragraph;
+                               end if;
+                           elsif Format_Object.Next_Paragraph_Format_Type = 
In_Table then
+                               -- If in a table, ends a row.
+                               ARM_Output.Table_Marker (Output_Object, 
ARM_Output.End_Row);
+                               ARM_Input.Replace_Char (Input_Object);
+                               Format_Object.Last_Non_Space := False;
+                               -- There should be nothing above the table at
+                               -- this point. Complain about other commands
+                               -- (this is a signficant aid to building 
tables):
+                               declare
+                                   Start_Depth : Natural := 1;
+                               begin
+                                   --Find the table:
+                                   for I in reverse 1 .. 
Format_State.Nesting_Stack_Ptr loop
+                                       if 
Format_State.Nesting_Stack(I).Command = Table then
+                                           Start_Depth := I;
+                                           exit;
+                                       end if;
+                                   end loop;
+                                   if 
Format_State.Nesting_Stack(Start_Depth+1).Command /= Table_Param_Body then
+                                       Ada.Text_IO.Put_Line ("   ** Wrong 
command on top of table, line " & ARM_Input.Line_String (Input_Object));
+                                       Ada.Text_IO.Put_Line ("      Command=" 
& Format_State.Nesting_Stack(Start_Depth+1).Name & " Class=" &
+                                           
Data.Command_Type'Image(Format_State.Nesting_Stack(Start_Depth+1).Command));
+                                   elsif Format_State.Nesting_Stack_Ptr /= 
Start_Depth+1 then
+                                       Ada.Text_IO.Put_Line ("   ** Unfinished 
commands detected at end of row, line " & ARM_Input.Line_String (Input_Object));
+                                   end if;
+                                   for I in reverse Start_Depth+2 .. 
Format_State.Nesting_Stack_Ptr loop
+                                       Ada.Text_IO.Put_Line ("      Open 
command=" &
+                                           Format_State.Nesting_Stack(I).Name 
& " Class=" &
+                                           
Data.Command_Type'Image(Format_State.Nesting_Stack(I).Command));
+                                   end loop;
+                               end;
+
+                           else -- Normal paragraph:
+                               -- Output a space if the last character was
+                               -- not a space and the next character is
+                               -- not a space. Eliminate any leading blanks
+                               -- added for formatting:
+                               if Format_Object.In_Paragraph and then
+                                  Format_Object.Last_Non_Space then
+                                   ARM_Output.Ordinary_Character 
(Output_Object, ' ');
+                                   Format_Object.Last_Non_Space := False;
+                               end if;
+                               -- Skip any leading spaces for the next 
paragraph:
+                               while Char = ' ' loop
+                                   ARM_Input.Get_Char (Input_Object, Char);
+                               end loop;
+                               ARM_Input.Replace_Char (Input_Object);
+                           end if;
+                       else -- Hard paragraph break. Only one, no matter
+                           -- how many blank lines there are:
+                           while Char = Ascii.LF loop
+                               ARM_Input.Get_Char (Input_Object, Char);
+                           end loop;
+                           if Format_Object.Next_Paragraph_Format_Type = 
Example_Text or else
+                              Format_Object.Next_Paragraph_Format_Type = 
Child_Example_Text or else
+                              Format_Object.Next_Paragraph_Format_Type = 
Indented_Example_Text or else
+                              Format_Object.Next_Paragraph_Format_Type = 
Display or else
+                              Format_Object.Next_Paragraph_Format_Type = 
Syntax_Display or else
+                              Format_Object.Next_Paragraph_Format_Type = 
Syntax_Production then
+                               null; -- In these formats, blanks remain.
+                           else
+                               -- Also remove any leading blanks from the next
+                               -- paragraph:
+                               while Char = ' ' loop
+                                   ARM_Input.Get_Char (Input_Object, Char);
+                               end loop;
+                           end if;
+                           ARM_Input.Replace_Char (Input_Object);
+                           Check_End_Paragraph; -- End the paragraph.
+                       end if;
+                   when ' ' =>
+                       if Format_Object.Next_Paragraph_Format_Type = 
Example_Text or else
+                          Format_Object.Next_Paragraph_Format_Type = 
Child_Example_Text or else
+                          Format_Object.Next_Paragraph_Format_Type = 
Indented_Example_Text or else
+                          Format_Object.Next_Paragraph_Format_Type = Display 
or else
+                          Format_Object.Next_Paragraph_Format_Type = 
Syntax_Display or else
+                          Format_Object.Next_Paragraph_Format_Type = 
Syntax_Production then
+                           -- Spaces are significant these formats.
+                           Check_Paragraph;
+                           ARM_Output.Hard_Space (Output_Object);
+                       else
+                           if Format_Object.In_Paragraph then
+                               if Format_Object.No_Start_Paragraph then
+                                   -- Not really in a paragraph.
+Ada.Text_IO.Put_Line ("Attempt to write into a deleted paragraph, on line " & 
ARM_Input.Line_String (Input_Object));
+                                   -- We'll probably crash soon.
+                                   null;
+                               else
+                                   ARM_Output.Ordinary_Character 
(Output_Object, ' ');
+                               end if;
+                           -- else we never want to start a paragraph with a 
space.
+                           end if;
+                       end if;
+                       Format_Object.Last_Non_Space := False;
+                   when Ascii.SUB =>
+                       -- End of file.
+                       exit Reading_Loop;
+                   when others =>
+                       if Format_State.Nesting_Stack_Ptr /= 0 and then
+                          Format_State.Nesting_Stack 
(Format_State.Nesting_Stack_Ptr).Close_Char /= ' ' and then
+                          Format_State.Nesting_Stack 
(Format_State.Nesting_Stack_Ptr).Close_Char = Char then
+                           -- Closing a command, remove it from the stack.
+                           Handle_End_of_Command;
+                       else
+                           Check_Paragraph;
+                           ARM_Output.Ordinary_Character (Output_Object, Char);
+                           null; -- Ordinary characters, output them.
+                           Format_Object.Last_Non_Space := True;
+                       end if;
+               end case;
+           end;
+        end loop Reading_Loop;
+    exception
+       when ARM_Output.Not_Valid_Error =>
+           Ada.Text_IO.Put_Line ("** Output validity error processing line " & 
ARM_Input.Line_String (Input_Object));
+           raise;
+    end Real_Process;
+
+
+    procedure Process (Format_Object : in out Format_Type;
+                      File_Name : in String;
+                      Output_Object : in out ARM_Output.Output_Type'Class;
+                      Section_Name : in String;
+                      Section_Number : in ARM_Contents.Section_Number_Type;
+                      Starts_New_Section : in Boolean) is
+       -- Process the contents for File_Name, writing the results to
+       -- Output_Object. (Output_Object uses dispatching calls to provide
+       -- the correct formatting). Section_Name is the name of the section
+       -- for this file. Starts_New_Section is True if the file starts
+       -- a new section. Section_Number is the number (or letter) of the
+       -- section. Values > 20 represent annex letters (21 => A, 22 => B, etc.)
+       Input_Object : Arm_File.File_Input_Type;
+       Format_State : Format_State_Type;
+    begin
+       Ada.Text_IO.Put_Line ("-- Processing " & File_Name);
+       begin
+           Arm_File.Open (Input_Object, File_Name);
+       exception
+           when others =>
+               Ada.Text_IO.Put_Line ("** Unable to open file " & File_Name);
+               raise;
+       end;
+       if Starts_New_Section then
+           Format_Object.Clause_Number := (Section => Section_Number,
+               Clause => 0, Subclause => 0, Subsubclause => 0);
+           declare
+               use type ARM_Contents.Section_Number_Type;
+           begin
+               if Section_Number = 0 then -- No title at all.
+                   ARM_Output.Section (Output_Object,
+                                       Section_Title => "",
+                                       Section_Name => Section_Name);
+               elsif Section_Number < ARM_Contents.ANNEX_START then
+                   ARM_Output.Section (Output_Object,
+                                       Section_Title => Ada.Strings.Fixed.Trim 
(
+                                                        
ARM_Contents.Lookup_Title (ARM_Contents.Section,
+                                                               (Section => 
Section_Number, others => 0)), Ada.Strings.Right),
+                                       Section_Name => Section_Name);
+               else
+                   -- We don't have a way to tell between the three kinds of 
annexes, so we try them all:
+                   begin
+                       ARM_Output.Section (Output_Object,
+                                           Section_Title => 
Ada.Strings.Fixed.Trim (
+                                                            
ARM_Contents.Lookup_Title (ARM_Contents.Normative_Annex,
+                                                                   (Section => 
Section_Number, others => 0)), Ada.Strings.Right),
+                                           Section_Name => Section_Name);
+                   exception
+                       when ARM_Contents.Not_Found_Error =>
+                           begin
+                                ARM_Output.Section (Output_Object,
+                                                   Section_Title => 
Ada.Strings.Fixed.Trim (
+                                                                    
ARM_Contents.Lookup_Title (ARM_Contents.Informative_Annex,
+                                                                           
(Section => Section_Number, others => 0)), Ada.Strings.Right),
+                                                   Section_Name => 
Section_Name);
+                           exception
+                               when ARM_Contents.Not_Found_Error =>
+                                   ARM_Output.Section (Output_Object,
+                                                       Section_Title => 
Ada.Strings.Fixed.Trim (
+                                                                        
ARM_Contents.Lookup_Title (ARM_Contents.Plain_Annex,
+                                                                               
(Section => Section_Number, others => 0)), Ada.Strings.Right),
+                                                       Section_Name => 
Section_Name);
+                                   -- If this fails, too, we just propagate to 
the outer handler.
+                           end;
+                   end;
+               end if;
+           exception
+               when ARM_Contents.Not_Found_Error =>
+                   Ada.Text_IO.Put_Line ("** Unable to find section title, 
line " & ARM_File.Line_String (Input_Object));
+           end;
+           Format_Object.Next_Note := 1;
+           Format_Object.Next_Paragraph := 1;
+           Format_Object.Next_Insert_Para := 1;
+           Format_Object.Next_AARM_Sub := 'a';
+           Format_Object.Next_Enumerated_Num := 1;
+           Format_Object.Enumerated_Level := 0;
+
+           Format_Object.Text_Format := ARM_Output.NORMAL_FORMAT;
+
+           Format_Object.No_Prefix := False;
+           Format_Object.No_Para_Num := False;
+           Format_Object.Keep_with_Next := False;
+           Format_Object.Space_After := ARM_Output.Normal;
+           Format_Object.No_Breaks := False;
+           Format_Object.In_Change := False;
+           Format_Object.Last_Non_Space := False;
+
+           Format_Object.Next_Paragraph_Change_Kind := ARM_Database.None;
+
+           Format_Object.Style := ARM_Output.Normal; -- The default.
+           Format_Object.Indent := 0; -- No indent to start.
+           Format_Object.In_Paragraph := False;
+           Format_Object.No_Start_Paragraph := False;
+       end if;
+
+       Real_Process (Format_Object, Format_State, Input_Object, Output_Object);
+
+       -- Reached end of the file/input object.
+       -- Kill any open paragraph:
+       if Format_Object.In_Paragraph and then (not 
Format_Object.No_Start_Paragraph) then
+           ARM_Output.End_Paragraph (Output_Object);
+           Format_Object.In_Paragraph := False;
+           Format_Object.No_Start_Paragraph := False;
+        end if;
+       Ada.Text_IO.Put_Line ("  Lines processed: " &
+               ARM_File.Line_String (Input_Object));
+       Arm_File.Close (Input_Object);
+       if Format_State.Nesting_Stack_Ptr /= 0 then
+           Ada.Text_IO.Put_Line ("   ** Unfinished commands detected.");
+           for I in reverse 1 .. Format_State.Nesting_Stack_Ptr loop
+               Ada.Text_IO.Put_Line ("      Open command=" &
+                   Format_State.Nesting_Stack(I).Name);
+           end loop;
+       end if;
+    end Process;
+
+
+    procedure Format (Format_Object : in out Format_Type;
+                     Text : in String;
+                     Output_Object : in out ARM_Output.Output_Type'Class;
+                     Text_Name : in String;
+                     No_Annotations : in Boolean) is
+       -- Format the contents of Text, writing the results to
+       -- Output_Object. (Output_Object uses dispatching calls to provide
+       -- the correct formatting). Text is assumed to be a component of
+       -- a larger section. Text_Name is an identifying name for error 
messages.
+       -- If No_Annotations is true, we don't want any annotations even if we
+       -- are generating a document with annotations.
+       Input_Object : Arm_String.String_Input_Type;
+       Format_State : Format_State_Type;
+       Real_Include_Annotations : Boolean := Format_Object.Include_Annotations;
+    begin
+       if No_Annotations then
+            Format_Object.Include_Annotations := False;
+       end if;
+       Arm_String.Open (Input_Object, Text, Text_Name);
+            -- Open the input object using a string for input.
+       Real_Process (Format_Object, Format_State, Input_Object, Output_Object);
+       Arm_String.Close (Input_Object);
+       Format_Object.Include_Annotations := Real_Include_Annotations;
+       if Format_State.Nesting_Stack_Ptr /= 0 then
+           Ada.Text_IO.Put_Line ("   ** Unfinished commands detected.");
+       end if;
+    end Format;
+
+end ARM_Format;
diff --git a/packages/ada-ref-man/progs/arm_frm.ads 
b/packages/ada-ref-man/progs/arm_frm.ads
new file mode 100755
index 0000000..ebf1485
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_frm.ads
@@ -0,0 +1,476 @@
+with ARM_Output,
+     ARM_Contents;
+--private -- Ada 2005
+with ARM_Input,
+     ARM_Database,
+     ARM_Subindex;
+package ARM_Format is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the routines to parse the input files, and
+    -- determine what to output.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2004, 2005, 2006, 2007, 2010, 2011, 2012, 2016
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  4/14/00 - RLB - Created base package.
+    --  4/18/00 - RLB - Added additional information to Object;
+    --                  added Scan.
+    --  4/24/00 - RLB - Added Change_Kind and Display_Index_Entries.
+    --          - RLB - Added Change format.
+    --  4/25/00 - RLB - Added Size.
+    --  4/26/00 - RLB - Added paragraph formats.
+    --  5/10/00 - RLB - Added additional paragraph kinds.
+    --  5/11/00 - RLB - Added numbers for enumerated paragraphs.
+    --  5/12/00 - RLB - Added attribute prefix text.
+    --  5/15/00 - RLB - Split input from parsing/formatting.
+    --  5/16/00 - RLB - Added database objects and Destroy.
+    --  5/23/00 - RLB - Added tab stops.
+    --  5/24/00 - RLB - Implemented subscript/superscript commands.
+    --  5/28/00 - RLB - Implemented index operations.
+    --  6/ 2/00 - RLB - Added Unit.
+    --  8/ 2/00 - RLB - Added Leading and Syntax_Leading styles.
+    --  8/ 4/00 - RLB - Added more new styles.
+    --  8/ 7/00 - RLB - Added Leading flag, removed Leading styles.
+    --  8/ 8/00 - RLB - Added Attr_Leading flag.
+    --  8/16/00 - RLB - Added No_Para_Num flag, removed No_Pnum formats.
+    --  8/17/00 - RLB - Changed Leading flag to Space_After.
+    --  8/28/00 - RLB - Added flags for ChgAttribute and ChgImpldef commands.
+    --  8/31/00 - RLB - Added the New_Changes change kind.
+    --  9/26/00 - RLB - Added Syntax_Display format.
+    --  6/17/02 - RLB - Added Ada95 changes sections.
+    --  7/18/02 - RLB - Moved document type here.
+    --          - RLB - Added Changes_Only and versioning for individual 
changes.
+    --  9/10/04 - RLB - Added support for nested changes.
+    --  9/14/04 - RLB - Moved Change_Version_Type to ARM_Contents.
+    -- 11/03/04 - RLB - Added Nested_X2_Bulleted.
+    -- 11/16/04 - RLB - Added Attr_Prefix_Text_Change_Kind.
+    -- 12/06/04 - RLB - Added reference chain for Format_Type.
+    -- 12/11/04 - RLB - Increased Syntax_NT length.
+    -- 10/17/05 - RLB - Added Glossary change items.
+    -- 10/28/05 - RLB - Added Language-Define subindexes.
+    --  1/12/06 - RLB - Replaced "Document" with a number of new more general
+    --                  properties.
+    --  1/16/06 - RLB - Added "Unnumbered_Section" counter, so we can assign
+    --                  names without special cases.
+    --  1/18/06 - RLB - Added "Example_Font".
+    --  9/22/06 - RLB - Added "Use_ISO_2004_Note_Format".
+    --          - RLB - Revised to use Clause_Number_Type.
+    --  9/25/06 - RLB - Added "Use_ISO_2004_Contents_Format".
+    -- 10/04/06 - RLB - Added "Use_ISO_2004_List_Format".
+    --  2/ 5/07 - RLB - Added Usage_Note for ASIS, and renamed Wide paragraph
+    --                  kinds.
+    --  2/13/07 - RLB - Redid output formating to use an explict indent;
+    --                  added ChildExample.
+    --  2/16/07 - RLB - Added Indent.
+    --  2/19/07 - RLB - Added Title format.
+    --  4/23/10 - RLB - Added Ada 2005 header.
+    --  8/ 8/11 - RLB - Added Aspect DB.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    --  3/12/12 - RLB - Lengthened unit name so
+    --                  
"Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Equal_Case_Insensitive"
+    --                  would fit (have we lost our minds??).
+    --  8/31/12 - RLB - Put glossary components into a subrecord to prevent
+    --                  inappropriate usage.
+    -- 10/18/12 - RLB - Put impdef components into a subrecord to prevent
+    --                  inappropriate usage.
+    --          - RLB - Added more specific hanging_indent formats, along with
+    --                  small.
+    -- 11/26/12 - RLB - Added subdivision names.
+    -- 12/17/12 - RLB - Added Ada 2012 AARM sections.
+    --  3/17/16 - RLB - Removed Changes_Only, added Base_Change_Version.
+
+    type Format_Type is tagged limited private;
+
+    type Change_Kind is (Old_Only, New_Only, Show_Changes, New_Changes);
+        -- Which changes to show?
+        -- If Old_Only, we will get the original Ada Reference Manual or AARM.
+        -- If New_Only, we will get the reference documents with the updates
+        -- up to the Change_Version specified included.
+        -- If Show_Changes, we will get the reference documents with the
+        -- updates up to the Base_Change_Version specified included; and
+        -- insertions and deletions will be shown for versions
+        -- Base_Change_Version .. Change_Version.
+        -- If New_Changes, original RM text removed, but new RM text will be
+        -- shown as inserted, up to and including the Change_Version specified.
+        -- In all cases, changes with versions newer than Change_Version are
+        -- ignored. Thus Change_Version = '0' is the same as Old_Only no
+        -- matter what command is given.
+        --
+        -- Note: Previous versions of this tool had Changes_Only as well;
+        -- that is the same as Show_Changes with Base_Change_Version =
+        -- Change_Version. (The previous version's Show_Changes is
+        -- equivalent to this version's Show_Changes with
+        -- Base_Change_Version = 1.)
+
+    procedure Create (Format_Object : in out Format_Type;
+                      Changes : in ARM_Format.Change_Kind;
+                      Change_Version : in ARM_Contents.Change_Version_Type;
+                      Base_Change_Version : in 
ARM_Contents.Change_Version_Type;
+                      Display_Index_Entries : in Boolean;
+                      Include_Annotations : in Boolean;
+                      Include_ISO : in Boolean;
+                      Link_Non_Terminals : in Boolean;
+                      Number_Paragraphs : in Boolean;
+                      Examples_Font : in ARM_Output.Font_Family_Type;
+                      Use_ISO_2004_Note_Format : in Boolean;
+                      Use_ISO_2004_Contents_Format : in Boolean;
+                      Use_ISO_2004_List_Format : in Boolean;
+                      Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind);
+        -- Initialize an input object. Changes, Change_Version, and
+        -- Base_Change_Version determine
+        -- which changes should be displayed. If Display_Index_Entries is True,
+        -- index entries will be printed in the document; otherwise, they
+        -- will not generate any visible text (although they might generate
+        -- a link anchor). If Include_Annotations is True, annotations (AARM
+        -- text) will be included in the output; otherwise it will not be.
+        -- If Include_ISO is True, ISOOnly text will be included in the output
+        -- (and NotISO text will not); otherwise the reverse is true.
+        -- If Link_Non_Terminals is True, links will be generated for
+        -- each Non_Terminal, linking it to its definition.
+        -- If Number_Paragraphs is true, paragraphs will be numbered (per
+        -- subclause); otherwise they will not be.
+        -- Example_Font specifies the font that examples will be set in.
+        -- If Use_ISO_2004_Note_Format is true, that format will be used;
+        -- else the Ada95 standard's format will be used for notes.
+        -- If Use_ISO_2004_Contents_Format is true, that format will be used;
+        -- else the Ada95 standard's format will be used for the table of 
contents.
+        -- If Use_ISO_2004_List_Format is true, then lists will be lettered;
+        -- else the Ada95 standard's numbering format will be used for
+        -- enumerated lists.
+        -- The top-level (and other) subdivision names are as specified
+        -- in Top_Level_Subdivision_Name.
+
+    procedure Destroy (Format_Object : in out Format_Type);
+        -- Destroy a format object, releasing any resources.
+
+    procedure Scan (Format_Object : in out Format_Type;
+                    File_Name : in String;
+                    Section_Number : in ARM_Contents.Section_Number_Type;
+                    Starts_New_Section : in Boolean);
+        -- Scans the contents for File_Name, determining the table of contents
+        -- for the section. The results are written to the contents package.
+        -- Starts_New_Section is True if the file starts a new section.
+        -- Section_Number is the number (or letter) of the section.
+        -- Note: We need this scanning pass so we can process @SeeSec,
+        -- @SeeSecNum, and similar commands. For that, we need the full names
+        -- of the sections and clauses.
+
+    procedure Write_Table_of_Contents (
+                        Format_Object : in out Format_Type;
+                       Output_Object : in out ARM_Output.Output_Type'Class);
+        -- Writes the table of contents for the document. (It will have
+        -- a section name of "TOC").
+
+    procedure Process (Format_Object : in out Format_Type;
+                       File_Name : in String;
+                       Output_Object : in out ARM_Output.Output_Type'Class;
+                       Section_Name : in String;
+                       Section_Number : in ARM_Contents.Section_Number_Type;
+                       Starts_New_Section : in Boolean);
+        -- Process the contents for File_Name, writing the results to
+        -- Output_Object. (Output_Object uses dispatching calls to provide
+        -- the correct formatting). Section_Name is the name of the section
+        -- for this file. Starts_New_Section is True if the file starts
+        -- a new section. Section_Number is the number (or letter) of the
+        -- section. Values > 20 represent annex letters (21 => A, 22 => B, 
etc.)
+
+    procedure Format (Format_Object : in out Format_Type;
+                      Text : in String;
+                      Output_Object : in out ARM_Output.Output_Type'Class;
+                      Text_Name : in String;
+                      No_Annotations : in Boolean);
+        -- Format the contents of Text, writing the results to
+        -- Output_Object. (Output_Object uses dispatching calls to provide
+        -- the correct formatting). Text is assumed to be a component of
+        -- a larger section. Text_Name is an identifying name for error 
messages.
+        -- If No_Annotations is true, we don't want any annotations even if we
+        -- are generating a document with annotations.
+
+private
+    type Paragraph_Type is (Plain, Introduction,
+        Language_Design, -- AARM-only.
+        Syntax, Resolution, Legality,
+        Static_Semantics, Link_Time, Run_Time, Bounded_Errors,
+        Erroneous, Requirements, Documentation, Metrics, Permissions, Advice,
+        Notes, Single_Note, Examples,
+        Ada83_Inconsistencies, Ada83_Incompatibilities, -- AARM-only.
+        Ada83_Extensions, Ada83_Wording, -- AARM-only.
+        Ada95_Inconsistencies, Ada95_Incompatibilities, -- AARM-only.
+        Ada95_Extensions, Ada95_Wording, -- AARM-only.
+        Ada2005_Inconsistencies, Ada2005_Incompatibilities, -- AARM-only.
+        Ada2005_Extensions, Ada2005_Wording, -- AARM-only.
+        Ada2012_Inconsistencies, Ada2012_Incompatibilities, -- AARM-only.
+        Ada2012_Extensions, Ada2012_Wording, -- AARM-only.
+        Element_Ref, Child_Ref, Usage_Note, -- For ASIS (AASIS-only).
+        -- AARM annotations (no headers)
+        Reason, Ramification, Proof, Imp_Note, Corr_Change, Discussion,
+        Honest, Glossary_Marker, Bare_Annotation,
+        -- Format only:
+        Wide_Above, Example_Text, Child_Example_Text,
+        Indented_Example_Text, Code_Indented, Indent, Bulleted, 
Nested_Bulleted,
+        Nested_X2_Bulleted,
+        Display, Syntax_Display, Syntax_Indented, Syntax_Production,
+        Enumerated, Nested_Enumerated,
+        Hanging_Indented_1, Hanging_Indented_2, Hanging_Indented_3,
+        Hanging_Indented_4, Small, Title, In_Table);
+
+    type Reference;
+    type Reference_Ptr is access Reference;
+    type Reference is record
+        Ref_Name : ARM_Input.Command_Name_Type;
+        Ref_Len  : Natural; -- Length of the reference.
+        Is_DR_Ref : Boolean; -- True for a DR reference; False for an AI 
reference.
+        Next : Reference_Ptr;
+    end record;
+
+    type Glossary_Info_Type (Active : Boolean := False;
+                             Change_Kind : 
ARM_Database.Paragraph_Change_Kind_Type := ARM_Database.None) is record
+                                -- The Change_Kind of ToGlossary.
+        case Active is
+            when False => null; -- No glossary entry in use.
+            when True =>
+                -- Glossary actively being processed; used only when
+                -- processing [Chg]ToGlossary[Also] commands.
+                Term : String (1..50); -- Glossary term.
+                Term_Len : Natural := 0;
+                Add_to_Glossary : Boolean;
+                        -- Add this item to the Glossary. (Not the same
+                        -- as "Active"; when generating older versions
+                        -- of a document, this would be False for a
+                        -- new glossary entry.)
+                Displayed : Boolean;
+                        -- The text was displayed in the document.
+                case Change_Kind is
+                    when ARM_Database.None => null;
+                    when others =>
+                        Version : ARM_Contents.Change_Version_Type;
+                            -- The version number of the changed paragraph.
+                end case;
+        end case;
+    end record;
+
+    type Impdef_Command_Type is (None, Aspect, Impdef, Docreq, ImplAdv);
+
+    type Impdef_Info_Type (Command : Impdef_Command_Type := None) is record
+        case Command is
+            when None => null; -- No impdef, docreq, impladv, aspectdesc in 
use.
+            when others =>
+                -- Impdef, Docreq, Impladv, Aspectdesc actively being 
processed;
+                -- used only when processing ImplDef, ChgImplDef,
+                --    ChgDocReq, ChgImplAdv, and ChgAspectDesc.
+                Change_Kind : ARM_Database.Paragraph_Change_Kind_Type := 
ARM_Database.None;
+                        -- The Change_Kind of the command.
+                Version : ARM_Contents.Change_Version_Type;
+                        -- If the kind is not "None", this is the version
+                        -- number of the changed paragraph.
+                Initial_Version : ARM_Contents.Change_Version_Type;
+                        -- This is the version number of the original 
paragraph.
+                Paragraph_String : String (1 .. 10); -- Paragraph number.
+                Paragraph_Len : Natural;
+                Add_to_DB : Boolean;
+                        -- Add this item to the appropriate DB. (Not the same
+                        -- as "Active"; when generating older versions
+                        -- of a document, this would be False for a
+                        -- new impdef, docreq, etc. entry.)
+                case Command is
+                    when Aspect =>
+                        Aspect_Name : String (1..30); -- Aspect name text
+                        Aspect_Name_Len : Natural := 0;
+                    when others => null;
+                end case;
+        end case;
+    end record;
+
+    type Format_Type is tagged limited record
+        -- Document information:
+        Changes : ARM_Format.Change_Kind; -- No Both here.
+        Change_Version : ARM_Contents.Change_Version_Type;
+        Base_Change_Version : ARM_Contents.Change_Version_Type;
+        Display_Index_Entries : Boolean;
+        Include_Annotations : Boolean;
+        Include_ISO : Boolean;
+        Link_Non_Terminals : Boolean;
+        Number_Paragraphs : Boolean;
+        Examples_Font : ARM_Output.Font_Family_Type;
+        Use_ISO_2004_Note_Format : Boolean;
+        Use_ISO_2004_Contents_Format : Boolean;
+        Use_ISO_2004_List_Format : Boolean;
+        Top_Level_Subdivision_Name : 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+
+        -- Clause numbers:
+        Clause_Number : ARM_Contents.Clause_Number_Type;
+             -- The current clause number (Section, clause, subclause, 
subsubclause).
+        Unnumbered_Section : Natural; -- The current (if any) clause number
+                -- for unnumbered sections.
+
+        -- Paragraph format info:
+        Next_Paragraph_Change_Kind : ARM_Database.Paragraph_Change_Kind_Type;
+                             -- The change kind of the next paragraph. This is
+                             -- reset to none after each paragraph.
+        Next_Paragraph_Version : ARM_Contents.Change_Version_Type;
+                             -- If the kind is not "None", this is the version
+                             -- number of the changed paragraph.
+        Last_Paragraph_Subhead_Type : Paragraph_Type;
+                             -- The last paragraph subhead generated.
+        Next_Paragraph_Subhead_Type : Paragraph_Type;
+                             -- The next paragraph subhead to generate (not
+                             -- necessarily the same as 
Next_Paragraph_Format_Type).
+                             -- This indicates the current paragraph type.
+        Next_Paragraph_Format_Type : Paragraph_Type;
+                             -- The format type of the next paragraph to
+                             -- generate. We keep this separately so that the
+                             -- first paragraph of a grouping can be in a
+                             -- different format than the standard one, and
+                             -- still generate a subheading.
+        Paragraph_Tab_Stops : ARM_Output.Tab_Info := ARM_Output.NO_TABS;
+                             -- The tab stops for the next paragraph.
+        In_Bundle : Boolean := False;
+                             -- Are we in a bundle?
+        References : Reference_Ptr := null;
+                             -- Any references to generate at the start of the
+                             -- next paragraph.
+
+        -- Paragraph numbering info:
+        Next_Note : Natural; -- The number of the next note. These are
+                             -- per-section, not per-clause (unless ISO 2004 
is set).
+        Next_Paragraph : Positive; -- The number of the next paragraph. These
+                             -- are per-(sub)clause.
+        Next_Insert_Para : Positive; -- The subnumber of the next inserted
+                             -- paragraph.
+        Next_AARM_Sub : Character; -- The letter of the next AARM subclause.
+                             -- These are reset when the paragraph number
+                             -- changes.
+        Next_AARM_Insert_Para : Positive; -- The subnumber of the next inserted
+                             -- AARM paragraph.
+        Next_Enumerated_Num : Positive;
+                             -- If the format is enumerated, this is the
+                             -- number of the next paragraph.
+        Enumerated_Level : Natural;
+                             -- Number of enumerated formats that we're in.
+        Current_Paragraph_String : String (1 .. 10);
+                             -- The current paragraph number string (only
+                             -- valid if In_Paragraph is True).
+        Current_Paragraph_Len : Natural;
+
+        -- Text format info:
+        Text_Format : ARM_Output.Format_Type; -- Holds the current text format.
+
+        Style : ARM_Output.Paragraph_Style_Type; -- What is the current 
paragraph style?
+        Indent : ARM_Output.Paragraph_Indent_Type; -- What is the current 
paragraph indent?
+        In_Paragraph : Boolean; -- Are we currently in a paragraph?
+        No_Start_Paragraph : Boolean; -- Did we suppress "Start_Paragraph"?
+        No_Prefix : Boolean; -- Should we suppress any prefix on the next 
paragraph?
+        No_Para_Num : Boolean; -- Should we suppress the paragraph number on 
the next paragraph?
+        Keep_with_Next : Boolean; -- Should we force this paragraph to bind to 
the next
+                                  -- (disallowing a page break between)?
+        Space_After : ARM_Output.Space_After_Type; -- Space following this
+                             -- paragraph.
+        No_Breaks : Boolean; -- Should we allow page breaks in this paragraph?
+        In_Change : Boolean; -- Are we in a change region?
+        Last_Non_Space : Boolean; -- Is the last character written into the
+                        -- paragraph a non-space? (If nothing has been
+                        -- written into the paragraph, then this is False).
+
+        -- Indexing:
+        Unit : String (1..72);  -- Unit for predefined definitions. Used only
+                                -- by a handful of indexing commands.
+        Unit_Len : Natural := 0;
+
+        -- Syntax:
+        Syntax_NT : String (1..80); -- Syntax non-terminal; used only during 
the
+                                    -- processing of the Syn command.
+        Syntax_NT_Len : Natural := 0;
+        Syntax_Tab : String (1..40); -- Syntax tab string; used only during the
+                                    -- processing of the Syn command.
+        Syntax_Tab_Len : Natural := 0;
+
+        -- Attributes:
+        Prefix_Text : String (1..200) := "@b{NONE!}" & (10..200 => ' ');
+            -- This text is used as part of the attribute list text.
+            -- It is shared between multiple attributes, which is why it is
+            -- handled this way.
+        Prefix_Text_Len : Natural := 9;
+
+        Attr_Prefix : String (1..10); -- Attribute prefix text
+        Attr_Prefix_Len : Natural := 0;
+        Attr_Prefix_Change_Kind : ARM_Database.Paragraph_Change_Kind_Type;
+        Attr_Prefix_Version : ARM_Contents.Change_Version_Type;
+        Attr_Name : String (1..30); -- Attribute name text
+        Attr_Name_Len : Natural := 0;
+        Attr_Leading : Boolean := False; -- Attribute leading flag
+        Attr_Change_Kind : ARM_Database.Paragraph_Change_Kind_Type;
+        Attr_Prefix_Text_Change_Kind : ARM_Database.Paragraph_Change_Kind_Type;
+        Attr_Version : ARM_Contents.Change_Version_Type;
+        Attr_Initial_Version : ARM_Contents.Change_Version_Type;
+            -- The above ten items are used only when processing Attribute
+            -- and Attribute_Leading commands.
+
+        Attr_DB : ARM_Database.Database_Type;
+
+        -- Pragmas:
+        Pragma_DB : ARM_Database.Database_Type;
+
+        -- Glossary:
+        Glossary_Info : Glossary_Info_Type;
+        Glossary_DB : ARM_Database.Database_Type;
+
+        -- Aspects:
+        Aspect_DB : ARM_Database.Database_Type;
+            -- Also see Impdef_Info, below.
+
+        -- Implementation advice:
+        Impladv_DB : ARM_Database.Database_Type;
+            -- Also see Impdef_Info, below.
+
+        -- Documentation requirements:
+        Docreq_DB : ARM_Database.Database_Type;
+            -- Also see Impdef_Info, below.
+
+        -- Implementation-defined:
+        Impdef_DB : ARM_Database.Database_Type;
+            -- Also see Impdef_Info, below.
+
+        -- For all of the above four:
+        Impdef_Info : Impdef_Info_Type;
+            -- Used only during processing of ImplDef, ChgImplDef,
+            --    ChgDocReq, ChgImplAdv, and ChgAspectDesc.
+
+        -- Language-Defined entity subindexes:
+        Package_Index : ARM_Subindex.Subindex_Type;
+        Type_Index : ARM_Subindex.Subindex_Type;
+        Subprogram_Index : ARM_Subindex.Subindex_Type;
+        Exception_Index : ARM_Subindex.Subindex_Type;
+        Object_Index : ARM_Subindex.Subindex_Type;
+
+    end record;
+end ARM_Format;
diff --git a/packages/ada-ref-man/progs/arm_frmd.adb 
b/packages/ada-ref-man/progs/arm_frmd.adb
new file mode 100755
index 0000000..e9cdc2c
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_frmd.adb
@@ -0,0 +1,552 @@
+with Ada.Characters.Handling,
+     Ada.Strings.Fixed;
+package body ARM_Format.Data is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains various data used by the input file parser.
+    --
+    -- ---------------------------------------
+    -- Copyright 2011, 2012  AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  8/ 8/11 - RLB - Split from base package, mainly to reduce the
+    --                 size of that package.
+    --         - RLB - Added aspect index commands.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/19/11 - RLB - Added AspectDefn command.
+    -- 10/20/11 - RLB - Added DeletedPragmaSyn command.
+    -- 10/26/11 - RLB - Added versioned break commands.
+    --  3/27/12 - RLB - Added more versioned break commands.
+    -- 12/17/12 - RLB - Added Ada 2012 AARM headings.
+
+
+    function Command (Name : in ARM_Input.Command_Name_Type) return 
Command_Type is
+       -- Return the command value for a particular command name:
+       Canonical_Name : constant String :=
+           Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (Name, 
Ada.Strings.Right));
+    begin
+       if Canonical_Name = "begin" then
+           return Text_Begin;
+       elsif Canonical_Name = "end" then
+           return Text_End;
+       elsif Canonical_Name = "redundant" then
+           return Redundant;
+       elsif Canonical_Name = "comment" then
+           return Comment;
+       elsif Canonical_Name = "noprefix" then
+           return No_Prefix;
+       elsif Canonical_Name = "noparanum" then
+           return No_Para_Num;
+       elsif Canonical_Name = "keepnext" then
+           return Keep_with_Next;
+       elsif Canonical_Name = "leading" then
+           return Leading;
+       elsif Canonical_Name = "trailing" then
+           return Trailing;
+       elsif Canonical_Name = "+" then -- Can't happen directly, but can 
happen through stacking.
+           return Up;
+       elsif Canonical_Name = "-" then -- Can't happen directly, but can 
happen through stacking.
+           return Down;
+       elsif Canonical_Name = "thinline" then
+           return Thin_Line;
+       elsif Canonical_Name = "thickline" then
+           return Thick_Line;
+       elsif Canonical_Name = "tabclear" then
+           return Tab_Clear;
+       elsif Canonical_Name = "tabset" then
+           return Tab_Set;
+       elsif Canonical_Name = "table" then
+           return Table;
+       elsif Canonical_Name = "picturealone" then
+           return Picture_Alone;
+       elsif Canonical_Name = "pictureinline" then
+           return Picture_Inline;
+       elsif Canonical_Name = "last" then
+           return Table_Last;
+       elsif Canonical_Name = "part" then
+           return Part;
+       elsif Canonical_Name = "newpage" then
+           return New_Page;
+       elsif Canonical_Name = "rmnewpage" then
+           return RM_New_Page;
+       elsif Canonical_Name = "softpage" then
+           return Soft_Page;
+       elsif Canonical_Name = "newcolumn" then
+           return New_Column;
+       elsif Canonical_Name = "newpagever" then
+           return New_Page_for_Version;
+       elsif Canonical_Name = "rmnewpagever" then
+           return RM_New_Page_for_Version;
+       elsif Canonical_Name = "notisormnewpagever" then
+           return Not_Iso_RM_New_Page_for_Version;
+       elsif Canonical_Name = "isoonlyrmnewpagever" then
+           return Iso_Only_RM_New_Page_for_Version;
+       elsif Canonical_Name = "newcolumnver" then
+           return New_Column_for_Version;
+       elsif Canonical_Name = "b" or else Canonical_Name = "bold" then
+           return Bold;
+       elsif Canonical_Name = "i" or else Canonical_Name = "italics" then
+           return Italic;
+       elsif Canonical_Name = "r" or else Canonical_Name = "roman" then
+           return Roman;
+       elsif Canonical_Name = "s" or else Canonical_Name = "swiss" then
+           return Swiss;
+       elsif Canonical_Name = "f" or else Canonical_Name = "fixed" then
+           return Fixed;
+       elsif Canonical_Name = "ri" then
+           return Roman_Italic;
+       elsif Canonical_Name = "shrink" then
+           return Shrink;
+       elsif Canonical_Name = "grow" then
+           return Grow;
+       elsif Canonical_Name = "black" then
+           return Black;
+       elsif Canonical_Name = "red" then
+           return Red;
+       elsif Canonical_Name = "green" then
+           return Green;
+       elsif Canonical_Name = "blue" then
+           return Blue;
+       elsif Canonical_Name = "key" then
+           return Keyword;
+       elsif Canonical_Name = "nt" then
+           return Non_Terminal;
+       elsif Canonical_Name = "ntf" then
+           return Non_Terminal_Format;
+       elsif Canonical_Name = "exam" then
+           return Example_Text;
+       elsif Canonical_Name = "examcom" then
+           return Example_Comment;
+       elsif Canonical_Name = "indexlist" then
+           return Index_List;
+       elsif Canonical_Name = "defn" then
+           return Defn;
+       elsif Canonical_Name = "defn2" then
+           return Defn2;
+       elsif Canonical_Name = "rootdefn" then
+           return RootDefn;
+       elsif Canonical_Name = "rootdefn2" then
+           return RootDefn2;
+       elsif Canonical_Name = "pdefn" then
+           return PDefn;
+       elsif Canonical_Name = "pdefn2" then
+           return PDefn2;
+       elsif Canonical_Name = "indexsee" then
+           return Index_See;
+       elsif Canonical_Name = "indexseealso" then
+           return Index_See_Also;
+       elsif Canonical_Name = "seeother" then
+           return See_Other;
+       elsif Canonical_Name = "seealso" then
+           return See_Also;
+       elsif Canonical_Name = "rootlibunit" then
+           return Index_Root_Unit;
+       elsif Canonical_Name = "childunit" then
+           return Index_Child_Unit;
+       elsif Canonical_Name = "subchildunit" then
+           return Index_Subprogram_Child_Unit;
+       elsif Canonical_Name = "adatypedefn" then
+           return Index_Type;
+       elsif Canonical_Name = "adasubtypedefn" then
+           return Index_Subtype;
+       elsif Canonical_Name = "adasubdefn" then
+           return Index_Subprogram;
+       elsif Canonical_Name = "adaexcdefn" then
+           return Index_Exception;
+       elsif Canonical_Name = "adaobjdefn" then
+           return Index_Object;
+       elsif Canonical_Name = "adapackdefn" then
+           return Index_Package;
+       elsif Canonical_Name = "adadefn" then
+           return Index_Other;
+       elsif Canonical_Name = "indexcheck" then
+           return Index_Check;
+       elsif Canonical_Name = "attr" then
+           return Index_Attr;
+       elsif Canonical_Name = "prag" then
+           return Index_Pragma;
+       elsif Canonical_Name = "aspectdefn" then
+           return Index_Aspect;
+       elsif Canonical_Name = "syn" then
+           return Syntax_Rule;
+       elsif Canonical_Name = "syn2" then
+           return Syntax_Term;
+       elsif Canonical_Name = "synf" then
+           return Syntax_Term_Undefined;
+       elsif Canonical_Name = "syni" then
+           return Syntax_Prefix;
+       elsif Canonical_Name = "syntaxsummary" then
+           return Syntax_Summary;
+       elsif Canonical_Name = "syntaxxref" then
+           return Syntax_Xref;
+       elsif Canonical_Name = "addedsyn" then
+           return Added_Syntax_Rule;
+       elsif Canonical_Name = "deletedsyn" then
+           return Deleted_Syntax_Rule;
+       elsif Canonical_Name = "toglossary" then
+           return To_Glossary;
+       elsif Canonical_Name = "toglossaryalso" then
+           return To_Glossary_Also;
+       elsif Canonical_Name = "chgtoglossary" then
+           return Change_To_Glossary;
+       elsif Canonical_Name = "chgtoglossaryalso" then
+           return Change_To_Glossary_Also;
+       elsif Canonical_Name = "glossarylist" then
+           return Glossary_List;
+       elsif Canonical_Name = "prefixtype" then
+           return Prefix_Type;
+       elsif Canonical_Name = "chgprefixtype" then
+           return Change_Prefix_Type;
+       elsif Canonical_Name = "endprefixtype" then
+           return Reset_Prefix_Type;
+       elsif Canonical_Name = "attribute" then
+           return Attribute;
+       elsif Canonical_Name = "attributeleading" then
+           return Attribute_Leading;
+       elsif Canonical_Name = "chgattribute" then
+           return Change_Attribute;
+       elsif Canonical_Name = "attributelist" then
+           return Attribute_List;
+       elsif Canonical_Name = "pragmasyn" then
+           return Pragma_Syntax;
+       elsif Canonical_Name = "pragmalist" then
+           return Pragma_List;
+       elsif Canonical_Name = "addedpragmasyn" then
+           return Added_Pragma_Syntax;
+       elsif Canonical_Name = "deletedpragmasyn" then
+           return Deleted_Pragma_Syntax;
+       elsif Canonical_Name = "impldef" then
+           return Implementation_Defined;
+       elsif Canonical_Name = "chgimpldef" then
+           return Change_Implementation_Defined;
+       elsif Canonical_Name = "impldeflist" then
+           return Implementation_Defined_List;
+       elsif Canonical_Name = "chgimpladvice" then
+           return Change_Implementation_Advice;
+       elsif Canonical_Name = "addedimpladvicelist" then
+           return Added_Implementation_Advice_List;
+       elsif Canonical_Name = "chgdocreq" then
+           return Change_Documentation_Requirement;
+       elsif Canonical_Name = "addeddocreqlist" then
+           return Added_Documentation_Requirements_List;
+       elsif Canonical_Name = "chgaspectdesc" then
+           return Change_Aspect_Description;
+       elsif Canonical_Name = "addedaspectlist" then
+           return Added_Aspect_Description_List;
+       elsif Canonical_Name = "packagelist" then
+           return Package_List;
+       elsif Canonical_Name = "typelist" then
+           return Type_List;
+       elsif Canonical_Name = "subprogramlist" then
+           return Subprogram_List;
+       elsif Canonical_Name = "exceptionlist" then
+           return Exception_List;
+       elsif Canonical_Name = "objectlist" then
+           return Object_List;
+       elsif Canonical_Name = "labeledsection" then
+           return Labeled_Section;
+       elsif Canonical_Name = "labeledsectionnobreak" then
+           return Labeled_Section_No_Break;
+       elsif Canonical_Name = "labeledclause" then
+           return Labeled_Clause;
+       elsif Canonical_Name = "labeledsubclause" then
+           return Labeled_Subclause;
+       elsif Canonical_Name = "labeledsubsubclause" then
+           return Labeled_Subsubclause;
+       elsif Canonical_Name = "labeledannex" then
+           return Labeled_Annex;
+       elsif Canonical_Name = "labeledinformativeannex" then
+           return Labeled_Informative_Annex;
+       elsif Canonical_Name = "labelednormativeannex" then
+           return Labeled_Normative_Annex;
+       elsif Canonical_Name = "unnumberedsection" then
+           return Unnumbered_Section;
+       elsif Canonical_Name = "labeledrevisedannex" then
+           return Labeled_Revised_Annex;
+       elsif Canonical_Name = "labeledrevisedinformativeannex" then
+           return Labeled_Revised_Informative_Annex;
+       elsif Canonical_Name = "labeledrevisednormativeannex" then
+           return Labeled_Revised_Normative_Annex;
+       elsif Canonical_Name = "labeledaddedannex" then
+           return Labeled_Added_Annex;
+       elsif Canonical_Name = "labeledaddedinformativeannex" then
+           return Labeled_Added_Informative_Annex;
+       elsif Canonical_Name = "labeledaddednormativeannex" then
+           return Labeled_Added_Normative_Annex;
+       elsif Canonical_Name = "labeledrevisedsection" then
+           return Labeled_Revised_Section;
+       elsif Canonical_Name = "labeledrevisedclause" then
+           return Labeled_Revised_Clause;
+       elsif Canonical_Name = "labeledrevisedsubclause" then
+           return Labeled_Revised_Subclause;
+       elsif Canonical_Name = "labeledrevisedsubsubclause" then
+           return Labeled_Revised_Subsubclause;
+       elsif Canonical_Name = "labeledaddedsection" then
+           return Labeled_Added_Section;
+       elsif Canonical_Name = "labeledaddedclause" then
+           return Labeled_Added_Clause;
+       elsif Canonical_Name = "labeledaddedsubclause" then
+           return Labeled_Added_Subclause;
+       elsif Canonical_Name = "labeledaddedsubsubclause" then
+           return Labeled_Added_Subsubclause;
+       elsif Canonical_Name = "labeleddeletedclause" then
+           return Labeled_Deleted_Clause;
+       elsif Canonical_Name = "labeleddeletedsubclause" then
+           return Labeled_Deleted_Subclause;
+       elsif Canonical_Name = "labeleddeletedsubsubclause" then
+           return Labeled_Deleted_Subsubclause;
+       elsif Canonical_Name = "subheading" then
+           return Subheading;
+       elsif Canonical_Name = "addedsubheading" then
+           return Added_Subheading;
+       elsif Canonical_Name = "heading" then
+           return Heading;
+       elsif Canonical_Name = "center" then
+           return Center;
+       elsif Canonical_Name = "right" then
+           return Right;
+       elsif Canonical_Name = "prefacesection" then
+           return Preface_Section;
+       elsif Canonical_Name = "refsec" then
+           return Ref_Section;
+       elsif Canonical_Name = "refsecnum" then
+           return Ref_Section_Number;
+       elsif Canonical_Name = "refsecbynum" then
+           return Ref_Section_By_Number;
+       elsif Canonical_Name = "locallink" then
+           return Local_Link;
+       elsif Canonical_Name = "localtarget" then
+           return Local_Target;
+       elsif Canonical_Name = "urllink" then
+           return URL_Link;
+       elsif Canonical_Name = "ailink" then
+           return AI_Link;
+       elsif Canonical_Name = "chg" then
+           return Change;
+       elsif Canonical_Name = "chgadded" then
+           return Change_Added;
+       elsif Canonical_Name = "chgdeleted" then
+           return Change_Deleted;
+       elsif Canonical_Name = "chgref" then
+           return Change_Reference;
+       elsif Canonical_Name = "chgnote" then
+           return Change_Note;
+       elsif Canonical_Name = "introname" then
+           return Intro_Name;
+       elsif Canonical_Name = "syntaxname" then
+           return Syntax_Name;
+       elsif Canonical_Name = "resolutionname" then
+           return Resolution_Name;
+       elsif Canonical_Name = "legalityname" then
+           return Legality_Name;
+       elsif Canonical_Name = "staticsemname" then
+           return Static_Name;
+       elsif Canonical_Name = "linktimename" then
+           return Link_Name;
+       elsif Canonical_Name = "runtimename" then
+           return Run_Name;
+       elsif Canonical_Name = "boundedname" then
+           return Bounded_Name;
+       elsif Canonical_Name = "erronname" then
+           return Erroneous_Name;
+       elsif Canonical_Name = "implreqname" then
+           return Req_Name;
+       elsif Canonical_Name = "docreqname" then
+           return Doc_Name;
+       elsif Canonical_Name = "metricsname" then
+           return Metrics_Name;
+       elsif Canonical_Name = "implpermname" then
+           return Permission_Name;
+       elsif Canonical_Name = "impladvicename" then
+           return Advice_Name;
+       elsif Canonical_Name = "notesname" then
+           return Notes_Name;
+       elsif Canonical_Name = "singlenotename" then
+           return Single_Note_Name;
+       elsif Canonical_Name = "examplesname" then
+           return Examples_Name;
+       elsif Canonical_Name = "metarulesname" then
+           return Meta_Name;
+       elsif Canonical_Name = "inconsistent83name" then
+           return Inconsistent83_Name;
+       elsif Canonical_Name = "incompatible83name" then
+           return Incompatible83_Name;
+       elsif Canonical_Name = "extend83name" then
+           return Extend83_Name;
+       elsif Canonical_Name = "diffword83name" then
+           return Wording83_Name;
+       elsif Canonical_Name = "inconsistent95name" then
+           return Inconsistent95_Name;
+       elsif Canonical_Name = "incompatible95name" then
+           return Incompatible95_Name;
+       elsif Canonical_Name = "extend95name" then
+           return Extend95_Name;
+       elsif Canonical_Name = "diffword95name" then
+           return Wording95_Name;
+       elsif Canonical_Name = "inconsistent2005name" then
+           return Inconsistent2005_Name;
+       elsif Canonical_Name = "incompatible2005name" then
+           return Incompatible2005_Name;
+       elsif Canonical_Name = "extend2005name" then
+           return Extend2005_Name;
+       elsif Canonical_Name = "diffword2005name" then
+           return Wording2005_Name;
+       elsif Canonical_Name = "inconsistent2012name" then
+           return Inconsistent2012_Name;
+       elsif Canonical_Name = "incompatible2012name" then
+           return Incompatible2012_Name;
+       elsif Canonical_Name = "extend2012name" then
+           return Extend2012_Name;
+       elsif Canonical_Name = "diffword2012name" then
+           return Wording2012_Name;
+       elsif Canonical_Name = "syntaxtitle" then
+           return Syntax_Title;
+       elsif Canonical_Name = "resolutiontitle" then
+           return Resolution_Title;
+       elsif Canonical_Name = "legalitytitle" then
+           return Legality_Title;
+       elsif Canonical_Name = "staticsemtitle" then
+           return Static_Title;
+       elsif Canonical_Name = "linktimetitle" then
+           return Link_Title;
+       elsif Canonical_Name = "runtimetitle" then
+           return Run_Title;
+       elsif Canonical_Name = "boundedtitle" then
+           return Bounded_Title;
+       elsif Canonical_Name = "errontitle" then
+           return Erroneous_Title;
+       elsif Canonical_Name = "implreqtitle" then
+           return Req_Title;
+       elsif Canonical_Name = "docreqtitle" then
+           return Doc_Title;
+       elsif Canonical_Name = "metricstitle" then
+           return Metrics_Title;
+       elsif Canonical_Name = "implpermtitle" then
+           return Permission_Title;
+       elsif Canonical_Name = "impladvicetitle" then
+           return Advice_Title;
+       elsif Canonical_Name = "notestitle" then
+           return Notes_Title;
+       elsif Canonical_Name = "singlenotetitle" then
+           return Single_Note_Title;
+       elsif Canonical_Name = "examplestitle" then
+           return Examples_Title;
+       elsif Canonical_Name = "metarulestitle" then
+           return Meta_Title;
+       elsif Canonical_Name = "inconsistent83title" then
+           return Inconsistent83_Title;
+       elsif Canonical_Name = "incompatible83title" then
+           return Incompatible83_Title;
+       elsif Canonical_Name = "extend83title" then
+           return Extend83_Title;
+       elsif Canonical_Name = "diffword83title" then
+           return Wording83_Title;
+       elsif Canonical_Name = "inconsistent95title" then
+           return Inconsistent95_Title;
+       elsif Canonical_Name = "incompatible95title" then
+           return Incompatible95_Title;
+       elsif Canonical_Name = "extend95title" then
+           return Extend95_Title;
+       elsif Canonical_Name = "diffword95title" then
+           return Wording95_Title;
+       elsif Canonical_Name = "inconsistent2005title" then
+           return Inconsistent2005_Title;
+       elsif Canonical_Name = "incompatible2005title" then
+           return Incompatible2005_Title;
+       elsif Canonical_Name = "extend2005title" then
+           return Extend2005_Title;
+       elsif Canonical_Name = "diffword2005title" then
+           return Wording2005_Title;
+       elsif Canonical_Name = "inconsistent2012title" then
+           return Inconsistent2012_Title;
+       elsif Canonical_Name = "incompatible2012title" then
+           return Incompatible2012_Title;
+       elsif Canonical_Name = "extend2012title" then
+           return Extend2012_Title;
+       elsif Canonical_Name = "diffword2012title" then
+           return Wording2012_Title;
+       elsif Canonical_Name = "em" then
+           return EM_Dash;
+       elsif Canonical_Name = "en" then
+           return EN_Dash;
+       elsif Canonical_Name = "lt" then
+           return LT;
+       elsif Canonical_Name = "leq" then
+           return LE;
+       elsif Canonical_Name = "gt" then
+           return GT;
+       elsif Canonical_Name = "geq" then
+           return GE;
+       elsif Canonical_Name = "neq" then
+           return NE;
+       elsif Canonical_Name = "pi" then
+           return PI;
+       elsif Canonical_Name = "times" then
+           return Times;
+       elsif Canonical_Name = "porm" then
+           return PorM;
+       elsif Canonical_Name = "singlequote" then
+           return Single_Quote;
+       elsif Canonical_Name = "latin1" then
+           return LATIN_1;
+       elsif Canonical_Name = "unicode" then
+           return Unicode;
+       elsif Canonical_Name = "ceiling" then
+           return Ceiling;
+       elsif Canonical_Name = "floor" then
+           return Floor;
+       elsif Canonical_Name = "abs" then
+           return Absolute;
+       elsif Canonical_Name = "log" then
+           return Log;
+       elsif Canonical_Name = "thin" then
+           return Thin_Space;
+       elsif Canonical_Name = "lquote" then
+           return Left_Quote;
+       elsif Canonical_Name = "lquotes" then
+           return Left_Quote_Pair;
+       elsif Canonical_Name = "ldquote" then
+           return Left_Double_Quote;
+       elsif Canonical_Name = "rquote" then
+           return Right_Quote;
+       elsif Canonical_Name = "rquotes" then
+           return Right_Quote_Pair;
+       elsif Canonical_Name = "rdquote" then
+           return Right_Double_Quote;
+       elsif Canonical_Name = "smldotlessi" then
+           return Small_Dotless_I;
+       elsif Canonical_Name = "capdottedi" then
+           return Capital_Dotted_I;
+       else
+           return Unknown;
+       end if;
+    end Command;
+
+end ARM_Format.Data;
diff --git a/packages/ada-ref-man/progs/arm_frmd.ads 
b/packages/ada-ref-man/progs/arm_frmd.ads
new file mode 100755
index 0000000..7e64fff
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_frmd.ads
@@ -0,0 +1,319 @@
+private package ARM_Format.Data is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains various data used by the input file parser.
+    --
+    -- ---------------------------------------
+    -- Copyright 2011, 2012  AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  8/ 8/11 - RLB - Split from base package, mainly to reduce the
+    --                 size of that package.
+    --         - RLB - Added aspect index commands.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/19/11 - RLB - Added AspectDefn command.
+    -- 10/20/11 - RLB - Added DeletedPragmaSyn command.
+    -- 10/26/11 - RLB - Added versioned break commands.
+    --  3/27/12 - RLB - Added more versioned break commands.
+    -- 10/18/12 - RLB - Added more specific hanging_indent commands.
+    -- 12/17/12 - RLB - Added Ada 2012 AARM headings.
+
+
+    type LString is record
+       Length : Natural;
+       Str : String(1..40);
+    end record;
+    Paragraph_Kind_Name : constant array (Paragraph_Type) of LString :=
+       (Plain           => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Introduction    => (Length => 17, Str => "Introductory Text            
           "), -- IntroName
+        Language_Design => (Length => 25, Str => "Language Design Principle    
           "), -- MetaRulesName
+        Syntax          => (Length => 11, Str => "Syntax Rule                  
           "), -- SyntaxName
+        Resolution      => (Length => 20, Str => "Name Resolution Rule         
           "), -- ResolutionName
+        Legality        => (Length => 13, Str => "Legality Rule                
           "), -- LegalityName
+        Static_Semantics=> (Length => 20, Str => "Static Semantic Item         
           "), -- StaticSemName
+        Link_Time       => (Length => 21, Str => "Post-Compilation Rule        
           "), -- LinkTimeName
+        Run_Time        => (Length => 21, Str => "Dynamic Semantic Item        
           "), -- RunTimeName
+        Bounded_Errors  => (Length => 24, Str => "Bounded (Run-Time) Error     
           "), -- BoundedName
+        Erroneous       => (Length => 19, Str => "Erroneous Execution          
           "), -- ErronName
+        Requirements    => (Length => 26, Str => "Implementation Requirement   
           "), -- ImplReqName
+        Documentation   => (Length => 25, Str => "Documentation Requirement    
           "), -- DocReqName
+        Metrics         => (Length =>  6, Str => "Metric                       
           "), -- MetricsName
+        Permissions     => (Length => 25, Str => "Implementation Permission    
           "), -- ImplPermName
+        Advice          => (Length => 21, Str => "Implementation Advice        
           "), -- ImplAdviceName
+        Notes           => (Length =>  4, Str => "Note                         
           "), -- NotesName
+        Single_Note     => (Length =>  4, Str => "Note                         
           "), -- SimpleNoteName
+        Examples        => (Length =>  7, Str => "Example                      
           "), -- ExamplesName
+        Ada83_Inconsistencies
+                        => (Length => 25, Str => "Inconsistency with Ada 83    
           "), -- Inconsistent83Name
+        Ada83_Incompatibilities
+                        => (Length => 27, Str => "Incompatibility with Ada 83  
           "), -- Incompatible83Name
+        Ada83_Extensions=> (Length => 19, Str => "Extension to Ada 83          
           "), -- Extend83Name
+        Ada83_Wording   => (Length => 26, Str => "Wording Change from Ada 83   
           "), -- DiffWord83Name
+        Ada95_Inconsistencies
+                        => (Length => 25, Str => "Inconsistency with Ada 95    
           "), -- Inconsistent95Name
+        Ada95_Incompatibilities
+                        => (Length => 27, Str => "Incompatibility with Ada 95  
           "), -- Incompatible95Name
+        Ada95_Extensions=> (Length => 19, Str => "Extension to Ada 95          
           "), -- Extend95Name
+        Ada95_Wording   => (Length => 26, Str => "Wording Change from Ada 95   
           "), -- DiffWord95Name
+        Ada2005_Inconsistencies
+                        => (Length => 27, Str => "Inconsistency with Ada 2005  
           "), -- Inconsistent2005Name
+        Ada2005_Incompatibilities
+                        => (Length => 29, Str => "Incompatibility with Ada 
2005           "), -- Incompatible2005Name
+        Ada2005_Extensions
+                        => (Length => 21, Str => "Extension to Ada 2005        
           "), -- Extend2005Name
+        Ada2005_Wording => (Length => 28, Str => "Wording Change from Ada 2005 
           "), -- DiffWord2005Name
+        Ada2012_Inconsistencies
+                        => (Length => 27, Str => "Inconsistency with Ada 2012  
           "), -- Inconsistent2012Name
+        Ada2012_Incompatibilities
+                        => (Length => 29, Str => "Incompatibility with Ada 
2012           "), -- Incompatible2012Name
+        Ada2012_Extensions
+                        => (Length => 21, Str => "Extension to Ada 2012        
           "), -- Extend2012Name
+        Ada2012_Wording => (Length => 28, Str => "Wording Change from Ada 2012 
           "), -- DiffWord2012Name
+        Element_Ref     => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Child_Ref       => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Usage_Note      => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Reason          => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Ramification    => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Proof           => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Imp_Note        => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Corr_Change     => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Discussion      => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Honest          => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Glossary_Marker => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Bare_Annotation => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Wide_Above      => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Example_Text    => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Child_Example_Text => (Length =>  0, Str => (others => ' ')), -- Not 
used.
+        Indented_Example_Text=>(Length =>  0, Str => (others => ' ')), -- Not 
used.
+        Code_Indented   => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Indent          => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Bulleted        => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Nested_Bulleted => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Nested_X2_Bulleted=>(Length=>  0, Str => (others => ' ')), -- Not used.
+        Display         => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Syntax_Display  => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Syntax_Indented => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Syntax_Production=>(Length =>  0, Str => (others => ' ')), -- Not used.
+        Enumerated      => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Nested_Enumerated=>(Length =>  0, Str => (others => ' ')), -- Not used.
+        Hanging_Indented_1=>(Length => 0, Str => (others => ' ')), -- Not used.
+        Hanging_Indented_2=>(Length => 0, Str => (others => ' ')), -- Not used.
+        Hanging_Indented_3=>(Length => 0, Str => (others => ' ')), -- Not used.
+        Hanging_Indented_4=>(Length => 0, Str => (others => ' ')), -- Not used.
+        Small           => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Title           => (Length =>  0, Str => (others => ' ')), -- Not used.
+        In_Table        => (Length =>  0, Str => (others => ' '))); -- Not 
used.
+
+    Paragraph_Kind_Title : constant array (Paragraph_Type) of LString :=
+       (Plain           => (Length =>  0, Str => (others => ' ')),
+        Introduction    => (Length =>  0, Str => (others => ' ')), -- 
IntroTitle (deleted).
+        Language_Design => (Length => 26, Str => "Language Design Principles   
           "), -- MetaRulesTitle
+        Syntax          => (Length =>  6, Str => "Syntax                       
           "), -- SyntaxTitle
+        Resolution      => (Length => 21, Str => "Name Resolution Rules        
           "), -- ResolutionTitle
+        Legality        => (Length => 14, Str => "Legality Rules               
           "), -- LegalityTitle
+        Static_Semantics=> (Length => 16, Str => "Static Semantics             
           "), -- StaticSemTitle
+        Link_Time       => (Length => 22, Str => "Post-Compilation Rules       
           "), -- LinkTimeTitle
+        Run_Time        => (Length => 17, Str => "Dynamic Semantics            
           "), -- RunTimeTitle
+        Bounded_Errors  => (Length => 25, Str => "Bounded (Run-Time) Errors    
           "), -- BoundedTitle
+        Erroneous       => (Length => 19, Str => "Erroneous Execution          
           "), -- ErronTitle
+        Requirements    => (Length => 27, Str => "Implementation Requirements  
           "), -- ImplReqTitle
+        Documentation   => (Length => 26, Str => "Documentation Requirements   
           "), -- DocReqTitle
+        Metrics         => (Length =>  7, Str => "Metrics                      
           "), -- MetricsTitle
+        Permissions     => (Length => 26, Str => "Implementation Permissions   
           "), -- ImplPermTitle
+        Advice          => (Length => 21, Str => "Implementation Advice        
           "), -- ImplAdviceTitle
+        Notes           => (Length =>  5, Str => "NOTES                        
           "), -- NotesTitle
+        Single_Note     => (Length =>  5, Str => "NOTES                        
           "), -- SimpleNoteTitle
+        Examples        => (Length =>  8, Str => "Examples                     
           "), -- ExamplesTitle
+        Ada83_Inconsistencies
+                        => (Length => 27, Str => "Inconsistencies With Ada 83  
           "), -- Inconsistent83Title
+        Ada83_Incompatibilities
+                        => (Length => 29, Str => "Incompatibilities With Ada 
83           "), -- Incompatible83Title
+        Ada83_Extensions=> (Length => 20, Str => "Extensions to Ada 83         
           "), -- Extend83Title
+        Ada83_Wording   => (Length => 27, Str => "Wording Changes from Ada 83  
           "), -- DiffWord83Title
+        Ada95_Inconsistencies
+                        => (Length => 27, Str => "Inconsistencies With Ada 95  
           "), -- Inconsistent95Title
+        Ada95_Incompatibilities
+                        => (Length => 29, Str => "Incompatibilities With Ada 
95           "), -- Incompatible95Title
+        Ada95_Extensions=> (Length => 20, Str => "Extensions to Ada 95         
           "), -- Extend95Title
+        Ada95_Wording   => (Length => 27, Str => "Wording Changes from Ada 95  
           "), -- DiffWord95Title
+        Ada2005_Inconsistencies
+                        => (Length => 29, Str => "Inconsistencies With Ada 
2005           "), -- Inconsistent2005Title
+        Ada2005_Incompatibilities
+                        => (Length => 31, Str => "Incompatibilities With Ada 
2005         "), -- Incompatible2005Title
+        Ada2005_Extensions
+                        => (Length => 22, Str => "Extensions to Ada 2005       
           "), -- Extend2005Title
+        Ada2005_Wording => (Length => 29, Str => "Wording Changes from Ada 
2005           "), -- DiffWord2005Title
+        Ada2012_Inconsistencies
+                        => (Length => 29, Str => "Inconsistencies With Ada 
2012           "), -- Inconsistent2012Title
+        Ada2012_Incompatibilities
+                        => (Length => 31, Str => "Incompatibilities With Ada 
2012         "), -- Incompatible2012Title
+        Ada2012_Extensions
+                        => (Length => 22, Str => "Extensions to Ada 2012       
           "), -- Extend2012Title
+        Ada2012_Wording => (Length => 29, Str => "Wording Changes from Ada 
2012           "), -- DiffWord2012Title
+        Element_Ref     => (Length => 19, Str => "Element Reference:           
           "), -- Paragraph start.
+        Child_Ref       => (Length => 28, Str => "Child Elements returned by:  
           "), -- Paragraph start.
+        Usage_Note      => (Length => 12, Str => "Usage Note:                  
           "), -- Paragraph start.
+        Reason          => (Length =>  8, Str => "Reason:                      
           "), -- Paragraph start.
+        Ramification    => (Length => 14, Str => "Ramification:                
           "), -- Paragraph start.
+        Proof           => (Length =>  7, Str => "Proof:                       
           "), -- Paragraph start.
+        Imp_Note        => (Length => 21, Str => "Implementation Note:         
           "), -- Paragraph start.
+        Corr_Change     => (Length =>  8, Str => "Change:                      
           "), -- Paragraph start.
+        Discussion      => (Length => 12, Str => "Discussion:                  
           "), -- Paragraph start.
+        Honest          => (Length => 14, Str => "To be honest:                
           "), -- Paragraph start.
+        Glossary_Marker => (Length => 16, Str => "Glossary entry:              
           "), -- Paragraph start.
+        Bare_Annotation => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Wide_Above      => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Example_Text    => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Child_Example_Text => (Length =>  0, Str => (others => ' ')), -- Not 
used.
+        Indented_Example_Text=>(Length =>  0, Str => (others => ' ')), -- Not 
used.
+        Code_Indented   => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Indent          => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Bulleted        => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Nested_Bulleted => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Nested_X2_Bulleted=>(Length=>  0, Str => (others => ' ')), -- Not used.
+        Display         => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Syntax_Display  => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Syntax_Indented => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Syntax_Production=>(Length =>  0, Str => (others => ' ')), -- Not used.
+        Enumerated      => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Nested_Enumerated=>(Length =>  0, Str => (others => ' ')), -- Not used.
+        Hanging_Indented_1=>(Length => 0, Str => (others => ' ')), -- Not used.
+        Hanging_Indented_2=>(Length => 0, Str => (others => ' ')), -- Not used.
+        Hanging_Indented_3=>(Length => 0, Str => (others => ' ')), -- Not used.
+        Hanging_Indented_4=>(Length => 0, Str => (others => ' ')), -- Not used.
+        Small           => (Length =>  0, Str => (others => ' ')), -- Not used.
+        Title           => (Length =>  0, Str => (others => ' ')), -- Not used.
+        In_Table        => (Length =>  0, Str => (others => ' '))); -- Not 
used.
+
+
+    type Command_Type is (
+       -- Paragraphs:
+       Text_Begin, Text_End, Redundant, Comment, Part, New_Page, Soft_Page,
+       New_Column, RM_New_Page, New_Page_for_Version, New_Column_for_Version,
+       RM_New_Page_for_Version, Not_Iso_RM_New_Page_for_Version,
+       Iso_Only_RM_New_Page_for_Version,
+       -- Basic text formatting:
+       Bold, Italic, Roman, Swiss, Fixed, Roman_Italic, Shrink, Grow,
+       Black, Red, Green, Blue,
+       Keyword, Non_Terminal, Non_Terminal_Format,
+       Example_Text, Example_Comment,
+       No_Prefix, No_Para_Num, Keep_with_Next,
+        Leading, Trailing, Up, Down, Thin_Line, Thick_Line, Tab_Clear, Tab_Set,
+       -- Tables:
+       Table, Table_Param_Caption, Table_Param_Header, Table_Param_Body, 
Table_Last,
+       -- Pictures:
+       Picture_Alone, Picture_Inline,
+        -- Indexing:
+       Index_List,
+       Defn, RootDefn, PDefn, Defn2, RootDefn2, PDefn2, Index_See,
+       Index_See_Also, See_Other, See_Also,
+       Index_Root_Unit, Index_Child_Unit, Index_Subprogram_Child_Unit,
+       Index_Type, Index_Subtype, Index_Subprogram,
+       Index_Exception, Index_Object, Index_Package,
+       Index_Other, Index_Check, Index_Attr, Index_Pragma, Index_Aspect,
+       -- Clause labels:
+       Labeled_Section, Labeled_Section_No_Break, Labeled_Clause,
+       Labeled_Subclause, Labeled_Subsubclause,
+       Labeled_Revised_Section, Labeled_Revised_Clause, 
Labeled_Revised_Subclause, Labeled_Revised_Subsubclause,
+        Labeled_Added_Section, Labeled_Added_Clause, Labeled_Added_Subclause, 
Labeled_Added_Subsubclause,
+        Labeled_Deleted_Clause, Labeled_Deleted_Subclause, 
Labeled_Deleted_Subsubclause,
+       Preface_Section,
+       Labeled_Annex, Labeled_Revised_Annex, Labeled_Added_Annex,
+       Labeled_Informative_Annex, Labeled_Revised_Informative_Annex,
+        Labeled_Added_Informative_Annex,
+       Labeled_Normative_Annex, Labeled_Revised_Normative_Annex,
+        Labeled_Added_Normative_Annex,
+       Unnumbered_Section, Subheading, Heading, Center, Right,
+        Added_Subheading,
+       -- Clause references:
+       Ref_Section, Ref_Section_Number, Ref_Section_by_Number,
+       -- Links:
+       Local_Target, Local_Link, URL_Link, AI_Link,
+       -- Information:
+       Syntax_Rule, Syntax_Rule_RHS, Syntax_Term, Syntax_Term_Undefined,
+       Syntax_Prefix, Syntax_Summary, Syntax_Xref,
+       Added_Syntax_Rule, Deleted_Syntax_Rule,
+       Implementation_Defined, Implementation_Defined_List,
+       To_Glossary, To_Glossary_Also,
+       Change_To_Glossary, Change_To_Glossary_Also,
+       Glossary_Text_Param, -- This is a parameter of the last four.
+       Glossary_List,
+        Prefix_Type, Reset_Prefix_Type, Attribute, Attribute_Leading, 
Attribute_Text_Param, -- The last is a parameter of Attribute.
+       Attribute_List,
+       Pragma_Syntax, Pragma_List, Added_Pragma_Syntax, Deleted_Pragma_Syntax,
+       Package_List, Type_List, Subprogram_List, Exception_List, Object_List,
+       -- Corrigendum changes:
+       Change, Change_Param_Old, Change_Param_New, -- The latter are the 
parameters of "Change".
+       Change_Reference, Change_Note,
+       Change_Added, Change_Added_Param, Change_Deleted, Change_Deleted_Param,
+       Change_Implementation_Defined,
+       Change_Impdef_Text_Param, -- This is a parameter of the previous.
+       Change_Implementation_Advice,
+       Change_Impladv_Text_Param, -- This is a parameter of the previous.
+       Added_Implementation_Advice_List,
+       Change_Documentation_Requirement,
+       Change_DocReq_Text_Param, -- This is a parameter of the previous.
+       Added_Documentation_Requirements_List,
+       Change_Aspect_Description,
+       Change_AspectDesc_Text_Param, -- This is a parameter of the previous.
+       Added_Aspect_Description_List,
+       Change_Attribute, Change_Prefix_Type,
+       Change_Prefix_Text_Param, -- This is a parameter of the previous.
+       -- Text macros:
+       Intro_Name, Syntax_Name, Resolution_Name, Legality_Name, Static_Name,
+       Link_Name, Run_Name, Bounded_Name, Erroneous_Name, Req_Name,
+       Doc_Name, Metrics_Name, Permission_Name, Advice_Name, Notes_Name,
+       Single_Note_Name, Examples_Name, Meta_Name, Inconsistent83_Name,
+       Incompatible83_Name, Extend83_Name, Wording83_Name,
+       Inconsistent95_Name, Incompatible95_Name, Extend95_Name, Wording95_Name,
+       Inconsistent2005_Name, Incompatible2005_Name, Extend2005_Name, 
Wording2005_Name,
+       Inconsistent2012_Name, Incompatible2012_Name, Extend2012_Name, 
Wording2012_Name,
+       Syntax_Title, Resolution_Title, Legality_Title, Static_Title,
+       Link_Title, Run_Title, Bounded_Title, Erroneous_Title, Req_Title,
+       Doc_Title, Metrics_Title, Permission_Title, Advice_Title, Notes_Title,
+       Single_Note_Title,
+       Examples_Title, Meta_Title, Inconsistent83_Title, Incompatible83_Title,
+       Extend83_Title, Wording83_Title, Inconsistent95_Title, 
Incompatible95_Title,
+       Extend95_Title, Wording95_Title, Inconsistent2005_Title, 
Incompatible2005_Title,
+       Extend2005_Title, Wording2005_Title, Inconsistent2012_Title, 
Incompatible2012_Title,
+       Extend2012_Title, Wording2012_Title,
+       -- Character macros:
+       EM_Dash, EN_Dash, LE, LT, GE, GT, NE, PI, Times, PorM, Single_Quote,
+       Latin_1, Unicode, Ceiling, Floor, Absolute, Log, Thin_Space,
+       Left_Quote, Right_Quote, Left_Double_Quote, Right_Double_Quote,
+       Left_Quote_Pair, Right_Quote_Pair, Small_Dotless_I, Capital_Dotted_I,
+       Unknown);
+
+
+    function Command (Name : in ARM_Input.Command_Name_Type)
+        return Command_Type;
+       -- Return the command value for a particular command name:
+
+end ARM_Format.Data;
\ No newline at end of file
diff --git a/packages/ada-ref-man/progs/arm_frms.adb 
b/packages/ada-ref-man/progs/arm_frms.adb
new file mode 100755
index 0000000..8dc3d50
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_frms.adb
@@ -0,0 +1,1016 @@
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This subprogram is part of the command processor.
+    --
+    -- We use dispatching calls to call the formatter, so the details of
+    -- formatting are insulated from the code that reads the source and
+    -- determines the details of the text.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2004, 2005, 2006, 2007, 2009, 2011
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  2/10/06 - RLB - Split from base package.
+    --  9/22/06 - RLB - Revised to use Clause_Number_Type, and to support
+    --                 Subsubclauses.
+    -- 10/16/06 - RLB - Added definition of old non-terminals for NT linking.
+    --  2/16/07 - RLB - Added missing code to handle comments here.
+    --  7/31/07 - RLB - Added code to detect duplicated titles.
+    -- 12/18/07 - RLB - Added Plain_Annex and associated commands.
+    --  5/06/09 - RLB - Added Labeled_Deleted_xxx.
+    --  5/07/09 - RLB - Changed above to load dead clauses.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+
+separate(ARM_Format)
+procedure Scan (Format_Object : in out Format_Type;
+               File_Name : in String;
+               Section_Number : in ARM_Contents.Section_Number_Type;
+               Starts_New_Section : in Boolean) is
+    -- Scans the contents for File_Name, determining the table of contents
+    -- for the section. The results are written to the contents package.
+    -- Starts_New_Section is True if the file starts a new section.
+    -- Section_Number is the number (or letter) of the section.
+
+    type Items is record
+        Command : Command_Type;
+        Close_Char : Character; -- Ought to be }, ], >, or ).
+    end record;
+    Nesting_Stack : array (1 .. 60) of Items;
+    Nesting_Stack_Ptr : Natural := 0;
+    Saw_a_Section_Header : Boolean := False;
+
+    Input_Object : ARM_File.File_Input_Type;
+
+    procedure Set_Nesting_for_Command (Command : in Command_Type;
+                                      Param_Ch : in Character) is
+        -- Push the command onto the nesting stack.
+    begin
+        if Nesting_Stack_Ptr < Nesting_Stack'Last then
+           Nesting_Stack_Ptr := Nesting_Stack_Ptr + 1;
+           Nesting_Stack (Nesting_Stack_Ptr) :=
+               (Command => Command,
+                Close_Char => ARM_Input.Get_Close_Char (Param_Ch));
+--Ada.Text_IO.Put_Line (" &Stack (" & Command_Type'Image(Command) & "); 
Close-Char=" &
+--  Nesting_Stack(Nesting_Stack_Ptr).Close_Char);
+        else
+           Ada.Text_IO.Put_Line ("** Nesting stack overflow on line" & 
ARM_File.Line_String (Input_Object));
+           for I in reverse Nesting_Stack'range loop
+               Ada.Text_IO.Put_Line ("-- Command at" & Natural'Image(I) & " 
has a close char of '" &
+                   Nesting_Stack (Nesting_Stack_Ptr).Close_Char & "' for " & 
Command_Type'Image(Nesting_Stack (Nesting_Stack_Ptr).Command));
+           end loop;
+           raise Program_Error;
+        end if;
+    end Set_Nesting_for_Command;
+
+
+    procedure Scan_Command_with_Parameter is
+        -- Scan the start of a command with a parameter.
+        -- The parameter character has been scanned, and
+        -- a stack item pushed.
+        Title : ARM_Contents.Title_Type;
+        Title_Length : Natural;
+
+        procedure Get_Change_Version (Is_First : in Boolean;
+                                     Version : out 
ARM_Contents.Change_Version_Type) is
+           -- Get a parameter named "Version", containing a character
+           -- representing the version number.
+           Ch, Close_Ch : Character;
+        begin
+           ARM_Input.Check_Parameter_Name (Input_Object,
+               Param_Name => "Version" & (8..ARM_Input.Command_Name_Type'Last 
=> ' '),
+               Is_First => Is_First,
+               Param_Close_Bracket => Close_Ch);
+           if Close_Ch /= ' ' then
+               -- Get the version character:
+               ARM_File.Get_Char (Input_Object, Ch);
+               Version := ARM_Contents.Change_Version_Type(Ch);
+               ARM_File.Get_Char (Input_Object, Ch);
+               if Ch /= Close_Ch then
+                   Ada.Text_IO.Put_Line ("  ** Bad close for change version on 
line " & ARM_File.Line_String (Input_Object));
+                   ARM_File.Replace_Char (Input_Object);
+               end if;
+           -- else no parameter. Weird.
+           end if;
+        end Get_Change_Version;
+
+    begin
+        case Nesting_Stack(Nesting_Stack_Ptr).Command is
+           when Labeled_Section | Labeled_Section_No_Break |
+                Labeled_Annex | Labeled_Informative_Annex |
+                Labeled_Normative_Annex | Labeled_Clause |
+                Labeled_Subclause | Labeled_Subsubclause =>
+               -- Load the title into the Title string:
+               ARM_Input.Copy_to_String_until_Close_Char (
+                   Input_Object,
+                   Nesting_Stack(Nesting_Stack_Ptr).Close_Char,
+                   Title, Title_Length);
+               Title(Title_Length+1 .. Title'Last) :=
+                   (others => ' ');
+               if Nesting_Stack(Nesting_Stack_Ptr).Command = Labeled_Subclause 
then
+                   Format_Object.Clause_Number :=
+                       (Section   => Format_Object.Clause_Number.Section,
+                        Clause    => Format_Object.Clause_Number.Clause,
+                        Subclause => Format_Object.Clause_Number.Subclause + 1,
+                        Subsubclause => 0);
+               elsif Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Subsubclause then
+                   Format_Object.Clause_Number.Subsubclause :=
+                       Format_Object.Clause_Number.Subsubclause + 1;
+               elsif Nesting_Stack(Nesting_Stack_Ptr).Command = Labeled_Clause 
then
+                   Format_Object.Clause_Number :=
+                       (Section   => Format_Object.Clause_Number.Section,
+                        Clause    => Format_Object.Clause_Number.Clause + 1,
+                        Subclause => 0, Subsubclause => 0);
+               elsif Saw_a_Section_Header then
+                   Ada.Text_IO.Put_Line ("  ** Multiple section headers in a 
file, line " &
+                           ARM_File.Line_String (Input_Object));
+               else
+                   Saw_a_Section_Header := True;
+                   Format_Object.Clause_Number :=
+                       (Section   => Format_Object.Clause_Number.Section, -- 
Will be set elsewhere.
+                        Clause    => 0,
+                        Subclause => 0, Subsubclause => 0);
+               end if;
+
+               begin
+                   declare
+                       Ref : constant String := 
ARM_Contents.Lookup_Clause_Number (Title);
+                   begin
+                       -- If we get here, this title is already defined. Oops.
+                       Ada.Text_IO.Put_Line ("  ** Title """ &
+                           Title(1..Title_Length) & """ is multiply defined on 
line " &
+                           ARM_File.Line_String (Input_Object));
+                       Ada.Text_IO.Put_Line ("     Initial use is for clause " 
& Ref);
+                   end;
+               exception
+                   when ARM_Contents.Not_Found_Error =>
+                       -- OK, not previously defined.
+
+                       -- Load the title into the contents package:
+                       if Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Subclause then
+                           ARM_Contents.Add (Title, ARM_Contents.Subclause,
+                                             Format_Object.Clause_Number);
+                       elsif Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Subsubclause then
+                           ARM_Contents.Add (Title, ARM_Contents.Subsubclause,
+                                             Format_Object.Clause_Number);
+                       elsif Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Clause then
+                           ARM_Contents.Add (Title, ARM_Contents.Clause,
+                                             Format_Object.Clause_Number);
+                       elsif Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Section or else
+                             Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Section_No_Break then
+                           ARM_Contents.Add (Title, ARM_Contents.Section,
+                                             Format_Object.Clause_Number);
+                       elsif Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Annex then
+                           ARM_Contents.Add (Title, ARM_Contents.Plain_Annex,
+                                             Format_Object.Clause_Number);
+                       elsif Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Normative_Annex then
+                           ARM_Contents.Add (Title, 
ARM_Contents.Normative_Annex,
+                                             Format_Object.Clause_Number);
+                       else
+                           ARM_Contents.Add (Title, 
ARM_Contents.Informative_Annex,
+                                             Format_Object.Clause_Number);
+                       end if;
+               end;
+
+               Nesting_Stack_Ptr := Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Header)");
+
+           when Unnumbered_Section =>
+               -- Load the title into the Title string:
+               ARM_Input.Copy_to_String_until_Close_Char (
+                   Input_Object,
+                   Nesting_Stack(Nesting_Stack_Ptr).Close_Char,
+                   Title, Title_Length);
+               Title(Title_Length+1 .. Title'Last) :=
+                   (others => ' ');
+               Format_Object.Unnumbered_Section :=
+                   Format_Object.Unnumbered_Section + 1;
+               -- This section will be numbered 0.Unnumbered_Section:
+               Format_Object.Clause_Number :=
+                   (Section   => 0,
+                    Clause    => Format_Object.Unnumbered_Section,
+                    Subclause => 0, Subsubclause => 0);
+
+               begin
+                   declare
+                       Ref : constant String := 
ARM_Contents.Lookup_Clause_Number (Title);
+                   begin
+                       -- If we get here, this title is already defined. Oops.
+                       Ada.Text_IO.Put_Line ("  ** Title """ &
+                           Title(1..Title_Length) & """ is multiply defined on 
line " &
+                           ARM_File.Line_String (Input_Object));
+                       Ada.Text_IO.Put_Line ("     Initial use is for clause " 
& Ref);
+                   end;
+               exception
+                   when ARM_Contents.Not_Found_Error =>
+                       -- OK, not previously defined.
+
+                       -- Load the title into the contents package:
+                       ARM_Contents.Add (Title, 
ARM_Contents.Unnumbered_Section,
+                                         Format_Object.Clause_Number);
+               end;
+
+               Nesting_Stack_Ptr := Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Header)");
+
+           when Labeled_Revised_Annex |
+                Labeled_Revised_Informative_Annex |
+                Labeled_Revised_Normative_Annex |
+                Labeled_Revised_Section |
+                Labeled_Revised_Clause |
+                Labeled_Revised_Subclause |
+                Labeled_Revised_Subsubclause =>
+               declare
+                   Old_Title : ARM_Contents.Title_Type;
+                   Old_Title_Length : Natural;
+                   Close_Ch : Character;
+                   Version : ARM_Contents.Change_Version_Type := '0';
+                   Initial_Version : ARM_Contents.Change_Version_Type := '0';
+               begin
+                   Get_Change_Version (Is_First => True,
+                                       Version => Version);
+
+                   -- Check for the optional "InitialVersion" parameter,
+                   -- stopping when we reach "New":
+                   declare
+                       Which_Param : ARM_Input.Param_Num;
+                       Ch              : Character;
+                   begin
+                       -- If there is no InitialVersion command, use the same
+                       -- version of the rest of the command.
+                       loop
+                           ARM_Input.Check_One_of_Parameter_Names 
(Input_Object,
+                               Param_Name_1 => "InitialVersion" & 
(15..ARM_Input.Command_Name_Type'Last => ' '),
+                               Param_Name_2 => "New" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                               Is_First => False,
+                               Param_Found => Which_Param,
+                               Param_Close_Bracket => Close_Ch);
+
+                           if Which_Param = 1 and then Close_Ch /= ' ' then
+                               -- Found InitialVersion
+                               ARM_File.Get_Char (Input_Object, Ch);
+                               Initial_Version := Ch;
+                               ARM_File.Get_Char (Input_Object, Ch);
+                               if Ch /= Close_Ch then
+                                   Ada.Text_IO.Put_Line ("  ** Bad close for 
InitialVersion parameter on line " &
+                                       ARM_File.Line_String (Input_Object));
+                                   ARM_File.Replace_Char (Input_Object);
+                               end if;
+                           else -- We found "New" (or an error)
+                               exit; -- Handling of New is below.
+                           end if;
+                       end loop;
+                   end;
+
+                   if Close_Ch /= ' ' then
+                       -- There is a parameter:
+                       -- Load the new title into the Title string:
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           Close_Ch,
+                           Title, Title_Length);
+                       Title(Title_Length+1 .. Title'Last) :=
+                           (others => ' ');
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                           Param_Name => "Old" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                           Is_First => False,
+                           Param_Close_Bracket => Close_Ch);
+                       if Close_Ch /= ' ' then
+                           -- There is a parameter:
+                           -- Load the new title into the Title string:
+                           ARM_Input.Copy_to_String_until_Close_Char (
+                               Input_Object,
+                               Close_Ch,
+                               Old_Title, Old_Title_Length);
+                           Old_Title(Old_Title_Length+1 .. Old_Title'Last) :=
+                               (others => ' ');
+                       end if;
+                   end if;
+                   ARM_File.Get_Char (Input_Object, Close_Ch);
+                   if Close_Ch /= Nesting_Stack(Nesting_Stack_Ptr).Close_Char 
then
+                       Ada.Text_IO.Put_Line ("  ** Bad close for 
Labeled_Revised_(SubClause|Annex) on line " & ARM_File.Line_String 
(Input_Object));
+                       ARM_File.Replace_Char (Input_Object);
+                   end if;
+
+                   if Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Revised_Subclause then
+                       Format_Object.Clause_Number :=
+                           (Section   => Format_Object.Clause_Number.Section,
+                            Clause    => Format_Object.Clause_Number.Clause,
+                            Subclause => Format_Object.Clause_Number.Subclause 
+ 1,
+                            Subsubclause => 0);
+                   elsif Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Revised_Subsubclause then
+                       Format_Object.Clause_Number.Subsubclause :=
+                           Format_Object.Clause_Number.Subsubclause + 1;
+                   elsif Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Revised_Clause then
+                       Format_Object.Clause_Number :=
+                           (Section   => Format_Object.Clause_Number.Section,
+                            Clause    => Format_Object.Clause_Number.Clause + 
1,
+                            Subclause => 0, Subsubclause => 0);
+                   elsif Saw_a_Section_Header then
+                       Ada.Text_IO.Put_Line ("  ** Multiple section headers in 
a file, line " &
+                               ARM_File.Line_String (Input_Object));
+                   else
+                       Saw_a_Section_Header := True;
+                       Format_Object.Clause_Number :=
+                           (Section   => Format_Object.Clause_Number.Section, 
-- Will be set elsewhere.
+                            Clause    => 0,
+                            Subclause => 0, Subsubclause => 0);
+                   end if;
+
+                   begin
+                       declare
+                           Ref : constant String := 
ARM_Contents.Lookup_Clause_Number (Title);
+                       begin
+                           -- If we get here, this title is already defined. 
Oops.
+                           Ada.Text_IO.Put_Line ("  ** Title """ &
+                               Title(1..Title_Length) & """ is multiply 
defined on line " &
+                               ARM_File.Line_String (Input_Object));
+                           Ada.Text_IO.Put_Line ("     Initial use is for 
clause " & Ref);
+                       end;
+                   exception
+                       when ARM_Contents.Not_Found_Error =>
+                           -- OK, not previously defined.
+
+                           -- Load the title into the contents package:
+                           if Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Revised_Subclause then
+                               ARM_Contents.Add (Title, ARM_Contents.Subclause,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Version);
+                               ARM_Contents.Add_Old (Old_Title,
+                                                 ARM_Contents.Subclause,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Initial_Version);
+                           elsif Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Revised_Subsubclause then
+                               ARM_Contents.Add (Title, 
ARM_Contents.Subsubclause,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Version);
+                               ARM_Contents.Add_Old (Old_Title,
+                                                 ARM_Contents.Subsubclause,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Initial_Version);
+                           elsif Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Revised_Clause then
+                               ARM_Contents.Add (Title, ARM_Contents.Clause,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Version);
+                               ARM_Contents.Add_Old (Old_Title,
+                                                 ARM_Contents.Clause,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Initial_Version);
+                           elsif Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Revised_Section then
+                               ARM_Contents.Add (Title, ARM_Contents.Section,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Version);
+                               ARM_Contents.Add_Old (Old_Title,
+                                                 ARM_Contents.Section,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Initial_Version);
+                           elsif Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Revised_Annex then
+                               ARM_Contents.Add (Title,
+                                                 ARM_Contents.Plain_Annex,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Version);
+                               ARM_Contents.Add_Old (Old_Title,
+                                                 ARM_Contents.Plain_Annex,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Initial_Version);
+                           elsif Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Revised_Normative_Annex then
+                               ARM_Contents.Add (Title,
+                                                 ARM_Contents.Normative_Annex,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Version);
+                               ARM_Contents.Add_Old (Old_Title,
+                                                 ARM_Contents.Normative_Annex,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Initial_Version);
+                           else -- Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Revised_Informative_Annex then
+                               ARM_Contents.Add (Title,
+                                                 
ARM_Contents.Informative_Annex,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Version);
+                               ARM_Contents.Add_Old (Old_Title,
+                                                 
ARM_Contents.Informative_Annex,
+                                                 Format_Object.Clause_Number,
+                                                 Version => Initial_Version);
+                           end if;
+                   end;
+
+                   Nesting_Stack_Ptr := Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Header)");
+               end;
+
+           when Labeled_Added_Annex |
+                Labeled_Added_Informative_Annex |
+                Labeled_Added_Normative_Annex |
+                Labeled_Added_Section |
+                Labeled_Added_Clause |
+                Labeled_Added_Subclause |
+                Labeled_Added_Subsubclause =>
+               declare
+                   Ch : Character;
+                   Version : ARM_Contents.Change_Version_Type := '0';
+                   How : ARM_Output.Change_Type;
+                   use type ARM_Output.Change_Type;
+               begin
+                   Get_Change_Version (Is_First => True,
+                                       Version => Version);
+                   ARM_Input.Check_Parameter_Name (Input_Object,
+                       Param_Name => "Name" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                       Is_First => False,
+                       Param_Close_Bracket => Ch);
+                   if Ch /= ' ' then
+                       -- There is a parameter:
+                       -- Load the new title into the Title string:
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           Ch,
+                           Title, Title_Length);
+                       Title(Title_Length+1 .. Title'Last) :=
+                           (others => ' ');
+                   end if;
+                   ARM_File.Get_Char (Input_Object, Ch);
+                   if Ch /= Nesting_Stack(Nesting_Stack_Ptr).Close_Char then
+                       Ada.Text_IO.Put_Line ("  ** Bad close for 
Labeled_Added_(Sub)Clause on line " & ARM_File.Line_String (Input_Object));
+                       ARM_File.Replace_Char (Input_Object);
+                   end if;
+
+                   -- Determine the insertion state for this label:
+                   Calc_Change_Disposition (Format_Object,
+                       Version => Version,
+                       Operation => ARM_Output.Insertion,
+                       Text_Kind => How);
+
+                   if How = Do_Not_Display_Text then
+                       null; -- Nothing to display, so we do *not* number it
+                             -- or insert it into the contents database.
+                   else
+                       begin
+                           declare
+                               Ref : constant String := 
ARM_Contents.Lookup_Clause_Number (Title);
+                           begin
+                               -- If we get here, this title is already 
defined. Oops.
+                               Ada.Text_IO.Put_Line ("  ** Title """ &
+                                   Title(1..Title_Length) & """ is multiply 
defined on line " &
+                                   ARM_File.Line_String (Input_Object));
+                               Ada.Text_IO.Put_Line ("     Initial use is for 
clause " & Ref);
+                           end;
+                       exception
+                           when ARM_Contents.Not_Found_Error =>
+                               -- OK, not previously defined.
+
+                               -- Load the title into the contents package:
+                               if Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Added_Subclause then
+                                   Format_Object.Clause_Number :=
+                                       (Section   => 
Format_Object.Clause_Number.Section,
+                                        Clause    => 
Format_Object.Clause_Number.Clause,
+                                        Subclause => 
Format_Object.Clause_Number.Subclause + 1,
+                                        Subsubclause => 0);
+                                   ARM_Contents.Add (Title, 
ARM_Contents.Subclause,
+                                                     
Format_Object.Clause_Number,
+                                                     Version => Version);
+                                   ARM_Contents.Add_Old ((others => ' '),
+                                                     ARM_Contents.Subclause,
+                                                     
Format_Object.Clause_Number);
+                               elsif Nesting_Stack(Nesting_Stack_Ptr).Command 
= Labeled_Added_Subsubclause then
+                                   Format_Object.Clause_Number.Subsubclause :=
+                                       
Format_Object.Clause_Number.Subsubclause + 1;
+                                   ARM_Contents.Add (Title, 
ARM_Contents.Subsubclause,
+                                                     
Format_Object.Clause_Number,
+                                                     Version => Version);
+                                   ARM_Contents.Add_Old ((others => ' '),
+                                                     ARM_Contents.Subsubclause,
+                                                     
Format_Object.Clause_Number);
+                               elsif Nesting_Stack(Nesting_Stack_Ptr).Command 
= Labeled_Added_Clause then
+                                   Format_Object.Clause_Number :=
+                                       (Section   => 
Format_Object.Clause_Number.Section,
+                                        Clause    => 
Format_Object.Clause_Number.Clause + 1,
+                                        Subclause => 0, Subsubclause => 0);
+                                   ARM_Contents.Add (Title, 
ARM_Contents.Clause,
+                                                     
Format_Object.Clause_Number,
+                                                     Version => Version);
+                                   ARM_Contents.Add_Old ((others => ' '),
+                                                     ARM_Contents.Clause,
+                                                     
Format_Object.Clause_Number);
+                               elsif Nesting_Stack(Nesting_Stack_Ptr).Command 
= Labeled_Added_Section then
+                                   if Saw_a_Section_Header then
+                                       Ada.Text_IO.Put_Line ("  ** Multiple 
section headers in a file, line " &
+                                               ARM_File.Line_String 
(Input_Object));
+                                   end if;
+                                   Saw_a_Section_Header := True;
+                                   Format_Object.Clause_Number :=
+                                       (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                        Clause    => 0,
+                                        Subclause => 0, Subsubclause => 0);
+                                   ARM_Contents.Add (Title,
+                                                     ARM_Contents.Section,
+                                                     
Format_Object.Clause_Number,
+                                                     Version => Version);
+                                   ARM_Contents.Add_Old ((others => ' '),
+                                                     ARM_Contents.Section,
+                                                     
Format_Object.Clause_Number);
+                               elsif Nesting_Stack(Nesting_Stack_Ptr).Command 
= Labeled_Added_Annex then
+                                   if Saw_a_Section_Header then
+                                       Ada.Text_IO.Put_Line ("  ** Multiple 
section headers in a file, line " &
+                                               ARM_File.Line_String 
(Input_Object));
+                                   end if;
+                                   Saw_a_Section_Header := True;
+                                   Format_Object.Clause_Number :=
+                                       (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                        Clause    => 0,
+                                        Subclause => 0, Subsubclause => 0);
+                                   ARM_Contents.Add (Title,
+                                                     ARM_Contents.Plain_Annex,
+                                                     
Format_Object.Clause_Number,
+                                                     Version => Version);
+                                   ARM_Contents.Add_Old ((others => ' '),
+                                                     ARM_Contents.Plain_Annex,
+                                                     
Format_Object.Clause_Number);
+                               elsif Nesting_Stack(Nesting_Stack_Ptr).Command 
= Labeled_Added_Normative_Annex then
+                                   if Saw_a_Section_Header then
+                                       Ada.Text_IO.Put_Line ("  ** Multiple 
section headers in a file, line " &
+                                               ARM_File.Line_String 
(Input_Object));
+                                   end if;
+                                   Saw_a_Section_Header := True;
+                                   Format_Object.Clause_Number :=
+                                       (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                        Clause    => 0,
+                                        Subclause => 0, Subsubclause => 0);
+                                   ARM_Contents.Add (Title,
+                                                     
ARM_Contents.Normative_Annex,
+                                                     
Format_Object.Clause_Number,
+                                                     Version => Version);
+                                   ARM_Contents.Add_Old ((others => ' '),
+                                                     
ARM_Contents.Normative_Annex,
+                                                     
Format_Object.Clause_Number);
+                               else -- 
Nesting_Stack(Nesting_Stack_Ptr).Command = Labeled_Added_Informative_Annex then
+                                   if Saw_a_Section_Header then
+                                       Ada.Text_IO.Put_Line ("  ** Multiple 
section headers in a file, line " &
+                                               ARM_File.Line_String 
(Input_Object));
+                                   end if;
+                                   Saw_a_Section_Header := True;
+                                   Format_Object.Clause_Number :=
+                                       (Section   => 
Format_Object.Clause_Number.Section, -- Will be set elsewhere.
+                                        Clause    => 0,
+                                        Subclause => 0, Subsubclause => 0);
+                                   ARM_Contents.Add (Title,
+                                                     
ARM_Contents.Informative_Annex,
+                                                     
Format_Object.Clause_Number,
+                                                     Version => Version);
+                                   ARM_Contents.Add_Old ((others => ' '),
+                                                     
ARM_Contents.Informative_Annex,
+                                                     
Format_Object.Clause_Number);
+                               end if;
+                       end;
+                   end if;
+
+                   Nesting_Stack_Ptr := Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Header)");
+               end;
+
+           when Labeled_Deleted_Clause |
+                Labeled_Deleted_Subclause |
+                Labeled_Deleted_Subsubclause =>
+               declare
+                   Ch : Character;
+                   Version : ARM_Contents.Change_Version_Type := '0';
+                   How : ARM_Output.Change_Type;
+                   use type ARM_Output.Change_Type;
+               begin
+                   Get_Change_Version (Is_First => True,
+                                       Version => Version);
+                   ARM_Input.Check_Parameter_Name (Input_Object,
+                       Param_Name => "Name" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                       Is_First => False,
+                       Param_Close_Bracket => Ch);
+                   if Ch /= ' ' then
+                       -- There is a parameter:
+                       -- Load the new title into the Title string:
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           Ch,
+                           Title, Title_Length);
+                       Title(Title_Length+1 .. Title'Last) :=
+                           (others => ' ');
+                   end if;
+                   ARM_File.Get_Char (Input_Object, Ch);
+                   if Ch /= Nesting_Stack(Nesting_Stack_Ptr).Close_Char then
+                       Ada.Text_IO.Put_Line ("  ** Bad close for 
Labeled_Deleted_(Sub)Clause on line " & ARM_File.Line_String (Input_Object));
+                       ARM_File.Replace_Char (Input_Object);
+                   end if;
+
+                   -- Determine the insertion state for this label:
+                   Calc_Change_Disposition (Format_Object,
+                       Version => Version,
+                       Operation => ARM_Output.Deletion,
+                       Text_Kind => How);
+
+--Ada.Text_IO.Put_Line ("Labeled_Deleted disp: " & 
ARM_Output.Change_Type'Image(How));
+                   if How = ARM_Output.None then
+                       -- Normal text, number normally.
+                       begin
+                           declare
+                               Ref : constant String := 
ARM_Contents.Lookup_Clause_Number (Title);
+                           begin
+                               -- If we get here, this title is already 
defined. Oops.
+                               Ada.Text_IO.Put_Line ("  ** Title """ &
+                                   Title(1..Title_Length) & """ is multiply 
defined on line " &
+                                   ARM_File.Line_String (Input_Object));
+                               Ada.Text_IO.Put_Line ("     Initial use is for 
clause " & Ref);
+                           end;
+                       exception
+                           when ARM_Contents.Not_Found_Error =>
+                               -- OK, not previously defined.
+
+                               -- Load the title into the contents package:
+                               if Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Deleted_Subclause then
+                                   Format_Object.Clause_Number :=
+                                       (Section   => 
Format_Object.Clause_Number.Section,
+                                        Clause    => 
Format_Object.Clause_Number.Clause,
+                                        Subclause => 
Format_Object.Clause_Number.Subclause + 1,
+                                        Subsubclause => 0);
+                                   ARM_Contents.Add (Title, 
ARM_Contents.Subclause,
+                                                     
Format_Object.Clause_Number,
+                                                     Version => '0'); -- 
Version here is an insertion version, and this was available from the beginning.
+                                   ARM_Contents.Add_Old ((others => ' '),
+                                                     ARM_Contents.Subclause,
+                                                     
Format_Object.Clause_Number);
+                               elsif Nesting_Stack(Nesting_Stack_Ptr).Command 
= Labeled_Deleted_Subsubclause then
+                                   Format_Object.Clause_Number.Subsubclause :=
+                                       
Format_Object.Clause_Number.Subsubclause + 1;
+                                   ARM_Contents.Add (Title, 
ARM_Contents.Subsubclause,
+                                                     
Format_Object.Clause_Number,
+                                                     Version => '0');
+                                   ARM_Contents.Add_Old ((others => ' '),
+                                                     ARM_Contents.Subsubclause,
+                                                     
Format_Object.Clause_Number);
+                           else -- Nesting_Stack(Nesting_Stack_Ptr).Command = 
Labeled_Deleted_Clause then
+                               Format_Object.Clause_Number :=
+                                   (Section   => 
Format_Object.Clause_Number.Section,
+                                    Clause    => 
Format_Object.Clause_Number.Clause + 1,
+                                    Subclause => 0, Subsubclause => 0);
+                               ARM_Contents.Add (Title, ARM_Contents.Clause,
+                                                 Format_Object.Clause_Number,
+                                                 Version => '0');
+                               ARM_Contents.Add_Old ((others => ' '),
+                                                 ARM_Contents.Clause,
+                                                 Format_Object.Clause_Number);
+                           end if;
+                       end;
+                   elsif How = ARM_Output.Insertion then
+                       -- Huh? We're deleting here.
+                       raise Program_Error;
+                   elsif How = ARM_Output.Deletion then
+                       -- We'll just display the header without a number.
+                       -- But we need to insert it so that x-refs don't
+                       -- fail.
+                       begin
+                           declare
+                               Ref : constant String := 
ARM_Contents.Lookup_Clause_Number (Title);
+                           begin
+                               -- If we get here, this title is already 
defined. Oops.
+                               Ada.Text_IO.Put_Line ("  ** Title """ &
+                                   Title(1..Title_Length) & """ is multiply 
defined on line " &
+                                   ARM_File.Line_String (Input_Object));
+                               Ada.Text_IO.Put_Line ("     Initial use is for 
clause " & Ref);
+                           end;
+                       exception
+                           when ARM_Contents.Not_Found_Error =>
+                               -- OK, not previously defined.
+
+                               -- Load the title into the contents package as 
a dead clause:
+                               ARM_Contents.Add (Title, 
ARM_Contents.Dead_Clause,
+                                                 (Section   => 0,
+                                                  Clause    => 1,
+                                                  Subclause => 0,
+                                                  Subsubclause => 0),
+                                                 Version => '0');
+                               ARM_Contents.Add_Old ((others => ' '),
+                                                 ARM_Contents.Dead_Clause,
+                                                 (Section   => 0,
+                                                  Clause    => 1,
+                                                  Subclause => 0,
+                                                  Subsubclause => 0));
+                       end;
+
+                   elsif How = Do_Not_Display_Text then
+                       null; -- Nothing to display/number.
+                   end if;
+
+                   Nesting_Stack_Ptr := Nesting_Stack_Ptr - 1;
+--Ada.Text_IO.Put_Line (" &Unstack (Header)");
+               end;
+
+           when Syntax_Rule | Added_Syntax_Rule | Deleted_Syntax_Rule =>
+               -- @Syn{[Tabs=<Tabset>, ]LHS=<Non-terminal>, RHS=<Production>}
+               -- @AddedSyn{Version=[<Version>],[Tabs=<Tabset>, 
]LHS=<Non-terminal>, RHS=<Production>}
+               -- @DeletedSyn{Version=[<Version>],[Tabs=<Tabset>, 
]LHS=<Non-terminal>, RHS=<Production>}
+               -- We need to index the non-terminal, so we can link to it
+               -- later. (If we didn't do this here, we wouldn't be able
+               -- to handle forward references.)
+               -- We only care about the non-terminal, so we skip the other
+               -- parts.
+               declare
+                   Close_Ch, Ch : Character;
+                   Seen_First_Param : Boolean := False;
+                   Non_Terminal : String (1..120);
+                   NT_Len : Natural := 0;
+               begin
+                   if Nesting_Stack(Nesting_Stack_Ptr).Command /= Syntax_Rule 
then
+                       -- Get and skip the Version parameter.
+                       Seen_First_Param := True;
+                       Get_Change_Version (Is_First => True,
+                                           Version => Ch);
+                   end if;
+
+                   -- Peek to see if Tabs parmeter is present, and skip it if
+                   -- it is:
+                   ARM_File.Get_Char (Input_Object, Ch);
+                   ARM_File.Replace_Char (Input_Object);
+                   if Ch = 'T' or else Ch = 't' then
+                       ARM_Input.Check_Parameter_Name (Input_Object,
+                          Param_Name => "Tabs" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                          Is_First => (not Seen_First_Param),
+                          Param_Close_Bracket => Close_Ch);
+                       Seen_First_Param := True;
+                       if Close_Ch /= ' ' then
+                           -- Grab the tab string:
+                           ARM_Input.Skip_until_Close_Char (
+                               Input_Object,
+                               Close_Ch);
+                       -- else no parameter. Weird.
+                       end if;
+                   end if;
+
+                   -- Get the LHS parameter and save it:
+                   ARM_Input.Check_Parameter_Name (Input_Object,
+                       Param_Name => "LHS" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                       Is_First => (not Seen_First_Param),
+                       Param_Close_Bracket => Close_Ch);
+                   if Close_Ch /= ' ' then
+                       -- Copy over the non-terminal:
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           Close_Ch,
+                           Non_Terminal,
+                           NT_Len);
+                   -- else no parameter. Weird.
+                   end if;
+
+                   -- Skip the RHS parameter:
+                   ARM_Input.Check_Parameter_Name (Input_Object,
+                      Param_Name => "RHS" & 
(4..ARM_Input.Command_Name_Type'Last => ' '),
+                      Is_First => False,
+                      Param_Close_Bracket => Close_Ch);
+                   Seen_First_Param := True;
+                   if Close_Ch /= ' ' then
+                       -- Grab the tab string:
+                       ARM_Input.Skip_until_Close_Char (
+                           Input_Object,
+                           Close_Ch);
+                   -- else no parameter. Weird.
+                   end if;
+
+                   declare
+                       The_Non_Terminal : constant String :=
+                           Ada.Characters.Handling.To_Lower (
+                               Get_Current_Item (Format_Object, Input_Object,
+                                   Non_Terminal(1..NT_Len))); -- Handle 
embedded @Chg.
+                       The_Old_Non_Terminal : constant String :=
+                           Ada.Characters.Handling.To_Lower (
+                               Get_Old_Item (Format_Object, Input_Object,
+                                   Non_Terminal(1..NT_Len))); -- Handle 
embedded @Chg.
+                   begin
+                       if Ada.Strings.Fixed.Index (The_Non_Terminal, "@") /= 0 
then
+                           -- Still embedded commands, do not register.
+                           Ada.Text_IO.Put_Line ("** Saw Non-Terminal with 
embedded commands: " &
+                               Non_Terminal(1..NT_Len) & " in " & 
Clause_String (Format_Object));
+                       elsif The_Non_Terminal = "" then
+                           null; -- Deleted Non-Terminal, nothing to do.
+                       else
+                           -- Save the non-terminal:
+                           declare
+                               Link_Target : ARM_Syntax.Target_Type;
+                           begin
+                                ARM_Syntax.Add_Non_Terminal
+                                    (NT_Name => The_Non_Terminal,
+                                     For_Clause => Clause_String 
(Format_Object),
+                                     Link_Target => Link_Target);
+                           end;
+--Ada.Text_IO.Put_Line ("%% Saw simple Non-Terminal: " & The_Non_Terminal & " 
in "
+--   & Clause_String (Format_Object));
+                       end if;
+                       if The_Old_Non_Terminal = "" then
+                           null; -- No old Non-Terminal, nothing to do.
+                       elsif ARM_Syntax.Non_Terminal_Clause 
(The_Old_Non_Terminal) /= "" then
+                           null; -- This non-terminal is already defined;
+                               -- that presumably is a *new* definition,
+                               -- we'll use that instead of this one.
+                       else
+                           -- Save the non-terminal:
+                           declare
+                               Link_Target : ARM_Syntax.Target_Type;
+                           begin
+                                ARM_Syntax.Add_Non_Terminal
+                                    (NT_Name => The_Old_Non_Terminal,
+                                     For_Clause => Clause_String 
(Format_Object),
+                                     Link_Target => Link_Target);
+                           end;
+--Ada.Text_IO.Put_Line ("%% Saw simple old Non-Terminal: " & 
The_Old_Non_Terminal & " in "
+--   & Clause_String (Format_Object));
+                       end if;
+                   end;
+               end;
+
+           when Comment =>
+--Ada.Text_IO.Put_Line("Comment with Close=" & 
Nesting_Stack(Nesting_Stack_Ptr).Close_Char &
+--   " on line " & ARM_File.Line_String (Input_Object));
+               -- Skip the contents of this command.
+               ARM_Input.Skip_until_Close_Char (Input_Object,
+                   Nesting_Stack(Nesting_Stack_Ptr).Close_Char);
+               ARM_File.Replace_Char (Input_Object); -- Put the close 
character back.
+--Ada.Text_IO.Put_Line("Comment done");
+
+           when others =>
+               null; -- Not in scanner.
+        end case;
+    end Scan_Command_with_Parameter;
+
+
+    procedure Handle_End_of_Command is
+        -- Unstack and handle the end of Commands.
+    begin
+        case Nesting_Stack(Nesting_Stack_Ptr).Command is
+           when others =>
+               -- No special handling needed.
+               null;
+        end case;
+--Ada.Text_IO.Put_Line (" &Unstack (Normal-"& 
Command_Type'Image(Nesting_Stack(Nesting_Stack_Ptr).Command) & ")");
+        Nesting_Stack_Ptr := Nesting_Stack_Ptr - 1;
+    end Handle_End_of_Command;
+
+
+    procedure Scan_Special is
+        -- Scan a special command/macro/tab.
+        -- These all start with '@'.
+        -- @xxxx is a command. It may have parameters delimited by
+        -- (), {}, [], or <>. There does not appear to be an escape, so
+        -- we don't have to worry about '}' being used in {} brackets,
+        -- for example. (Must be a pain to write, though.)
+        Command_Name : ARM_Input.Command_Name_Type;
+        Ch : Character;
+    begin
+        ARM_File.Get_Char (Input_Object, Ch);
+        if Ch = '\' then
+           -- This represents a tab (or the end of centered text). We're
+           -- done here.
+           return;
+        elsif Ch = '=' then
+           -- This marks the beginning of centered text.
+           -- We're done here.
+           return;
+        elsif Ch = '^' then
+           -- This represented a tab stop (these should have been
+           -- deleted from the input). We're done here.
+           return;
+        elsif Ch = '@' then
+           -- This represents @ in the text. We're done here.
+           return;
+        elsif Ch = ' ' then
+           -- This represents a hard space in the text. We're done here.
+           return;
+        elsif Ch = ';' then
+           -- This seems to be an end of command (or substitution) marker.
+           -- For instance, it is used in Section 1:
+           -- .. the distinction between @ResolutionName@;s and ...
+           -- This converts to:
+           -- .. the distinction between Name Resolution Rules and ...
+           -- Without it, the 's' would append to the command name, and
+           -- we would get the wrong command. Thus, it itself does nothing
+           -- at all, so we're done here.
+           return;
+        elsif Ch = '-' then
+           -- This represents a subscript. It has an argument.
+           ARM_File.Get_Char (Input_Object, Ch);
+           if ARM_Input.Is_Open_Char (Ch) then -- Start parameter:
+               Set_Nesting_for_Command
+                   (Command  => Unknown,
+                    Param_Ch => Ch);
+           else -- No parameter. Weird.
+               ARM_File.Replace_Char (Input_Object);
+           end if;
+           return;
+        elsif Ch = '+' then
+           -- This represents a superscript. It has an argument.
+           ARM_File.Get_Char (Input_Object, Ch);
+           if ARM_Input.Is_Open_Char (Ch) then -- Start parameter:
+               Set_Nesting_for_Command
+                   (Command  => Unknown,
+                    Param_Ch => Ch);
+           else -- No parameter. Weird.
+               ARM_File.Replace_Char (Input_Object);
+           end if;
+           return;
+        elsif Ch = ':' then
+           -- This is a period type marker. We're done here.
+           return;
+        elsif Ch = '*' then
+           -- This is a line break. We're done here.
+           return;
+        elsif Ch = '|' then
+           -- This is a soft line break. We're done here.
+           return;
+        elsif Ch = '!' then
+           -- This is a soft hyphen break. We're done here.
+           return;
+        elsif Ch = Ascii.LF then
+           -- Stand alone '@'.
+           -- I now believe this is an error. It appears in
+           -- Infosys.MSS, and seems to have something to do with formatting.
+           return;
+        end if;
+        ARM_File.Replace_Char (Input_Object);
+        Arm_Input.Get_Name (Input_Object, Command_Name);
+--Ada.Text_IO.Put_Line("Command=" & Command_Name & " Nesting=" & 
Natural'Image(Nesting_Stack_Ptr));
+
+        ARM_File.Get_Char (Input_Object, Ch);
+        if ARM_Input.Is_Open_Char (Ch) then -- Start parameter:
+           Set_Nesting_for_Command
+               (Command  => Command (Ada.Characters.Handling.To_Lower 
(Command_Name)),
+                Param_Ch => Ch);
+           Scan_Command_with_Parameter;
+        else
+           ARM_File.Replace_Char (Input_Object);
+           -- We're not interested in commands with no parameters.
+        end if;
+    end Scan_Special;
+
+begin
+    Ada.Text_IO.Put_Line ("-- Scanning " & File_Name);
+    begin
+        Arm_File.Open (Input_Object, File_Name);
+    exception
+        when others =>
+           Ada.Text_IO.Put_Line ("** Unable to open file " & File_Name);
+           raise;
+    end;
+    if Starts_New_Section then
+        Format_Object.Clause_Number := (Section => Section_Number, others => 
0);
+    end if;
+    loop
+        declare
+           Char : Character;
+        begin
+           ARM_File.Get_Char (Input_Object, Char);
+--Ada.Text_IO.Put_Line("Char=" & Char & " Nesting=" & 
Natural'Image(Nesting_Stack_Ptr));
+           case Char is
+               when '@' =>
+                   Scan_Special;
+               when Ascii.SUB =>
+                   exit; -- End of file.
+               when others =>
+                   if Nesting_Stack_Ptr /= 0 and then
+                      Nesting_Stack (Nesting_Stack_Ptr).Close_Char /= ' ' and 
then
+                      Nesting_Stack (Nesting_Stack_Ptr).Close_Char = Char then
+                       -- Closing a command, remove it from the stack.
+                       Handle_End_of_Command;
+                   else
+                       null; -- Ordinary characters, nothing to do.
+                   end if;
+           end case;
+        end;
+    end loop;
+    -- Reached end of the file.
+    Ada.Text_IO.Put_Line ("  Lines scanned: " &
+                    ARM_File.Line_String (Input_Object));
+    ARM_File.Close (Input_Object);
+    if Nesting_Stack_Ptr /= 0 then
+        Ada.Text_IO.Put_Line ("   ** Unfinished commands detected.");
+    end if;
+end Scan;
+
+
diff --git a/packages/ada-ref-man/progs/arm_html.adb 
b/packages/ada-ref-man/progs/arm_html.adb
new file mode 100755
index 0000000..1632539
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_html.adb
@@ -0,0 +1,5755 @@
+with -- ARM_Output,
+     -- ARM_Contents,
+     -- Ada.Text_IO,
+     Ada.Exceptions,
+     Ada.Strings.Maps.Constants,
+     Ada.Strings.Fixed,
+     Ada.Unchecked_Deallocation;
+package body ARM_HTML is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package defines the HTML output object.
+    -- Output objects are responsible for implementing the details of
+    -- a particular format.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
+    --          2008, 2009, 2011, 2012, 2013, 2016
+    -- AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  4/19/00 - RLB - Created base package.
+    --  4/21/00 - RLB - Added line break and hard space routines.
+    --  4/24/00 - RLB - Added DR references and Insert/Delete text formats.
+    --  4/25/00 - RLB - Added size to format.
+    --  4/26/00 - RLB - Added paragraph formats.
+    --  4/29/00 - RLB - Added more paragraph formats.
+    --  5/10/00 - RLB - Added even more formats.
+    --          - RLB - Added End_Hang_Item.
+    --  5/12/00 - RLB - Added No_Prefix to Start_Paragraph.
+    --  5/13/00 - RLB - Added Special_Character.
+    --  5/16/00 - RLB - Added additional special characters.
+    --  5/17/00 - RLB - Added New_Page.
+    --  5/22/00 - RLB - Added Includes_Changes to Create.
+    --  5/23/00 - RLB - Added multi-column formats and New_Column.
+    --               - Added Tab_Info and Tab_Stops.
+    --  5/24/00 - RLB - Added Location to Text_Format.
+    --         - RLB - Added No_Breaks and Keep_with_Next to Start_Paragraph.
+    --  5/25/00 - RLB - Added Big_Files to Create. Added Justification.
+    --         - RLB - Added Separator_Lines and TOC routines.
+    --         - RLB - Added "Legal" to the footer, pointing at the title page.
+    --  5/26/00 - RLB - Added table operations.
+    --  5/28/00 - RLB - Added index references.
+    --  6/ 2/00 - RLB - Added Soft_Line_Break.
+    --  8/ 2/00 - RLB - Added Soft_Hyphen_Break and left and right quote
+    --                 characters.
+    --         - RLB - Added additional styles.
+    --  8/ 7/00 - RLB - Added Leading flag to Start_Paragraph, removed 
"Leading"
+    --                 styles.
+    --  8/11/00 - RLB - Added Hanging_in_Bulleted styles.
+    --  8/16/00 - RLB - Added Code_Indented_Nested_Bulleted.
+    --  8/17/00 - RLB - Replaced "Leading" by "Space_After".
+    --                 - RLB - Added Nested_Enumerated.
+    --  8/22/00 - RLB - Added Revised_Clause_Header.
+    --  9/ 8/00 - RLB - Removed soft hyphen, as this does not work on either
+    --                 browser I tried.
+    --  9/26/00 - RLB - Added Syntax_Summary style.
+    --  9/27/00 - RLB - Added tab emulation when in the fixed font.
+    --  9/28/00 - RLB - Added some style sheets.
+    --         - RLB - Updated to use absolute positioning for paragraph
+    --                 numbers (this looks much better than floating).
+    --  7/18/01 - RLB - Added "Indented" style to supported styles for
+    --                 multi-column.
+    --         - RLB - Implemented single "Big-File" support.
+    --  7/18/02 - RLB - Removed Document parameter from Create, replaced by
+    --                 three strings and For_ISO boolean.
+    --         - RLB - Added AI_Reference.
+    --         - RLB - Added Change_Version_Type and uses.
+    --  1/15/03 - RLB - Removed space from DIV.paranum, as it doesn't validate
+    --                 with it.
+    --  4/10/03 - RLB - Updated to add access to search pages (not generated
+    --                 here; make them by hand, it only needs to be done once).
+    --         - RLB - Updated to insure that changes are separated by a space.
+    --  4/11/03 - RLB - Changed some formats to meet WC3 validation 
requirements.
+    --  9/09/04 - RLB - Removed unused junk noted by Stephen Leake.
+    --  9/10/04 - RLB - Added "Both" to possible changes to handle
+    --                 replacement of changed text.
+    --  9/14/04 - RLB - Moved Change_Version_Type to ARM_Contents.
+    --         - RLB - Changed to use left/right quotes whether or not Unicode
+    --                 is being used. (These work on IE, but not on old
+    --                 Netscape.)
+    --  9/16/04 - RLB - Added a charset meta in the header, so that browsers
+    --                 can't misinterpret these documents.
+    -- 11/03/04 - RLB - Added Nested_X2_Bulleted.
+    -- 11/15/04 - RLB - Added Indented_Nested_Bulleted.
+    -- 12/15/04 - RLB - Added wider columns.
+    --  1/24/05 - RLB - Added Inner_Indented.
+    --  2/ 1/05 - RLB - Added Turkish chars to allow an AARM note.
+    --  3/15/05 - RLB - Turned on Unicode characters at Pascal's insistence.
+    --  3/17/05 - RLB - Removed ceiling and floor characters because they don't
+    --                 work on Windows.
+    --  4/ 7/05 - RLB - Added "Related Documents" link, so users can go between
+    --                 the RM and AARM (and also so that they see the ARA
+    --                 sponsor ads).
+    --  5/27/05 - RLB - Added arbitrary Unicode characters.
+    --  1/11/06 - RLB - Eliminated dispatching Create in favor of tailored
+    --                 versions.
+    --  1/12/06 - RLB - Added a number of parameters to Create.
+    --  1/16/06 - RLB - Reduced space around button bars.
+    --  1/18/06 - RLB - Added additional styles.
+    --  1/19/06 - RLB - Added code so that only styles that are used are
+    --                 included in the result (this decreases the minimum
+    --                 file size by a lot).
+    --  1/21/06 - RLB - Specified leading for Swiss example styles, because
+    --                 they are too close otherwise.
+    --  1/28/06 - RLB - Changed so that button highlights are removed 
correctly.
+    --         - RLB - Added tab emulation settings.
+    --  2/ 8/06 - RLB - Added additional parameters to the table command.
+    --  2/10/06 - RLB - Added even more additional parameters to the
+    --                 table command.
+    --         - RLB - Added picture command.
+    --  2/19/06 - RLB - Added Number_Paragraphs flag and large letter count.
+    --  3/01/06 - RLB - Fixed bug in Text_Format when changing fonts.
+    --  3/03/06 - RLB - Moved paragraph numbers down slightly; this looks a lot
+    --                 better on Firefox, and better even on IE.
+    --         - RLB - Added Optimize_for_Firefox flag, and associated style
+    --                 changes.
+    --         - RLB - Added code so that spaces after an opening tag
+    --                 and before a closing tag are converted to non-breaking.
+    --  3/28/06 - RLB - Removed unnecessary space from headers.
+    --  3/30/06 - RLB - Added a bit of space around inline pictures.
+    --  9/21/06 - RLB - Added Body_Font.
+    --  9/22/06 - RLB - Added Subsubclause.
+    --  9/23/06 - RLB - Fixed bug in borderless tables.
+    --  9/25/06 - RLB - Handled optional renaming of TOC.
+    --         - RLB - Added Last_Column_Width to Start_Table.
+    --         - RLB - Fixed broken enumerated style.
+    -- 10/13/06 - RLB - Added specifiable colors.
+    --          - RLB - Added Local_Link_Start and Local_Link_End to allow
+    --                 formatting in the linked text.
+    -- 11/10/06 - RLB - Fixed nesting of text formatting *again*. (AARM 13.11
+    --                 failed WC 3 validation.)
+    --  2/ 9/07 - RLB - Changed comments on AI_Reference.
+    --  2/14/07 - RLB - Revised to separate style and indent information
+    --                 for paragraphs.
+    --  2/15/07 - RLB - Redid enumeration and bullet indenting to make the
+    --                 formats work consistently on Firefox and IE.
+    --  2/19/07 - RLB - Added Title style.
+    -- 12/14/07 - RLB - Added code to support multi-column text without
+    --                 requiring New_Column calls.
+    -- 12/18/07 - RLB - Added Plain_Annex.
+    -- 12/19/07 - RLB - Added DOS_Filename flag.
+    --         - RLB - Added limited colors to Text_Format.
+    --  1/02/08 - RLB - Made DOS filenames into all CAPS.
+    --  5/ 7/09 - RLB - Added code to prevent making links to dead clauses.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/25/11 - RLB - Added old insertion version to Revised_Clause_Header.
+    --  2/15/12 - RLB - Removed horizontal rules from page breaks in HTML;
+    --                 they never are necessary and cause weird looks for
+    --                 breaks put in solely to make the "final" version look
+    --                 good in PDF form.
+    --  5/18/12 - RLB - Added anchors to each paragraph number as suggested
+    --                 on comp.lang.ada.
+    --  8/31/12 - RLB - Added Output_Path.
+    -- 10/18/12 - RLB - Added additional hanging styles.
+    -- 11/26/12 - RLB - Added subdivision names to Clause_Header and
+    --                 Revised_Clause_Header.
+    -- 12/17/12 - RLB - Added AI12 references. Defined a change color for
+    --                 "version 4" (Ada 202x).
+    --  3/26/13 - RLB - Added Script_HTML.
+    --  2/ 8/16 - RLB - Added styles for the Ada-Auth.org header.
+    --               - Defined change colors for versions 5 and 6. (Actually
+    --                 "borrowed" the color for version 2, so the new colors
+    --                 are for version 2 and 6. Can't use dark blue, as links
+    --                 are that color.)
+    --  3/ 3/16 - RLB - The color change is hell on the RR manuals. Redid
+    --                 it to switch the colors only if version 5 is in use.
+    --  4/20/16 - RLB - Slightly increased the base indent as a lot of
+    --                 paragraph numbers are overlapping.
+    --               - Added Force_New_Revision_Colors.
+
+    LINE_LENGTH : constant := 78;
+       -- Maximum intended line length.
+
+    SWISS_FONT_CODE : constant String := "<font face=""Arial, Helvetica"">";
+
+    SMALL_SWISS_FONT_CODE : constant String := "<font face=""Arial, 
Helvetica"" size=-1>";
+
+    TINY_SWISS_FONT_CODE : constant String := "<font face=""Arial, Helvetica"" 
size=-2>";
+
+    LEADING_PERCENT : constant := 70;
+       -- Leading is 70% of normal height.
+    TRAILING_PERCENT : constant := 150;
+       -- Leading is 150% of normal height.
+
+    INDENT_EMS_FOR_PARANUMS : constant := 18;
+       -- Indent *all* text (for HTML 4) this amount to leave (some) room for
+       -- the paragraph numbers. In 0.1 EMs.
+
+    OPTIMIZE_FOR_FIREFOX : constant Boolean := True;
+       -- If True, we'll optimize for Firefox; otherwise, we'll optimize for
+       -- IE 6. Note that IE generally shows the Firefox code better than
+       -- Firefox shows the IE code, so we generally recommend setting to
+       -- True unless IE must be perfect. (Modern versions of IE are more
+       -- like Firefox, so it's unlikely that setting this to False should
+       -- be needed.)
+
+    type Tag_Kind is (DIV, UL, DL);
+
+    type Format_Info_Type is record
+       Defined: Boolean := False;
+       Tag    : Tag_Kind;
+       Size   : Integer; -- In relative "units" (based on the normal size). A 
unit is 125%/80% of normal.
+       Font   : ARM_Output.Font_Family_Type;
+       Indent : Natural; -- In "units". (A unit is = 2EM of the full sized 
font).
+       Right_Indent : Natural; -- In "units". (A unit is = 2EM of the full 
sized font).
+       Hang_Outdent : Natural; -- In "units". (A unit is = 2EM of the full 
sized font).
+               -- This is the amount that the hanging text hangs out. Normal
+               -- text starts at Hang_Outdent + Indent "units".
+       Before : Integer; -- Vertical space before in 0.1 EM.
+       After  : Natural; -- Vertical space after in 0.1 EM.
+    end record;
+
+    -- In the following, "Default" means the Body_Font.
+    Paragraph_Info : array
+       (ARM_Output.Paragraph_Style_Type, ARM_Output.Paragraph_Indent_Type) of
+          Format_Info_Type;
+       -- Defined below in the body of the package.
+
+    -- Are the various styles used??
+    Paragraph_Used : array (ARM_Output.Paragraph_Style_Type,
+                           ARM_Output.Paragraph_Indent_Type) of Boolean;
+    Revision_Used : array (ARM_Contents.Change_Version_Type) of Boolean;
+    Paranum_Used : Boolean;
+
+
+    procedure Free is new Ada.Unchecked_Deallocation (Column_Text_Item_Type, 
Column_Text_Ptr);
+
+    function Make_Clause_Anchor_Name (Output_Object : in HTML_Output_Type;
+                                     Clause_Number : in String) return String 
is
+       -- Internal routine.
+       -- Returns the Clause anchor name for the current output object and
+       -- Clause_Number.
+        Clause_Name : String(1..10);
+        Clause_Name_Len : Natural;
+    begin
+        if Clause_Number'Length >= 7 and then
+          Clause_Number(Clause_Number'First .. Clause_Number'First + 5) =
+          "Annex " then
+           Clause_Name(1) := Clause_Number(Clause_Number'First + 6);
+               -- We only want the letter.
+           Clause_Name_Len := 1;
+        else
+           Clause_Name_Len := Clause_Number'Length;
+           Clause_Name(1..Clause_Name_Len) := Clause_Number;
+           for I in 1 .. Clause_Name_Len loop
+               if Clause_Name(I) = '.' then
+                   Clause_Name(I) := '-';
+               end if;
+           end loop;
+        end if;
+        if Output_Object.DOS_Filenames and (not Output_Object.Big_Files) then
+           -- If the section number is a single character, then
+           -- prefix it with '-':
+           if Clause_Name_Len = 1 then
+               Clause_Name(2) := Clause_Name(1);
+               Clause_Name(1) := '-';
+               Clause_Name_Len := 2;
+           elsif Clause_Name_Len = 2 then
+               null;
+           else
+               if Clause_Name(2) = '-' then
+                   Clause_Name(2..Clause_Name_Len+1) :=
+                       Clause_Name(1..Clause_Name_Len);
+                   Clause_Name(1) := '-';
+                   Clause_Name_Len := Clause_Name_Len + 1;
+               end if;
+               -- OK, the section name is exactly two characters.
+               -- Figure out the Clause name.
+               if Clause_Name_Len < 4 or else
+                  Clause_Name(3) /= '-' or else
+                  Clause_Name(4) not in '0'..'9' or else
+                   (Clause_Name_Len >= 5 and then
+                   Clause_Name(5) /= '-' and then Clause_Name(5) not in 
'0'..'9') or else
+                   (Clause_Name_Len >= 6 and then
+                   Clause_Name(5) /= '-' and then Clause_Name(6) /= '-') then
+                   -- The clause number is 1 or 2 digits following a '-',
+                   -- and is either the end of the string or followed by a '-'.
+                   Ada.Exceptions.Raise_Exception (Program_Error'Identity,
+                      "Weird clause number:" & Clause_Number);
+               elsif Clause_Name_Len = 4 or else Clause_Name(5) = '-' then
+                   -- Clause is a single digit.
+                   Clause_Name(3..Clause_Name_Len-1) :=
+                       Clause_Name(4..Clause_Name_Len);
+                   Clause_Name_Len := Clause_Name_Len - 1;
+               elsif Clause_Name(4) = '1' then
+                   -- Clause is 10..19
+                   Clause_Name(3) := Character'Val(
+                       
Character'Pos(Clause_Name(5))-Character'Pos('0')+Character'Pos('A'));
+                   Clause_Name(4..Clause_Name_Len-2) :=
+                       Clause_Name(6..Clause_Name_Len);
+                   Clause_Name_Len := Clause_Name_Len - 2;
+               elsif Clause_Name(4) = '2' then
+                   -- Clause is 20..29
+                   Clause_Name(3) := Character'Val(
+                       
Character'Pos(Clause_Name(5))-Character'Pos('0')+Character'Pos('A')+10);
+                   Clause_Name(4..Clause_Name_Len-2) :=
+                       Clause_Name(6..Clause_Name_Len);
+                   Clause_Name_Len := Clause_Name_Len - 2;
+               elsif Clause_Name(4) = '3' then
+                   -- Clause is 30..39
+                   if Clause_Name(5) > '5' then
+                       Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                          "MS-DOS filename: Clause too large=" & 
Clause_Number);
+                   end if;
+                   Clause_Name(3) := Character'Val(
+                       
Character'Pos(Clause_Name(5))-Character'Pos('0')+Character'Pos('A')+20);
+                   Clause_Name(4..Clause_Name_Len-2) :=
+                       Clause_Name(6..Clause_Name_Len);
+                   Clause_Name_Len := Clause_Name_Len - 2;
+               else
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                      "MS-DOS filename: Clause too large=" & Clause_Number);
+               end if;
+               -- OK, the section number is exactly two characters, and the
+               -- clause number is exactly one. Figure out the subclause
+               -- name:
+               if Clause_Name_Len = 3 then
+                   null; -- We're done, no subclause.
+               elsif Clause_Name_Len < 5 or else
+                  Clause_Name(4) /= '-' or else
+                  Clause_Name(5) not in '0'..'9' or else
+                   (Clause_Name_Len >= 6 and then
+                   Clause_Name(6) /= '-' and then Clause_Name(6) not in 
'0'..'9') or else
+                   (Clause_Name_Len >= 7 and then
+                   Clause_Name(6) /= '-' and then Clause_Name(7) /= '-') then
+                   -- The subclause number is 1 or 2 digits following a '-',
+                   -- and is either the end of the string or followed by a '-'.
+                   Ada.Exceptions.Raise_Exception (Program_Error'Identity,
+                      "Weird subclause number:" & Clause_Number);
+               elsif Clause_Name_Len = 5 or else Clause_Name(6) = '-' then
+                   -- SubClause is a single digit.
+                   Clause_Name(4..Clause_Name_Len-1) :=
+                       Clause_Name(5..Clause_Name_Len);
+                   Clause_Name_Len := Clause_Name_Len - 1;
+               elsif Clause_Name(5) = '1' then
+                   -- SubClause is 10..19
+                   Clause_Name(4) := Character'Val(
+                       
Character'Pos(Clause_Name(6))-Character'Pos('0')+Character'Pos('A'));
+                   Clause_Name(5..Clause_Name_Len-2) :=
+                       Clause_Name(7..Clause_Name_Len);
+                   Clause_Name_Len := Clause_Name_Len - 2;
+               elsif Clause_Name(5) = '2' then
+                   -- SubClause is 20..29
+                   Clause_Name(4) := Character'Val(
+                       
Character'Pos(Clause_Name(6))-Character'Pos('0')+Character'Pos('A')+10);
+                   Clause_Name(5..Clause_Name_Len-2) :=
+                       Clause_Name(7..Clause_Name_Len);
+                   Clause_Name_Len := Clause_Name_Len - 2;
+               elsif Clause_Name(5) = '3' then
+                   -- SubClause is 30..39
+                   if Clause_Name(6) > '5' then
+                       Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                          "MS-DOS filename: Subclause too large=" & 
Clause_Number);
+                   end if;
+                   Clause_Name(4) := Character'Val(
+                       
Character'Pos(Clause_Name(6))-Character'Pos('0')+Character'Pos('A')+20);
+                   Clause_Name(5..Clause_Name_Len-2) :=
+                       Clause_Name(7..Clause_Name_Len);
+                   Clause_Name_Len := Clause_Name_Len - 2;
+               else
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                      "MS-DOS filename: Subclause too large=" & Clause_Number);
+               end if;
+               -- OK, the section number is exactly two characters, and the
+               -- clause number is one, and the subclause number is one or 
zero.
+               -- Figure out the subsubclause name:
+               if Clause_Name_Len < 5 then
+                   null; -- We're done, no subsubclause.
+               elsif Clause_Name_Len < 6 or else
+                  Clause_Name(5) /= '-' or else
+                  Clause_Name(6) not in '0'..'9' or else
+                   (Clause_Name_Len >= 7 and then
+                   Clause_Name(7) not in '0'..'9') or else
+                   (Clause_Name_Len >= 8) then
+                   -- The subsubclause number is 1 or 2 digits following a '-',
+                   -- and is the end of the string
+                   Ada.Exceptions.Raise_Exception (Program_Error'Identity,
+                      "Weird subclause number:" & Clause_Number);
+               elsif Clause_Name_Len = 6 then
+                   -- SubSubClause is a single digit.
+                   Clause_Name(5) := Clause_Name(6);
+                   Clause_Name_Len := 5;
+               elsif Clause_Name(6) = '1' then
+                   -- SubSubClause is 10..19
+                   Clause_Name(5) := Character'Val(
+                       
Character'Pos(Clause_Name(7))-Character'Pos('0')+Character'Pos('A'));
+                   Clause_Name_Len := 5;
+               elsif Clause_Name(5) = '2' then
+                   -- SubSubClause is 20..29
+                   Clause_Name(5) := Character'Val(
+                       
Character'Pos(Clause_Name(7))-Character'Pos('0')+Character'Pos('A')+10);
+                   Clause_Name_Len := 5;
+               elsif Clause_Name(5) = '3' then
+                   -- SubSubClause is 30..39
+                   if Clause_Name(6) > '5' then
+                       Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                          "MS-DOS filename: Subsubclause too large=" & 
Clause_Number);
+                   end if;
+                   Clause_Name(5) := Character'Val(
+                       
Character'Pos(Clause_Name(7))-Character'Pos('0')+Character'Pos('A')+20);
+                   Clause_Name_Len := 5;
+               else
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                      "MS-DOS filename: Subsubclause too large=" & 
Clause_Number);
+               end if;
+           end if;
+       end if;
+       return Clause_Name(1..Clause_Name_Len);
+    end Make_Clause_Anchor_Name;
+
+
+    function Make_Clause_File_Name (Output_Object : in HTML_Output_Type;
+                                   Clause_Number : in String) return String is
+       -- Internal routine.
+       -- Returns the Clause file name for the current output object and
+       -- Clause_Number. This does not include any path or extension.
+    begin
+       if Output_Object.Big_Files then -- One big file.
+           return Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right);
+       else -- Clause files.
+           if Output_Object.DOS_Filenames then
+               return Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right) &
+                   Make_Clause_Anchor_Name (Output_Object, Clause_Number);
+           else
+               return Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right) &
+                   "-" & Make_Clause_Anchor_Name (Output_Object, 
Clause_Number);
+           end if;
+       end if;
+    end Make_Clause_File_Name;
+
+
+    function Make_Clause_Link_Name (Output_Object : in HTML_Output_Type;
+                                   Clause_Number : in String) return String is
+       -- Internal routine.
+       -- Returns the link name for a link to the given clause.
+    begin
+       if Output_Object.Big_Files then -- One big file.
+           -- Note this is a self-reference, so the file name is not needed.
+           return "#" & Make_Clause_Anchor_Name (Output_Object, Clause_Number);
+       else -- Clause files.
+           if Output_Object.DOS_Filenames then
+               return Make_Clause_File_Name (Output_Object, Clause_Number) & 
".HTM";
+           else
+               return Make_Clause_File_Name (Output_Object, Clause_Number) & 
".html";
+           end if;
+       end if;
+    end Make_Clause_Link_Name;
+
+
+    procedure Put_EMs (Fyle : in Ada.Text_IO.File_Type;
+                      Value : in Natural) is
+       -- Put an EMs Value (Value is in 0.1 EM).
+    begin
+       if Value <= 9 then
+           Ada.Text_IO.Put (Fyle, '0');
+       elsif Value <= 99 then
+           Ada.Text_IO.Put (Fyle, Character'Val(Character'Pos('0') + (Value / 
10)));
+       else
+           Ada.Text_IO.Put (Fyle, Natural'Image (Value / 10));
+       end if;
+       Ada.Text_IO.Put (Fyle, '.');
+       Ada.Text_IO.Put (Fyle, Character'Val(Character'Pos('0') + (Value Mod 
10)));
+       Ada.Text_IO.Put (Fyle, "em");
+    end Put_EMs;
+
+
+    procedure Make_Navigation_Bar (Output_Object : in out HTML_Output_Type;
+                                  Is_Top : in Boolean) is
+       -- Internal routine.
+       -- Generate a properly formatted navigation bar.
+       Clause : constant String :=
+           Ada.Strings.Unbounded.To_String(Output_Object.Current_Clause);
+    begin
+        if Output_Object.Use_Buttons then
+           if Is_Top and then Output_Object.HTML_Kind > HTML_3 then
+               Ada.Text_IO.Put (Output_Object.Output_File, "<div 
style=""margin-top: 0.6em; margin-bottom: 0.0em"">");
+           elsif (not Is_Top) and then Output_Object.HTML_Kind > HTML_3 then
+               Ada.Text_IO.Put (Output_Object.Output_File, "<div 
style=""margin-top: 0.0em; margin-bottom: 0.6em"">");
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, "<P>");
+           end if;
+           Ada.Text_IO.Put (Output_Object.Output_File, "<A HREF=""");
+           if Output_Object.Big_Files then
+               Ada.Text_IO.Put (Output_Object.Output_File, "#TOC");
+           elsif Output_Object.DOS_Filenames then
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right) &
+                      "-TOC.HTM");
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right) &
+                      "-TOC.html");
+           end if;
+           if Output_Object.DOS_Filenames then
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, """><IMG 
SRC=""CONT.GIF"" ALT=""Contents"" BORDER=0></A>&nbsp;");
+                   -- Border=0 prevents the link highlight from being applied.
+           else
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, """><IMG 
SRC=""cont.gif"" ALT=""Contents"" BORDER=0></A>&nbsp;");
+                   -- Border=0 prevents the link highlight from being applied.
+           end if;
+           if Ada.Strings.Unbounded.Length(Output_Object.Index_URL) /= 0 then
+               Ada.Text_IO.Put (Output_Object.Output_File, "&nbsp;<A HREF=""");
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Unbounded.To_String(Output_Object.Index_URL));
+               if Output_Object.DOS_Filenames then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, """><IMG 
SRC=""INDEX.GIF"" ALT=""Index"" BORDER=0></A>&nbsp;");
+               else
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, """><IMG 
SRC=""index.gif"" ALT=""Index"" BORDER=0></A>&nbsp;");
+               end if;
+           else -- Link to the section named "Index".
+               begin
+                   -- Note: We do the following in one big glup so that if
+                   -- Not_Found_Error is raised, nothing is output.
+                   if Output_Object.DOS_Filenames then
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"&nbsp;<A HREF=""" &
+                           Make_Clause_Link_Name (Output_Object,
+                               ARM_Contents.Lookup_Clause_Number ("Index" & (6 
.. ARM_Contents.Title_Type'Last => ' '))) &
+                           """><IMG SRC=""INDEX.GIF"" ALT=""Index"" 
BORDER=0></A>&nbsp;");
+                   else
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"&nbsp;<A HREF=""" &
+                           Make_Clause_Link_Name (Output_Object,
+                               ARM_Contents.Lookup_Clause_Number ("Index" & (6 
.. ARM_Contents.Title_Type'Last => ' '))) &
+                           """><IMG SRC=""index.gif"" ALT=""Index"" 
BORDER=0></A>&nbsp;");
+                   end if;
+               exception
+                   when ARM_Contents.Not_Found_Error =>
+                       null; -- No section named "Index".
+               end;
+           end if;
+           if Ada.Strings.Unbounded.Length(Output_Object.Ref_URL) /= 0 then
+               Ada.Text_IO.Put (Output_Object.Output_File, "&nbsp;<A HREF=""");
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Unbounded.To_String(Output_Object.Ref_URL));
+               if Output_Object.DOS_Filenames then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, """><IMG 
SRC=""LIB.GIF"" ALT=""References"" BORDER=0></A>&nbsp;");
+               else
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, """><IMG 
SRC=""lib.gif"" ALT=""References"" BORDER=0></A>&nbsp;");
+               end if;
+           else -- Link to the section named "References".
+               begin
+                   -- Note: We do the following in one big glup so that if
+                   -- Not_Found_Error is raised, nothing is output.
+                   if Output_Object.DOS_Filenames then
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"&nbsp;<A HREF=""" &
+                           Make_Clause_Link_Name (Output_Object,
+                               ARM_Contents.Lookup_Clause_Number ("References" 
& (11 .. ARM_Contents.Title_Type'Last => ' '))) &
+                           """><IMG SRC=""LIB.GIF"" ALT=""References"" 
BORDER=0></A>&nbsp;");
+                   else
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"&nbsp;<A HREF=""" &
+                           Make_Clause_Link_Name (Output_Object,
+                               ARM_Contents.Lookup_Clause_Number ("References" 
& (11 .. ARM_Contents.Title_Type'Last => ' '))) &
+                           """><IMG SRC=""lib.gif"" ALT=""References"" 
BORDER=0></A>&nbsp;");
+                   end if;
+               exception
+                   when ARM_Contents.Not_Found_Error =>
+                       null; -- No section named "References".
+               end;
+           end if;
+           if Ada.Strings.Unbounded.Length(Output_Object.Srch_URL) /= 0 then
+               Ada.Text_IO.Put (Output_Object.Output_File, "&nbsp;<A HREF=""");
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Unbounded.To_String(Output_Object.Srch_URL));
+               if Output_Object.DOS_Filenames then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, """><IMG 
SRC=""FIND.GIF"" ALT=""Search"" BORDER=0></A>&nbsp;");
+               else
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, """><IMG 
SRC=""find.gif"" ALT=""Search"" BORDER=0></A>&nbsp;");
+               end if;
+           else -- Link to the section named "References".
+               begin
+                   -- Note: We do the following in one big glup so that if
+                   -- Not_Found_Error is raised, nothing is output.
+                   if Output_Object.DOS_Filenames then
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"&nbsp;<A HREF=""" &
+                           Make_Clause_Link_Name (Output_Object,
+                               ARM_Contents.Lookup_Clause_Number ("Search" & 
(7 .. ARM_Contents.Title_Type'Last => ' '))) &
+                           """><IMG SRC=""FIND.GIF"" ALT=""Search"" 
BORDER=0></A>&nbsp;");
+                   else
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"&nbsp;<A HREF=""" &
+                           Make_Clause_Link_Name (Output_Object,
+                               ARM_Contents.Lookup_Clause_Number ("Search" & 
(7 .. ARM_Contents.Title_Type'Last => ' '))) &
+                           """><IMG SRC=""find.gif"" ALT=""Search"" 
BORDER=0></A>&nbsp;");
+                   end if;
+               exception
+                   when ARM_Contents.Not_Found_Error =>
+                       null; -- No section named "Index".
+               end;
+           end if;
+           if Clause /= "" then
+               begin
+                   -- Note: We do the following in one big glup so that if
+                   -- Not_Found_Error is raised, nothing is output.
+                   Ada.Text_IO.Put (Output_Object.Output_File, "&nbsp;<A 
HREF=""" &
+                       Make_Clause_Link_Name (Output_Object,
+                           ARM_Contents.Previous_Clause(Clause)));
+                   if Output_Object.DOS_Filenames then
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"""><IMG SRC=""PREV.GIF"" ALT=""Previous"" BORDER=0></A>&nbsp;");
+                   else
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"""><IMG SRC=""prev.gif"" ALT=""Previous"" BORDER=0></A>&nbsp;");
+                   end if;
+               exception
+                   when ARM_Contents.Not_Found_Error =>
+                       null; -- Probably the first section.
+               end;
+               begin
+                   -- Note: We do the following in one big glup so that if
+                   -- Not_Found_Error is raised, nothing is output.
+                   Ada.Text_IO.Put (Output_Object.Output_File, "&nbsp;<A 
HREF=""" &
+                       Make_Clause_Link_Name (Output_Object,
+                           ARM_Contents.Next_Clause(Clause)));
+                   if Output_Object.DOS_Filenames then
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"""><IMG SRC=""NEXT.GIF"" ALT=""Next"" BORDER=0></A>&nbsp;");
+                   else
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"""><IMG SRC=""next.gif"" ALT=""Next"" BORDER=0></A>&nbsp;");
+                   end if;
+               exception
+                   when ARM_Contents.Not_Found_Error =>
+                       null; -- Probably the last section.
+               end;
+           end if;
+           if Output_Object.HTML_Kind > HTML_3 then
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "</div>");
+           else
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "</P>");
+           end if;
+        else -- Use text navigation
+           Ada.Text_IO.Put (Output_Object.Output_File, "<P><A HREF=""");
+           if Output_Object.Big_Files then
+               Ada.Text_IO.Put (Output_Object.Output_File, "#TOC");
+           elsif Output_Object.DOS_Filenames then
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right) &
+                      "-TOC.HTM");
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right) &
+                      "-TOC.html");
+           end if;
+           Ada.Text_IO.Put (Output_Object.Output_File, """>Contents</A>");
+           if Ada.Strings.Unbounded.Length(Output_Object.Index_URL) /= 0 then
+               Ada.Text_IO.Put (Output_Object.Output_File, 
"&nbsp;&nbsp;&nbsp;");
+               Ada.Text_IO.Put (Output_Object.Output_File, "<A HREF=""");
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Unbounded.To_String(Output_Object.Index_URL));
+               Ada.Text_IO.Put (Output_Object.Output_File, """>Index</A>");
+           else -- Link to the section named "Index".
+               begin
+                   -- Note: We do the following in one big glup so that if
+                   -- Not_Found_Error is raised, nothing is output.
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"&nbsp;&nbsp;&nbsp;<A HREF=""" &
+                       Make_Clause_Link_Name (Output_Object,
+                           ARM_Contents.Lookup_Clause_Number ("Index" & (6 .. 
ARM_Contents.Title_Type'Last => ' '))) &
+                       """>Index</A>");
+               exception
+                   when ARM_Contents.Not_Found_Error =>
+                       null; -- No section named "Index".
+               end;
+           end if;
+           if Ada.Strings.Unbounded.Length(Output_Object.Srch_URL) /= 0 then
+               Ada.Text_IO.Put (Output_Object.Output_File, 
"&nbsp;&nbsp;&nbsp;");
+               Ada.Text_IO.Put (Output_Object.Output_File, "<A HREF=""");
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Unbounded.To_String(Output_Object.Srch_URL));
+               Ada.Text_IO.Put (Output_Object.Output_File, """>Search</A>");
+           else -- Link to the section named "Search".
+               begin
+                   -- Note: We do the following in one big glup so that if
+                   -- Not_Found_Error is raised, nothing is output.
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"&nbsp;&nbsp;&nbsp;<A HREF=""" &
+                       Make_Clause_Link_Name (Output_Object,
+                           ARM_Contents.Lookup_Clause_Number ("Search" & (7 .. 
ARM_Contents.Title_Type'Last => ' '))) &
+                       """>Search</A>");
+               exception
+                   when ARM_Contents.Not_Found_Error =>
+                       null; -- No section named "Search".
+               end;
+           end if;
+           if Ada.Strings.Unbounded.Length(Output_Object.Ref_URL) /= 0 then
+               Ada.Text_IO.Put (Output_Object.Output_File, 
"&nbsp;&nbsp;&nbsp;");
+               Ada.Text_IO.Put (Output_Object.Output_File, "<A HREF=""");
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Unbounded.To_String(Output_Object.Ref_URL));
+               Ada.Text_IO.Put (Output_Object.Output_File, """>Reference 
Documents</A>");
+           else -- Link to the section named "References".
+               begin
+                   -- Note: We do the following in one big glup so that if
+                   -- Not_Found_Error is raised, nothing is output.
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"&nbsp;&nbsp;&nbsp;<A HREF=""" &
+                       Make_Clause_Link_Name (Output_Object,
+                           ARM_Contents.Lookup_Clause_Number ("References" & 
(11 .. ARM_Contents.Title_Type'Last => ' '))) &
+                       """>Reference Documents</A>");
+               exception
+                   when ARM_Contents.Not_Found_Error =>
+                       null; -- No section named "References".
+               end;
+           end if;
+           if Clause /= "" then
+               begin
+                   -- Note: We do the following in one big glup so that if
+                   -- Not_Found_Error is raised, nothing is output.
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
"&nbsp;&nbsp;&nbsp;<A HREF=""" &
+                       Make_Clause_Link_Name (Output_Object,
+                           ARM_Contents.Previous_Clause(Clause)));
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
""">Previous</A>");
+               exception
+                   when ARM_Contents.Not_Found_Error =>
+                       null; -- Probably the first section.
+               end;
+               begin
+                   -- Note: We do the following in one big glup so that if
+                   -- Not_Found_Error is raised, nothing is output.
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
"&nbsp;&nbsp;&nbsp;<A HREF=""" &
+                       Make_Clause_Link_Name (Output_Object,
+                           ARM_Contents.Next_Clause(Clause)));
+                   Ada.Text_IO.Put (Output_Object.Output_File, """>Next</A>");
+               exception
+                   when ARM_Contents.Not_Found_Error =>
+                       null; -- Probably the last section.
+               end;
+           end if;
+
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "</P>");
+        end if;
+    end Make_Navigation_Bar;
+
+
+    type Special_Style_Kinds is (None,
+                                Hanging_Term,
+                                Hanging_Body,
+                                Bulleted_Item,
+                                Bulleted_No_Prefix);
+
+    procedure Make_Style (Output_Object : in out HTML_Output_Type;
+                         Name : in String;
+                         Style : in ARM_Output.Paragraph_Style_Type;
+                         Indent : in ARM_Output.Paragraph_Indent_Type;
+                         Kind : Special_Style_Kinds := None;
+                         Enumerated_Adjustment : in Boolean := False) is
+       -- Internal routine.
+        -- Generate the style needed.
+
+        function Units_to_EMs (Value : in Natural) return Natural is
+           -- Convert Value from indentation units to EMs. (0.1 EMs, really).
+           Normal : Boolean;
+        begin
+           if Output_Object.HTML_Kind = HTML_4_Only then
+               case Paragraph_Info(Style, Indent).Font is
+                   when ARM_Output.Default =>
+                       Normal := ARM_Output."=" (Output_Object.Body_Font, 
ARM_Output.Roman);
+                   when ARM_Output.Roman =>
+                       Normal := True;
+                   when ARM_Output.Fixed | ARM_Output.Swiss => -- Start at 90% 
(otherwise they are huge!)
+                       Normal := False;
+               end case;
+               if Normal then
+                   case Paragraph_Info(Style, Indent).Size is
+                       when 0 => return Value * 20;
+                       when 1 => return Value * 16; -- 20/1.25.
+                       when 2 => return Value * 13; -- 20/1.56.
+                       when 3 => return Value * 10; -- 20/1.93.
+                       when -1 => return Value * 25; -- 20/0.80.
+                       when -2 => return Value * 31; -- 20/0.64.
+                       when -3 => return Value * 40; -- 20/0.50.
+                       when others => return Value; -- Out of range.
+                   end case;
+               else -- Start at 90% (otherwise they are huge!)
+                   case Paragraph_Info(Style, Indent).Size is
+                       when 0 => return Value * 22; -- 20/0.90
+                       when 1 => return Value * 18; -- 20/1.13.
+                       when 2 => return Value * 14; -- 20/1.40.
+                       when 3 => return Value * 11; -- 20/1.75.
+                       when -1 => return Value * 28; -- 20/0.72.
+                       when -2 => return Value * 34; -- 20/0.58.
+                       when -3 => return Value * 44; -- 20/0.45.
+                       when others => return Value; -- Out of range.
+                   end case;
+               end if;
+           elsif ARM_Output."=" (Paragraph_Info(Style, Indent).Font, 
ARM_Output.Fixed) then
+               -- Special case, see below.
+               case Paragraph_Info(Style, Indent).Size is
+                   when 0 => return Value * 20;
+                   when 1 => return Value * 16; -- 20/1.25.
+                   when 2 => return Value * 13; -- 20/1.56.
+                   when 3 => return Value * 10; -- 20/1.93.
+                   when -1 => return Value * 25; -- 20/0.80.
+                   when -2 => return Value * 31; -- 20/0.64.
+                   when -3 => return Value * 40; -- 20/0.50.
+                   when others => return Value; -- Out of range.
+               end case;
+           else
+               return Value * 20; -- No font sizes here.
+           end if;
+        end Units_to_EMs;
+
+    begin
+       if not Paragraph_Used (Style, Indent) then
+           return; -- Not used, so don't generate.
+       end if;
+       if Kind = Hanging_Term and then Output_Object.HTML_Kind = HTML_4_Only 
then
+           -- Special case for better hanging.
+            Ada.Text_IO.Put (Output_Object.Output_File, "    DIV.");
+            Ada.Text_IO.Put (Output_Object.Output_File, Name & "-Term {");
+           if OPTIMIZE_FOR_FIREFOX then
+               -- Tested on Firefox 1.5.
+                Ada.Text_IO.Put (Output_Object.Output_File, "float: left; ");
+                   -- This does not work on IE: it adds extra spaces, and 
leaves
+                   -- it effective after a <BR>. We could probably work around
+                   -- those, but then Firefox would look like crap again.
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, "position: 
absolute; top: auto; left: 0.6em; ");
+                   -- This does not work on Firefox: the text is too high by
+                   -- about half a line and thus doesn't line up properly.
+           end if;
+       elsif Kind = Hanging_Body and then Output_Object.HTML_Kind = 
HTML_4_Only then
+            Ada.Text_IO.Put (Output_Object.Output_File, "    DIV.");
+            Ada.Text_IO.Put (Output_Object.Output_File, Name & "-Body {");
+       elsif (Kind = Bulleted_Item or else Kind = Bulleted_No_Prefix) and then
+                  Output_Object.HTML_Kind = HTML_4_Only then
+            Ada.Text_IO.Put (Output_Object.Output_File, "    DIV.");
+            Ada.Text_IO.Put (Output_Object.Output_File, Name & " {");
+       else
+            case Paragraph_Info(Style, Indent).Tag is
+               when DIV =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "    DIV.");
+               when UL =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "    UL.");
+               when DL =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "    DL.");
+            end case;
+            Ada.Text_IO.Put (Output_Object.Output_File, Name & " {");
+       end if;
+        case Paragraph_Info(Style, Indent).Font is
+           when ARM_Output.Default =>
+               if ARM_Output."=" (Output_Object.Body_Font, ARM_Output.Roman) 
then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "font-family: 
""Times New Roman"", Times, serif");
+               else
+                   Ada.Text_IO.Put (Output_Object.Output_File, "font-family: 
Arial, Helvetica, sans-serif");
+               end if;
+           when ARM_Output.Roman => Ada.Text_IO.Put 
(Output_Object.Output_File, "font-family: ""Times New Roman"", Times, serif");
+           when ARM_Output.Swiss => Ada.Text_IO.Put 
(Output_Object.Output_File, "font-family: Arial, Helvetica, sans-serif");
+           when ARM_Output.Fixed => Ada.Text_IO.Put 
(Output_Object.Output_File, "font-family: ""Courier New"", monospace");
+        end case;
+        if Output_Object.HTML_Kind = HTML_4_Only then
+           -- The font size is set by the outer item.
+           declare
+               Normal : Boolean;
+            begin
+               case Paragraph_Info(Style, Indent).Font is
+                   when ARM_Output.Default =>
+                       Normal := ARM_Output."=" (Output_Object.Body_Font, 
ARM_Output.Roman);
+                   when ARM_Output.Roman =>
+                       Normal := True;
+                   when ARM_Output.Fixed | ARM_Output.Swiss => -- Start at 90% 
(otherwise they are huge!)
+                       Normal := False;
+               end case;
+               if Normal then
+                   case Paragraph_Info(Style, Indent).Size is
+                       when 0 => null; -- Default.
+                       when 1 => Ada.Text_IO.Put (Output_Object.Output_File, 
"; font-size: 125%");
+                       when 2 => Ada.Text_IO.Put (Output_Object.Output_File, 
"; font-size: 156%");
+                       when 3 => Ada.Text_IO.Put (Output_Object.Output_File, 
"; font-size: 195%");
+                       when -1 => Ada.Text_IO.Put (Output_Object.Output_File, 
"; font-size: 80%");
+                       when -2 => Ada.Text_IO.Put (Output_Object.Output_File, 
"; font-size: 64%");
+                       when -3 => Ada.Text_IO.Put (Output_Object.Output_File, 
"; font-size: 50%");
+                       when others => null; -- Out of range.
+                   end case;
+               else -- Start at 90% (otherwise they are huge!)
+                   -- Note: This size adjustment is for sections of text, not 
for in-line text.
+                   case Paragraph_Info(Style, Indent).Size is
+                       when 0 => Ada.Text_IO.Put (Output_Object.Output_File, 
"; font-size: 90%");
+                       when 1 => Ada.Text_IO.Put (Output_Object.Output_File, 
"; font-size: 113%");
+                       when 2 => Ada.Text_IO.Put (Output_Object.Output_File, 
"; font-size: 140%");
+                       when 3 => Ada.Text_IO.Put (Output_Object.Output_File, 
"; font-size: 175%");
+                       when -1 => Ada.Text_IO.Put (Output_Object.Output_File, 
"; font-size: 72%");
+                       when -2 => Ada.Text_IO.Put (Output_Object.Output_File, 
"; font-size: 58%");
+                       when -3 => Ada.Text_IO.Put (Output_Object.Output_File, 
"; font-size: 45%");
+                       when others => null; -- Out of range.
+                   end case;
+               end if;
+            end;
+           -- Set the leading, because otherwise the lines are too close on IE.
+           Ada.Text_IO.Put (Output_Object.Output_File, "; line-height: 122%");
+        elsif ARM_Output."=" (Paragraph_Info(Style, Indent).Font, 
ARM_Output.Fixed) then
+           -- Special case because the font otherwise gets too small and
+           -- loses bold-facing.
+           case Paragraph_Info(Style, Indent).Size is
+               when 0 => null; -- Default.
+               when 1 => Ada.Text_IO.Put (Output_Object.Output_File, "; 
font-size: 125%");
+               when 2 => Ada.Text_IO.Put (Output_Object.Output_File, "; 
font-size: 156%");
+               when 3 => Ada.Text_IO.Put (Output_Object.Output_File, "; 
font-size: 195%");
+               when -1 => Ada.Text_IO.Put (Output_Object.Output_File, "; 
font-size: 80%");
+               when -2 => Ada.Text_IO.Put (Output_Object.Output_File, "; 
font-size: 64%");
+               when -3 => Ada.Text_IO.Put (Output_Object.Output_File, "; 
font-size: 50%");
+               when others => null; -- Out of range.
+           end case;
+        -- else the size will be set explicitly for HTML_4_Compatible.
+        end if;
+       if Kind = Hanging_Body then
+           if Output_Object.Number_Paragraphs then
+               Ada.Text_IO.Put (Output_Object.Output_File, "; margin-left: ");
+               Put_Ems (Output_Object.Output_File,
+                        Units_to_EMs(Paragraph_Info(Style, Indent).Indent +
+                                     Paragraph_Info(Style, 
Indent).Hang_Outdent) +
+                        INDENT_EMS_FOR_PARANUMS);
+           else
+                if Paragraph_Info(Style, Indent).Indent + 
Paragraph_Info(Style, Indent).Hang_Outdent /= 0 then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "; margin-left: 
");
+                   Put_Ems (Output_Object.Output_File,
+                            Units_to_EMs(Paragraph_Info(Style, Indent).Indent +
+                                         Paragraph_Info(Style, 
Indent).Hang_Outdent));
+                end if;
+           end if;
+       elsif Enumerated_Adjustment then
+           -- Adjust the left margin to indent the prefix slightly (1/4 of a 
unit):
+           declare
+               Org_Margin : Natural :=
+                   Units_to_EMs(Paragraph_Info(Style, Indent).Indent);
+               Prefix_Indent : Natural :=
+                  Units_to_EMs(1) / 4;
+           begin
+               Ada.Text_IO.Put (Output_Object.Output_File, "; margin-left: ");
+               if Output_Object.Number_Paragraphs then
+                   Put_Ems (Output_Object.Output_File, Org_Margin + 
Prefix_Indent +
+                            INDENT_EMS_FOR_PARANUMS);
+               else
+                   Put_Ems (Output_Object.Output_File, Org_Margin + 
Prefix_Indent);
+               end if;
+           end;
+       else
+           if Output_Object.Number_Paragraphs then
+               Ada.Text_IO.Put (Output_Object.Output_File, "; margin-left: ");
+               Put_Ems (Output_Object.Output_File, 
Units_to_EMs(Paragraph_Info(Style, Indent).Indent) +
+                        INDENT_EMS_FOR_PARANUMS);
+           else
+                if Paragraph_Info(Style, Indent).Indent /= 0 then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "; margin-left: 
");
+                   Put_Ems (Output_Object.Output_File, 
Units_to_EMs(Paragraph_Info(Style, Indent).Indent));
+                end if;
+           end if;
+       end if;
+       if Kind = Hanging_Term and then Output_Object.HTML_Kind = HTML_4_Only 
then
+           -- We let the body provide the necessary right margin. If we don't
+           -- do this, the following item can end up with an inappropriate 
indent.
+           null;
+           --Ada.Text_IO.Put (Output_Object.Output_File, "; margin-bottom: 
0em");
+        elsif Paragraph_Info(Style, Indent).Right_Indent /= 0 then
+           Ada.Text_IO.Put (Output_Object.Output_File, "; margin-right: ");
+           Put_Ems (Output_Object.Output_File, 
Units_to_EMs(Paragraph_Info(Style, Indent).Right_Indent));
+        end if;
+        if Paragraph_Info(Style, Indent).Before /= 0 then
+           Ada.Text_IO.Put (Output_Object.Output_File, "; margin-top: ");
+           Put_Ems (Output_Object.Output_File, Paragraph_Info(Style, 
Indent).Before);
+        elsif Paragraph_Info(Style, Indent).Tag /= DIV then
+           -- The default is non-zero.
+           Ada.Text_IO.Put (Output_Object.Output_File, "; margin-top: 0em");
+        end if;
+       if Kind = Hanging_Term and then Output_Object.HTML_Kind = HTML_4_Only 
then
+           -- We let the body provide the necessary space below. If we don't
+           -- do this, the next line can end up with an inappropriate indent.
+           Ada.Text_IO.Put (Output_Object.Output_File, "; margin-bottom: 0em");
+       elsif Paragraph_Info(Style, Indent).After /= 0 then
+           Ada.Text_IO.Put (Output_Object.Output_File, "; margin-bottom: ");
+           Put_Ems (Output_Object.Output_File, Paragraph_Info(Style, 
Indent).After);
+        end if;
+       if Kind = Bulleted_Item and then Output_Object.HTML_Kind = HTML_4_Only 
then
+           -- Set the list item and "disc" format:
+           Ada.Text_IO.Put (Output_Object.Output_File, "; display: list-item; 
list-style-type: disc");
+        end if;
+        -- Done, close it.
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "}");
+    end Make_Style;
+
+
+    procedure Make_Hung_Text_Style
+                    (Output_Object : in out HTML_Output_Type;
+                     Name   : in String;
+                     Style  : in ARM_Output.Paragraph_Style_Type;
+                     Indent : in ARM_Output.Paragraph_Indent_Type) is
+       -- Internal routine.
+        -- Generate the style needed.
+    begin
+       if Output_Object.HTML_Kind = HTML_4_Only then
+           if ARM_Output."=" (Style, ARM_Output.Enumerated) or else
+              ARM_Output."=" (Style, ARM_Output.Small_Enumerated) then
+               Make_Style (Output_Object, Name, Style, Indent,
+                           Kind => Hanging_Term,
+                           Enumerated_Adjustment => True);
+           else
+               Make_Style (Output_Object, Name, Style, Indent,
+                           Kind => Hanging_Term);
+           end if;
+       else -- HTML_4_Compatible
+            Ada.Text_IO.Put (Output_Object.Output_File, "    DD." & Name & " 
{");
+            Ada.Text_IO.Put (Output_Object.Output_File, "margin-left: ");
+            case Paragraph_Info(Style, Indent).Size is
+               when 0 => Put_Ems (Output_Object.Output_File, 
Paragraph_Info(Style, Indent).Hang_Outdent * 20);
+               when 1 => Put_Ems (Output_Object.Output_File, 
Paragraph_Info(Style, Indent).Hang_Outdent * 16); -- 20/1.25.
+               when 2 => Put_Ems (Output_Object.Output_File, 
Paragraph_Info(Style, Indent).Hang_Outdent * 13); -- 20/1.56.
+               when -1 => Put_Ems (Output_Object.Output_File, 
Paragraph_Info(Style, Indent).Hang_Outdent * 25); -- 20/0.80.
+               when -2 => Put_Ems (Output_Object.Output_File, 
Paragraph_Info(Style, Indent).Hang_Outdent * 31); -- 20/0.64.
+               when -3 => Put_Ems (Output_Object.Output_File, 
Paragraph_Info(Style, Indent).Hang_Outdent * 40); -- 20/0.50.
+               when others => null; -- Out of range.
+            end case;
+            -- Done, close it.
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "}");
+       end if;
+    end Make_Hung_Text_Style;
+
+
+    function Paragraph_Name
+                    (Style  : in ARM_Output.Paragraph_Style_Type;
+                     Indent : in ARM_Output.Paragraph_Indent_Type) return 
String is
+       -- Internal routine.
+       -- Create the name for the Style and Indent.
+       -- These had better be unique, and all possibilities (including 
impossible
+       -- ones) had better have names.
+       use type ARM_Output.Paragraph_Indent_Type;
+    begin
+       case Style is
+           when ARM_Output.Normal =>
+                if Indent = 0 then
+                   return "Normal";
+               else
+                   -- This was: Indent 1: "SyntaxIndented"; Indent 2:
+                   -- "CodeIndented"; Indent 3: "Indented"; Indent 4: 
"InnerIndented".
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent);
+               end if;
+           when ARM_Output.Wide_Above =>
+                if Indent = 0 then
+                   return "WideAbove";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "WideAbove";
+               end if;
+           when ARM_Output.Small =>
+                if Indent = 0 then
+                   return "Small";
+                elsif Indent = 1 then
+                   return "Notes";
+                elsif Indent = 2 then
+                   return "Annotations";
+               else
+                   -- This was: Indent 3: "SmallSyntaxIndented"; Indent 4:
+                   -- "SmallCodeIndented"; Indent 5: "SmallIndented"; Indent 
6: "SmallInnerIndented".
+                   return "SmallIndented" & Character'Val(Character'Pos('0') + 
Indent);
+               end if;
+           when ARM_Output.Small_Wide_Above =>
+                if Indent = 0 then
+                   return "SmallWideAbove";
+                elsif Indent = 2 then
+                   return "AnnotationsWideAbove";
+               else
+                   return "SmallIndented" & Character'Val(Character'Pos('0') + 
Indent) & "WideAbove";
+               end if;
+           when ARM_Output.Header =>
+                if Indent = 0 then
+                   return "Header";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "Header";
+               end if;
+           when ARM_Output.Small_Header =>
+                if Indent = 0 then
+                   return "SmallHeader";
+                elsif Indent = 1 then
+                   return "NotesHeader";
+               else
+                   return "SmallIndented" & Character'Val(Character'Pos('0') + 
Indent) & "Header";
+               end if;
+           when ARM_Output.Index =>
+                if Indent = 0 then
+                   return "Index";
+               else -- Should be not used.
+                   return "IndexIndented" & Character'Val(Character'Pos('0') + 
Indent);
+               end if;
+           when ARM_Output.Syntax_Summary =>
+                if Indent = 1 then
+                   return "SyntaxSummary";
+               else -- Should be not used.
+                   return "SynSumInd" & Character'Val(Character'Pos('0') + 
Indent);
+               end if;
+           when ARM_Output.Title =>
+                if Indent = 0 then
+                   return "Title";
+               else -- Should be not used.
+                   return "TitleIndented" & Character'Val(Character'Pos('0') + 
Indent);
+               end if;
+           when ARM_Output.Examples =>
+                if Indent = 1 then
+                   return "Examples";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "Examples";
+               end if;
+           when ARM_Output.Small_Examples =>
+                if Indent = 3 then
+                   return "SmallExamples";
+               else
+                   return "SmallIndented" & Character'Val(Character'Pos('0') + 
Indent) & "Examples";
+               end if;
+           when ARM_Output.Swiss_Examples =>
+                if Indent = 1 then
+                   return "SwissExamples";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "SwissExamples";
+               end if;
+           when ARM_Output.Small_Swiss_Examples =>
+                if Indent = 3 then
+                   return "SmallSwissExamples";
+               else
+                   return "SmallIndented" & Character'Val(Character'Pos('0') + 
Indent) & "SwissExamples";
+               end if;
+           when ARM_Output.Bulleted =>
+                if Indent = 1 then
+                   return "Bulleted";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "Bulleted";
+               end if;
+           when ARM_Output.Small_Bulleted =>
+                if Indent = 3 then
+                   return "SmallBulleted";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "SmallBulleted";
+               end if;
+           when ARM_Output.Nested_Bulleted =>
+                if Indent = 1 then
+                   return "NestedBulleted";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "NestedBulleted";
+               end if;
+           when ARM_Output.Small_Nested_Bulleted =>
+                if Indent = 3 then
+                   return "SmallNestedBulleted";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "SmallNestedBulleted";
+               end if;
+           when ARM_Output.Enumerated =>
+                if Indent = 1 then
+                   return "Enumerated";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "Enumerated";
+               end if;
+           when ARM_Output.Small_Enumerated =>
+                if Indent = 3 then
+                   return "SmallEnumerated";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "SmallEnumerated";
+               end if;
+           when ARM_Output.Giant_Hanging =>
+                if Indent = 4 then
+                   return "GiantHanging";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "GiantHanging";
+               end if;
+           when ARM_Output.Small_Giant_Hanging =>
+                if Indent = 6 then
+                   return "SmallGiantHanging";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "SmallGiantHanging";
+               end if;
+           when ARM_Output.Wide_Hanging =>
+                if Indent = 3 then
+                   return "WideHanging";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "WideHanging";
+               end if;
+           when ARM_Output.Small_Wide_Hanging =>
+                if Indent = 5 then
+                   return "SmallWideHanging";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "SmallWideHanging";
+               end if;
+           when ARM_Output.Medium_Hanging =>
+                if Indent = 2 then
+                   return "MediumHanging";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "MediumHanging";
+               end if;
+           when ARM_Output.Small_Medium_Hanging =>
+                if Indent = 4 then
+                   return "SmallMediumHanging";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "SmallMediumHanging";
+               end if;
+           when ARM_Output.Narrow_Hanging =>
+                if Indent = 1 then
+                   return "NarrowHanging";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "NarrowHanging";
+               end if;
+           when ARM_Output.Small_Narrow_Hanging =>
+                if Indent = 3 then
+                   return "SmallNarrowHanging";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "SmallNarrowHanging";
+               end if;
+           when ARM_Output.Hanging_in_Bulleted =>
+                if Indent = 3 then
+                   return "Hanging_in_Bulleted";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "Hanging_in_Bulleted";
+               end if;
+           when ARM_Output.Small_Hanging_in_Bulleted =>
+                if Indent = 5 then
+                   return "SmallHanging_in_Bulleted";
+               else
+                   return "Indented" & Character'Val(Character'Pos('0') + 
Indent) & "SmallHanging_in_Bulleted";
+               end if;
+       end case;
+    end Paragraph_Name;
+
+
+    procedure Make_Paragraph_Styles
+                    (Output_Object : in out HTML_Output_Type) is
+       -- Internal routine.
+       -- Generate all of the paragraph and related styles.
+    begin
+       -- Basic element styles:
+       if Paranum_Used then
+           if Output_Object.HTML_Kind = HTML_4_Compatible then
+               if OPTIMIZE_FOR_FIREFOX then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, "    
DIV.paranum {float: left; font-family: Arial, Helvetica, sans-serif; width: 
2.8em; " &
+                                                                    
"margin-left: -0.4em; margin-right: -3.0em; margin-top: 0.2em}");
+                    -- Uses floating items. These usually don't work on IE (it
+                   -- adds extra spaces for no reason). However, with the
+                   -- indents, this seems to work properly on IE, too.
+               else
+                   -- Absolute positioning (CSS2) works better on IE, but
+                   -- Firefox tends to draw these too high.
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, "    
DIV.paranum {position: absolute; font-family: Arial, Helvetica, sans-serif; 
left: 0.5em; top: auto; margin-top: 0.2em}");
+               end if;
+               -- If these are completely ignored, the paragraph number will
+               -- end up on a line by itself. That's fine.
+           else
+               if OPTIMIZE_FOR_FIREFOX then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, "    
DIV.paranum {float: left; font-family: Arial, Helvetica, sans-serif; font-size: 
64%; width: 2.8em; " &
+                                                                    
"margin-left: -0.4em; margin-right: -3.0em; margin-top: 0.2em}");
+                   -- Uses floating elements; see above.
+               else
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, "    
DIV.paranum {position: absolute; font-family: Arial, Helvetica, sans-serif; 
font-size: 64%; " &
+                                                                    "left: 
0.5em; top: auto; margin-top: 0.2em}");
+                   -- Uses absolute positioning; see above.
+               end if;
+           end if;
+       end if;
+
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "    TT {font-family: 
""Courier New"", monospace}");
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "    DT {display: 
compact}"); -- CSS2. This doesn't seem to work on IE 4.01, but it is harmless.
+
+        -- Revision styles:
+       if Revision_Used ('0') then
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.insert0 
{text-decoration: underline; color: black}");
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.delete0 
{text-decoration: line-through; color: black }");
+            --Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.both0 
{text-decoration: underline, line-through; color: black }");
+               -- Both doesn't seem to work, so forget it.
+       -- else not used, don't generate it.
+       end if;
+       if Revision_Used ('1') then
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.insert1 
{text-decoration: underline; color: rgb(0,51,51) }"); -- (Very) dark turquoise.
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.delete1 
{text-decoration: line-through; color: rgb(0,51,51) }");
+            --Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.both1 
{text-decoration: underline, line-through; color: rgb(0,51,51) }");
+               -- Both doesn't seem to work, so forget it.
+       -- else not used, don't generate it.
+       end if;
+       if Revision_Used ('2') then
+           if Revision_Used ('5') or else 
Output_Object.Force_New_Revision_Colors then
+               -- Ugly color here, nice color for #5
+                Ada.Text_IO.Put_Line (Output_Object.Output_File, "    
SPAN.insert2 {text-decoration: underline; color: rgb(102,0,153) }"); -- Violet.
+                Ada.Text_IO.Put_Line (Output_Object.Output_File, "    
SPAN.delete2 {text-decoration: line-through; color: rgb(102,0,153) }");
+                --Ada.Text_IO.Put_Line (Output_Object.Output_File, "    
SPAN.both2 {text-decoration: underline, line-through; color: rgb(102,0,153) }");
+                   -- Both doesn't seem to work, so forget it.
+           else -- Use the nice green here.
+                Ada.Text_IO.Put_Line (Output_Object.Output_File, "    
SPAN.insert2 {text-decoration: underline; color: rgb(0,102,0) }"); -- Dark 
green.
+                Ada.Text_IO.Put_Line (Output_Object.Output_File, "    
SPAN.delete2 {text-decoration: line-through; color: rgb(0,102,0) }");
+                --Ada.Text_IO.Put_Line (Output_Object.Output_File, "    
SPAN.both2 {text-decoration: underline, line-through; color: rgb(0,102,0) }");
+                   -- Both doesn't seem to work, so forget it.
+           end if;
+       -- else not used, don't generate it.
+       end if;
+       if Revision_Used ('3') then
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.insert3 
{text-decoration: underline; color: rgb(102,51,0) }"); -- Dark brown.
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.delete3 
{text-decoration: line-through; color: rgb(102,51,0) }");
+            --Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.both3 
{text-decoration: underline, line-through; color: rgb(102,51,0) }");
+               -- Both doesn't seem to work, so forget it.
+       -- else not used, don't generate it.
+       end if;
+       if Revision_Used ('4') then
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.insert4 
{text-decoration: underline; color: rgb(153,0,0) }"); -- Dark red.
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.delete4 
{text-decoration: line-through; color: rgb(153,0,0) }");
+            --Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.both4 
{text-decoration: underline, line-through; color: rgb(153,0,0) }");
+               -- Both doesn't seem to work, so forget it.
+       -- else not used, don't generate it.
+       end if;
+       if Revision_Used ('5') then
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.insert5 
{text-decoration: underline; color: rgb(0,102,0) }"); -- Dark green.
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.delete5 
{text-decoration: line-through; color: rgb(0,102,0) }");
+            --Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.both5 
{text-decoration: underline, line-through; color: rgb(0,102,0) }");
+               -- Both doesn't seem to work, so forget it.
+       -- else not used, don't generate it.
+       end if;
+       if Revision_Used ('6') then
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.insert6 
{text-decoration: underline; color: rgb(0,102,153) }"); -- Turquiose.
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.delete6 
{text-decoration: line-through; color: rgb(0,102,153) }");
+            --Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.both6 
{text-decoration: underline, line-through; color: rgb(0,102,153) }");
+               -- Both doesn't seem to work, so forget it.
+       -- else not used, don't generate it.
+       end if;
+
+        -- Link styles:
+       -- We don't need these (they're given in the BODY command), but I've
+       -- kept them in case we want to change these in the future.
+        --Ada.Text_IO.Put_Line (Output_Object.Output_File, "    A:link {color: 
rgb(0,0,255)}");
+        --Ada.Text_IO.Put_Line (Output_Object.Output_File, "    A:visited 
{color: rgb(128,0,128)}");
+       -- The following styles are for the Ada-Auth.Org header. It would be 
nice
+       -- if we could skip them if they're not needed, but we don't have the
+       -- information needed to do that.
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "    A.Bar:link 
{font-family: Arial, Helvetica, sans-serif; font-style: normal; 
text-decoration: none; color: rgb(204,204,51)}");
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "    A.Bar:visited 
{font-family: Arial, Helvetica, sans-serif; font-style: normal; 
text-decoration: none; color: rgb(204,204,51)}");
+
+       -- Paragraph styles:
+       for S in ARM_Output.Unprefixed_Style_Subtype loop
+           for I in ARM_Output.Paragraph_Indent_Type loop
+               Make_Style (Output_Object, Paragraph_Name (S, I), S, I);
+           end loop;
+       end loop;
+
+       for S in ARM_Output.Bullet_Prefixed_Style_Subtype loop
+           -- These styles do not allow Indent 0.
+           for I in 1 .. ARM_Output.Paragraph_Indent_Type'Last loop
+               if Output_Object.HTML_Kind = HTML_4_Only then
+                   Make_Style (Output_Object, Paragraph_Name (S, I) & 
"-NoPrefix", S, I,
+                               Kind => Bulleted_No_Prefix);
+                   Make_Style (Output_Object, Paragraph_Name (S, I), S, I,
+                               Kind => Bulleted_Item);
+               else
+                   Make_Style (Output_Object, Paragraph_Name (S, I), S, I);
+               end if;
+           end loop;
+       end loop;
+
+       for S in ARM_Output.Text_Prefixed_Style_Subtype loop
+           -- These styles do not allow Indent 0.
+           for I in 1 .. ARM_Output.Paragraph_Indent_Type'Last loop
+               if Paragraph_Used (S, I) then
+                   Make_Style (Output_Object, Paragraph_Name (S, I), S, I, 
Kind => Hanging_Body);
+                   Make_Hung_Text_Style (Output_Object, Paragraph_Name (S, I), 
S, I);
+               -- else not used.
+               end if;
+           end loop;
+       end loop;
+
+    end Make_Paragraph_Styles;
+
+
+    MAGIC_STYLE_MARKER : constant String := "&%$# STYLES GO HERE #$%&";
+
+
+    procedure Start_HTML_File (Output_Object : in out HTML_Output_Type;
+                              File_Name : in String;
+                              Title : in String;
+                              Clause : in String) is
+       -- Internal routine.
+       -- Create an HTML file, and generate the needed text to start an HTML
+       -- file. The file name is just the name portion, not the path or
+       -- extension. Clause is the properly formatted Clause number for
+       -- this file, if known.
+    begin
+--Ada.Text_IO.Put_Line ("--Creating " & File_Name & ".html");
+       if Output_Object.HTML_Kind > HTML_3 then
+           Ada.Text_IO.Create (Output_Object.Output_File, Ada.Text_IO.Out_File,
+               Ada.Strings.Unbounded.To_String (Output_Object.Output_Path) &
+                   File_Name & ".$$$");
+       elsif Output_Object.DOS_Filenames then
+           Ada.Text_IO.Create (Output_Object.Output_File, Ada.Text_IO.Out_File,
+               Ada.Strings.Unbounded.To_String (Output_Object.Output_Path) &
+                   File_Name & ".HTM");
+       else
+           Ada.Text_IO.Create (Output_Object.Output_File, Ada.Text_IO.Out_File,
+               Ada.Strings.Unbounded.To_String (Output_Object.Output_Path) &
+                   File_Name & ".html");
+       end if;
+       -- Save the current clause:
+       Output_Object.Current_Clause :=
+           Ada.Strings.Unbounded.To_Unbounded_String(Clause);
+       -- File introduction:
+       if Output_Object.HTML_Kind > HTML_3 then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "<!DOCTYPE HTML 
PUBLIC ""-//W3C//DTD HTML 4.01 Transitional//EN""");
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"""http://www.w3.org/TR/html4/loose.dtd"";>"); -- HTML 4.01 (with depreciated 
features)
+       else
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "<!DOCTYPE HTML 
PUBLIC ""-//W3C//DTD HTML 3.2//EN"">"); -- HTML 3.2
+       end if;
+                                                                               
                       -- so the result can be used on version 3 browsers.)
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "<HTML>");
+       -- Header information:
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "<HEAD>");
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "    <TITLE>" & Title 
& "</TITLE>");
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "    <META 
http-equiv=""Content-Type"" content=""text/html; charset=iso-8859-1"">");
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "    <META 
NAME=""Author"" CONTENT=""JTC1/SC22/WG9/ARG, by Randall Brukardt, ARG 
Editor"">");
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "    <META 
NAME=""GENERATOR"" CONTENT=""Arm_Form.Exe, Ada Reference Manual generator"">");
+       if Output_Object.HTML_Kind = HTML_4_Only then
+            -- The style sheet.
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "    <STYLE 
type=""text/css"">");
+           -- Element styles:
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "    H4.centered 
{text-align: center}");
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.swiss 
{font-family: Arial, Helvetica, sans-serif; font-size: 92%}");
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "    SPAN.roman 
{font-family: ""Times New Roman"", Times, serif}");
+
+           -- Paragraph styles:
+           --Paragraph_Used := (others => (others => True)); -- Force showing 
all, we don't know what is used.
+           --Revision_Used := (others => True);
+           --Paranum_Used := True;
+           --Make_Paragraph_Styles (Output_Object);
+           -- Dummy line to be replaced after the file is created.
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, 
MAGIC_STYLE_MARKER);
+
+           Paragraph_Used := (others => (others => False));
+           Revision_Used := (others => False);
+           Paranum_Used := False;
+
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "    </STYLE>");
+       elsif Output_Object.HTML_Kind = HTML_4_Compatible then
+            -- The style sheet.
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "    <STYLE 
type=""text/css"">");
+
+           -- Paragraph styles:
+           --Paragraph_Used := (others => (others => True)); -- Force showing 
all, we don't know what is used.
+           --Revision_Used := (others => True);
+           --Paranum_Used := True;
+           --Make_Paragraph_Styles (Output_Object);
+           -- Dummy line to be replaced after the file is created.
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, 
MAGIC_STYLE_MARKER);
+
+           Paragraph_Used := (others => (others => False));
+           Revision_Used := (others => False);
+           Paranum_Used := False;
+
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "    </STYLE>");
+       end if;
+
+       if Ada.Strings.Unbounded.Length(Output_Object.Script_HTML) /= 0 then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File,
+               Ada.Strings.Unbounded.To_String(Output_Object.Script_HTML));
+       end if;
+
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "</HEAD>");
+        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+           "<BODY TEXT=""" & Output_Object.Text_Color &
+           """ BGCOLOR=""" & Output_Object.Background_Color &
+           """ LINK=""" & Output_Object.Link_Color &
+           """ VLINK=""" & Output_Object.VLink_Color &
+           """ ALINK=""" & Output_Object.ALink_Color & """>");
+
+       if Ada.Strings.Unbounded.Length(Output_Object.Header_HTML) /= 0 then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File,
+               Ada.Strings.Unbounded.To_String(Output_Object.Header_HTML));
+       end if;
+
+       if Output_Object.Nav_on_Top then
+           Make_Navigation_Bar (Output_Object, Is_Top => True);
+       -- else no navigation bar
+       end if;
+
+       if Output_Object.Nav_on_Top or else
+          Ada.Strings.Unbounded.Length(Output_Object.Header_HTML) /= 0 then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "<HR>"); -- 
Horizontal line (rule).
+       -- else nothing on top at all.
+       end if;
+    end Start_HTML_File;
+
+
+    procedure End_HTML_File (Output_Object : in out HTML_Output_Type) is
+       -- Internal routine.
+       -- Generate the needed text to end an HTML file. Also closes the file.
+    begin
+       Ada.Text_IO.New_Line (Output_Object.Output_File); -- Blank line to set 
off paragraphs.
+
+       if Output_Object.Nav_on_Bottom or else
+          Ada.Strings.Unbounded.Length(Output_Object.Footer_HTML) /= 0 then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "<HR>"); -- 
Horizontal line (rule).
+       -- else nothing on top at all.
+       end if;
+
+       if Output_Object.Nav_on_Bottom then
+           Make_Navigation_Bar (Output_Object, Is_Top => False);
+       -- else no navigation bar.
+       end if;
+
+       if Ada.Strings.Unbounded.Length(Output_Object.Footer_HTML) /= 0 then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File,
+               Ada.Strings.Unbounded.To_String(Output_Object.Footer_HTML));
+       end if;
+
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "</BODY>");
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "</HTML>");
+       if Output_Object.HTML_Kind <= HTML_3 then
+           Ada.Text_IO.Close (Output_Object.Output_File);
+       else -- Close and reread the file to add JUST the styles used by the
+            -- file; this decreases the minimum size of the files (by as
+            -- much as 7K as of this writing [1/2006]), which matters when
+            -- there are hundreds.
+            -- We also check spaces before end tags and after opening tags;
+            -- these should be &nbsp;. (See 9.1 in HTML 4.0: "In order to
+            -- avoid problems with SGML line break rules and inconsistencies
+            -- among extant implementations, authors should not rely on user
+            -- agents to render white space immediately after a start tag or
+            -- immediately before an end tag.") We haven't seen a problem
+            -- with this, but why ask for trouble?
+            -- Note that we assume that all occurrences of "<" and ">" in
+            -- the literal text are written as "&lt;" and "&gt;"; violations
+            -- might cause the conversion of spaces to non-breaking spaces,
+            -- which should not cause problems in general. We also assume that
+            -- all end tags are on one line (they are all very short), so
+            -- any ">" is the end of a start tag unless there is a "</" 
preceding it.
+           declare
+               Original_Name : constant String := Ada.Text_IO.Name 
(Output_Object.Output_File);
+               Reading_File : Ada.Text_IO.File_Type;
+               Real_Name : constant String :=
+                   Ada.Strings.Fixed.Head (Original_Name, 
Original_Name'Length-3);
+               Buffer : String (1..1000);
+               Len : Natural;
+               Body_Seen : Boolean := False;
+               Loc : Natural;
+           begin
+               Ada.Text_IO.Close (Output_Object.Output_File);
+               Ada.Text_IO.Open (Reading_File, Ada.Text_IO.In_File,
+                   Original_Name);
+               if Output_Object.DOS_Filenames then
+                   Ada.Text_IO.Create (Output_Object.Output_File, 
Ada.Text_IO.Out_File,
+                       Real_Name & "HTM");
+               else
+                   Ada.Text_IO.Create (Output_Object.Output_File, 
Ada.Text_IO.Out_File,
+                       Real_Name & "html");
+               end if;
+               begin
+                   loop
+                       Ada.Text_IO.Get_Line (Reading_File, Buffer, Len);
+                       if Buffer(1..Len) = MAGIC_STYLE_MARKER then
+                           -- Output only the styles used here.
+                           Make_Paragraph_Styles (Output_Object);
+                       elsif not Body_Seen then
+                           if Ada.Strings.Fixed.Index (Buffer(1..Len), 
"<BODY") /= 0 then
+                               Body_Seen := True;
+                           end if;
+                           Ada.Text_IO.Put_Line (Output_Object.Output_File, 
Buffer(1..Len));
+                       else
+                           -- Replace spaces before end tags:
+                           loop
+                               Loc := Ada.Strings.Fixed.Index (Buffer(1..Len), 
" </");
+                               exit when Loc = 0;
+                               Buffer(Loc+6..Len+5) := Buffer(Loc+1..Len);
+                               Buffer(Loc..Loc+5) := "&nbsp;";
+                               Len := Len+5;
+                           end loop;
+                           -- Replace spaces after start tags:
+                           Loc := 1;
+                           while Loc < Len loop
+                               if Buffer(Loc..Loc+1) = "> " then
+                                   -- Candidate; check that this isn't an end 
tag.
+                                   for I in reverse 1..Loc-1 loop
+                                       if Buffer(I) = '/' then
+                                           -- End tag, nothing to do.
+                                           Loc := Loc + 2;
+                                           exit;
+                                       elsif Buffer(I) = '<' or else I = 1 then
+                                           -- Start tag (including reaching the
+                                           -- start of the line), replace.
+                                           Buffer(Loc+7..Len+5) := 
Buffer(Loc+2..Len);
+                                           Buffer(Loc+1..Loc+6) := "&nbsp;";
+                                           Len := Len+5;
+                                           Loc := Loc + 7;
+                                           -- If these is the *last* character 
on the
+                                           -- line, we have to "unbreak" the 
line, else we'd get an extra space.
+                                           if Loc > Len then
+                                               Ada.Text_IO.Put 
(Output_Object.Output_File, Buffer(1..Len));
+                                               goto Skip_Write;
+                                           end if;
+                                           exit;
+                                       -- else continue.
+                                       end if;
+                                   end loop;
+                               else
+                                   Loc := Loc + 1;
+                               end if;
+                           end loop;
+
+                           Ada.Text_IO.Put_Line (Output_Object.Output_File, 
Buffer(1..Len));
+                       <<Skip_Write>> null;
+                       end if;
+                   end loop;
+               exception
+                   when Ada.Text_IO.End_Error => null; -- Done copying.
+               end;
+               Ada.Text_IO.Close (Output_Object.Output_File);
+               Ada.Text_IO.Delete (Reading_File); -- This was temporary.
+           end;
+       end if;
+    end End_HTML_File;
+
+
+    procedure Create (Output_Object : in out HTML_Output_Type;
+                     Big_Files : in Boolean;
+                     File_Prefix : in String;
+                     Output_Path : in String;
+                     DOS_Filenames : in Boolean;
+                     HTML_Kind : in HTML_Type;
+                     Use_Unicode : in Boolean;
+                     Number_Paragraphs : in Boolean;
+                     Ref_URL : in String;
+                     Srch_URL : in String;
+                     Index_URL : in String;
+                     Use_Buttons : Boolean;
+                     Nav_On_Top : Boolean;
+                     Nav_On_Bottom : Boolean;
+                     Tab_Emulation : Tab_Emulation_Type;
+                     Script_HTML : String;
+                     Header_HTML : String;
+                     Footer_HTML : String;
+                     Title : in String := "";
+                     Body_Font : ARM_Output.Font_Family_Type;
+                     Force_New_Revision_Colors : Boolean;
+                     Text_Color : Color_String;
+                     Background_Color : Color_String;
+                     Link_Color : Color_String;
+                     VLink_Color : Color_String;
+                     ALink_Color : Color_String) is
+       -- Create an Output_Object for a document.
+       -- Generate a few large output files if
+       -- Big_Files is True; otherwise generate smaller output files.
+       -- The prefix of the output file names is File_Prefix - this
+       -- should be no more than 5 characters allowed in file names.
+       -- The files will be written into Output_Path.
+       -- If DOS_Filename is true, use 8.3 file names;
+       -- in that case, File_Prefix must be less than 4 characters in length;
+       -- and no clause or subclause number may exceed 35 if Big_Files is 
False.
+       -- The title of the document is Title.
+       -- HTML_Kind determines the kind of HTML generated; HTML_3 works on
+       -- every browser but has little control over formatting;
+       -- HTML_4_Compatible has better control, but tries to make the results
+       -- look good on older browsers; HTML_4_Only uses maximum formatting,
+       -- but makes no attempt to look good on browsers older than IE 5.0 and
+       -- Firefox 1.0.
+       -- If Use_Unicode is true, Unicode characters available on US versions
+       -- of Windows 2000 are used when appropriate; otherwise, Unicode
+       -- characters are only used when explicitly requested with
+       -- Unicode_Character (other characters are replaced with reasonable
+       -- equivalents). [Note: It's known that IE on Windows 95/98/ME cannot
+       -- display Unicode characters.] Use_Unicode has no effect if HTML_Kind
+       -- is set to HTML_3.
+       -- Number_Paragraphs means that paragraph numbers will be used;
+       -- otherwise, the Number parameter to Start_Paragraph must be "".
+       -- Ref_URL, Srch_URL, and Index_URL are the URLs (possibly relative)
+       -- for the "References", "Search", and "Index" buttons/labels,
+       -- respectively. If null, these buttons/labels link to sections named
+       -- "References", "Search", and "Index"; if these do not exist, the
+       -- buttons/labels are omitted.
+       -- If Use_Buttons is true, button images are used, otherwise text labels
+       -- are used for the navigation bar.
+       -- If Nav_On_Top is true, the navigation bar will appear in the header
+       -- of each page. If Nav_On_Bottom is true, the navigation bar will
+       -- appear in the footer of each page.
+       -- Tab_Emulation determines how tabs are emulated.
+       -- Script_HTML gives self-contained HTML that will appear immediately
+       -- before the </HEAD> of every page. This usually will contain
+       -- Javascript scripts or CSS styles. The original intent was to allow
+       -- adding the Google Analytics script to each page.
+       -- Header_HTML gives self-contained HTML that will appear before the
+       -- navigation bar in the header. Footer_HTML gives self-contained HTML
+       -- that will appear after the navigation bar in the footer.
+       -- Body_Font selects the default font for the document body.
+       -- Text_Color specifies the default text color; Background_Color
+       -- specifies the default background color; Link_Color specifies the
+       -- default color of normal links; VLink_Color specifies the
+       -- default color of visited links; and ALink_Color specifies the
+       -- default color of active (in the act of clinking) links.
+    begin
+       if Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Already valid object");
+       end if;
+       Output_Object.Is_Valid := True;
+       Ada.Strings.Fixed.Move (Target => Output_Object.File_Prefix,
+                               Source => File_Prefix);
+       Output_Object.Title := Ada.Strings.Unbounded.To_Unbounded_String 
(Title);
+       Output_Object.Big_Files := Big_Files;
+       Output_Object.Output_Path := 
Ada.Strings.Unbounded.To_Unbounded_String(Output_Path);
+       Output_Object.DOS_Filenames := DOS_Filenames;
+       Output_Object.HTML_Kind := HTML_Kind;
+       Output_Object.Use_Unicode := Use_Unicode;
+       Output_Object.Number_Paragraphs := Number_Paragraphs;
+       Output_Object.Ref_URL := 
Ada.Strings.Unbounded.To_Unbounded_String(Ref_URL);
+       Output_Object.Srch_URL := 
Ada.Strings.Unbounded.To_Unbounded_String(Srch_URL);
+       Output_Object.Index_URL := 
Ada.Strings.Unbounded.To_Unbounded_String(Index_URL);
+       Output_Object.Use_Buttons := Use_Buttons;
+       Output_Object.Nav_on_Top := Nav_on_Top;
+       Output_Object.Nav_on_Bottom := Nav_on_Bottom;
+       Output_Object.Tab_Emulation := Tab_Emulation;
+       Output_Object.Script_HTML := 
Ada.Strings.Unbounded.To_Unbounded_String(Script_HTML);
+       Output_Object.Header_HTML := 
Ada.Strings.Unbounded.To_Unbounded_String(Header_HTML);
+       Output_Object.Footer_HTML := 
Ada.Strings.Unbounded.To_Unbounded_String(Footer_HTML);
+       Output_Object.Body_Font := Body_Font;
+       Output_Object.Force_New_Revision_Colors := Force_New_Revision_Colors;
+       Output_Object.Text_Color := Text_Color;
+       Output_Object.Background_Color := Background_Color;
+       Output_Object.Link_Color := Link_Color;
+       Output_Object.VLink_Color := VLink_Color;
+       Output_Object.ALink_Color := ALink_Color;
+
+       if DOS_Filenames then
+           if File_Prefix'Length > 3 then
+               Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                   "HTML File Prefix too long - MS-DOS mode");
+           end if;
+       else
+           if File_Prefix'Length > 5 then
+               Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                   "HTML File Prefix too long");
+           end if;
+       end if;
+
+       if Output_Object.Big_Files then
+           Start_HTML_File (Output_Object,
+                            Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right),
+                            Ada.Strings.Unbounded.To_String 
(Output_Object.Title),
+                            Clause => "");
+           -- Insert an anchor for the title page:
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "<A 
NAME=""TTL""></A>");
+       end if;
+    end Create;
+
+
+    procedure Close (Output_Object : in out HTML_Output_Type) is
+       -- Close an Output_Object. No further output to the object is
+       -- allowed after this call.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Ada.Text_IO.Is_Open (Output_Object.Output_File) then
+           End_HTML_File (Output_Object);
+       end if;
+       Output_Object.Is_Valid := False;
+    end Close;
+
+
+    procedure Section (Output_Object : in out HTML_Output_Type;
+                      Section_Title : in String;
+                      Section_Name : in String) is
+       -- Start a new section. The title is Section_Title (this is
+       -- intended for humans). The name is Section_Name (this is
+       -- intended to be suitable to be a portion of a file name).
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Section in paragraph");
+       end if;
+       -- We don't generate a file here for HTML. We generate a file for each
+       -- clause.
+       if Section_Name'Length > 3 then
+           Output_Object.Section_Name := Section_Name (Section_Name'First .. 
Section_Name'First + 2);
+       else
+           Output_Object.Section_Name := (others => '-');
+           Output_Object.Section_Name (1 .. Section_Name'Length) := 
Section_Name;
+       end if;
+    end Section;
+
+
+    procedure Set_Columns (Output_Object : in out HTML_Output_Type;
+                          Number_of_Columns : in ARM_Output.Column_Count) is
+       -- Set the number of columns.
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "In paragraph");
+       end if;
+       if Number_of_Columns >= 4 then
+           -- We have special processing for 4 or more columns. Note that we
+           -- assume do not contain any nested paragraph formats.
+           Output_Object.Current_Column := 1;
+           Output_Object.Current_Item := 1;
+       elsif Output_Object.Column_Count >= 4 and then Number_of_Columns = 1 
then
+           -- Finished processing columns, output the columns as a table.
+           if Output_Object.Current_Column = 1 then
+               -- No New_Column calls; break this into columns ourselves.
+               -- Current_Item represents the total number of items + 2
+               -- (there is a double count for the end of the paragraph).
+               declare
+                   Col_Count : Natural := Output_Object.Current_Item - 2;
+                   Where : Column_Text_Ptr;
+               begin
+                   Col_Count := (Col_Count + Output_Object.Column_Count - 1) /
+                       Output_Object.Column_Count;
+Ada.Text_IO.Put_Line("  @@ Calc columns for" & 
Natural'Image(Output_Object.Column_Count) &
+  " columns;" & Natural'Image(Output_Object.Current_Item - 1) & " total 
items;" &
+  Natural'Image(Col_Count) & " per column.");
+
+                   -- Split the item list into the appropriate columns.
+                   -- Note that this list is stored in reverse order.
+                   for I in reverse 2 .. Output_Object.Column_Count loop
+--Ada.Text_IO.Put_Line("  @@   For column" & Natural'Image(I) & " split at 
item" &
+--Natural'Image(Col_Count*(I-1)));
+                       Where := Output_Object.Column_Text(1);
+                       exit when Where = null; -- No columns to look at.
+                       if Where.Item <= Col_Count*(I-1) then
+                           -- This column is empty.
+                           null;
+                       else
+                           Output_Object.Column_Text(I) := Where;
+                           while Where.Next /= null and then
+                               Where.Next.Item > Col_Count*(I-1) loop
+                               Where.Item := Where.Item - Col_Count*(I-1);
+                               Where := Where.Next;
+                           end loop;
+                           if Where = null then
+                               Output_Object.Column_Text(1) := null;
+                           else
+                               Output_Object.Column_Text(1) := Where.Next;
+                               Where.Next := null;
+--Ada.Text_IO.Put_Line("    split item=" & Natural'Image(Where.Item));
+                               Where.Item := Where.Item - Col_Count*(I-1);
+                           end if;
+                       end if;
+                   end loop;
+               end;
+           --else there were explicit New_Column calls; no need to
+           --do anything here.
+           end if;
+           if Output_Object.HTML_Kind = HTML_3 then
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"<UL><UL><TABLE Width=""70%"">"); -- Table with no border or caption, takes up 
70% of the screen.
+           else
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                   "<div class=""" & Paragraph_Name (ARM_Output.Normal, 2) & 
"""><table width=""70%"">"); -- Table with no border or caption, takes up 70% 
of the screen.
+               Paragraph_Used(ARM_Output.Normal, 2) := True;
+           end if;
+           -- And start the first row:
+           Ada.Text_IO.Put (Output_Object.Output_File, "<TR><TD 
align=""left"">");
+           for Item in 1 .. 5000 loop
+               for Col in 1 .. Output_Object.Column_Count loop
+                   declare
+                       Find : Column_Text_Ptr := 
Output_Object.Column_Text(Col);
+                       Temp : Column_Text_Ptr;
+                   begin
+                       -- We're going to free this item after outputting it.
+                       if Find = null then
+                           null;
+                       elsif Find.Next = null then
+                           if Find.Item /= Item then
+                               Find := null;
+                           else
+                               Output_Object.Column_Text(Col) := null;
+                           end if;
+                       else
+                           while Find.Next /= null and then Find.Next.Item /= 
Item loop
+                               Find := Find.Next;
+                           end loop;
+                           Temp := Find;
+                           Find := Find.Next;
+                           Temp.Next := null;
+                       end if;
+                       if Find /= null then
+                           Ada.Text_IO.Put (Output_Object.Output_File,
+                               Find.Text (1 .. Find.Length));
+                           -- This should always be the last item:
+                           if Find.Next /= null then
+                               Ada.Text_IO.Put_Line ("** Column Item invariant 
failure!");
+                           end if;
+                           Free (Find);
+                       else -- No item, make a blank.
+                           Ada.Text_IO.Put (Output_Object.Output_File,
+                               "&nbsp;");
+                       end if;
+                   end;
+                   Ada.Text_IO.Put (Output_Object.Output_File, "<TD 
align=""left"">");
+               end loop;
+               if Output_Object.Column_Text = Column_Text_Ptrs_Type'(others => 
null) then
+                   -- We've output everything.
+                   Ada.Text_IO.New_Line (Output_Object.Output_File);
+                   if Output_Object.HTML_Kind = HTML_3 then
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"</TABLE></UL></UL>");
+                   else
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"</table></div>");
+                   end if;
+                   exit;
+               end if;
+               -- End the row:
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Ada.Text_IO.Put (Output_Object.Output_File, "<TR><TD 
align=""left"">");
+           end loop;
+           Output_Object.Current_Column := 0;
+           Output_Object.Current_Item := 0;
+       -- else Two and Three column formats are displayed without any columns.
+       -- This is mainly used for the syntax cross-reference and index, and
+       -- these definitely look better without columns.
+       end if;
+       Output_Object.Column_Count := Number_of_Columns;
+    end Set_Columns;
+
+
+    procedure Check_Clause_File (Output_Object : in out HTML_Output_Type) is
+       -- Check that a Clause file has been made for this clause; if not,
+       -- create one.
+    begin
+       if not Ada.Text_IO.Is_Open (Output_Object.Output_File) then
+           if (not Output_Object.Big_Files) and then
+                 Output_Object.DOS_Filenames and then
+                 Output_Object.Section_Name(1) = '-' then
+                   Start_HTML_File (Output_Object,
+                       Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right) &
+                           Make_Clause_Anchor_Name (Output_Object, 
Output_Object.Section_Name(2..3)), "", Clause => "");
+           else
+               Start_HTML_File (Output_Object,
+                   Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right) &
+                       "-" & Output_Object.Section_Name, "", Clause => "");
+           end if;
+       end if;
+    end Check_Clause_File;
+
+
+    procedure Put_Compatibility_Font_Info (Output_Object : in out 
HTML_Output_Type;
+                                          Style  : in 
ARM_Output.Paragraph_Style_Type;
+                                          Indent : in 
ARM_Output.Paragraph_Indent_Type) is
+       -- Internal:
+        -- Output the font information for HTML 4.0 compatibility mode.
+    begin
+        if Output_Object.HTML_Kind = HTML_4_Compatible then
+           case Paragraph_Info(Style, Indent).Font is
+               when ARM_Output.Default =>
+                   if ARM_Output."=" (Output_Object.Body_Font, 
ARM_Output.Swiss) then
+                       Ada.Text_IO.Put (Output_Object.Output_File, 
SWISS_FONT_CODE);
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
SWISS_FONT_CODE'Length;
+                   -- else nothing for Roman.
+                   end if;
+               when ARM_Output.Roman =>
+                   null;
+               when ARM_Output.Swiss =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
SWISS_FONT_CODE);
+                   Output_Object.Char_Count := Output_Object.Char_Count + 
SWISS_FONT_CODE'Length;
+               when ARM_Output.Fixed =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "<TT>");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 4;
+           end case;
+           if ARM_Output."=" (Paragraph_Info(Style, Indent).Font, 
ARM_Output.Fixed) then
+               null; -- No font change here.
+           else
+               case Paragraph_Info(Style, Indent).Size is
+                   when 0 => null;
+                   when 1 =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<font 
size=""+1"">");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
16;
+                   when 2 =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<font 
size=""+2"">");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
16;
+                   when 3 =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<font 
size=""+3"">");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
16;
+                   when -1 =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<font 
size=""-1"">");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
16;
+                   when -2 =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<font 
size=""-2"">");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
16;
+                   when -3 =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<font 
size=""-3"">");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
16;
+                   when others => null; -- Not supported.
+               end case;
+           end if;
+        end if;
+    end Put_Compatibility_Font_Info;
+
+
+    procedure Put_End_Compatibility_Font_Info (Output_Object : in out 
HTML_Output_Type;
+                                              Style  : in 
ARM_Output.Paragraph_Style_Type;
+                                              Indent : in 
ARM_Output.Paragraph_Indent_Type) is
+       -- Internal:
+        -- Output the font information for HTML 4.0 compatibility mode.
+    begin
+        if Output_Object.HTML_Kind = HTML_4_Compatible then
+           if ARM_Output."=" (Paragraph_Info(Style, Indent).Font, 
ARM_Output.Fixed) then
+               null; -- No font change here.
+           else
+               case Paragraph_Info(Style, Indent).Size is
+                   when 0 => null;
+                   when 1 =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "</font>");
+                   when 2 =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "</font>");
+                   when -1 =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "</font>");
+                   when -2 =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "</font>");
+                   when -3 =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "</font>");
+                   when others => null; -- Not supported.
+               end case;
+           end if;
+           case Paragraph_Info(Style, Indent).Font is
+               when ARM_Output.Default =>
+                   if ARM_Output."=" (Output_Object.Body_Font, 
ARM_Output.Swiss) then
+                       Ada.Text_IO.Put (Output_Object.Output_File, "</font>");
+                   -- else nothing for Roman.
+                   end if;
+               when ARM_Output.Roman =>
+                   null;
+               when ARM_Output.Swiss =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</font>");
+               when ARM_Output.Fixed =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</tt>");
+           end case;
+        end if;
+    end Put_End_Compatibility_Font_Info;
+
+
+    procedure Start_Paragraph (Output_Object : in out HTML_Output_Type;
+                              Style     : in ARM_Output.Paragraph_Style_Type;
+                              Indent    : in ARM_Output.Paragraph_Indent_Type;
+                              Number    : in String;
+                              No_Prefix : in Boolean := False;
+                              Tab_Stops : in ARM_Output.Tab_Info := 
ARM_Output.NO_TABS;
+                              No_Breaks : in Boolean := False;
+                              Keep_with_Next : in Boolean := False;
+                              Space_After : in ARM_Output.Space_After_Type
+                                  := ARM_Output.Normal;
+                              Justification : in ARM_Output.Justification_Type
+                                  := ARM_Output.Default) is
+       -- Start a new paragraph. The style and indent of the paragraph is as
+       -- specified. The (AA)RM paragraph number (which might include update
+       -- and version numbers as well: [12.1/1]) is Number. If the format is
+       -- a type with a prefix (bullets, hangining items), the prefix is
+       -- omitted if No_Prefix is true. Tab_Stops defines the tab stops for
+       -- the paragraph. If No_Breaks is True, we will try to avoid page breaks
+       -- in the paragraph. If Keep_with_Next is true, we will try to avoid
+       -- separating this paragraph and the next one. (These may have no
+       -- effect in formats that don't have page breaks). Space_After
+       -- specifies the amount of space following the paragraph. Justification
+       -- specifies the text justification for the paragraph. Not_Valid_Error
+       -- is raised if Tab_Stops /= NO_TABS for a hanging or bulleted format.
+
+       procedure Put_Style (Name : in String;
+                            Include_Compatibility : in Boolean := True;
+                            Use_DIV : in Boolean := False) is
+           -- Output a style for HTML 4.0; if Include_Compatibility is True,
+           -- include compatibility font information as well.
+           -- If Use_DIV is true, ignore the contents of the
+           -- style data and use a DIV.
+       begin
+           if Use_DIV then
+               Ada.Text_IO.Put (Output_Object.Output_File, "<div");
+               Output_Object.Char_Count := 4;
+           else
+               case Paragraph_Info(Style, Indent).Tag is
+                   when DIV =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<div");
+                       Output_Object.Char_Count := 4;
+                   when UL =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<ul");
+                       Output_Object.Char_Count := 3;
+                   when DL =>
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<dl");
+                       Output_Object.Char_Count := 3;
+               end case;
+           end if;
+           Ada.Text_IO.Put (Output_Object.Output_File, " class=""" & Name & 
"""");
+           Output_Object.Char_Count := Output_Object.Char_Count + 8 + 
Name'Length + 1;
+           case Justification is
+               when ARM_Output.Default | ARM_Output.Left | 
ARM_Output.Justified =>
+                   null;
+               when ARM_Output.Center =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, " 
style=""text-align: center""");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 27;
+               when ARM_Output.Right =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, " 
style=""text-align: right""");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 26;
+           end case;
+           case Space_After is
+               when ARM_Output.Normal =>
+                   null;
+               when ARM_Output.Narrow =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, " 
style=""margin-bottom: ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 24;
+                   Put_EMs(Output_Object.Output_File, (Paragraph_Info(Style, 
Indent).After * LEADING_PERCENT) / 100);
+                   Ada.Text_IO.Put (Output_Object.Output_File, """");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 6;
+               when ARM_Output.Wide =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, " 
style=""margin-bottom: ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 24;
+                   Put_EMs(Output_Object.Output_File, (Paragraph_Info(Style, 
Indent).After * TRAILING_PERCENT) / 100);
+                   Ada.Text_IO.Put (Output_Object.Output_File, """");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 6;
+           end case;
+           Ada.Text_IO.Put (Output_Object.Output_File, ">");
+           Output_Object.Char_Count := Output_Object.Char_Count + 1;
+           if Output_Object.HTML_Kind = HTML_4_Compatible and then 
Include_Compatibility then
+               Put_Compatibility_Font_Info (Output_Object, Style, Indent);
+           end if;
+       end Put_Style;
+
+       function Paranum_Anchor (Number : in String) return String is
+           -- Create the string for an anchor from a paragraph number.
+           -- Note that anchors cannot use "/", so we strip the
+           -- slash part. "." is allowed (as well as "-", "_", and ":", but
+           -- nothing else). We don't need the slash part (the version number),
+           -- as paragraph numbers are unique without it, and the version
+           -- is specified by the enclosing document (given by the rest of
+           -- the page).
+           Where : constant Natural := Ada.Strings.Fixed.Index (Number, "/");
+       begin
+           if Where = 0 then
+               return Number;
+           else
+               return Number(Number'First..Where-1);
+           end if;
+       end Paranum_Anchor;
+
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Already in paragraph");
+       end if;
+       if not Output_Object.Number_Paragraphs and then
+           Number /= "" then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Paragraph number when none used");
+       end if;
+       if not Paragraph_Info(Style, Indent).Defined then
+            Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+               "Undefined style " & 
ARM_Output.Paragraph_Style_Type'Image(Style) &
+               " and indent" & ARM_Output.Paragraph_Indent_Type'Image(Indent));
+       end if;
+
+       Output_Object.Is_In_Paragraph := True;
+       Output_Object.Had_Prefix := not No_Prefix;
+       Output_Object.Char_Count := 0;
+       Output_Object.Disp_Char_Count := 0;
+       Output_Object.Disp_Large_Char_Count := 0;
+       Output_Object.Any_Nonspace := False;
+       Output_Object.Last_Was_Space := True; -- Start of line
+       Output_Object.Conditional_Space := False;
+       Output_Object.Saw_Hang_End := False;
+        Output_Object.In_Local_Link := False;
+       Check_Clause_File (Output_Object);
+       -- Note: We only support Justification for the Normal and Wide styles.
+       if Output_Object.Column_Count >= 4 then
+           -- Formatting is deferred; only a few formats are supported.
+           if Tab_Stops.Number /= 0 then
+               Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                   "Tabs in 4+ column text");
+           end if;
+           case Style is
+               when ARM_Output.Normal =>
+                   null;
+               when others =>
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Unsupported format in 4+ column text - " & 
ARM_Output.Paragraph_Style_Type'Image(Style));
+           end case;
+           if Number /= "" then
+               Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                   "No paragraph numbers in 4+ column text");
+           end if;
+           return; -- Nothing more to do here.
+       end if;
+
+       -- Set up tabs:
+       case Style is
+           when ARM_Output.Normal | ARM_Output.Wide_Above |
+                ARM_Output.Small | ARM_Output.Small_Wide_Above |
+                ARM_Output.Header | ARM_Output.Small_Header |
+                ARM_Output.Index | ARM_Output.Syntax_Summary |
+                ARM_Output.Title |
+                ARM_Output.Examples | ARM_Output.Small_Examples |
+                ARM_Output.Swiss_Examples | ARM_Output.Small_Swiss_Examples =>
+               Output_Object.Tab_Stops := Tab_Stops;
+               -- No tabs in HTML; we'll emulate them for fixed fonts.
+               -- We'll expand proportional stops here (text characters
+               -- are larger than the variable ones these are set up for).
+               Output_Object.Can_Emulate_Tabs :=
+                   ARM_Output."=" (Paragraph_Info(Style, Indent).Font, 
ARM_Output.Fixed);
+               for I in 1 .. Tab_Stops.Number loop
+                   if ARM_Output."=" (Tab_Stops.Stops(I).Kind,
+                                      ARM_Output.Left_Proportional) then
+                       if ARM_Output."=" (Paragraph_Info(Style, Indent).Font, 
ARM_Output.Fixed) then
+                           Output_Object.Tab_Stops.Stops(I).Stop :=
+                               (Tab_Stops.Stops(I).Stop * 13 / 12);
+                       else -- Proportional characters are smaller.
+                           Output_Object.Tab_Stops.Stops(I).Stop :=
+                               (Tab_Stops.Stops(I).Stop * 5 / 4);
+                       end if;
+                   else
+                       Output_Object.Tab_Stops.Stops(I).Stop :=
+                               Tab_Stops.Stops(I).Stop;
+                   end if;
+               end loop;
+
+           when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted |
+                ARM_Output.Small_Bulleted | ARM_Output.Small_Nested_Bulleted |
+                ARM_Output.Giant_Hanging | ARM_Output.Wide_Hanging |
+                ARM_Output.Medium_Hanging | ARM_Output.Narrow_Hanging |
+                ARM_Output.Hanging_in_Bulleted |
+                ARM_Output.Small_Giant_Hanging | ARM_Output.Small_Wide_Hanging 
|
+                ARM_Output.Small_Medium_Hanging | 
ARM_Output.Small_Narrow_Hanging |
+                ARM_Output.Small_Hanging_in_Bulleted |
+                ARM_Output.Enumerated | ARM_Output.Small_Enumerated =>
+               if Tab_Stops.Number /= 0 then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Tabs in hanging/bulleted paragraph");
+               end if;
+               Output_Object.Can_Emulate_Tabs := False;
+       end case;
+
+       if Output_Object.HTML_Kind = HTML_3 then
+           -- Note: We can't control the space below the paragraphs here, so
+           -- Space_After is ignored.
+           -- Make any indents:
+           for I in 1 .. Indent loop
+               Ada.Text_IO.Put (Output_Object.Output_File, "<UL>");
+               Output_Object.Char_Count := Output_Object.Char_Count + 4;
+           end loop;
+           case Style is
+               when ARM_Output.Normal | ARM_Output.Wide_Above |
+                    ARM_Output.Header =>
+                   if ARM_Output."=" (Indent, 0) then
+                       case Justification is
+                           when ARM_Output.Default | ARM_Output.Left | 
ARM_Output.Justified =>
+                               Ada.Text_IO.Put (Output_Object.Output_File, 
"<P>");
+                               Output_Object.Char_Count := 3;
+                           when ARM_Output.Center =>
+                               Ada.Text_IO.Put (Output_Object.Output_File, "<P 
ALIGN=CENTER>");
+                               Output_Object.Char_Count := 16;
+                           when ARM_Output.Right =>
+                               Ada.Text_IO.Put (Output_Object.Output_File, "<P 
ALIGN=RIGHT>");
+                               Output_Object.Char_Count := 15;
+                       end case;
+                   else
+                       null; -- Formatting is hard in HTML 3!
+                   end if;
+
+               when ARM_Output.Small | ARM_Output.Small_Wide_Above |
+                    ARM_Output.Small_Header =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "<FONT 
SIZE=-1>");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 14;
+
+               when ARM_Output.Index =>
+                   -- Note: We don't put this in a smaller font.
+                   if ARM_Output."=" (Indent, 0) then
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<P>");
+                       Output_Object.Char_Count := 3;
+                   else
+                       null; -- Formatting is hard in HTML 3!
+                   end if;
+
+               when ARM_Output.Syntax_Summary =>
+                   -- Note: We don't put this in a smaller font.
+                   null;
+
+               when ARM_Output.Title =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "<FONT 
SIZE=+3>");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 14;
+
+               when ARM_Output.Examples =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "<TT>");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 4;
+               when ARM_Output.Small_Examples =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "<TT><FONT 
SIZE=-1>");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 18;
+               when ARM_Output.Swiss_Examples =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
SWISS_FONT_CODE);
+                   Output_Object.Char_Count := Output_Object.Char_Count + 
SWISS_FONT_CODE'Length;
+               when ARM_Output.Small_Swiss_Examples =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
SMALL_SWISS_FONT_CODE);
+                   Output_Object.Char_Count := Output_Object.Char_Count + 
SMALL_SWISS_FONT_CODE'Length;
+
+               when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted =>
+                   if No_Prefix then
+                       null;
+                   else
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<LI 
TYPE=DISC>");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
14;
+                   end if;
+
+               when ARM_Output.Small_Bulleted | 
ARM_Output.Small_Nested_Bulleted =>
+                   if No_Prefix then
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<FONT 
SIZE=-1>");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
14;
+                   else
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<LI 
TYPE=DISC><FONT SIZE=-1>");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
28;
+                   end if;
+
+               when ARM_Output.Giant_Hanging | ARM_Output.Wide_Hanging |
+                    ARM_Output.Medium_Hanging | ARM_Output.Narrow_Hanging |
+                    ARM_Output.Hanging_in_Bulleted |
+                    ARM_Output.Enumerated =>
+                   if No_Prefix then
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<DL><DD>");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
8;
+                       Output_Object.Saw_Hang_End := True;
+                   else -- Has prefix.
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<DL><DT>");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
8;
+                       Output_Object.Saw_Hang_End := False;
+                   end if;
+
+               when ARM_Output.Small_Giant_Hanging | 
ARM_Output.Small_Wide_Hanging |
+                    ARM_Output.Small_Medium_Hanging | 
ARM_Output.Small_Narrow_Hanging |
+                    ARM_Output.Small_Hanging_in_Bulleted |
+                    ARM_Output.Small_Enumerated =>
+                   if No_Prefix then
+                       Ada.Text_IO.Put (Output_Object.Output_File, 
"<DL><DD><FONT SIZE=-1>");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
22;
+                       Output_Object.Saw_Hang_End := True;
+                   else -- Has prefix.
+                       Ada.Text_IO.Put (Output_Object.Output_File, 
"<DL><DT><FONT SIZE=-1>");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
22;
+                       Output_Object.Saw_Hang_End := False;
+                   end if;
+           end case;
+           Output_Object.Paragraph_Style  := Style;
+           Output_Object.Paragraph_Indent := Indent;
+           Output_Object.Font := ARM_Output.Default;
+           Output_Object.Is_Bold := False;
+           Output_Object.Is_Italic := False;
+           Output_Object.Size := 0;
+           Output_Object.Color := ARM_Output.Default;
+           Output_Object.Change := ARM_Output.None;
+           Output_Object.Version := '0';
+           Output_Object.Added_Version := '0';
+           if Number /= "" then -- Has paragraph number.
+               Ada.Text_IO.Put (Output_Object.Output_File, "<A NAME=""p");
+               Ada.Text_IO.Put (Output_Object.Output_File, 
Paranum_Anchor(Number));
+               Ada.Text_IO.Put (Output_Object.Output_File, """>");
+               Ada.Text_IO.Put (Output_Object.Output_File, 
TINY_SWISS_FONT_CODE);
+               Ada.Text_IO.Put (Output_Object.Output_File, Number);
+               Ada.Text_IO.Put (Output_Object.Output_File, Number);
+               Ada.Text_IO.Put (Output_Object.Output_File, "</FONT></A> ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 
TINY_SWISS_FONT_CODE'Length + Number'Length + 8;
+               Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count 
+ ((Number'Length+1)/2) + 1;
+                   -- Note: Count these as half characters, as the font is so 
small.
+               --Output_Object.Disp_Large_Char_Count := <unchanged>;
+           end if;
+
+       elsif Output_Object.HTML_Kind = HTML_4_Compatible then
+           if Number /= "" then -- Has paragraph number.
+               Paranum_Used := True;
+               Ada.Text_IO.Put (Output_Object.Output_File, "<div 
class=""paranum"">");
+               Ada.Text_IO.Put (Output_Object.Output_File, "<a name=""p");
+               Ada.Text_IO.Put (Output_Object.Output_File, 
Paranum_Anchor(Number));
+               Ada.Text_IO.Put (Output_Object.Output_File, """><font 
size=-2>");
+               Ada.Text_IO.Put (Output_Object.Output_File, Number);
+               Ada.Text_IO.Put (Output_Object.Output_File, "</font></a>");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "</div>");
+               Output_Object.Char_Count := 0;
+               Output_Object.Disp_Char_Count := 0;
+               Output_Object.Disp_Large_Char_Count := 0;
+               Output_Object.Any_Nonspace := False;
+               Output_Object.Last_Was_Space := True; -- Start of line
+               Output_Object.Conditional_Space := False; -- Don't need it here.
+           end if;
+
+           case Style is
+               when ARM_Output.Normal | ARM_Output.Wide_Above |
+                    ARM_Output.Header |
+                    ARM_Output.Small  | ARM_Output.Small_Wide_Above |
+                    ARM_Output.Small_Header |
+                    ARM_Output.Index | ARM_Output.Syntax_Summary |
+                    ARM_Output.Title |
+                    ARM_Output.Examples | ARM_Output.Swiss_Examples |
+                    ARM_Output.Small_Examples | 
ARM_Output.Small_Swiss_Examples =>
+                   Put_Style (Paragraph_Name (Style, Indent));
+
+               when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted |
+                    ARM_Output.Small_Bulleted | 
ARM_Output.Small_Nested_Bulleted =>
+                   Put_Style (Paragraph_Name (Style, Indent), 
Include_Compatibility => False);
+                   if No_Prefix then
+                       null;
+                   else
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<li 
type=disc>");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
14;
+                   end if;
+                   Put_Compatibility_Font_Info (Output_Object, Style, Indent);
+
+               when ARM_Output.Giant_Hanging | ARM_Output.Wide_Hanging |
+                    ARM_Output.Medium_Hanging | ARM_Output.Narrow_Hanging |
+                    ARM_Output.Hanging_in_Bulleted |
+                    ARM_Output.Enumerated |
+                    ARM_Output.Small_Giant_Hanging | 
ARM_Output.Small_Wide_Hanging |
+                    ARM_Output.Small_Medium_Hanging | 
ARM_Output.Small_Narrow_Hanging |
+                    ARM_Output.Small_Hanging_in_Bulleted |
+                    ARM_Output.Small_Enumerated =>
+                   declare
+                       PName : constant String :=
+                               Paragraph_Name (Style, Indent);
+                   begin
+                       Put_Style (PName, Include_Compatibility => False);
+                       if No_Prefix then
+                           Ada.Text_IO.Put (Output_Object.Output_File, "<dd 
class="" & PName & "">");
+                           Output_Object.Char_Count := 
Output_Object.Char_Count + 13 + PName'Length;
+                           Output_Object.Saw_Hang_End := True;
+                       else -- Has prefix.
+                           Ada.Text_IO.Put (Output_Object.Output_File, "<dt>");
+                           Output_Object.Char_Count := 
Output_Object.Char_Count + 4;
+                           Output_Object.Saw_Hang_End := False;
+                       end if;
+                       Put_Compatibility_Font_Info (Output_Object, Style, 
Indent);
+                   end;
+
+           end case;
+           Output_Object.Paragraph_Style  := Style;
+           Output_Object.Paragraph_Indent := Indent;
+           Output_Object.Font := ARM_Output.Default;
+           Output_Object.Is_Bold := False;
+           Output_Object.Is_Italic := False;
+           Output_Object.Size := 0;
+           Output_Object.Color := ARM_Output.Default;
+           Output_Object.Change := ARM_Output.None;
+           Output_Object.Version := '0';
+           Output_Object.Added_Version := '0';
+           if Number /= "" then -- Has paragraph number.
+               if Paragraph_Info(Style, Indent).Indent = 0 and then
+                  ((not No_Prefix) or else
+                    Style in ARM_Output.Unprefixed_Style_Subtype) then
+                   -- No indent, either a prefix or a style that doesn't
+                   -- have a prefix.
+                   -- We may have to make a space for the paragraph number,
+                   -- as absolute positioned or floating items can overlap
+                   -- others.
+                   for I in 1 .. (Number'Length+2)-(INDENT_EMS_FOR_PARANUMS/5) 
loop
+                       -- We assume that each space is roughly equal to
+                       -- 0.5em (that should be conservative).
+                       Ada.Text_IO.Put (Output_Object.Output_File, "&nbsp;");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
1;
+                       Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                       --Output_Object.Disp_Large_Char_Count := <unchanged>;
+                   end loop;
+               -- else is indented, so we don't need to make space.
+               end if;
+           end if;
+       else -- HTML_4_Only.
+           if Number /= "" then -- Has paragraph number.
+               Paranum_Used := True;
+               Ada.Text_IO.Put (Output_Object.Output_File, "<div 
class=""paranum"">");
+               Ada.Text_IO.Put (Output_Object.Output_File, "<a name=""p");
+               Ada.Text_IO.Put (Output_Object.Output_File, 
Paranum_Anchor(Number));
+               Ada.Text_IO.Put (Output_Object.Output_File, """>");
+               Ada.Text_IO.Put (Output_Object.Output_File, Number);
+               Ada.Text_IO.Put (Output_Object.Output_File, "</a>");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "</div>");
+               Output_Object.Char_Count := 0;
+               Output_Object.Disp_Char_Count := 0;
+               Output_Object.Disp_Large_Char_Count := 0;
+               Output_Object.Any_Nonspace := False;
+               Output_Object.Last_Was_Space := True; -- Start of line
+               Output_Object.Conditional_Space := False; -- Don't need it here.
+           end if;
+
+           case Style is
+               when ARM_Output.Normal | ARM_Output.Wide_Above |
+                    ARM_Output.Header |
+                    ARM_Output.Small  | ARM_Output.Small_Wide_Above |
+                    ARM_Output.Small_Header |
+                    ARM_Output.Index | ARM_Output.Syntax_Summary |
+                    ARM_Output.Title |
+                    ARM_Output.Examples | ARM_Output.Swiss_Examples |
+                    ARM_Output.Small_Examples | 
ARM_Output.Small_Swiss_Examples =>
+                   Put_Style (Paragraph_Name (Style, Indent));
+
+               when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted |
+                    ARM_Output.Small_Bulleted | 
ARM_Output.Small_Nested_Bulleted =>
+                   -- We use formatted DIVs here, as otherwise the indenting
+                   -- varies wildly between Firefox and IE (and does not
+                   -- match similar enumerated lists).
+                   if No_Prefix then
+                       Put_Style (Paragraph_Name (Style, Indent) & 
"-NoPrefix", Use_DIV => True);
+                   else
+                       Put_Style (Paragraph_Name (Style, Indent), Use_DIV => 
True);
+                   end if;
+
+               when ARM_Output.Giant_Hanging | ARM_Output.Wide_Hanging |
+                    ARM_Output.Medium_Hanging | ARM_Output.Narrow_Hanging |
+                    ARM_Output.Hanging_in_Bulleted |
+                    ARM_Output.Enumerated |
+                    ARM_Output.Small_Giant_Hanging | 
ARM_Output.Small_Wide_Hanging |
+                    ARM_Output.Small_Medium_Hanging | 
ARM_Output.Small_Narrow_Hanging |
+                    ARM_Output.Small_Hanging_in_Bulleted |
+                    ARM_Output.Small_Enumerated =>
+                   if No_Prefix then
+                       Put_Style (Paragraph_Name (Style, Indent) & "-Body", 
Use_DIV => True);
+                       Output_Object.Saw_Hang_End := True;
+                   else -- Has prefix.
+                       Put_Style (Paragraph_Name (Style, Indent) & "-Term", 
Use_DIV => True);
+                       Output_Object.Saw_Hang_End := False;
+                   end if;
+           end case;
+           Output_Object.Paragraph_Style  := Style;
+           Output_Object.Paragraph_Indent := Indent;
+           Output_Object.Font := ARM_Output.Default;
+           Output_Object.Is_Bold := False;
+           Output_Object.Is_Italic := False;
+           Output_Object.Size := 0;
+           Output_Object.Color := ARM_Output.Default;
+           Output_Object.Change := ARM_Output.None;
+           Output_Object.Version := '0';
+           Output_Object.Added_Version := '0';
+           if Number /= "" then -- Has paragraph number.
+               if Paragraph_Info(Style, Indent).Indent = 0 and then
+                  ((not No_Prefix) or else
+                    Style in ARM_Output.Unprefixed_Style_Subtype) then
+                   -- No indent, either a prefix or a style that doesn't
+                   -- have a prefix.
+                   -- We may have to make a space for the paragraph number,
+                   -- as absolute positioned or floating items can overlap
+                   -- others.
+                   for I in 1 .. 
(Number'Length+2)-((INDENT_EMS_FOR_PARANUMS+5)*3/10) loop
+                       -- We assume that each space is roughly equal to
+                       -- 0.33em (that should be conservative). We also assume
+                       -- that the normal left edge space is 1.0em (this is
+                       -- true on IE 5&6). Paragraph numbers are positioned
+                       -- at 0.5ems, so the additional difference is +5.
+                       Ada.Text_IO.Put (Output_Object.Output_File, "&nbsp;");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
1;
+                       Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                       --Output_Object.Disp_Large_Char_Count := <unchanged>;
+                   end loop;
+               -- else is indented, so we don't need to make space.
+               end if;
+           end if;
+       end if;
+       Paragraph_Used(Style, Indent) := True;
+
+       -- Note: No_Breaks and Keep_with_Next have no effect here, because
+       -- HTML doesn't have page breaks.
+    end Start_Paragraph;
+
+
+    procedure End_Paragraph (Output_Object : in out HTML_Output_Type) is
+       -- End a paragraph.
+
+       procedure Put_End_Style (Style  : in ARM_Output.Paragraph_Style_Type;
+                                Indent : in ARM_Output.Paragraph_Indent_Type;
+                                Include_Compatibility : in Boolean := True) is
+           -- Output a end style for HTML 4.0; if Include_Compatibility is 
True,
+           -- include compatibility font information as well.
+       begin
+           if Output_Object.HTML_Kind = HTML_4_Compatible and then 
Include_Compatibility then
+               Put_End_Compatibility_Font_Info (Output_Object, Style, Indent);
+           end if;
+           case Paragraph_Info(Style, Indent).Tag is
+               when DIV =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</div>");
+               when UL =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</ul>");
+               when DL =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</dl>");
+           end case;
+       end Put_End_Style;
+
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       Output_Object.Is_In_Paragraph := False;
+       if Output_Object.In_Local_Link then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Unclosed Local_Link");
+           Output_Object.In_Local_Link := False;
+       end if;
+       if Output_Object.Column_Count >= 4 then
+           -- Formatting is deferred; only a few formats are supported.
+           if Output_Object.Column_Text (Output_Object.Current_Column) /= null 
and then
+              Output_Object.Column_Text (Output_Object.Current_Column).Item = 
Output_Object.Current_Item then
+               Output_Object.Column_Text 
(Output_Object.Current_Column).End_Para := True;
+           end if;
+           Output_Object.Current_Item := Output_Object.Current_Item + 2; -- 
Skip an item.
+            Output_Object.Char_Count := 0;
+            Output_Object.Disp_Char_Count := 0;
+           Output_Object.Disp_Large_Char_Count := 0;
+           Output_Object.Any_Nonspace := False;
+           Output_Object.Last_Was_Space := True; -- Start of line.
+           Output_Object.Conditional_Space := False; -- Don't need it here.
+           return; -- Nothing else to do here.
+       end if;
+
+       if Output_Object.HTML_Kind = HTML_3 then
+           case Output_Object.Paragraph_Style is
+               when ARM_Output.Normal | ARM_Output.Wide_Above | 
ARM_Output.Header |
+                    ARM_Output.Index =>
+                   if ARM_Output."=" (Output_Object.Paragraph_Indent, 0) then
+                       Ada.Text_IO.Put (Output_Object.Output_File, "</P>");
+                   -- else let the indent nesting handling it.
+                   end if;
+               when ARM_Output.Syntax_Summary =>
+                   null;
+               when ARM_Output.Small | ARM_Output.Small_Wide_Above |
+                    ARM_Output.Small_Header =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</FONT>");
+               when ARM_Output.Title =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</FONT>");
+
+               when ARM_Output.Examples =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</TT>");
+               when ARM_Output.Small_Examples =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</FONT>");
+               when ARM_Output.Swiss_Examples =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</FONT>");
+               when ARM_Output.Small_Swiss_Examples =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</FONT>");
+
+               when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted =>
+                   if Output_Object.Had_Prefix then
+                       Ada.Text_IO.Put (Output_Object.Output_File, "</LI>");
+                   -- else nothing to do.
+                   end if;
+               when ARM_Output.Small_Bulleted | 
ARM_Output.Small_Nested_Bulleted =>
+                   if Output_Object.Had_Prefix then
+                       Ada.Text_IO.Put (Output_Object.Output_File, 
"</FONT></LI>");
+                   else
+                       Ada.Text_IO.Put (Output_Object.Output_File, "</FONT>");
+                   end if;
+
+               when ARM_Output.Giant_Hanging | ARM_Output.Wide_Hanging |
+                    ARM_Output.Medium_Hanging | ARM_Output.Narrow_Hanging |
+                    ARM_Output.Hanging_in_Bulleted |
+                    ARM_Output.Enumerated =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</DL>");
+
+               when ARM_Output.Small_Giant_Hanging | 
ARM_Output.Small_Wide_Hanging |
+                    ARM_Output.Small_Medium_Hanging | 
ARM_Output.Small_Narrow_Hanging |
+                    ARM_Output.Small_Hanging_in_Bulleted |
+                    ARM_Output.Small_Enumerated =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</FONT></DL>");
+
+           end case;
+           -- Reverse any indents:
+           for I in reverse 1 .. Output_Object.Paragraph_Indent loop
+               Ada.Text_IO.Put (Output_Object.Output_File, "</UL>");
+           end loop;
+           Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+
+       elsif Output_Object.HTML_Kind = HTML_4_Only then
+           case Output_Object.Paragraph_Style is
+               when ARM_Output.Normal | ARM_Output.Wide_Above |
+                    ARM_Output.Header |
+                    ARM_Output.Small  | ARM_Output.Small_Wide_Above |
+                    ARM_Output.Small_Header |
+                    ARM_Output.Index | ARM_Output.Syntax_Summary |
+                    ARM_Output.Title |
+                    ARM_Output.Examples | ARM_Output.Swiss_Examples |
+                    ARM_Output.Small_Examples | 
ARM_Output.Small_Swiss_Examples =>
+                   Put_End_Style (Output_Object.Paragraph_Style,
+                                  Output_Object.Paragraph_Indent);
+               when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted |
+                    ARM_Output.Small_Bulleted | 
ARM_Output.Small_Nested_Bulleted =>
+                   -- We've overridden the style class here.
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</div>");
+               when ARM_Output.Giant_Hanging | ARM_Output.Wide_Hanging |
+                    ARM_Output.Medium_Hanging | ARM_Output.Narrow_Hanging |
+                    ARM_Output.Hanging_in_Bulleted |
+                    ARM_Output.Enumerated |
+                    ARM_Output.Small_Giant_Hanging | 
ARM_Output.Small_Wide_Hanging |
+                    ARM_Output.Small_Medium_Hanging | 
ARM_Output.Small_Narrow_Hanging |
+                    ARM_Output.Small_Hanging_in_Bulleted |
+                    ARM_Output.Small_Enumerated =>
+                   -- We've overridden the style class here.
+                   Ada.Text_IO.Put (Output_Object.Output_File, "</div>");
+           end case;
+           Ada.Text_IO.New_Line (Output_Object.Output_File);
+       else -- if Output_Object.HTML_Kind = HTML_4_Compatible
+           case Output_Object.Paragraph_Style is
+               when ARM_Output.Normal | ARM_Output.Wide_Above |
+                    ARM_Output.Header |
+                    ARM_Output.Small  | ARM_Output.Small_Wide_Above |
+                    ARM_Output.Small_Header |
+                    ARM_Output.Index | ARM_Output.Syntax_Summary |
+                    ARM_Output.Title |
+                    ARM_Output.Examples | ARM_Output.Swiss_Examples |
+                    ARM_Output.Small_Examples | 
ARM_Output.Small_Swiss_Examples =>
+                   Put_End_Style (Output_Object.Paragraph_Style,
+                                  Output_Object.Paragraph_Indent);
+               when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted |
+                    ARM_Output.Small_Bulleted | 
ARM_Output.Small_Nested_Bulleted =>
+                   Put_End_Compatibility_Font_Info (Output_Object,
+                                                    
Output_Object.Paragraph_Style,
+                                                    
Output_Object.Paragraph_Indent);
+                   if Output_Object.Had_Prefix then
+                       Ada.Text_IO.Put (Output_Object.Output_File, "</li>");
+                   -- else null;
+                   end if;
+                   Put_End_Style (Output_Object.Paragraph_Style,
+                                  Output_Object.Paragraph_Indent,
+                                  Include_Compatibility => False);
+               when ARM_Output.Giant_Hanging | ARM_Output.Wide_Hanging |
+                    ARM_Output.Medium_Hanging | ARM_Output.Narrow_Hanging |
+                    ARM_Output.Hanging_in_Bulleted |
+                    ARM_Output.Enumerated |
+                    ARM_Output.Small_Giant_Hanging | 
ARM_Output.Small_Wide_Hanging |
+                    ARM_Output.Small_Medium_Hanging | 
ARM_Output.Small_Narrow_Hanging |
+                    ARM_Output.Small_Hanging_in_Bulleted |
+                    ARM_Output.Small_Enumerated =>
+                   Put_End_Style (Output_Object.Paragraph_Style,
+                                  Output_Object.Paragraph_Indent);
+           end case;
+           Ada.Text_IO.New_Line (Output_Object.Output_File);
+       end if;
+        Output_Object.Char_Count := 0;
+        Output_Object.Disp_Char_Count := 0;
+        Output_Object.Disp_Large_Char_Count := 0;
+       Output_Object.Any_Nonspace := False;
+        Output_Object.Last_Was_Space := True; -- Start of line.
+        Output_Object.Conditional_Space := False; -- Don't need it here.
+    end End_Paragraph;
+
+
+    procedure Category_Header (Output_Object : in out HTML_Output_Type;
+                              Header_Text : String) is
+       -- Output a Category header (that is, "Legality Rules",
+       -- "Dynamic Semantics", etc.)
+       -- (Note: We did not use a enumeration here to insure that these
+       -- headers are spelled the same in all output versions).
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Header in paragraph");
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+       if Output_Object.HTML_Kind = HTML_4_Only then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H4 
Class=""centered"">" & Header_Text & "</H4>");
+       else
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H4 
ALIGN=CENTER>" & Header_Text & "</H4>");
+       end if;
+       Output_Object.Char_Count := 0;
+       Output_Object.Disp_Char_Count := 0;
+        Output_Object.Disp_Large_Char_Count := 0;
+       Output_Object.Any_Nonspace := False;
+        Output_Object.Last_Was_Space := True; -- Start of line.
+        Output_Object.Conditional_Space := False; -- Don't need it here.
+    end Category_Header;
+
+
+    procedure Clause_Header (Output_Object     : in out HTML_Output_Type;
+                            Header_Text       : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False) is
+       -- Output a Clause header. The level of the header is specified
+       -- in Level. The Clause Number is as specified; the top-level (and
+       -- other) subdivision names are as specified. These should appear in
+       -- the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Header in paragraph");
+       end if;
+
+       if not Output_Object.Big_Files then
+           if Ada.Text_IO.Is_Open (Output_Object.Output_File) then
+               End_HTML_File (Output_Object);
+           end if;
+
+           -- Special for table of contents:
+           if Clause_Number = "" and then
+               (Header_Text = "Table of Contents" or else -- Ada 95 format
+                Header_Text = "Contents") then -- ISO 2004 format.
+                Start_HTML_File (Output_Object,
+                   Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right) &
+                       "-TOC", Header_Text, "");
+               if Header_Text = "Table of Contents" then -- Ada 95 format
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>Table 
of Contents</H1>");
+               else
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"<H1>Contents</H1>");
+               end if;
+               Output_Object.Char_Count := 0;
+               Output_Object.Disp_Char_Count := 0;
+               Output_Object.Disp_Large_Char_Count := 0;
+               Output_Object.Any_Nonspace := False;
+               Output_Object.Last_Was_Space := True; -- Start of line.
+               Output_Object.Conditional_Space := False; -- Don't need it here.
+               return;
+           end if;
+
+           Start_HTML_File (Output_Object,
+                   Make_Clause_File_Name (Output_Object, Clause_Number),
+                   Header_Text, Clause_Number);
+       else -- Big Files:
+           if Clause_Number = "" and then
+               (Header_Text = "Table of Contents" or else -- Ada 95 format
+                Header_Text = "Contents") then -- ISO 2004 format.
+               -- Insert an anchor:
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "<A 
NAME=""TOC""></A>");
+               if Header_Text = "Table of Contents" then -- Ada 95 format
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>Table 
of Contents</H1>");
+               else
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"<H1>Contents</H1>");
+               end if;
+               Output_Object.Char_Count := 0;
+               Output_Object.Disp_Char_Count := 0;
+               Output_Object.Disp_Large_Char_Count := 0;
+               Output_Object.Any_Nonspace := False;
+               Output_Object.Last_Was_Space := True; -- Start of line.
+               Output_Object.Conditional_Space := False; -- Don't need it here.
+               return;
+           end if;
+           -- Insert an anchor:
+           Ada.Text_IO.Put (Output_Object.Output_File, "<A NAME=""");
+           Ada.Text_IO.Put (Output_Object.Output_File,
+               Make_Clause_Anchor_Name (Output_Object, Clause_Number));
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, """></A>");
+       end if;
+
+       case Level is
+           when ARM_Contents.Plain_Annex =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" & 
Clause_Number &
+                   "<BR>"); -- Note: Clause_Number includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, Header_Text & 
"</H1>");
+           when ARM_Contents.Normative_Annex =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" & 
Clause_Number & "</H1>");
+                               -- Note: Clause_Number includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"<H2>(normative)</H2>");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" & 
Header_Text & "</H1>");
+           when ARM_Contents.Informative_Annex =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" & 
Clause_Number & "</H1>");
+                               -- Note: Clause_Number includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"<H2>(informative)</H2>");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" & 
Header_Text & "</H1>");
+           when ARM_Contents.Unnumbered_Section  =>
+               if Header_Text /= "" then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" &
+                                         Header_Text & "</H1>");
+               end if;
+           when ARM_Contents.Section =>
+               case Top_Level_Subdivision_Name is
+                   when ARM_Output.Chapter =>
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"<H1>Chapter " &
+                                             Clause_Number & ": " & 
Header_Text & "</H1>");
+                   when ARM_Output.Section =>
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"<H1>Section " &
+                                             Clause_Number & ": " & 
Header_Text & "</H1>");
+                   when ARM_Output.Clause =>
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" 
&
+                                             Clause_Number & " &nbsp; " & 
Header_Text & "</H1>");
+               end case;
+           when ARM_Contents.Clause | ARM_Contents.Subclause |
+                ARM_Contents.Subsubclause =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" &
+                                     Clause_Number & ' ' & Header_Text & 
"</H1>");
+           when ARM_Contents.Dead_Clause  =>
+               raise Program_Error; -- No headers for dead clauses.
+       end case;
+       Output_Object.Char_Count := 0;
+       Output_Object.Disp_Char_Count := 0;
+        Output_Object.Disp_Large_Char_Count := 0;
+       Output_Object.Any_Nonspace := False;
+        Output_Object.Last_Was_Space := True; -- Start of line.
+        Output_Object.Conditional_Space := False; -- Don't need it here.
+       -- No page breaks in HTML, so we don't need to look at No_Page_Break.
+    end Clause_Header;
+
+
+    procedure Revised_Clause_Header
+                           (Output_Object     : in out HTML_Output_Type;
+                            New_Header_Text   : in String;
+                            Old_Header_Text   : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Version           : in 
ARM_Contents.Change_Version_Type;
+                            Old_Version       : in 
ARM_Contents.Change_Version_Type;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False) is
+       -- Output a revised clause header. Both the original and new text will
+       -- be output. The level of the header is specified in Level. The Clause
+       -- Number is as specified; the top-level (and other) subdivision names
+       -- are as specified. These should appear in the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- Version is the insertion version of the new text; Old_Version is
+       -- the insertion version of the old text.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+       function Header_Text return String is
+       begin
+           if Output_Object.HTML_Kind = HTML_3 then
+               if Old_Version = '0' then -- Old text is original text
+                   return "<U>" & New_Header_Text & "</U><S>" & 
Old_Header_Text & "</S>";
+               else
+                   return "<U>" & New_Header_Text & "</U><S><U>" & 
Old_Header_Text & "</U></S>";
+               end if;
+           elsif Old_Version = '0' then -- Old text is original text
+               Revision_Used(Version) := True;
+               return "<span class=""insert" & Version & """>" & 
New_Header_Text &
+                 "</span><span class=""delete" & Version & """>" & 
Old_Header_Text & "</span>";
+           else
+               Revision_Used(Version) := True;
+               Revision_Used(Old_Version) := True;
+               return "<span class=""insert" & Version & """>" & 
New_Header_Text &
+                 "</span><span class=""delete" & Version & """><span 
class=""insert" & Old_Version & """>" &
+                  Old_Header_Text & "</span></span>";
+           end if;
+       end Header_Text;
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Header in paragraph");
+       end if;
+
+       if not Output_Object.Big_Files then
+           if Ada.Text_IO.Is_Open (Output_Object.Output_File) then
+               End_HTML_File (Output_Object);
+           end if;
+
+           Start_HTML_File (Output_Object,
+                   Make_Clause_File_Name (Output_Object, Clause_Number),
+                   New_Header_Text, Clause_Number);
+       else -- Big Files:
+           -- Insert an anchor:
+           Ada.Text_IO.Put (Output_Object.Output_File, "<A NAME=""");
+           Ada.Text_IO.Put (Output_Object.Output_File,
+               Make_Clause_Anchor_Name (Output_Object, Clause_Number));
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, """></A>");
+       end if;
+
+       case Level is
+           when ARM_Contents.Plain_Annex =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" & 
Clause_Number &
+                   "<BR>"); -- Note: Clause_Number includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, Header_Text & 
"</H1>");
+           when ARM_Contents.Normative_Annex =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" & 
Clause_Number & "</H1>");
+                               -- Note: Clause_Number includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"<H2>(normative)</H2>");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" & 
Header_Text & "</H1>");
+           when ARM_Contents.Informative_Annex =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" & 
Clause_Number & "</H1>");
+                               -- Note: Clause_Number includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"<H2>(informative)</H2>");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" & 
Header_Text & "</H1>");
+           when ARM_Contents.Unnumbered_Section =>
+               if Header_Text /= "" then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" &
+                                         Header_Text & "</H1>");
+               end if;
+           when ARM_Contents.Section =>
+               case Top_Level_Subdivision_Name is
+                   when ARM_Output.Chapter =>
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"<H1>Chapter " &
+                                             Clause_Number & ": " & 
Header_Text & "</H1>");
+                   when ARM_Output.Section =>
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"<H1>Section " &
+                                             Clause_Number & ": " & 
Header_Text & "</H1>");
+                   when ARM_Output.Clause =>
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" 
&
+                                             Clause_Number & " &nbsp; " & 
Header_Text & "</H1>");
+               end case;
+           when ARM_Contents.Clause | ARM_Contents.Subclause |
+                ARM_Contents.Subsubclause =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "<H1>" &
+                                     Clause_Number & ' ' & Header_Text & 
"</H1>");
+           when ARM_Contents.Dead_Clause  =>
+               raise Program_Error; -- No headers for dead clauses.
+       end case;
+       Output_Object.Char_Count := 0;
+       Output_Object.Disp_Char_Count := 0;
+        Output_Object.Disp_Large_Char_Count := 0;
+       Output_Object.Any_Nonspace := False;
+        Output_Object.Last_Was_Space := True; -- Start of line.
+        Output_Object.Conditional_Space := False; -- Don't need it here.
+       -- No page breaks in HTML, so we don't need to look at No_Page_Break.
+    end Revised_Clause_Header;
+
+
+    procedure TOC_Marker (Output_Object : in out HTML_Output_Type;
+                         For_Start : in Boolean) is
+       -- Mark the start (if For_Start is True) or end (if For_Start is
+       -- False) of the table of contents data. Output objects that
+       -- auto-generate the table of contents can use this to do needed
+       -- actions.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       null; -- We don't care about this.
+    end TOC_Marker;
+
+
+    procedure New_Page (Output_Object : in out HTML_Output_Type;
+                       Kind : ARM_Output.Page_Kind_Type := 
ARM_Output.Any_Page) is
+       -- Output a page break.
+       -- Note that this has no effect on non-printing formats.
+       -- Any_Page breaks to the top of the next page (whatever it is);
+       -- Odd_Page_Only breaks to the top of the odd-numbered page;
+       -- Soft_Page allows a page break but does not force one (use in
+       -- "No_Breaks" paragraphs.)
+       -- Raises Not_Valid_Error if in a paragraph if Kind = Any_Page or
+       -- Odd_Page, and if not in a paragraph if Kind = Soft_Page.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       case Kind is
+           when ARM_Output.Any_Page | ARM_Output.Odd_Page_Only =>
+               if Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Page in paragraph");
+               end if;
+               -- No real page breaks supported.
+               --Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"<P><BR><BR></P>");
+               --Ada.Text_IO.Put_Line (Output_Object.Output_File, "<HR>"); -- 
Horizontal line.
+               --Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"<P><BR></P>");
+               -- This horizontal rule looks awful when inserted solely to
+               -- make PDF formats look good; and it doesn't make much sense
+               -- any other time, either. (Why would we want to start a page
+               -- with this?) So it's been removed completely; and we have no
+               -- other page breaks in HTML.
+           when ARM_Output.Soft_Page =>
+               if not Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Soft page not in paragraph");
+               end if;
+               null; -- No page breaks in HTML.
+       end case;
+    end New_Page;
+
+
+    procedure Separator_Line (Output_Object : in out HTML_Output_Type;
+                             Is_Thin : Boolean := True) is
+       -- Output a separator line. It is thin if "Is_Thin" is true.
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Separator in paragraph");
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+       if Is_Thin then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "<HR SIZE=1>"); -- 
Horizontal line.
+       else
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "<HR SIZE=2>"); -- 
Horizontal line.
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+    end Separator_Line;
+
+
+    procedure Start_Table (Output_Object : in out HTML_Output_Type;
+                          Columns : in ARM_Output.Column_Count;
+                          First_Column_Width : in ARM_Output.Column_Count;
+                          Last_Column_Width : in ARM_Output.Column_Count;
+                          Alignment : in ARM_Output.Column_Text_Alignment;
+                          No_Page_Break : in Boolean;
+                          Has_Border : in Boolean;
+                          Small_Text_Size : in Boolean;
+                          Header_Kind : in ARM_Output.Header_Kind_Type) is
+       -- Starts a table. The number of columns is Columns; the first
+       -- column has First_Column_Width times the normal column width, and
+       -- the last column has Last_Column_Width times the normal column width.
+       -- Alignment is the horizontal text alignment within the columns.
+       -- No_Page_Break should be True to keep the table intact on a single
+       -- page; False to allow it to be split across pages.
+       -- Has_Border should be true if a border is desired, false otherwise.
+       -- Small_Text_Size means that the contents will have the AARM size;
+       -- otherwise it will have the normal size.
+       -- Header_Kind determines whether the table has headers.
+       -- This command starts a paragraph; the entire table is a single
+       -- paragraph. Text will be considered part of the caption until the
+       -- next table marker call.
+       -- Raises Not_Valid_Error if in a paragraph.
+       use type ARM_Output.Header_Kind_Type;
+       use type ARM_Output.Column_Text_Alignment;
+    begin
+       -- No_Page_Break, First_Column_Width, and Last_Column_Width not used,
+       -- the latter two because column width is calculated based on the
+       -- contents.
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Table in paragraph");
+       end if;
+
+       if Output_Object.HTML_Kind /= HTML_3 then
+            Ada.Text_IO.Put (Output_Object.Output_File, "<div class=""" &
+               Paragraph_Name(ARM_Output.Normal, 1) & """>");
+           Paragraph_Used(ARM_Output.Normal, 1) := True;
+       end if;
+       if Has_Border then
+            Ada.Text_IO.Put (Output_Object.Output_File, "<TABLE 
frame=""border"" rules=""all"" border=""2"" cellpadding=""4"">");
+       else
+            Ada.Text_IO.Put (Output_Object.Output_File, "<TABLE frame=""void"" 
rules=""none"" border=""0"" cellpadding=""2"">");
+       end if;
+       if Header_Kind = ARM_Output.Both_Caption_and_Header then
+            Ada.Text_IO.Put (Output_Object.Output_File, "<CAPTION>");
+           Output_Object.Char_Count := 9;
+           Output_Object.In_Header := True;
+       elsif Header_Kind = ARM_Output.Header_Only then
+           if Alignment = ARM_Output.Center_All then
+               Ada.Text_IO.Put (Output_Object.Output_File, "<TR><TH 
align=""center"">");
+               Output_Object.Char_Count := 24;
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, "<TR><TH 
align=""left"">");
+               Output_Object.Char_Count := 22;
+           end if;
+           Output_Object.In_Header := True;
+       else -- Header_Kind = ARM_Output.No_Headers then
+           if Alignment = ARM_Output.Center_All then
+               Ada.Text_IO.Put (Output_Object.Output_File, "<TR><TD 
align=""center"">");
+               Output_Object.Char_Count := 24;
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, "<TR><TD 
align=""left"">");
+               Output_Object.Char_Count := 22;
+           end if;
+           Output_Object.In_Header := False;
+       end if;
+       Output_Object.Disp_Char_Count := 0;
+        Output_Object.Disp_Large_Char_Count := 0;
+       Output_Object.Any_Nonspace := False;
+        Output_Object.Last_Was_Space := True; -- Start of line.
+        Output_Object.Conditional_Space := False; -- Don't need it here.
+
+       Output_Object.Is_In_Paragraph := True;
+       Output_Object.Is_In_Table := True;
+
+       Output_Object.Table_Column_Alignment := Alignment;
+       Output_Object.Table_Has_Small_Text := Small_Text_Size;
+       if Output_Object.Table_Has_Small_Text then
+           if Output_Object.HTML_Kind = HTML_4_Only then
+               Ada.Text_IO.Put (Output_Object.Output_File, "<SPAN 
STYLE=""font-size: 80%"">");
+               Output_Object.Char_Count := Output_Object.Char_Count + 29;
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, "<FONT 
SIZE=""-1"">");
+               Output_Object.Char_Count := Output_Object.Char_Count + 16;
+           end if;
+       end if;
+    end Start_Table;
+
+
+    procedure Table_Marker (Output_Object : in out HTML_Output_Type;
+                           Marker : in ARM_Output.Table_Marker_Type) is
+       -- Marks the end of an entity in a table.
+       -- If Marker is End_Caption, the table caption ends and the
+       --      future text is part of the table header.
+       -- If Marker is End_Header, the table header ends and the
+       --      future text is part of the table body.
+       -- If Marker is End_Row, a row in the table is completed, and another
+       --      row started.
+       -- If Marker is End_Row_Next_Is_Last, a row in the table is completed,
+       --      and another row started. That row is the last row in the table.
+       -- If Marker is End_Item, an item in the table header or body is ended,
+       --      and another started.
+       -- If Marker is End_Table, the entire table is finished.
+       -- Raises Not_Valid_Error if not in a table.
+       use type ARM_Output.Column_Text_Alignment;
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if (not Output_Object.Is_In_Paragraph) or (not 
Output_Object.Is_In_Table) then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Table marker not in table");
+       end if;
+
+       -- Close the small fonts (we always need to do this):
+       if Output_Object.Table_Has_Small_Text then
+           if Output_Object.HTML_Kind = HTML_4_Only then
+               Ada.Text_IO.Put (Output_Object.Output_File, "</SPAN>");
+               Output_Object.Char_Count := Output_Object.Char_Count + 7;
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, "</FONT>");
+               Output_Object.Char_Count := Output_Object.Char_Count + 7;
+           end if;
+       end if;
+
+       case Marker is
+           when ARM_Output.End_Item =>
+               -- Note: This isn't the first item on a row.
+               if Output_Object.In_Header then
+                   if Output_Object.Table_Column_Alignment = 
ARM_Output.Left_All then
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<TH 
align=""left"">");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
18;
+                   else
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<TH 
align=""center"">");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
20;
+                   end if;
+               else
+                   if Output_Object.Table_Column_Alignment = 
ARM_Output.Left_All then
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<TD 
align=""left"">");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
18;
+                   else
+                       Ada.Text_IO.Put (Output_Object.Output_File, "<TD 
align=""center"">");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
20;
+                   end if;
+               end if;
+           when ARM_Output.End_Caption =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "</CAPTION>");
+               if Output_Object.Table_Column_Alignment = ARM_Output.Center_All 
then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "<TR><TH 
align=""center"">");
+                   Output_Object.Char_Count := 24;
+               else
+                   Ada.Text_IO.Put (Output_Object.Output_File, "<TR><TH 
align=""left"">");
+                   Output_Object.Char_Count := 22;
+               end if;
+               Output_Object.Disp_Char_Count := 0;
+               Output_Object.Disp_Large_Char_Count := 0;
+               Output_Object.Any_Nonspace := False;
+               Output_Object.Last_Was_Space := True; -- Start of line.
+               Output_Object.Conditional_Space := False; -- Don't need it here.
+           when ARM_Output.End_Header =>
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               if Output_Object.Table_Column_Alignment = ARM_Output.Center_All 
then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "<TR><TD 
align=""center"">");
+                   Output_Object.Char_Count := 24;
+               else
+                   Ada.Text_IO.Put (Output_Object.Output_File, "<TR><TD 
align=""left"">");
+                   Output_Object.Char_Count := 22;
+               end if;
+               Output_Object.Disp_Char_Count := 0;
+               Output_Object.Disp_Large_Char_Count := 0;
+               Output_Object.Any_Nonspace := False;
+               Output_Object.Last_Was_Space := True; -- Start of line.
+               Output_Object.Conditional_Space := False; -- Don't need it here.
+               Output_Object.In_Header := False;
+           when ARM_Output.End_Row | ARM_Output.End_Row_Next_Is_Last =>
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               if Output_Object.Table_Column_Alignment = ARM_Output.Center_All 
then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "<TR><TD 
align=""center"">");
+                   Output_Object.Char_Count := 24;
+               else
+                   Ada.Text_IO.Put (Output_Object.Output_File, "<TR><TD 
align=""left"">");
+                   Output_Object.Char_Count := 22;
+               end if;
+               Output_Object.Disp_Char_Count := 0;
+               Output_Object.Disp_Large_Char_Count := 0;
+               Output_Object.Any_Nonspace := False;
+               Output_Object.Last_Was_Space := True; -- Start of line.
+               Output_Object.Conditional_Space := False; -- Don't need it here.
+           when ARM_Output.End_Table =>
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               if Output_Object.HTML_Kind /= HTML_3 then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"</table></div>");
+               else
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"</TABLE>");
+               end if;
+               Output_Object.Is_In_Paragraph := False;
+               Output_Object.Is_In_Table := False;
+       end case;
+
+       if Output_Object.Table_Has_Small_Text and then ARM_Output."/=" (Marker,
+           ARM_Output.End_Table) then
+           if Output_Object.HTML_Kind = HTML_4_Only then
+               Ada.Text_IO.Put (Output_Object.Output_File, "<SPAN 
STYLE=""font-size: 80%"">");
+               Output_Object.Char_Count := Output_Object.Char_Count + 29;
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, "<FONT 
SIZE=""-1"">");
+               Output_Object.Char_Count := Output_Object.Char_Count + 16;
+           end if;
+        end if;
+    end Table_Marker;
+
+
+    -- Text output: These are only allowed after a Start_Paragraph and
+    -- before any End_Paragraph. Raises Not_Valid_Error if not allowed.
+
+    Special_Set : constant Ada.Strings.Maps.Character_Set :=
+       Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set 
(Ada.Strings.Maps.Character_Range'(Low => Character'Val(127), High => 
Character'Val(255))),
+         Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('<'),
+           Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('>'),
+             Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('"'),
+                                     Ada.Strings.Maps.To_Set ('&')))));
+
+    No_Conditional_Set : constant Ada.Strings.Maps.Character_Set :=
+         Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set (' '),
+           Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('.'),
+             Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set (','),
+               Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set (':'),
+                 Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set (';'),
+                   Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('!'),
+                     Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('('),
+                                             Ada.Strings.Maps.To_Set 
(')'))))))));
+
+    Large_Char_Set : constant Ada.Strings.Maps.Character_Set :=
+       Ada.Strings.Maps."or" (Ada.Strings.Maps.Constants.Upper_Set,
+         Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set 
(Ada.Strings.Maps.Character_Range'(Low => '0', High => '9')),
+           Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('m'),
+             Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('w'),
+               Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('<'),
+                 Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('>'),
+                   Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('&'),
+                     Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('%'),
+                       Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('@'),
+                         Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('$'),
+                           Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set 
('*'),
+                             Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set 
('+'),
+                               Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set 
('='),
+                                 Ada.Strings.Maps."or" 
(Ada.Strings.Maps.To_Set ('?'),
+                                   Ada.Strings.Maps."or" 
(Ada.Strings.Maps.To_Set ('/'),
+                                     Ada.Strings.Maps."or" 
(Ada.Strings.Maps.To_Set ('\'),
+                                             Ada.Strings.Maps.To_Set 
('#')))))))))))))))));
+
+
+    procedure Output_Text (Output_Object : in out HTML_Output_Type;
+                          Text : in String) is
+       -- Output the text to the current output place.
+    begin
+       if Output_Object.Column_Count >= 4 then
+           if (Output_Object.Column_Text(Output_Object.Current_Column) = null) 
or else
+               -- No items stored.
+              (Output_Object.Column_Text(Output_Object.Current_Column).Item /=
+               Output_Object.Current_Item) then
+               -- Start a new item.
+               Output_Object.Column_Text(Output_Object.Current_Column) :=
+                   new Column_Text_Item_Type'(Text => (others => ' '),
+                       Length => 0, Item => Output_Object.Current_Item,
+                       End_Para => False, Next => 
Output_Object.Column_Text(Output_Object.Current_Column));
+           end if;
+           if Output_Object.Column_Text(Output_Object.Current_Column).Length +
+               Text'Length > 
Output_Object.Column_Text(Output_Object.Current_Column).Text'Length then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Column item full, but more text! - " &
+                       
Output_Object.Column_Text(Output_Object.Current_Column).Text(1..Output_Object.Column_Text(Output_Object.Current_Column).Length)
 & Text);
+           else
+               Output_Object.Column_Text(Output_Object.Current_Column).Text(
+                  
Output_Object.Column_Text(Output_Object.Current_Column).Length+1..
+                  
Output_Object.Column_Text(Output_Object.Current_Column).Length+Text'Length) :=
+                       Text;
+               Output_Object.Column_Text(Output_Object.Current_Column).Length 
:=
+                  
Output_Object.Column_Text(Output_Object.Current_Column).Length + Text'Length;
+           end if;
+       else -- Normal, use Text_IO.
+            Ada.Text_IO.Put (Output_Object.Output_File, Text);
+            Output_Object.Char_Count := Output_Object.Char_Count + Text'Length;
+       end if;
+    end Output_Text;
+
+
+    procedure Ordinary_Text (Output_Object : in out HTML_Output_Type;
+                            Text : in String) is
+       -- Output ordinary text.
+       -- The text must end at a word break, never in the middle of a word.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Text'Length = 0 then
+           return; -- Nothing to do.
+       end if;
+       if Ada.Strings.Fixed.Count (Text, Special_Set) = 0 then
+           if Output_Object.Char_Count + Text'Length >= LINE_LENGTH - 10 then
+               -- We can only break on a space.
+               for I in Text'range loop
+                   Ordinary_Character (Output_Object, Text(I));
+               end loop;
+           else
+               if Output_Object.Conditional_Space then
+                   Output_Object.Conditional_Space := False;
+                   if Ada.Strings.Maps.Is_In (Text(Text'First), 
No_Conditional_Set) then
+                       null; -- Don't need the conditional space.
+                   else
+                       Output_Text (Output_Object, " ");
+                       Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                       --Output_Object.Disp_Large_Char_Count := <unchanged>;
+                   end if;
+               end if;
+               Output_Text (Output_Object, Text);
+               Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count 
+ Text'Length;
+               Output_Object.Disp_Large_Char_Count :=
+                   Output_Object.Disp_Large_Char_Count +
+                   Ada.Strings.Fixed.Count (Text, Large_Char_Set);
+               Output_Object.Any_Nonspace := True;
+               Output_Object.Last_was_Space := Text(Text'Last) = ' ';
+           end if;
+       else
+           for I in Text'range loop
+               Ordinary_Character (Output_Object, Text(I));
+           end loop;
+       end if;
+    end Ordinary_Text;
+
+
+    procedure Ordinary_Character (Output_Object : in out HTML_Output_Type;
+                                 Char : in Character) is
+       -- Output an ordinary character.
+       -- Spaces will be used to break lines as needed.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.Conditional_Space then
+           Output_Object.Conditional_Space := False;
+           if Ada.Strings.Maps.Is_In (Char, No_Conditional_Set) then
+               null; -- Don't need the conditional space.
+           else
+               Output_Text (Output_Object, " ");
+               Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count 
+ 1;
+               --Output_Object.Disp_Large_Char_Count := <unchanged>;
+           end if;
+       end if;
+       Output_Object.Last_was_Space := False;
+       if Char = ' ' then
+           if Output_Object.Char_Count >= LINE_LENGTH - 10 and then
+               Output_Object.Column_Count < 4 then
+               if Output_Object.HTML_Kind > HTML_3 then
+                   -- Note: We leave the space here so that later code can tell
+                   -- the difference between a line broken on a space, and a
+                   -- line broken for because it's convinient.
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, " ");
+               else -- No later code.
+                   Ada.Text_IO.New_Line (Output_Object.Output_File);
+               end if;
+               Output_Object.Char_Count := 0;
+               Output_Object.Last_was_Space := True;
+           else
+               Output_Text (Output_Object, " ");
+               Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count 
+ 1;
+               --Output_Object.Disp_Large_Char_Count := <unchanged>;
+           end if;
+           -- Output_Object.Any_Nonspace := <unchanged>;
+           Output_Object.Last_was_Space := True;
+       elsif Char = '<' then
+           Output_Text (Output_Object, "&lt;");
+           Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count + 1;
+           Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+           Output_Object.Any_Nonspace := True;
+        elsif Char = '>' then
+           Output_Text (Output_Object, "&gt;");
+           Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count + 1;
+           Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+           Output_Object.Any_Nonspace := True;
+        elsif Char = '"' then
+           Output_Text (Output_Object, "&quot;");
+           Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count + 1;
+           -- No change in Disp_Large_Char_Count.
+           Output_Object.Any_Nonspace := True;
+        elsif Char = '&' then
+           Output_Text (Output_Object, "&amp;");
+           Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count + 1;
+           Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+           Output_Object.Any_Nonspace := True;
+        elsif Char >= Character'Val(126) then -- All higher Latin-1 characters.
+           case Character'Pos(Char) is
+               when 160 =>
+                   Output_Text (Output_Object, "&nbsp;");
+               when 161 =>
+                   Output_Text (Output_Object, "&iexcl;");
+               when 162 =>
+                   Output_Text (Output_Object, "&cent;");
+               when 163 =>
+                   Output_Text (Output_Object, "&pound;");
+               when 164 =>
+                   Output_Text (Output_Object, "&curren;");
+               when 165 =>
+                   Output_Text (Output_Object, "&yen;");
+               when 166 =>
+                   Output_Text (Output_Object, "&brvbar;");
+               when 167 =>
+                   Output_Text (Output_Object, "&sect;");
+               when 168 =>
+                   Output_Text (Output_Object, "&uml;");
+               when 169 =>
+                   Output_Text (Output_Object, "&copy;");
+               when 170 =>
+                   Output_Text (Output_Object, "&ordf;");
+               when 171 =>
+                   Output_Text (Output_Object, "&laquo;");
+               when 172 =>
+                   Output_Text (Output_Object, "&not;");
+               when 173 =>
+                   Output_Text (Output_Object, "&shy;");
+               when 174 =>
+                   Output_Text (Output_Object, "&reg;");
+               when 175 =>
+                   Output_Text (Output_Object, "&macr;");
+               when 176 =>
+                   Output_Text (Output_Object, "&deg;");
+               when 177 =>
+                   Output_Text (Output_Object, "&plusmn;");
+               when 178 =>
+                   Output_Text (Output_Object, "&sup2;");
+               when 179 =>
+                   Output_Text (Output_Object, "&sup3;");
+               when 180 =>
+                   Output_Text (Output_Object, "&acute;");
+               when 181 =>
+                   Output_Text (Output_Object, "&micro;");
+               when 182 =>
+                   Output_Text (Output_Object, "&para;");
+               when 183 =>
+                   Output_Text (Output_Object, "&middot;");
+               when 184 =>
+                   Output_Text (Output_Object, "&cedil;");
+               when 185 =>
+                   Output_Text (Output_Object, "&sup1;");
+               when 186 =>
+                   Output_Text (Output_Object, "&ordm;");
+               when 187 =>
+                   Output_Text (Output_Object, "&raquo;");
+               when 188 =>
+                   Output_Text (Output_Object, "&frac14;");
+               when 189 =>
+                   Output_Text (Output_Object, "&frac12;");
+               when 190 =>
+                   Output_Text (Output_Object, "&frac34;");
+               when 191 =>
+                   Output_Text (Output_Object, "&iquest;");
+               when 192 =>
+                   Output_Text (Output_Object, "&Agrave;");
+               when 193 =>
+                   Output_Text (Output_Object, "&Aacute;");
+               when 194 =>
+                   Output_Text (Output_Object, "&Acirc;");
+               when 195 =>
+                   Output_Text (Output_Object, "&Atilde;");
+               when 196 =>
+                   Output_Text (Output_Object, "&Auml;");
+               when 197 =>
+                   Output_Text (Output_Object, "&Aring;");
+               when 198 =>
+                   Output_Text (Output_Object, "&AElig;");
+               when 199 =>
+                   Output_Text (Output_Object, "&Ccedil;");
+               when 200 =>
+                   Output_Text (Output_Object, "&Egrave;");
+               when 201 =>
+                   Output_Text (Output_Object, "&Eacute;");
+               when 202 =>
+                   Output_Text (Output_Object, "&Ecirc;");
+               when 203 =>
+                   Output_Text (Output_Object, "&Euml;");
+               when 204 =>
+                   Output_Text (Output_Object, "&Igrave;");
+               when 205 =>
+                   Output_Text (Output_Object, "&Iacute;");
+               when 206 =>
+                   Output_Text (Output_Object, "&Icirc;");
+               when 207 =>
+                   Output_Text (Output_Object, "&Iuml;");
+               when 208 =>
+                   Output_Text (Output_Object, "&ETH;");
+               when 209 =>
+                   Output_Text (Output_Object, "&Ntilde;");
+               when 210 =>
+                   Output_Text (Output_Object, "&Ograve;");
+               when 211 =>
+                   Output_Text (Output_Object, "&Oacute;");
+               when 212 =>
+                   Output_Text (Output_Object, "&Ocirc;");
+               when 213 =>
+                   Output_Text (Output_Object, "&Otilde;");
+               when 214 =>
+                   Output_Text (Output_Object, "&Ouml;");
+               when 215 =>
+                   Output_Text (Output_Object, "&times;");
+               when 216 =>
+                   Output_Text (Output_Object, "&Oslash;");
+               when 217 =>
+                   Output_Text (Output_Object, "&Ugrave;");
+               when 218 =>
+                   Output_Text (Output_Object, "&Uacute;");
+               when 219 =>
+                   Output_Text (Output_Object, "&Ucirc;");
+               when 220 =>
+                   Output_Text (Output_Object, "&Uuml;");
+               when 221 =>
+                   Output_Text (Output_Object, "&Yacute;");
+               when 222 =>
+                   Output_Text (Output_Object, "&THORN;");
+               when 223 =>
+                   Output_Text (Output_Object, "&szlig;");
+
+               when 224 =>
+                   Output_Text (Output_Object, "&agrave;");
+               when 225 =>
+                   Output_Text (Output_Object, "&aacute;");
+               when 226 =>
+                   Output_Text (Output_Object, "&acirc;");
+               when 227 =>
+                   Output_Text (Output_Object, "&atilde;");
+               when 228 =>
+                   Output_Text (Output_Object, "&auml;");
+               when 229 =>
+                   Output_Text (Output_Object, "&aring;");
+               when 230 =>
+                   Output_Text (Output_Object, "&aelig;");
+               when 231 =>
+                   Output_Text (Output_Object, "&ccedil;");
+               when 232 =>
+                   Output_Text (Output_Object, "&egrave;");
+               when 233 =>
+                   Output_Text (Output_Object, "&eacute;");
+               when 234 =>
+                   Output_Text (Output_Object, "&ecirc;");
+               when 235 =>
+                   Output_Text (Output_Object, "&euml;");
+               when 236 =>
+                   Output_Text (Output_Object, "&igrave;");
+               when 237 =>
+                   Output_Text (Output_Object, "&iacute;");
+               when 238 =>
+                   Output_Text (Output_Object, "&icirc;");
+               when 239 =>
+                   Output_Text (Output_Object, "&iuml;");
+               when 240 =>
+                   Output_Text (Output_Object, "&eth;");
+               when 241 =>
+                   Output_Text (Output_Object, "&ntilde;");
+               when 242 =>
+                   Output_Text (Output_Object, "&ograve;");
+               when 243 =>
+                   Output_Text (Output_Object, "&oacute;");
+               when 244 =>
+                   Output_Text (Output_Object, "&ocirc;");
+               when 245 =>
+                   Output_Text (Output_Object, "&otilde;");
+               when 246 =>
+                   Output_Text (Output_Object, "&ouml;");
+               when 247 =>
+                   Output_Text (Output_Object, "&divide;");
+               when 248 =>
+                   Output_Text (Output_Object, "&oslash;");
+               when 249 =>
+                   Output_Text (Output_Object, "&ugrave;");
+               when 250 =>
+                   Output_Text (Output_Object, "&uacute;");
+               when 251 =>
+                   Output_Text (Output_Object, "&ucirc;");
+               when 252 =>
+                   Output_Text (Output_Object, "&uuml;");
+               when 253 =>
+                   Output_Text (Output_Object, "&yacute;");
+               when 254 =>
+                   Output_Text (Output_Object, "&thorn;");
+               when 255 =>
+                   Output_Text (Output_Object, "&yuml;");
+
+
+               when others =>
+                   declare
+                       Code : constant String :=
+                           Natural'Image(Character'Pos(Char));
+                   begin
+                       Output_Text (Output_Object, "&#" & Code(2..4) & ';');
+                   end;
+           end case;
+           Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count + 1;
+           if Ada.Strings.Maps.Is_In (Char, Large_Char_Set) then
+               Output_Object.Disp_Large_Char_Count :=
+                   Output_Object.Disp_Large_Char_Count + 1;
+           -- else not a large character.
+           end if;
+           Output_Object.Any_Nonspace := True;
+        else
+           Output_Text (Output_Object, Char & "");
+           Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count + 1;
+           if Ada.Strings.Maps.Is_In (Char, Large_Char_Set) then
+               Output_Object.Disp_Large_Char_Count :=
+                   Output_Object.Disp_Large_Char_Count + 1;
+           -- else not a large character.
+           end if;
+           Output_Object.Any_Nonspace := True;
+        end if;
+    end Ordinary_Character;
+
+
+    procedure Hard_Space (Output_Object : in out HTML_Output_Type) is
+        -- Output a hard space. No line break should happen at a hard space.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+        Output_Text (Output_Object, "&nbsp;");
+        Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count + 1;
+       -- Output_Object.Disp_Large_Char_Count := <unchanged>;
+       -- Output_Object.Any_Nonspace := <unchanged>;
+       Output_Object.Last_was_Space := True;
+        Output_Object.Conditional_Space := False; -- Never need a conditional 
space here.
+    end Hard_Space;
+
+
+    procedure Line_Break (Output_Object : in out HTML_Output_Type) is
+       -- Output a line break. This does not start a new paragraph.
+       -- This corresponds to a "<BR>" in HTML.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.Column_Count >= 4 then
+           -- Output is deferred; mark the end of an item.
+           if Output_Object.Column_Text (Output_Object.Current_Column) /= null 
and then
+              Output_Object.Column_Text (Output_Object.Current_Column).Item = 
Output_Object.Current_Item then
+               Output_Object.Column_Text 
(Output_Object.Current_Column).End_Para := False;
+           end if;
+           Output_Object.Current_Item := Output_Object.Current_Item + 1;
+            Output_Object.Char_Count := 0;
+            Output_Object.Disp_Char_Count := 0;
+           Output_Object.Disp_Large_Char_Count := 0;
+           Output_Object.Any_Nonspace := False;
+           Output_Object.Last_Was_Space := True; -- Start of line.
+           Output_Object.Conditional_Space := False; -- Don't need it here.
+       else -- Normal.
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "<BR>");
+            Output_Object.Char_Count := 0;
+            Output_Object.Disp_Char_Count := 0;
+           Output_Object.Disp_Large_Char_Count := 0;
+           Output_Object.Any_Nonspace := False;
+           Output_Object.Last_Was_Space := True; -- Start of line.
+           Output_Object.Conditional_Space := False; -- Don't need it here.
+       end if;
+    end Line_Break;
+
+
+    procedure Index_Line_Break (Output_Object : in out HTML_Output_Type;
+                               Clear_Keep_with_Next : in Boolean) is
+       -- Output a line break for the index. This does not start a new
+       -- paragraph in terms of spacing. This corresponds to a "<BR>"
+       -- in HTML. If Clear_Keep_with_Next is true, insure that the next
+       -- line does not require the following line to stay with it.
+       -- Raises Not_Valid_Error if the paragraph is not in the index format.
+    begin
+       if ARM_Output."/=" (Output_Object.Paragraph_Style, ARM_Output.Index) 
then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not index format");
+       end if;
+       Line_Break (Output_Object);
+    end Index_Line_Break;
+
+
+    procedure Soft_Line_Break (Output_Object : in out HTML_Output_Type) is
+       -- Output a soft line break. This is a place (in the middle of a
+       -- "word") that we allow a line break. It is usually used after
+       -- underscores in long non-terminals.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.HTML_Kind > HTML_3 and then Output_Object.Use_Unicode 
then
+            Output_Text (Output_Object, "&#8203;");
+       -- else no Soft break in HTML 3.2.
+       end if;
+    end Soft_Line_Break;
+
+
+    procedure Soft_Hyphen_Break (Output_Object : in out HTML_Output_Type) is
+       -- Output a soft line break, with a hyphen. This is a place (in the 
middle of
+       -- a "word") that we allow a line break. If the line break is used,
+       -- a hyphen will be added to the text.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+        null; -- Soft hyphens exist, but don't work on either Internet 
Exploder 4
+             -- or Netcrash 3. That is, they are always displayed. (They should
+             -- only be displayed at the location of a line break).
+        --Output_Text (Output_Object, "&shy;"); -- A Latin-1 char.
+    end Soft_Hyphen_Break;
+
+
+    procedure Tab (Output_Object : in out HTML_Output_Type) is
+       -- Output a tab, inserting space up to the next tab stop.
+       -- Raises Not_Valid_Error if the paragraph was created with
+       -- Tab_Stops = ARM_Output.NO_TABS.
+    begin
+       -- HTML does not have tabs. Emulation is not successful on proportional
+       -- fonts, so we let the user select how to do it.
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if ARM_Output."="(Output_Object.Tab_Stops, ARM_Output.NO_TABS) then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Tab, but none set");
+       end if;
+
+        Output_Object.Conditional_Space := False; -- Never need a conditional 
space here.
+        Output_Object.Last_was_Space := True; -- Treat this as a space.
+       if Output_Object.Tab_Emulation = Single_Space then
+           -- Don't emulate these, just use a single space.
+           Output_Text (Output_Object, "&nbsp;");
+           Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count + 1;
+           -- Output_Object.Disp_Large_Char_Count := <unchanged>;
+       elsif Output_Object.Tab_Emulation = Quad_Space then
+           -- Don't emulate these, just use a single space.
+           Output_Text (Output_Object, "&nbsp;&nbsp;&nbsp;&nbsp;");
+           Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count + 4;
+           -- Output_Object.Disp_Large_Char_Count := <unchanged>;
+       elsif Output_Object.Tab_Emulation = Emulate_Fixed_Only or else
+             Output_Object.Tab_Emulation = Emulate_Fixed_Only_Quad then
+           if Output_Object.Can_Emulate_Tabs or else
+               (not Output_Object.Any_Nonspace) then -- Always can emulate if 
they're first on a line.
+               Output_Text (Output_Object, "&nbsp;");
+               Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count 
+ 1;
+               -- Output_Object.Disp_Large_Char_Count := <unchanged>;
+               for I in 1 .. Output_Object.Tab_Stops.Number loop
+                   if Output_Object.Tab_Stops.Stops(I).Stop >= 
Output_Object.Disp_Char_Count then
+                       for J in Output_Object.Disp_Char_Count+1 .. 
Output_Object.Tab_Stops.Stops(I).Stop loop
+                           Output_Text (Output_Object, "&nbsp;");
+                           Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                           -- Output_Object.Disp_Large_Char_Count := 
<unchanged>;
+                       end loop;
+                       exit;
+                   end if;
+               end loop; -- If we drop out without finding a tab, we just use 
the single
+                         -- space already written.
+           elsif Output_Object.Tab_Emulation = Emulate_Fixed_Only then
+               -- Put in a space.
+               Output_Text (Output_Object, "&nbsp;");
+               Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count 
+ 1;
+               if ARM_Output."=" (Output_Object.Paragraph_Style, 
ARM_Output.Syntax_Summary) and then
+                   Output_Object.Column_Count > 1 then
+                   -- Special case (hack!) to make Syntax cross-reference look 
better:
+                   Output_Text (Output_Object, "&nbsp;&nbsp;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 2;
+               end if;
+               -- Output_Object.Disp_Large_Char_Count := <unchanged>;
+           elsif Output_Object.Tab_Emulation = Emulate_Fixed_Only_Quad then
+               -- Put in four hard spaces.
+               Output_Text (Output_Object, "&nbsp;&nbsp;&nbsp;&nbsp;");
+               Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count 
+ 4;
+               -- Output_Object.Disp_Large_Char_Count := <unchanged>;
+           end if;
+       else -- Emulate all.
+           Output_Text (Output_Object, "&nbsp;");
+           Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count + 1;
+           for I in 1 .. Output_Object.Tab_Stops.Number loop
+               if Output_Object.Tab_Stops.Stops(I).Stop >= 
Output_Object.Disp_Char_Count then
+                   for J in Output_Object.Disp_Char_Count+1 .. 
Output_Object.Tab_Stops.Stops(I).Stop loop
+                       Output_Text (Output_Object, "&nbsp;");
+                       Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   end loop;
+                   exit;
+               end if;
+           end loop; -- If we drop out without finding a tab, we just use the
+                     -- single space already written.
+           -- Output_Object.Disp_Large_Char_Count := <unchanged>;
+       end if;
+    end Tab;
+
+
+    procedure Special_Character (Output_Object : in out HTML_Output_Type;
+                                Char : in ARM_Output.Special_Character_Type) is
+       -- Output an special character.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.Conditional_Space then
+           Output_Object.Conditional_Space := False;
+           Output_Text (Output_Object, " ");
+           Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count + 1;
+           -- Output_Object.Disp_Large_Char_Count := <unchanged>;
+       end if;
+       case Char is
+           when ARM_Output.EM_Dash =>
+               if Output_Object.HTML_Kind > HTML_3 and 
Output_Object.Use_Unicode then
+                   Output_Text (Output_Object, "&mdash;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, "--");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 2;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 2;
+               end if;
+           when ARM_Output.EN_Dash =>
+               if Output_Object.HTML_Kind > HTML_3 and 
Output_Object.Use_Unicode then
+                   Output_Text (Output_Object, "&ndash;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, "-");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   --Output_Object.Disp_Large_Char_Count := <unchanged>;
+               end if;
+           when ARM_Output.GEQ =>
+               if Output_Object.HTML_Kind > HTML_3 and 
Output_Object.Use_Unicode then
+                   Output_Text (Output_Object, "&ge;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, ">=");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 2;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 2;
+               end if;
+           when ARM_Output.LEQ =>
+               if Output_Object.HTML_Kind > HTML_3 and 
Output_Object.Use_Unicode then
+                   Output_Text (Output_Object, "&le;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, "<=");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 2;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 2;
+               end if;
+           when ARM_Output.NEQ =>
+               if Output_Object.HTML_Kind > HTML_3 and 
Output_Object.Use_Unicode then
+                   Output_Text (Output_Object, "&ne;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, "/=");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 2;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 2;
+               end if;
+           when ARM_Output.PI =>
+               if Output_Object.HTML_Kind > HTML_3 and 
Output_Object.Use_Unicode then
+                   Output_Text (Output_Object, "&pi;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, "PI");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 2;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 2;
+               end if;
+           when ARM_Output.Left_Ceiling =>
+               if FALSE and (Output_Object.HTML_Kind > HTML_3 and 
Output_Object.Use_Unicode) then
+                   -- This character doesn't display on US Windows 2000/XP.
+                   Output_Text (Output_Object, "&lceil;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, "<I>Ceiling</I>(");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 8;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+               end if;
+           when ARM_Output.Right_Ceiling =>
+               if FALSE and (Output_Object.HTML_Kind > HTML_3 and 
Output_Object.Use_Unicode) then
+                   -- This character doesn't display on US Windows 2000/XP.
+                   Output_Text (Output_Object, "&rceil;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, ")");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   --Output_Object.Disp_Large_Char_Count := <unchanged>;
+               end if;
+           when ARM_Output.Left_Floor =>
+               if FALSE and (Output_Object.HTML_Kind > HTML_3 and 
Output_Object.Use_Unicode) then
+                   -- This character doesn't display on US Windows 2000/XP.
+                   Output_Text (Output_Object, "&lfloor;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, "<I>Floor</I>(");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 6;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+               end if;
+           when ARM_Output.Right_Floor =>
+               if FALSE and (Output_Object.HTML_Kind > HTML_3 and 
Output_Object.Use_Unicode) then
+                   -- This character doesn't display on US Windows 2000/XP.
+                   Output_Text (Output_Object, "&rfloor;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, ")");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+                   --Output_Object.Disp_Large_Char_Count := <unchanged>;
+               end if;
+           when ARM_Output.Thin_Space =>
+               if FALSE and (Output_Object.HTML_Kind > HTML_3 and 
Output_Object.Use_Unicode) then
+                   -- This character doesn't display on US Windows 2000/XP.
+                   Output_Text (Output_Object, "&thinsp;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, " ");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               end if;
+               --Output_Object.Disp_Large_Char_Count := <unchanged>;
+           when ARM_Output.Left_Quote =>
+               if Output_Object.HTML_Kind > HTML_3 then
+                   Output_Text (Output_Object, "&lsquo;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, "`");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               end if;
+               --Output_Object.Disp_Large_Char_Count := <unchanged>;
+           when ARM_Output.Right_Quote =>
+               if Output_Object.HTML_Kind > HTML_3 then
+                   Output_Text (Output_Object, "&rsquo;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, "'");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               end if;
+               --Output_Object.Disp_Large_Char_Count := <unchanged>;
+           when ARM_Output.Left_Double_Quote =>
+               if Output_Object.HTML_Kind > HTML_3 then
+                   Output_Text (Output_Object, "&ldquo;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, """");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               end if;
+               --Output_Object.Disp_Large_Char_Count := <unchanged>;
+           when ARM_Output.Right_Double_Quote =>
+               if Output_Object.HTML_Kind > HTML_3 then
+                   Output_Text (Output_Object, "&rdquo;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, """");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               end if;
+               --Output_Object.Disp_Large_Char_Count := <unchanged>;
+           when ARM_Output.Small_Dotless_I =>
+               if Output_Object.HTML_Kind > HTML_3 then --and 
Output_Object.Use_Unicode then -- We'll use it if it might be supported.
+                   Output_Text (Output_Object, "&#0305;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, "i");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               end if;
+               --Output_Object.Disp_Large_Char_Count := <unchanged>;
+           when ARM_Output.Capital_Dotted_I =>
+               if Output_Object.HTML_Kind > HTML_3 then --and 
Output_Object.Use_Unicode then -- We'll use it if it might be supported.
+                   Output_Text (Output_Object, "&#0304;");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               else
+                   Output_Text (Output_Object, "I");
+                   Output_Object.Disp_Char_Count := 
Output_Object.Disp_Char_Count + 1;
+               end if;
+               Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1;
+       end case;
+       Output_Object.Any_Nonspace := True;
+       Output_Object.Last_was_Space := False;
+    end Special_Character;
+
+
+    procedure Unicode_Character (Output_Object : in out HTML_Output_Type;
+                                Char : in ARM_Output.Unicode_Type) is
+       -- Output a Unicode character, with code position Char.
+       Char_Code : constant String := ARM_Output.Unicode_Type'Image(Char);
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.HTML_Kind = HTML_3 then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Unicode not available for HTML 3");
+       end if;
+       if Output_Object.Conditional_Space then
+           Output_Object.Conditional_Space := False;
+           Output_Text (Output_Object, " ");
+           Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count + 1;
+           --Output_Object.Disp_Large_Char_Count := <unchanged>;
+       end if;
+       -- We don't check if this is valid, we just use it. So be sparing!
+        Output_Text (Output_Object, "&#" & Char_Code(2..Char_Code'Length) & 
';');
+       Output_Object.Disp_Char_Count := Output_Object.Disp_Char_Count + 1;
+       Output_Object.Disp_Large_Char_Count := 
Output_Object.Disp_Large_Char_Count + 1; -- Assume it is large.
+       Output_Object.Any_Nonspace := True;
+       Output_Object.Last_was_Space := False;
+    end Unicode_Character;
+
+
+    procedure End_Hang_Item (Output_Object : in out HTML_Output_Type) is
+       -- Marks the end of a hanging item. Call only once per paragraph.
+       -- Raises Not_Valid_Error if the paragraph style is not in
+       -- Text_Prefixed_Style_Subtype, or if this has already been
+       -- called for the current paragraph, or if the paragraph was started
+       -- with No_Prefix = True.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.Paragraph_Style not in
+            ARM_Output.Text_Prefixed_Style_Subtype then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not a hanging paragraph - " & 
ARM_Output.Paragraph_Style_Type'Image(Output_Object.Paragraph_Style));
+       end if;
+       if Output_Object.Saw_Hang_End then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Already saw the end of the hanging part");
+       end if;
+       Output_Object.Saw_Hang_End := True;
+       if Output_Object.HTML_Kind = HTML_3 then
+           case Output_Object.Paragraph_Style is
+               -- Part of a definition list.
+               when ARM_Output.Small_Giant_Hanging | 
ARM_Output.Small_Wide_Hanging |
+                    ARM_Output.Small_Medium_Hanging | 
ARM_Output.Small_Narrow_Hanging |
+                    ARM_Output.Small_Hanging_in_Bulleted |
+                    ARM_Output.Small_Enumerated =>
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"</FONT><DD><FONT SIZE=-1>");
+               when others =>
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, "<DD>");
+           end case;
+       elsif Output_Object.HTML_Kind = HTML_4_Only then
+           declare
+               Saved_Format : ARM_Output.Format_Type;
+           begin
+               -- Save original format:
+               Saved_Format :=
+                     (Bold => Output_Object.Is_Bold,
+                      Italic => Output_Object.Is_Italic,
+                      Font => Output_Object.Font,
+                      Size => Output_Object.Size,
+                      Color => Output_Object.Color,
+                      Change => Output_Object.Change,
+                      Version => Output_Object.Version,
+                      Added_Version => Output_Object.Added_Version,
+                      Location => Output_Object.Location);
+
+               -- Close any open formatting (can't leave it open across a DIV):
+               Text_Format (Output_Object,
+                            Format => (Bold => False,
+                                       Italic => False,
+                                       Font => ARM_Output.Default,
+                                       Size => 0,
+                                       Color => ARM_Output.Default,
+                                       Change => ARM_Output.None,
+                                       Version => '0',
+                                       Added_Version => '0',
+                                       Location => ARM_Output.Normal));
+               -- This has to be a hanging style, so we ignore other cases:
+               Ada.Text_IO.Put (Output_Object.Output_File, "</div><div 
class=""" &
+                   Paragraph_Name (Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent) & "-Body"">");
+               -- If the prefix is too long, add a <BR>. A "unit" is 2.0 ems;
+               -- a large character is 0.65 ems; and a small character is 0.4 
ems.
+               -- That should be quite conservative.
+--Ada.Text_IO.Put_Line("Break hang check: large chars=" & 
Natural'Image(Output_Object.Disp_Large_Char_Count) &
+--" small chars=" & Natural'Image(Output_Object.Disp_Char_Count - 
Output_Object.Disp_Large_Char_Count) &
+--" Hang_Outdent=" & 
Natural'Image(Paragraph_Info(Output_Object.Paragraph_Format).Hang_Outdent));
+               if (Output_Object.Disp_Large_Char_Count*13) +
+                  
((Output_Object.Disp_Char_Count-Output_Object.Disp_Large_Char_Count)*8) >
+                  Paragraph_Info(Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent).Hang_Outdent*40 then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, "<br 
clear=""left"">");
+                       -- We use "clear=left" so that the next line always
+                       -- starts at the left margin. This shouldn't be 
necessary,
+                       -- but I've seen cases where it was.
+               else
+                   Ada.Text_IO.New_Line (Output_Object.Output_File);
+               end if;
+               -- Reopen any formatting (using the previously saved values):
+               Text_Format (Output_Object, Format => Saved_Format);
+           end;
+       else -- HTML 4 Compatibility
+           -- We have to close and reopen the font info here, so that we
+           -- properly nest these operations to pass the WC3 validator.
+           Put_End_Compatibility_Font_Info (Output_Object,
+                       Output_Object.Paragraph_Style,
+                       Output_Object.Paragraph_Indent);
+           -- This has to be a hanging style, so we ignore other cases:
+           Ada.Text_IO.Put (Output_Object.Output_File, "<dd class=""" &
+                   Paragraph_Name (Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent) & """>");
+           Put_Compatibility_Font_Info (Output_Object,
+                       Output_Object.Paragraph_Style,
+                       Output_Object.Paragraph_Indent);
+       end if;
+       Paragraph_Used(Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent) := True;
+        Output_Object.Char_Count := 0;
+       Output_Object.Disp_Char_Count := 0;
+       Output_Object.Disp_Large_Char_Count := 0;
+       Output_Object.Any_Nonspace := False;
+        Output_Object.Last_Was_Space := True; -- Start of line.
+        Output_Object.Conditional_Space := False; -- Don't need it here.
+    end End_Hang_Item;
+
+
+    procedure New_Column (Output_Object : in out HTML_Output_Type) is
+       -- Output a column break.
+       -- Raises Not_Valid_Error if in a paragraph, or if the number of
+       -- columns is 1.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "New Column in paragraph");
+       end if;
+       if Output_Object.Column_Count <= 1 then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in a multi-column area");
+       end if;
+       if Output_Object.Column_Count >= 4 then
+           Output_Object.Current_Column := Output_Object.Current_Column + 1;
+           Output_Object.Current_Item := 1;
+       -- else ignore it, no columns will be used.
+       end if;
+    end New_Column;
+
+
+    procedure Text_Format (Output_Object : in out HTML_Output_Type;
+                          Format : in ARM_Output.Format_Type) is
+       -- Change the text format so that all of the properties are as 
specified.
+       -- Note: Changes to these properties ought be stack-like; that is,
+       -- Bold on, Italic on, Italic off, Bold off is OK; Bold on, Italic on,
+       -- Bold off, Italic off should be avoided (as separate commands).
+       use type ARM_Output.Change_Type;
+       use type ARM_Output.Location_Type;
+       use type ARM_Output.Size_Type;
+       use type ARM_Output.Color_Type;
+
+       function Change_Needs_Close_or_Open return Boolean is
+           -- Returns True if "Change" needs to open or close something, based
+           -- on the current values of Output_Object.
+       begin
+           return (Format.Change /= Output_Object.Change or else
+                   Format.Version /= Output_Object.Version or else
+                   Format.Added_Version /= Output_Object.Added_Version);
+       end Change_Needs_Close_or_Open;
+
+       function Font_Needs_Close_or_Open return Boolean is
+           -- Returns True if "Font" needs to close something, based
+           -- on the current values of Output_Object and the new value.
+           -- Note that this depends on whether the Change needs to open
+           -- or close something; if it does, we need to close and reopen
+           -- the font even if it is not changing.
+       begin
+           return (ARM_Output."/=" (Format.Font, Output_Object.Font) or else
+                   Change_Needs_Close_or_Open);
+       end Font_Needs_Close_or_Open;
+
+       function Location_Needs_Close_or_Open return Boolean is
+           -- Returns True if "Location" needs to close something, based
+           -- on the current values of Output_Object and the new value.
+           -- Note that this depends on whether the Change or Font needs
+           -- to open or close something; if they do, we need to close and
+           -- reopen the location even if it is not changing.
+       begin
+           return Format.Location /= Output_Object.Location or else
+                  Change_Needs_Close_or_Open or else Font_Needs_Close_or_Open;
+       end Location_Needs_Close_or_Open;
+
+       function Color_Needs_Close_or_Open return Boolean is
+           -- Returns True if "Color" needs to close something, based
+           -- on the current values of Output_Object, and the new value.
+           -- Note that this depends on whether the Change, Font,
+           -- or Location needs to open or close something; if they do,
+           -- we need to close the size even if it is not changing.
+       begin
+           return (Format.Color /= Output_Object.Color or else
+                   Change_Needs_Close_or_Open or else Font_Needs_Close_or_Open 
or else
+                   Location_Needs_Close_or_Open);
+       end Color_Needs_Close_or_Open;
+
+       function Size_Needs_Close_or_Open return Boolean is
+           -- Returns True if "Size" needs to close something, based
+           -- on the current values of Output_Object, and the new value.
+           -- Note that this depends on whether the Change, Color, Font,
+           -- or Location needs to open or close something; if they do,
+           -- we need to close the size even if it is not changing.
+       begin
+           return (Format.Size /= Output_Object.Size or else
+                   Change_Needs_Close_or_Open or else Font_Needs_Close_or_Open 
or else
+                   Location_Needs_Close_or_Open or else 
Color_Needs_Close_or_Open);
+       end Size_Needs_Close_or_Open;
+
+       function Italic_Needs_Close_or_Open return Boolean is
+           -- Returns True if "Italic" needs to close something, based
+           -- on the current values of Output_Object, and the new value.
+           -- Note that this depends on whether the Change, Font, Color,
+           -- Location, or Size needs to open or close something; if they do,
+           -- we need to close the italics even if it is not changing.
+       begin
+           return (Format.Italic /= Output_Object.Is_Italic or else
+           Change_Needs_Close_or_Open or else Font_Needs_Close_or_Open or else
+           Location_Needs_Close_or_Open or else Size_Needs_Close_or_Open or 
else
+           Color_Needs_Close_or_Open);
+       end Italic_Needs_Close_or_Open;
+
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       -- We do these in this order so that the changes are stacked properly.
+       -- Note that we have to open and close stuff that is not changing
+       -- in order to get proper nesting in all cases.
+
+       if Output_Object.Is_Bold and then
+            ((not Format.Bold) or else
+           Italic_Needs_Close_or_Open) then
+           -- The latter so that nesting is preserved; we'll reopen
+           -- the boldfacing on the other side if needed. Otherwise, when
+           -- Bold remains on, we'd leave the markup open but close some outer
+           -- item. That's wrong (even though many browsers can handle it).
+           Output_Text (Output_Object, "</B>");
+           Output_Object.Is_Bold := False;
+       end if;
+
+       if Output_Object.Is_Italic and then
+            ((not Format.Italic) or else
+           Size_Needs_Close_or_Open) then
+           -- The latter so that nesting is preserved; we'll reopen
+           -- the italics on the other side in that case.
+           Output_Text (Output_Object, "</I>");
+           Output_Object.Is_Italic := False;
+       end if;
+
+       if Format.Size /= Output_Object.Size or else
+           Color_Needs_Close_or_Open then
+           -- The latter so that nesting is preserved; we'll reopen
+           -- the size on the other side in that case.
+           if Output_Object.Size /= 0 then
+               if Output_Object.HTML_Kind = HTML_4_Only then
+                   Output_Text (Output_Object, "</SPAN>");
+               else
+                   Output_Text (Output_Object, "</FONT>");
+               end if;
+               Output_Object.Size := 0; -- That's the size now.
+           end if;
+       end if;
+
+       if Format.Color /= Output_Object.Color or else
+           Location_Needs_Close_or_Open then
+           -- The latter so that nesting is preserved; we'll reopen
+           -- the size on the other side in that case.
+           if Output_Object.Color /= ARM_Output.Default then
+               if Output_Object.HTML_Kind = HTML_4_Only then
+                   Output_Text (Output_Object, "</SPAN>");
+               else
+                   Output_Text (Output_Object, "</FONT>");
+               end if;
+               Output_Object.Color := ARM_Output.Default; -- That's the color 
now.
+           end if;
+       end if;
+
+       if Format.Location /= Output_Object.Location or else
+           Change_Needs_Close_or_Open then
+           -- The latter so that nesting is preserved; we'll reopen
+           -- the location on the other side in that case.
+           case Output_Object.Location is
+               when ARM_Output.Superscript =>
+                   if Output_Object.HTML_Kind = HTML_4_Only then
+                       Output_Text (Output_Object, "</SPAN></SUP>");
+                   else
+                       Output_Text (Output_Object, "</FONT></SUP>");
+                   end if;
+               when ARM_Output.Subscript =>
+                   if Output_Object.HTML_Kind = HTML_4_Only then
+                       Output_Text (Output_Object, "</SPAN></SUB>");
+                   else
+                       Output_Text (Output_Object, "</FONT></SUB>");
+                   end if;
+               when ARM_Output.Normal =>
+                   null;
+           end case;
+           Output_Object.Location := ARM_Output.Normal; -- That's the location 
now.
+       end if;
+
+       if ARM_Output."/=" (Format.Font, Output_Object.Font) or else
+           Change_Needs_Close_or_Open then
+           -- The latter so that nesting is preserved; we'll reopen
+           -- the font on the other side in that case.
+           case Output_Object.Font is
+               when ARM_Output.Default => null;
+               when ARM_Output.Fixed =>
+                   Output_Text (Output_Object, "</TT>");
+               when ARM_Output.Roman =>
+                   if Output_Object.HTML_Kind = HTML_4_Only then
+                       Output_Text (Output_Object, "</SPAN>");
+                   else
+                       null; -- Default, currently.
+                       --Output_Text (Output_Object, "</FONT>");
+                   end if;
+               when ARM_Output.Swiss =>
+                   if Output_Object.HTML_Kind = HTML_4_Only then
+                       Output_Text (Output_Object, "</SPAN>");
+                   else
+                       Output_Text (Output_Object, "</FONT>");
+                   end if;
+           end case;
+           Output_Object.Font := ARM_Output.Default; -- We're now in the 
default state.
+       end if;
+
+       if Format.Change /= Output_Object.Change or else
+          Format.Version /= Output_Object.Version or else
+          Format.Added_Version /= Output_Object.Added_Version then
+           case Output_Object.Change is
+               when ARM_Output.Insertion =>
+                   if Output_Object.HTML_Kind = HTML_3 then
+                       Output_Text (Output_Object, "</U>");
+                   else
+                       --Output_Text (Output_Object, "</ins>");
+                       Output_Text (Output_Object, "</span>");
+                   end if;
+                   -- Note: We need to follow these with a space so that
+                   -- we don't get words running together for indexing
+                   -- purposes (Google, Ada Indexer). That's only a concern
+                   -- for deletions directly following insertions (at least in
+                   -- the absence of nesting), so we only add the extra space
+                   -- after insertions. RTF needs insertions and deletions
+                   -- without spaces to work properly, thus the source does not
+                   -- have them.
+                   -- If the last character of the displayed text is a space,
+                   -- we don't need this, and don't generate it. We do
+                   -- generate it for punctuation, as we want a space following
+                   -- that in general.
+                   -- If the next visible character is not in some sort of
+                   -- change section, we'd prefer to not generate
+                   -- the space, but there is no obvious way to determine that
+                   -- (we don't know when the command ends here).
+                   -- We can, however, generate a conditional space that is
+                   -- not generated if the next visible character is a space
+                   -- or punctuation (we don't usually want a space *before*
+                   -- punctuation).
+                   if Output_Object.Last_was_Space then
+                       null;
+                   else
+                       Output_Object.Conditional_Space := True;
+                   end if;
+               when ARM_Output.Deletion =>
+                   if Output_Object.HTML_Kind = HTML_3 then
+                       Output_Text (Output_Object, "</S>");
+                   else
+                       --Output_Text (Output_Object, "</del>");
+                       Output_Text (Output_Object, "</span>");
+                   end if;
+               when ARM_Output.Both =>
+                   if Output_Object.HTML_Kind = HTML_3 then
+                       Output_Text (Output_Object, "</S></U>");
+                   else
+                       --Output_Text (Output_Object, "</del></ins>");
+                       --Output_Text (Output_Object, "</span>");
+                       -- CSS2 doesn't allow multiple decorations in a single 
definition, so we have
+                       -- to nest them. But that might not be right, either 
(it works on IE).
+                       Output_Text (Output_Object, "</span></span>");
+                   end if;
+                   if Output_Object.Last_was_Space then -- See above for 
reasons for this.
+                       null;
+                   else
+                       Output_Object.Conditional_Space := True;
+                   end if;
+               when ARM_Output.None =>
+                   null;
+           end case;
+           case Format.Change is
+               when ARM_Output.Insertion =>
+                   if Output_Object.HTML_Kind = HTML_3 then
+                       Output_Text (Output_Object, "<U>");
+                   else
+                       --Output_Text (Output_Object, "<ins>");
+                       Output_Text (Output_Object, "<span class=""insert" & 
Format.Version & """>");
+                       Revision_Used(Format.Version) := True;
+                   end if;
+               when ARM_Output.Deletion =>
+                   if Output_Object.HTML_Kind = HTML_3 then
+                       Output_Text (Output_Object, "<S>");
+                   else
+                       --Output_Text (Output_Object, "<del>");
+                       Output_Text (Output_Object, "<span class=""delete" & 
Format.Version & """>");
+                       Revision_Used(Format.Version) := True;
+                   end if;
+               when ARM_Output.Both =>
+                   if Output_Object.HTML_Kind = HTML_3 then
+                       Output_Text (Output_Object, "<U><S>");
+                   else
+                       --Output_Text (Output_Object, "<ins><del>");
+                       --Output_Text (Output_Object, "<span class=""both" & 
Format.Version & """>");
+                       -- CSS2 doesn't allow multiple decorations in a single 
definition, so we have
+                       -- to nest them. But that might not be right, either 
(it works on IE).
+                       Output_Text (Output_Object, "<span class=""insert" & 
Format.Added_Version & """>");
+                       Output_Text (Output_Object, "<span class=""delete" & 
Format.Version & """>");
+                       Revision_Used(Format.Added_Version) := True;
+                       Revision_Used(Format.Version) := True;
+                   end if;
+               when ARM_Output.None =>
+                   null;
+           end case;
+           Output_Object.Change := Format.Change;
+           Output_Object.Version := Format.Version;
+           Output_Object.Added_Version := Format.Added_Version;
+       end if;
+
+       if ARM_Output."/=" (Format.Font, Output_Object.Font) then
+           case Format.Font is
+               when ARM_Output.Default => null;
+               when ARM_Output.Fixed =>
+                   Output_Text (Output_Object, "<TT>");
+               when ARM_Output.Roman =>
+                   if Output_Object.HTML_Kind = HTML_4_Only then
+                       Output_Text (Output_Object, "<SPAN Class=""roman"">");
+                   else
+                       null; -- Default, currently.
+                       --Output_Text (Output_Object, "<FONT xxx>");
+                   end if;
+               when ARM_Output.Swiss =>
+                   if Output_Object.HTML_Kind = HTML_4_Only then
+                       Output_Text (Output_Object, "<SPAN Class=""swiss"">");
+                   else
+                       Output_Text (Output_Object, SWISS_FONT_CODE);
+                   end if;
+           end case;
+           Output_Object.Font := Format.Font;
+       end if;
+
+       if Format.Location /= Output_Object.Location then
+           -- Note: Location needs to be changed before size, as they
+           -- typically are changed together, and <SUP> and <SUB> reset the
+           -- size.
+           case Format.Location is
+               when ARM_Output.Superscript =>
+                   if Output_Object.HTML_Kind = HTML_4_Only then
+                       Output_Text (Output_Object, "<SUP><SPAN 
STYLE=""font-size: 140%"">");
+                          -- This is a bit larger than +1; the text is usually 
too small.
+                   else
+                       Output_Text (Output_Object, "<SUP><FONT SIZE=""+1"">");
+                   end if;
+               when ARM_Output.Subscript =>
+                   if Output_Object.HTML_Kind = HTML_4_Only then
+                       Output_Text (Output_Object, "<SUB><SPAN 
STYLE=""font-size: 140%"">");
+                          -- This is a bit larger than +1; the text is usually 
too small.
+                   else
+                       Output_Text (Output_Object, "<SUB><FONT SIZE=""+1"">");
+                   end if;
+               when ARM_Output.Normal =>
+                   null;
+           end case;
+           Output_Object.Location := Format.Location;
+       end if;
+
+       if Format.Color /= Output_Object.Color then
+           if Output_Object.HTML_Kind = HTML_4_Only then
+               case Format.Color is
+                   when ARM_Output.Default => null;
+                   when ARM_Output.Black =>
+                       Output_Text (Output_Object, "<SPAN STYLE=""color: 
rgb(0,0,0)"">");
+                   when ARM_Output.Red   =>
+                       Output_Text (Output_Object, "<SPAN STYLE=""color: 
rgb(153,0,0)"">");
+                   when ARM_Output.Green =>
+                       Output_Text (Output_Object, "<SPAN STYLE=""color: 
rgb(0,153,0)"">");
+                   when ARM_Output.Blue  =>
+                       Output_Text (Output_Object, "<SPAN STYLE=""color: 
rgb(0,0,153)"">");
+               end case;
+           else
+               case Format.Color is
+                   when ARM_Output.Default => null;
+                   when ARM_Output.Black =>
+                       Output_Text (Output_Object, "<FONT COLOR=""#000000"">");
+                   when ARM_Output.Red   =>
+                       Output_Text (Output_Object, "<FONT COLOR=""#990000"">");
+                   when ARM_Output.Green =>
+                       Output_Text (Output_Object, "<FONT COLOR=""#009900"">");
+                   when ARM_Output.Blue  =>
+                       Output_Text (Output_Object, "<FONT COLOR=""#000099"">");
+               end case;
+           end if;
+           Output_Object.Color := Format.Color;
+       end if;
+
+       if Format.Size /= Output_Object.Size then
+           if Output_Object.HTML_Kind = HTML_4_Only then
+               case Format.Size is
+                   when 0 => null; -- Do nothing.
+                   when 1 => Output_Text (Output_Object, "<SPAN 
STYLE=""font-size: 125%"">");
+                   when 2 => Output_Text (Output_Object, "<SPAN 
STYLE=""font-size: 156%"">");
+                   when 3 => Output_Text (Output_Object, "<SPAN 
STYLE=""font-size: 194%"">");
+                   when 4 => Output_Text (Output_Object, "<SPAN 
STYLE=""font-size: 244%"">");
+                   when 5 => Output_Text (Output_Object, "<SPAN 
STYLE=""font-size: 305%"">");
+                   when -1 => Output_Text (Output_Object, "<SPAN 
STYLE=""font-size: 80%"">");
+                   when -2 => Output_Text (Output_Object, "<SPAN 
STYLE=""font-size: 64%"">");
+                   when -3 => Output_Text (Output_Object, "<SPAN 
STYLE=""font-size: 51%"">");
+                   when -4 => Output_Text (Output_Object, "<SPAN 
STYLE=""font-size: 41%"">");
+                   when -5 => Output_Text (Output_Object, "<SPAN 
STYLE=""font-size: 33%"">");
+                   when others =>
+                       -- Too much change:
+                       if Format.Size > 0 then
+                           Output_Text (Output_Object, "<SPAN 
STYLE=""font-size: 305%"">");
+                       else
+                           Output_Text (Output_Object, "<SPAN 
STYLE=""font-size: 33%"">");
+                       end if;
+               end case;
+           else
+               -- HTML sizes are 1..7, with a default of 3. So we limit the 
changes.
+               if Format.Size > 0 then
+                   if Format.Size > 5 then
+                       Output_Text (Output_Object, "<FONT SIZE=""+5"">");
+                   else
+                       Output_Text (Output_Object, "<FONT SIZE=""+" &
+                           Character'Val(Format.Size + Character'Pos('0')) & 
""">");
+                   end if;
+               elsif Format.Size < 0 then
+                   if Format.Size < -4 then
+                       Output_Text (Output_Object, "<FONT SIZE=""-4"">");
+                   else
+                       Output_Text (Output_Object, "<FONT SIZE=""-" &
+                           Character'Val(abs Format.Size + Character'Pos('0')) 
& """>");
+                   end if;
+               -- else Format.Size=0, nothing to do.
+               end if;
+           end if;
+           Output_Object.Size := Format.Size;
+       end if;
+
+       if Format.Italic and (not Output_Object.Is_Italic) then
+           Output_Text (Output_Object, "<I>");
+           Output_Object.Is_Italic := True;
+       end if;
+       if Format.Bold and (not Output_Object.Is_Bold) then
+           Output_Text (Output_Object, "<B>");
+           Output_Object.Is_Bold := True;
+       end if;
+
+    end Text_Format;
+
+
+    procedure Clause_Reference (Output_Object : in out HTML_Output_Type;
+                               Text : in String;
+                               Clause_Number : in String) is
+       -- Generate a reference to a clause in the standard. The text of
+       -- the reference is "Text", and the number of the clause is
+       -- Clause_Number. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Clause_Number = "X.X" then
+           -- Link to a dead clause, just output the text (presumably this
+           -- is deleted).
+            Ordinary_Text (Output_Object, Text);
+       else
+           Output_Text (Output_Object, "<A HREF=""");
+           declare
+               Name : constant String :=
+                   Make_Clause_Link_Name (Output_Object, Clause_Number);
+           begin
+               Output_Text (Output_Object, Name);
+           end;
+           Output_Text (Output_Object, """>");
+            Ordinary_Text (Output_Object, Text);
+           Output_Text (Output_Object, "</A>");
+       end if;
+    end Clause_Reference;
+
+
+    procedure Index_Target (Output_Object : in out HTML_Output_Type;
+                           Index_Key : in Natural) is
+       -- Generate a index target. This marks the location where an index
+       -- reference occurs. Index_Key names the index item involved.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, nothing is generated.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       -- Insert an anchor:
+       Output_Text (Output_Object, "<A NAME=""I");
+       declare
+           Key_Name : constant String := Natural'Image(Index_Key);
+       begin
+           Output_Text (Output_Object, Key_Name(2..Key_Name'Last));
+       end;
+       Output_Text (Output_Object, """></A>");
+    end Index_Target;
+
+
+    procedure Index_Reference (Output_Object : in out HTML_Output_Type;
+                              Text : in String;
+                              Index_Key : in Natural;
+                              Clause_Number : in String) is
+       -- Generate a reference to an index target in the standard. The text
+       -- of the reference is "Text", and Index_Key and Clause_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       Output_Text (Output_Object, "<A HREF=""");
+       if Output_Object.Big_Files then
+           null; -- No file name needed, this is a self-reference.
+       else
+           if Output_Object.DOS_Filenames then
+               Output_Text (Output_Object,
+                            Make_Clause_File_Name (Output_Object, 
Clause_Number)
+                                & ".HTM");
+           else
+               Output_Text (Output_Object,
+                            Make_Clause_File_Name (Output_Object, 
Clause_Number)
+                                & ".html");
+           end if;
+       end if;
+       Output_Text (Output_Object, "#I");
+       declare
+           Key_Name : constant String := Natural'Image(Index_Key);
+       begin
+           Output_Text (Output_Object, Key_Name(2..Key_Name'Last));
+       end;
+       Output_Text (Output_Object, """>");
+       Ordinary_Text (Output_Object, Text);
+       Output_Text (Output_Object, "</A>");
+    end Index_Reference;
+
+
+    procedure DR_Reference (Output_Object : in out HTML_Output_Type;
+                           Text : in String;
+                           DR_Number : in String) is
+       -- Generate a reference to an DR from the standard. The text
+       -- of the reference is "Text", and DR_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       declare
+           Num : Integer := Integer'Value(DR_Number(DR_Number'Last-3 .. 
DR_Number'Last));
+       begin
+           Output_Text (Output_Object, "<A HREF=""");
+           if Num <= 93 then -- In Defect Reports 1. -- %%%% Update if changed.
+               Output_Text (Output_Object, "defect1.html");
+           else -- In Defect Reports 2.
+               Output_Text (Output_Object, "defect2.html");
+           end if;
+           Output_Text (Output_Object, "#");
+           Output_Text (Output_Object, DR_Number);
+       end;
+        Output_Text (Output_Object, """>");
+        Ordinary_Text (Output_Object, Text);
+        Output_Text (Output_Object, "</A>");
+    end DR_Reference;
+
+
+    function Folded_AI95_Number (AI_String : in String) return String is
+       -- Internal routine.
+       -- Calculate the "folded" AI number from the full version.
+       -- AI_String should be in the form "AIzz-00xxx-yy", where -yy, 00,
+       -- and zz are optional, and 'zz' = 95 if given.
+       Result : String(1..5);
+       Hyphen_1 : Natural := Ada.Strings.Fixed.Index (AI_String, "-");
+       Hyphen_2 : Natural;
+    begin
+        if Hyphen_1 = 0 or else AI_String'Last < Hyphen_1+3 then
+           Result := "00001";
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Bad AI reference " & AI_String);
+       elsif Hyphen_1 = AI_String'First+4 and then
+           AI_String(AI_String'First..Hyphen_1-1) /= "AI95" then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Unknown AI reference " & AI_String);
+           Result := "00001";
+       elsif Hyphen_1 = AI_String'First+2 and then
+           AI_String(AI_String'First..Hyphen_1-1) /= "AI" then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Unknown short AI reference " & AI_String);
+           Result := "00001";
+       else
+           Hyphen_2 := Ada.Strings.Fixed.Index 
(AI_String(Hyphen_1+1..AI_String'Last), "-");
+           if Hyphen_2 = 0 then
+               if AI_String'Last = Hyphen_1+5 then
+                   Result := AI_String(Hyphen_1+1 .. Hyphen_1+5);
+               elsif AI_String'Last = Hyphen_1+4 then
+                   Result(2..5) := AI_String(Hyphen_1+1 .. Hyphen_1+4);
+                   Result(1) := '0';
+               elsif AI_String'Last = Hyphen_1+3 then
+                   Result(3..5) := AI_String(Hyphen_1+1 .. Hyphen_1+3);
+                   Result(1) := '0';
+                   Result(2) := '0';
+               else
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "AI reference too wrong length " & AI_String);
+                   Result := "00001";
+               end if;
+           else
+               if (Hyphen_2-1) - (Hyphen_1+1) = 5-1 then
+                   Result := AI_String (Hyphen_1+1 .. Hyphen_2-1);
+               elsif (Hyphen_2-1) - (Hyphen_1+1) = 4-1 then
+                   Result(2..5) := AI_String (Hyphen_1+1 .. Hyphen_2-1);
+                   Result(1) := '0';
+               elsif (Hyphen_2-1) - (Hyphen_1+1) = 3-1 then
+                   Result(3..5) := AI_String (Hyphen_1+1 .. Hyphen_2-1);
+                   Result(1) := '0';
+                   Result(2) := '0';
+               else
+                   Result := "00001";
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Bad AI reference (hyphen dist) " & AI_String);
+               end if;
+               if AI_String'Last < Hyphen_2+1 or else
+                  AI_String'Last > Hyphen_2+2 then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Bad AI alternative reference " & AI_String);
+               elsif  AI_String'Last = Hyphen_2+1 then
+                   Result(1) := Character'Pred(AI_String(Hyphen_2+1));
+               elsif AI_String'Last = Hyphen_2+2 and then 
AI_String(Hyphen_2+1) = '0' then
+                   Result(1) := Character'Pred(AI_String(Hyphen_2+2));
+               elsif AI_String'Last = Hyphen_2+2 and then 
AI_String(Hyphen_2+1) = '1' then
+                   if AI_String(Hyphen_2+2) = '0' then
+                       Result(1) := '9';
+                   else
+                       Result(1) := 
Character'Val(Character'Pos(AI_String(Hyphen_2+2)) - Character'Pos('1') + 
Character'Pos('A'));
+                   end if;
+               elsif AI_String'Last = Hyphen_2+2 and then 
AI_String(Hyphen_2+1) = '2' then
+                   Result(1) := 
Character'Val(Character'Pos(AI_String(Hyphen_2+2)) - Character'Pos('1') + 
Character'Pos('A') + 10);
+               else
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Bad AI alternative reference " & AI_String);
+               end if;
+           end if;
+       end if;
+       return Result;
+    end Folded_AI95_Number;
+
+
+    procedure AI_Reference (Output_Object : in out HTML_Output_Type;
+                           Text : in String;
+                           AI_Number : in String) is
+       -- Generate a reference to an AI from the standard. The text
+       -- of the reference is "Text", and AI_Number denotes
+       -- the target (in unfolded format). For hyperlinked formats, this should
+       -- generate a link; for other formats, the text alone is generated.
+       --
+       -- We assume AI number is of the form:
+       -- ZZZZ-nnnn-m whre ZZZZ=AI05, AI12, or SI99, nnnn is a four digit 
number,
+       -- and -m is an optional number (-1 is used if it is omitted); or
+       -- AIzz-nnnnn-mm where AIzz=AI95 or AI (meaning AI95);
+       -- nnnnn is a five digit number, and -mm is an optional two digit 
number.
+       -- We raise Not_Valid_Error otherwise.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if AI_Number'Length > 5 and then
+           AI_Number(AI_Number'First..AI_Number'First+4) = "AI12-" then
+           -- AI12:
+           if AI_Number'Length >= 9 then
+               if AI_Number(AI_Number'First+5) not in '0'..'9' or else
+                  AI_Number(AI_Number'First+6) not in '0'..'9' or else
+                  AI_Number(AI_Number'First+7) not in '0'..'9' or else
+                  AI_Number(AI_Number'First+8) not in '0'..'9' then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Bad number in AI12 number: " & AI_Number);
+               end if;
+           end if;
+           if AI_Number'Length = 9 then
+                Output_Text (Output_Object, "<A 
HREF=""http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AI12s/";);
+                Output_Text (Output_Object, AI_Number & "-1");
+           elsif AI_Number'Length = 11 then
+               if AI_Number(AI_Number'Last-1) /= '-' or else
+                  AI_Number(AI_Number'Last) not in '0'..'9' then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Bad sequence number in AI12 number: " & AI_Number);
+               end if;
+                Output_Text (Output_Object, "<A 
HREF=""http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AI12s/";);
+                Output_Text (Output_Object, AI_Number);
+           else
+               Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                   "Bad AI12 number: " & AI_Number);
+           end if;
+       elsif AI_Number'Length > 5 and then
+           AI_Number(AI_Number'First..AI_Number'First+4) = "AI05-" then
+           -- AI05:
+           if AI_Number'Length >= 9 then
+               if AI_Number(AI_Number'First+5) not in '0'..'9' or else
+                  AI_Number(AI_Number'First+6) not in '0'..'9' or else
+                  AI_Number(AI_Number'First+7) not in '0'..'9' or else
+                  AI_Number(AI_Number'First+8) not in '0'..'9' then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Bad number in AI05 number: " & AI_Number);
+               end if;
+           end if;
+           if AI_Number'Length = 9 then
+                Output_Text (Output_Object, "<A 
HREF=""http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AI05s/";);
+                Output_Text (Output_Object, AI_Number & "-1");
+           elsif AI_Number'Length = 11 then
+               if AI_Number(AI_Number'Last-1) /= '-' or else
+                  AI_Number(AI_Number'Last) not in '0'..'9' then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Bad sequence number in AI05 number: " & AI_Number);
+               end if;
+                Output_Text (Output_Object, "<A 
HREF=""http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AI05s/";);
+                Output_Text (Output_Object, AI_Number);
+           else
+               Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                   "Bad AI05 number: " & AI_Number);
+           end if;
+       elsif AI_Number'Length > 5 and then
+           AI_Number(AI_Number'First..AI_Number'First+4) = "SI99-" then
+           if AI_Number'Length >= 9 then
+               if AI_Number(AI_Number'First+5) not in '0'..'9' or else
+                  AI_Number(AI_Number'First+6) not in '0'..'9' or else
+                  AI_Number(AI_Number'First+7) not in '0'..'9' or else
+                  AI_Number(AI_Number'First+8) not in '0'..'9' then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Bad number in SI99 number: " & AI_Number);
+               end if;
+           end if;
+           if AI_Number'Length = 9 then
+                Output_Text (Output_Object, "<A 
HREF=""http://www.ada-auth.org/cgi-bin/cvsweb.cgi/SI99s/";);
+                Output_Text (Output_Object, AI_Number & "-1");
+           elsif AI_Number'Length = 11 then
+               if AI_Number(AI_Number'Last-1) /= '-' or else
+                  AI_Number(AI_Number'Last) not in '0'..'9' then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Bad sequence number in SI99 number: " & AI_Number);
+               end if;
+                Output_Text (Output_Object, "<A 
HREF=""http://www.ada-auth.org/cgi-bin/cvsweb.cgi/SI99s/";);
+                Output_Text (Output_Object, AI_Number);
+           else
+               Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                   "Bad SI99 number: " & AI_Number);
+           end if;
+       else -- Must be AI95:
+           declare
+               Folded : constant String :=
+                   Folded_AI95_Number(AI_Number); -- We don't want to have 
written anything if we raise an exception.
+           begin
+                Output_Text (Output_Object, "<A 
HREF=""http://www.ada-auth.org/cgi-bin/cvsweb.cgi/AIs/AI-";);
+                Output_Text (Output_Object, Folded);
+           end;
+       end if;
+        Output_Text (Output_Object, ".TXT"">");
+        Ordinary_Text (Output_Object, Text);
+        Output_Text (Output_Object, "</A>");
+
+    end AI_Reference;
+
+
+    procedure Local_Target (Output_Object : in out HTML_Output_Type;
+                           Text : in String;
+                           Target : in String) is
+       -- Generate a local target. This marks the potential target of local
+       -- links identified by "Target". Text is the text of the target.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, only the text is generated.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       -- Insert an anchor:
+       Output_Text (Output_Object, "<A NAME=""");
+        Output_Text (Output_Object, Target);
+       Output_Text (Output_Object, """>");
+        Ordinary_Text (Output_Object, Text);
+        Output_Text (Output_Object, "</A>");
+    end Local_Target;
+
+
+    procedure Local_Link (Output_Object : in out HTML_Output_Type;
+                         Text : in String;
+                         Target : in String;
+                         Clause_Number : in String) is
+       -- Generate a local link to the target and clause given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       -- Insert an anchor:
+       Output_Text (Output_Object, "<A HREF=""");
+       if Output_Object.Big_Files then
+           null; -- No file name needed, this is a self-reference.
+       else
+           if Output_Object.DOS_Filenames then
+               Output_Text (Output_Object,
+                            Make_Clause_File_Name (Output_Object, 
Clause_Number)
+                                & ".HTM");
+           else
+               Output_Text (Output_Object,
+                            Make_Clause_File_Name (Output_Object, 
Clause_Number)
+                                & ".html");
+           end if;
+       end if;
+       Output_Text (Output_Object, "#" & Target);
+       Output_Text (Output_Object, """>");
+       Ordinary_Text (Output_Object, Text);
+       Output_Text (Output_Object, "</A>");
+    end Local_Link;
+
+
+    procedure Local_Link_Start (Output_Object : in out HTML_Output_Type;
+                               Target : in String;
+                               Clause_Number : in String) is
+       -- Generate a local link to the target and clause given.
+       -- The link will surround text until Local_Link_End is called.
+       -- Local_Link_End must be called before this routine can be used again.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.In_Local_Link then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Already in a local link");
+       end if;
+        Output_Object.In_Local_Link := True;
+       -- Insert an anchor:
+       Output_Text (Output_Object, "<A HREF=""");
+       if Output_Object.Big_Files then
+           null; -- No file name needed, this is a self-reference.
+       else
+           if Output_Object.DOS_Filenames then
+               Output_Text (Output_Object,
+                            Make_Clause_File_Name (Output_Object, 
Clause_Number)
+                                & ".HTM");
+           else
+               Output_Text (Output_Object,
+                            Make_Clause_File_Name (Output_Object, 
Clause_Number)
+                                & ".html");
+           end if;
+       end if;
+       Output_Text (Output_Object, "#" & Target);
+       Output_Text (Output_Object, """>");
+    end Local_Link_Start;
+
+
+    procedure Local_Link_End (Output_Object : in out HTML_Output_Type;
+                             Target : in String;
+                             Clause_Number : in String) is
+       -- End a local link for the target and clause given.
+       -- This must be in the same paragraph as the Local_Link_Start.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if not Output_Object.In_Local_Link then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in a local link");
+       end if;
+       Output_Text (Output_Object, "</A>");
+        Output_Object.In_Local_Link := False;
+    end Local_Link_End;
+
+
+    procedure URL_Link (Output_Object : in out HTML_Output_Type;
+                       Text : in String;
+                       URL : in String) is
+       -- Generate a link to the URL given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       -- Insert an anchor:
+       Output_Text (Output_Object, "<A HREF=""");
+        Output_Text (Output_Object, URL);
+       Output_Text (Output_Object, """>");
+        Ordinary_Text (Output_Object, Text);
+        Output_Text (Output_Object, "</A>");
+    end URL_Link;
+
+
+    procedure Picture  (Output_Object : in out HTML_Output_Type;
+                       Name : in String;
+                       Descr : in String;
+                       Alignment : in ARM_Output.Picture_Alignment;
+                       Height, Width : in Natural;
+                       Border : in ARM_Output.Border_Kind) is
+       -- Generate a picture.
+       -- Name is the (simple) file name of the picture; Descr is a
+       -- descriptive name for the picture (it will appear in some web
+       -- browsers).
+       -- We assume that it is a .PNG or .JPG and that it will be present
+       -- in the same directory as the output files.
+       -- Alignment specifies the picture alignment.
+       -- Height and Width specify the picture size in pixels.
+       -- Border specifies the kind of border.
+
+       procedure Make_Img (Extra_Attribs : in String) is
+           H : constant String := Natural'Image(Height);
+           W : constant String := Natural'Image(Width);
+       begin
+           Output_Text (Output_Object, "<IMG src=""" & Name & """");
+           Output_Text (Output_Object, " height=""" & H(2..H'Last) &
+               """ width=""" & W(2..W'Last) & """");
+           if Extra_Attribs /= "" then
+               Output_Text (Output_Object, Extra_Attribs);
+           end if;
+           Output_Text (Output_Object, " alt=""" & Descr & """");
+           case Border is
+               when ARM_Output.None =>
+                   Output_Text (Output_Object, " border=""0"">");
+               when ARM_Output.Thin =>
+                   Output_Text (Output_Object, " border=""1"">");
+               when ARM_Output.Thick =>
+                   Output_Text (Output_Object, " border=""2"">");
+           end case;
+       end Make_Img;
+
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       case Alignment is
+           when ARM_Output.Inline =>
+               if not Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Not in paragraph");
+               end if;
+               if Output_Object.HTML_Kind = HTML_3 then
+                   Make_Img ("");
+               else
+                   Make_Img (" style=""margin-left: 0.3em; margin-right: 
0.3em""");
+               end if;
+           when ARM_Output.Float_Left =>
+               if not Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Not in paragraph");
+               end if;
+               if Output_Object.HTML_Kind = HTML_3 then
+                   Make_Img (" align=""left""");
+               else
+                   Make_Img (" align=""left"" style=""margin-right: 0.3em""");
+                       -- Space on right only; left should align with 
containing
+                       -- margin.
+               end if;
+           when ARM_Output.Float_Right =>
+               if not Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Not in paragraph");
+               end if;
+               if Output_Object.HTML_Kind = HTML_3 then
+                   Make_Img (" align=""right""");
+               else
+                   Make_Img (" align=""right"" style=""margin-left: 0.3em""");
+                       -- Space on right only; left should align with 
containing
+                       -- margin.
+               end if;
+           when ARM_Output.Alone_Left =>
+               if Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "In paragraph");
+               end if;
+               if Output_Object.HTML_Kind = HTML_4_Only then
+                   Output_Text (Output_Object, "<DIV Style=""text-align: left; 
margin-bottom: ");
+                   Put_EMs(Output_Object.Output_File, 
(Paragraph_Info(ARM_Output.Normal, 0).After * LEADING_PERCENT) / 100);
+                   Output_Text (Output_Object, """>");
+               else
+                   Output_Text (Output_Object, "<P>");
+               end if;
+               Make_Img("");
+               if Output_Object.HTML_Kind = HTML_4_Only then
+                   Output_Text (Output_Object, "</DIV>");
+               else
+                   Output_Text (Output_Object, "</P>");
+               end if;
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Output_Object.Char_Count := 0;
+               Output_Object.Disp_Char_Count := 0;
+               Output_Object.Disp_Large_Char_Count := 0;
+               Output_Object.Any_Nonspace := False;
+               Output_Object.Last_Was_Space := True; -- Start of line.
+               Output_Object.Conditional_Space := False; -- Don't need it here.
+           when ARM_Output.Alone_Right =>
+               if Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "In paragraph");
+               end if;
+               if Output_Object.HTML_Kind = HTML_4_Only then
+                   Output_Text (Output_Object, "<DIV Style=""text-align: 
right; margin-bottom: ");
+                   Put_EMs(Output_Object.Output_File, 
(Paragraph_Info(ARM_Output.Normal, 0).After * LEADING_PERCENT) / 100);
+                   Output_Text (Output_Object, """>");
+               else
+                   Output_Text (Output_Object, "<RIGHT>");
+               end if;
+               Make_Img("");
+               if Output_Object.HTML_Kind = HTML_4_Only then
+                   Output_Text (Output_Object, "</DIV>");
+               else
+                   Output_Text (Output_Object, "</RIGHT>");
+               end if;
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Output_Object.Char_Count := 0;
+               Output_Object.Disp_Char_Count := 0;
+               Output_Object.Disp_Large_Char_Count := 0;
+               Output_Object.Any_Nonspace := False;
+               Output_Object.Last_Was_Space := True; -- Start of line.
+               Output_Object.Conditional_Space := False; -- Don't need it here.
+           when ARM_Output.Alone_Center =>
+               if Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "In paragraph");
+               end if;
+               if Output_Object.HTML_Kind = HTML_4_Only then
+                   Output_Text (Output_Object, "<DIV Style=""text-align: 
center; margin-bottom: ");
+                   Put_EMs(Output_Object.Output_File, 
(Paragraph_Info(ARM_Output.Normal, 0).After * LEADING_PERCENT) / 100);
+                   Output_Text (Output_Object, """>");
+               else
+                   Output_Text (Output_Object, "<CENTER>");
+               end if;
+               Make_Img("");
+               if Output_Object.HTML_Kind = HTML_4_Only then
+                   Output_Text (Output_Object, "</DIV>");
+               else
+                   Output_Text (Output_Object, "</CENTER>");
+               end if;
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Output_Object.Char_Count := 0;
+               Output_Object.Disp_Char_Count := 0;
+               Output_Object.Disp_Large_Char_Count := 0;
+               Output_Object.Any_Nonspace := False;
+               Output_Object.Last_Was_Space := True; -- Start of line.
+               Output_Object.Conditional_Space := False; -- Don't need it here.
+       end case;
+    end Picture;
+
+begin
+    -- Define the styles:
+    -- Normal:
+    for I in ARM_Output.Paragraph_Indent_Type loop
+       Paragraph_Info(ARM_Output.Normal, I) :=
+               (Defined => True,
+                Tag  => DIV,
+                Size => 0, -- 18
+                Font => ARM_Output.Default,
+                Indent => Natural(I),
+                Right_Indent => 0,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 6); -- 120
+    end loop;
+    -- Wide_Above:
+    for I in ARM_Output.Paragraph_Indent_Type loop
+       Paragraph_Info(ARM_Output.Wide_Above, I) :=
+               (Defined => True,
+                Tag  => DIV,
+                Size => 0, -- 18
+                Font => ARM_Output.Default,
+                Indent => Natural(I),
+                Right_Indent => 0,
+                Hang_Outdent => 0,
+                Before => 6,
+                After => 6);
+    end loop;
+    -- Header:
+    for I in ARM_Output.Paragraph_Indent_Type loop
+       Paragraph_Info(ARM_Output.Header, I) :=
+               (Defined => True,
+                Tag  => DIV,
+                Size => 0, -- 18
+                Font => ARM_Output.Default,
+                Indent => Natural(I),
+                Right_Indent => 0,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 0);
+    end loop;
+    -- Small:
+    for I in ARM_Output.Paragraph_Indent_Type loop
+       Paragraph_Info(ARM_Output.Small, I) :=
+               (Defined => True,
+                Tag  => DIV,
+                Size => -1, -- 15
+                Font => ARM_Output.Default,
+                Indent => Natural(I),
+                Right_Indent => 0,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 6); -- 120
+    end loop;
+    -- Small_Wide_Above:
+    for I in ARM_Output.Paragraph_Indent_Type loop
+       Paragraph_Info(ARM_Output.Small_Wide_Above, I) :=
+               (Defined => True,
+                Tag  => DIV,
+                Size => -1, -- 15
+                Font => ARM_Output.Default,
+                Indent => Natural(I),
+                Right_Indent => 0,
+                Hang_Outdent => 0,
+                Before => 6,
+                After => 6);
+    end loop;
+    -- Small Header:
+    for I in ARM_Output.Paragraph_Indent_Type loop
+       Paragraph_Info(ARM_Output.Small_Header, I) :=
+               (Defined => True,
+                Tag  => DIV,
+                Size => -1, -- 15
+                Font => ARM_Output.Default,
+                Indent => Natural(I),
+                Right_Indent => 0,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 0);
+    end loop;
+
+    -- Examples:
+    for I in ARM_Output.Paragraph_Indent_Type loop
+       Paragraph_Info(ARM_Output.Examples, I) :=
+               (Defined => True,
+                Tag  => DIV,
+                Size => 0, -- 18
+                Font => ARM_Output.Fixed,
+                Indent => Natural(I),
+                Right_Indent => 0,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 6); -- 120
+    end loop;
+    -- Small Examples:
+    for I in ARM_Output.Paragraph_Indent_Type loop
+       Paragraph_Info(ARM_Output.Small_Examples, I) :=
+               (Defined => True,
+                Tag  => DIV,
+                Size => -1, -- 15
+                Font => ARM_Output.Fixed,
+                Indent => Natural(I),
+                Right_Indent => 0,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 6); -- 120
+    end loop;
+    -- Swiss Examples:
+    for I in ARM_Output.Paragraph_Indent_Type loop
+       Paragraph_Info(ARM_Output.Swiss_Examples, I) :=
+               (Defined => True,
+                Tag  => DIV,
+                Size => 0, -- 18
+                Font => ARM_Output.Swiss,
+                Indent => Natural(I),
+                Right_Indent => 0,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 6); -- 120
+    end loop;
+    -- Small Swiss Examples:
+    for I in ARM_Output.Paragraph_Indent_Type loop
+       Paragraph_Info(ARM_Output.Small_Swiss_Examples, I) :=
+               (Defined => True,
+                Tag  => DIV,
+                Size => -1, -- 15
+                Font => ARM_Output.Swiss,
+                Indent => Natural(I),
+                Right_Indent => 0,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 6); -- 120
+    end loop;
+
+    -- Bulleted:
+    -- Note: Indent = 0 is not allowed.
+    for I in 1 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Bulleted, I) :=
+               (Defined => True,
+                Tag  => UL,
+                Size => 0, -- 18
+                Font => ARM_Output.Default,
+                Indent => Natural(I),
+                Right_Indent => 1,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 5);
+    end loop;
+    -- Nested Bulleted:
+    -- Note: Indent = 0 is not allowed.
+    for I in 1 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Nested_Bulleted, I) :=
+               (Defined => True,
+                Tag  => UL,
+                Size => 0, -- 18
+                Font => ARM_Output.Default,
+                Indent => Natural(I),
+                Right_Indent => 1,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 5);
+    end loop;
+    -- Small Bulleted:
+    -- Note: Indent = 0 is not allowed.
+    for I in 1 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Small_Bulleted, I) :=
+               (Defined => True,
+                Tag  => UL,
+                Size => -1, -- 15
+                Font => ARM_Output.Default,
+                Indent => Natural(I),
+                Right_Indent => 1,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 5);
+    end loop;
+    -- Small Nested Bulleted:
+    -- Note: Indent = 0 is not allowed.
+    for I in 1 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Small_Nested_Bulleted, I) :=
+               (Defined => True,
+                Tag  => UL,
+                Size => -1, -- 15
+                Font => ARM_Output.Default,
+                Indent => Natural(I),
+                Right_Indent => 1,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 5);
+    end loop;
+
+    -- Enumerated:
+    -- Note: Indent = 0 is not allowed.
+    for I in 1 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Enumerated, I) :=
+               (Defined => True,
+                Tag  => DL,
+                Size => 0, -- 18
+                Font => ARM_Output.Default,
+                Indent => Natural(I)-1,
+                Right_Indent => 1,
+                Hang_Outdent => 1,
+                Before => 0,
+                After => 5);
+    end loop;
+    -- Small Enumerated:
+    -- Note: Indent = 0 is not allowed.
+    for I in 1 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Small_Enumerated, I) :=
+               (Defined => True,
+                Tag  => DL,
+                Size => -1, -- 15
+                Font => ARM_Output.Default,
+                Indent => Natural(I)-1,
+                Right_Indent => 1,
+                Hang_Outdent => 1,
+                Before => 0,
+                After => 5);
+    end loop;
+
+    -- Giant Hanging
+    -- Note: Indent < 4 is not allowed.
+    for I in 4 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Giant_Hanging, I) :=
+               (Defined => True,
+                Tag  => DL,
+                Size => 0, -- 18
+                Font => ARM_Output.Default,
+                Indent => Natural(I)-4,
+                Right_Indent => 0,
+                Hang_Outdent => 4,
+                Before => 0,
+                After => 6);
+    end loop;
+    -- Small Giant Hanging:
+    -- Note: Indent < 4 is not allowed.
+    for I in 4 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Small_Giant_Hanging, I) :=
+               (Defined => True,
+                Tag  => DL,
+                Size => -1, -- 15
+                Font => ARM_Output.Default,
+                Indent => Natural(I)-4,
+                Right_Indent => 0,
+                Hang_Outdent => 4,
+                Before => 0,
+                After => 6);
+    end loop;
+    -- Wide Hanging
+    -- Note: Indent < 3 is not allowed.
+    for I in 3 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Wide_Hanging, I) :=
+               (Defined => True,
+                Tag  => DL,
+                Size => 0, -- 18
+                Font => ARM_Output.Default,
+                Indent => Natural(I)-3,
+                Right_Indent => 0,
+                Hang_Outdent => 3,
+                Before => 0,
+                After => 6);
+    end loop;
+    -- Small Wide Hanging:
+    -- Note: Indent < 3 is not allowed.
+    for I in 3 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Small_Wide_Hanging, I) :=
+               (Defined => True,
+                Tag  => DL,
+                Size => -1, -- 15
+                Font => ARM_Output.Default,
+                Indent => Natural(I)-3,
+                Right_Indent => 0,
+                Hang_Outdent => 3,
+                Before => 0,
+                After => 6);
+    end loop;
+    -- Medium Hanging
+    -- Note: Indent < 2 is not allowed.
+    for I in 2 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Medium_Hanging, I) :=
+               (Defined => True,
+                Tag  => DL,
+                Size => 0, -- 18
+                Font => ARM_Output.Default,
+                Indent => Natural(I)-2,
+                Right_Indent => 0,
+                Hang_Outdent => 2,
+                Before => 0,
+                After => 6);
+    end loop;
+    -- Small Medium Hanging:
+    -- Note: Indent < 2 is not allowed.
+    for I in 2 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Small_Medium_Hanging, I) :=
+               (Defined => True,
+                Tag  => DL,
+                Size => -1, -- 15
+                Font => ARM_Output.Default,
+                Indent => Natural(I)-2,
+                Right_Indent => 0,
+                Hang_Outdent => 2,
+                Before => 0,
+                After => 6);
+    end loop;
+    -- Narrow Hanging
+    -- Note: Indent < 1 is not allowed.
+    for I in 1 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Narrow_Hanging, I) :=
+               (Defined => True,
+                Tag  => DL,
+                Size => 0, -- 18
+                Font => ARM_Output.Default,
+                Indent => Natural(I)-1,
+                Right_Indent => 0,
+                Hang_Outdent => 1,
+                Before => 0,
+                After => 6);
+    end loop;
+    -- Small Narrow Hanging:
+    -- Note: Indent < 1 is not allowed.
+    for I in 1 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Small_Narrow_Hanging, I) :=
+               (Defined => True,
+                Tag  => DL,
+                Size => -1, -- 15
+                Font => ARM_Output.Default,
+                Indent => Natural(I)-1,
+                Right_Indent => 0,
+                Hang_Outdent => 1,
+                Before => 0,
+                After => 6);
+    end loop;
+    -- Hanging in Bulleted
+    -- Note: Indent < 2 is not allowed.
+    for I in 2 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Hanging_in_Bulleted, I) :=
+               (Defined => True,
+                Tag  => DL,
+                Size => 0, -- 18
+                Font => ARM_Output.Default,
+                Indent => Natural(I)-2,
+                Right_Indent => 1,
+                Hang_Outdent => 2,
+                Before => 0,
+                After => 5);
+    end loop;
+    -- Small Hanging in Bulleted
+    -- Note: Indent < 2 is not allowed.
+    for I in 2 .. ARM_Output.Paragraph_Indent_Type'Last loop
+       Paragraph_Info(ARM_Output.Small_Hanging_in_Bulleted, I) :=
+               (Defined => True,
+                Tag  => DL,
+                Size => -1, -- 15
+                Font => ARM_Output.Default,
+                Indent => Natural(I)-2,
+                Right_Indent => 1,
+                Hang_Outdent => 2,
+                Before => 0,
+                After => 5);
+    end loop;
+
+    -- Index. Only define the form that we'll use.
+    Paragraph_Info(ARM_Output.Index, 0) :=
+               (Defined => True,
+                Tag  => DIV,
+                Size => 0,
+                Font => ARM_Output.Default,
+                Indent => 0,
+                Right_Indent => 0,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 0);
+
+    -- Syntax Summary. Only define the form that we'll use.
+    Paragraph_Info(ARM_Output.Syntax_Summary, 1) :=
+               (Defined => True,
+                Tag  => DIV,
+                Size => -1,
+                Font => ARM_Output.Default,
+                Indent => 1,
+                Right_Indent => 0,
+                Hang_Outdent => 0,
+                Before => 0,
+                After => 4);
+
+    -- Title. Only define the form that we'll use.
+    Paragraph_Info(ARM_Output.Title, 0) :=
+           (Defined => True,
+            Tag  => DIV,
+            Size => 3, -- 36
+            Font => ARM_Output.Default,
+            Indent => 0,
+            Right_Indent => 0,
+            Hang_Outdent => 0,
+            Before => 6,
+            After => 6);
+
+end ARM_HTML;
diff --git a/packages/ada-ref-man/progs/arm_html.ads 
b/packages/ada-ref-man/progs/arm_html.ads
new file mode 100755
index 0000000..3c07527
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_html.ads
@@ -0,0 +1,617 @@
+with ARM_Output,
+     ARM_Contents,
+     Ada.Text_IO;
+-- private
+with Ada.Strings.Unbounded;
+package ARM_HTML is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package defines the HTML output object.
+    -- Output objects are responsible for implementing the details of
+    -- a particular format.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2011, 2012, 2013,
+    --     2016
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  4/19/00 - RLB - Created base package.
+    --  4/21/00 - RLB - Added line break and hard space routines.
+    --  4/24/00 - RLB - Added DR references and Insert/Delete text formats.
+    --  4/25/00 - RLB - Added size to format.
+    --  5/10/00 - RLB - Added End_Hang_Item.
+    --  5/12/00 - RLB - Added No_Prefix to Start_Paragraph.
+    --  5/13/00 - RLB - Added Special_Character.
+    --  5/17/00 - RLB - Added New_Page.
+    --  5/22/00 - RLB - Added Includes_Changes to Create.
+    --  5/23/00 - RLB - Added Set_Column and New_Column.
+    --               - Added Tab_Info and Tab_Stops.
+    --  5/24/00 - RLB - Added Location to Text_Format.
+    --         - RLB - Added No_Breaks and Keep_with_Next to Start_Paragraph.
+    --  5/25/00 - RLB - Added Big_Files to Create. Added Justification.
+    --         - RLB - Added Separator_Lines and TOC routines.
+    --  5/26/00 - RLB - Added table operations.
+    --  6/ 2/00 - RLB - Added Soft_Line_Break.
+    --  8/ 2/00 - RLB - Added Soft_Hyphen_Break.
+    --  8/ 7/00 - RLB - Added Leading flag to Start_Paragraph.
+    --  8/17/00 - RLB - Replaced "Leading" by "Space_After".
+    --  8/22/00 - RLB - Added Revised_Clause_Header.
+    --  9/27/00 - RLB - Added tab emulation when in the fixed font.
+    --         - RLB - Added column emulation.
+    --  9/29/00 - RLB - Added Any_Nonspace flag.
+    --  7/18/01 - RLB - Added support for Big_Files.
+    --  7/18/02 - RLB - Removed Document parameter from Create, replaced by
+    --                 three strings and For_ISO boolean.
+    --         - RLB - Added AI_Reference.
+    --         - RLB - Added Change_Version_Type and uses.
+    --  9/10/04 - RLB - Added "Both" to possible changes to handle
+    --                 replacement of changed text.
+    --  9/14/04 - RLB - Moved Change_Version_Type to ARM_Contents.
+    --  5/27/05 - RLB - Added arbitrary Unicode characters.
+    --  1/11/06 - RLB - Eliminated dispatching Create in favor of tailored
+    --                 versions.
+    --  1/12/06 - RLB - Added a number of parameters to Create.
+    --  1/13/06 - RLB - Added new Link operations.
+    --  1/16/06 - RLB - Added Index_URL to Create.
+    --  1/27/06 - RLB - Added Tab_Emulation.
+    --  2/ 8/06 - RLB - Added additional parameters to the table command.
+    --  2/10/06 - RLB - Added even more additional parameters to the
+    --                 table command.
+    --         - RLB - Added picture command.
+    --  2/19/06 - RLB - Added Number_Paragraphs flag and large letter count.
+    --  9/21/06 - RLB - Added Body_Font.
+    --  9/25/06 - RLB - Added Last_Column_Width to Start_Table.
+    -- 10/13/06 - RLB - Added specifiable colors.
+    --          - RLB - Added Local_Link_Start and Local_Link_End to allow
+    --                 formatting in the linked text.
+    --  2/ 9/07 - RLB - Changed comments on AI_Reference.
+    --  2/13/07 - RLB - Revised to separate style and indent information
+    --                 for paragraphs.
+    -- 12/19/07 - RLB - Added DOS_Filename flag.
+    --         - RLB - Added limited colors to Text_Format.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/25/11 - RLB - Added old insertion version to Revised_Clause_Header.
+    --  8/31/12 - RLB - Added Output_Path.
+    -- 11/26/12 - RLB - Added subdivision names to Clause_Header and
+    --                 Revised_Clause_Header.
+    --  3/26/13 - RLB - Added HTML_Script to allow adding Google Analytics
+    --                 code as needed.
+    --  4/20/16 - RLB - Added Force_New_Revision_Colors.
+    --  8/18/16 - RLB - Added a more column text to avoid overflow.
+
+    type HTML_Output_Type is new ARM_Output.Output_Type with private;
+
+    type HTML_Type is (HTML_3, -- Use only HTML 3 elements.
+                      HTML_4_Compatible, -- Use HTML 4 when needed, but try to 
look good on old browsers.
+                      HTML_4_Only); -- Use only HTML 4 elements (no attempt to 
look good on old browsers).
+
+    type Tab_Emulation_Type is
+               (Single_Space,          -- Replace all tabs by a single space.
+                Quad_Space,            -- Replace all tabs by four hard spaces.
+                Emulate_Fixed_Only,    -- Emulate tabs in fixed font styles;
+                                       -- replace others by a single space.
+                Emulate_Fixed_Only_Quad,--Emulate tabs in fixed font styles;
+                                       -- replace others by four hard spaces.
+                Emulate_All);          -- Replace tabs in all styles; note that
+                                       -- it is unlikely that they will line
+                                       -- up perfectly for non-fixed fonts.
+
+    subtype Color_String is String (1..7); -- "#hhhhhh" to specify a color.
+
+    procedure Create (Output_Object : in out HTML_Output_Type;
+                     Big_Files : in Boolean;
+                     File_Prefix : in String;
+                     Output_Path : in String;
+                     DOS_Filenames : in Boolean;
+                     HTML_Kind : in HTML_Type;
+                     Use_Unicode : in Boolean;
+                     Number_Paragraphs : in Boolean;
+                     Ref_URL : in String;
+                     Srch_URL : in String;
+                     Index_URL : in String;
+                     Use_Buttons : Boolean;
+                     Nav_On_Top : Boolean;
+                     Nav_On_Bottom : Boolean;
+                     Tab_Emulation : Tab_Emulation_Type;
+                     Script_HTML : String;
+                     Header_HTML : String;
+                     Footer_HTML : String;
+                     Title : in String := "";
+                     Body_Font : ARM_Output.Font_Family_Type;
+                     Force_New_Revision_Colors : Boolean;
+                     Text_Color : Color_String;
+                     Background_Color : Color_String;
+                     Link_Color : Color_String;
+                     VLink_Color : Color_String;
+                     ALink_Color : Color_String);
+       -- Create an Output_Object for a document.
+       -- Generate a few large output files if
+       -- Big_Files is True; otherwise generate smaller output files.
+       -- The prefix of the output file names is File_Prefix - this
+       -- should be no more than 5 characters allowed in file names.
+       -- The files will be written into Output_Path.
+       -- If DOS_Filename is true, use 8.3 file names;
+       -- in that case, File_Prefix must be less than 4 characters in length;
+       -- and no clause or subclause number may exceed 35 if Big_Files is 
False.
+       -- The title of the document is Title.
+       -- HTML_Kind determines the kind of HTML generated; HTML_3 works on
+       -- every browser but has little control over formatting;
+       -- HTML_4_Compatible has better control, but tries to make the results
+       -- look good on older browsers; HTML_4_Only uses maximum formatting,
+       -- but makes no attempt to look good on browsers older than IE 5.0 and
+       -- Firefox 1.0.
+       -- If Use_Unicode is true, Unicode characters available on US versions
+       -- of Windows 2000 are used when appropriate; otherwise, Unicode
+       -- characters are only used when explicitly requested with
+       -- Unicode_Character (other characters are replaced with reasonable
+       -- equivalents). [Note: It's known that IE on Windows 95/98/ME cannot
+       -- display Unicode characters.] Use_Unicode has no effect if HTML_Kind
+       -- is set to HTML_3.
+       -- Number_Paragraphs means that paragraph numbers will be used;
+       -- otherwise, the Number parameter to Start_Paragraph must be "".
+       -- Ref_URL, Srch_URL, and Index_URL are the URLs (possibly relative)
+       -- for the "References", "Search", and "Index" buttons/labels,
+       -- respectively. If null, these buttons/labels link to sections named
+       -- "References", "Search", and "Index"; if these do not exist, the
+       -- buttons/labels are omitted.
+       -- If Use_Buttons is true, button images are used, otherwise text labels
+       -- are used for the navigation bar.
+       -- If Nav_On_Top is true, the navigation bar will appear in the header
+       -- of each page. If Nav_On_Bottom is true, the navigation bar will
+       -- appear in the footer of each page.
+       -- Tab_Emulation determines how tabs are emulated.
+       -- Script_HTML gives self-contained HTML that will appear immediately
+       -- before the </HEAD> of every page. This usually will contain
+       -- Javascript scripts or CSS styles. The original intent was to allow
+       -- adding the Google Analytics script to each page.
+       -- Header_HTML gives self-contained HTML that will appear before the
+       -- navigation bar in the header. Footer_HTML gives self-contained HTML
+       -- that will appear after the navigation bar in the footer.
+       -- Body_Font selects the default font for the document body.
+       -- Text_Color specifies the default text color; Background_Color
+       -- specifies the default background color; Link_Color specifies the
+       -- default color of normal links; VLink_Color specifies the
+       -- default color of visited links; and ALink_Color specifies the
+       -- default color of active (in the act of clinking) links.
+
+
+    procedure Close (Output_Object : in out HTML_Output_Type);
+       -- Close an Output_Object. No further output to the object is
+       -- allowed after this call.
+
+
+    procedure Section (Output_Object : in out HTML_Output_Type;
+                      Section_Title : in String;
+                      Section_Name : in String);
+       -- Start a new section. The title is Section_Title (this is
+       -- intended for humans). The name is Section_Name (this is
+       -- intended to be suitable to be a portion of a file name).
+
+    procedure Set_Columns (Output_Object : in out HTML_Output_Type;
+                          Number_of_Columns : in ARM_Output.Column_Count);
+       -- Set the number of columns.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Start_Paragraph (Output_Object : in out HTML_Output_Type;
+                              Style     : in ARM_Output.Paragraph_Style_Type;
+                              Indent    : in ARM_Output.Paragraph_Indent_Type;
+                              Number    : in String;
+                              No_Prefix : in Boolean := False;
+                              Tab_Stops : in ARM_Output.Tab_Info := 
ARM_Output.NO_TABS;
+                              No_Breaks : in Boolean := False;
+                              Keep_with_Next : in Boolean := False;
+                              Space_After : in ARM_Output.Space_After_Type
+                                  := ARM_Output.Normal;
+                              Justification : in ARM_Output.Justification_Type
+                                  := ARM_Output.Default);
+       -- Start a new paragraph. The style and indent of the paragraph is as
+       -- specified. The (AA)RM paragraph number (which might include update
+       -- and version numbers as well: [12.1/1]) is Number. If the format is
+       -- a type with a prefix (bullets, hangining items), the prefix is
+       -- omitted if No_Prefix is true. Tab_Stops defines the tab stops for
+       -- the paragraph. If No_Breaks is True, we will try to avoid page breaks
+       -- in the paragraph. If Keep_with_Next is true, we will try to avoid
+       -- separating this paragraph and the next one. (These may have no
+       -- effect in formats that don't have page breaks). Space_After
+       -- specifies the amount of space following the paragraph. Justification
+       -- specifies the text justification for the paragraph. Not_Valid_Error
+       -- is raised if Tab_Stops /= NO_TABS for a hanging or bulleted format.
+
+    procedure End_Paragraph (Output_Object : in out HTML_Output_Type);
+       -- End a paragraph.
+
+    procedure Category_Header (Output_Object : in out HTML_Output_Type;
+                              Header_Text : String);
+       -- Output a Category header (that is, "Legality Rules",
+       -- "Dynamic Semantics", etc.)
+       -- (Note: We did not use a enumeration here to insure that these
+       -- headers are spelled the same in all output versions).
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Clause_Header (Output_Object     : in out HTML_Output_Type;
+                            Header_Text       : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False);
+       -- Output a Clause header. The level of the header is specified
+       -- in Level. The Clause Number is as specified; the top-level (and
+       -- other) subdivision names are as specified. These should appear in
+       -- the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Revised_Clause_Header
+                           (Output_Object     : in out HTML_Output_Type;
+                            New_Header_Text   : in String;
+                            Old_Header_Text   : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Version           : in 
ARM_Contents.Change_Version_Type;
+                            Old_Version       : in 
ARM_Contents.Change_Version_Type;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False);
+       -- Output a revised clause header. Both the original and new text will
+       -- be output. The level of the header is specified in Level. The Clause
+       -- Number is as specified; the top-level (and other) subdivision names
+       -- are as specified. These should appear in the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- Version is the insertion version of the new text; Old_Version is
+       -- the insertion version of the old text.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure TOC_Marker (Output_Object : in out HTML_Output_Type;
+                         For_Start : in Boolean);
+       -- Mark the start (if For_Start is True) or end (if For_Start is
+       -- False) of the table of contents data. Output objects that
+       -- auto-generate the table of contents can use this to do needed
+       -- actions.
+
+    procedure New_Page (Output_Object : in out HTML_Output_Type;
+                       Kind : ARM_Output.Page_Kind_Type := 
ARM_Output.Any_Page);
+       -- Output a page break.
+       -- Note that this has no effect on non-printing formats.
+       -- Any_Page breaks to the top of the next page (whatever it is);
+       -- Odd_Page_Only breaks to the top of the odd-numbered page;
+       -- Soft_Page allows a page break but does not force one (use in
+       -- "No_Breaks" paragraphs.)
+       -- Raises Not_Valid_Error if in a paragraph if Kind = Any_Page or
+       -- Odd_Page, and if not in a paragraph if Kind = Soft_Page.
+
+    procedure New_Column (Output_Object : in out HTML_Output_Type);
+       -- Output a column break.
+       -- Raises Not_Valid_Error if in a paragraph, or if the number of
+       -- columns is 1.
+
+    procedure Separator_Line (Output_Object : in out HTML_Output_Type;
+                             Is_Thin : Boolean := True);
+       -- Output a separator line. It is thin if "Is_Thin" is true.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Start_Table (Output_Object : in out HTML_Output_Type;
+                          Columns : in ARM_Output.Column_Count;
+                          First_Column_Width : in ARM_Output.Column_Count;
+                          Last_Column_Width : in ARM_Output.Column_Count;
+                          Alignment : in ARM_Output.Column_Text_Alignment;
+                          No_Page_Break : in Boolean;
+                          Has_Border : in Boolean;
+                          Small_Text_Size : in Boolean;
+                          Header_Kind : in ARM_Output.Header_Kind_Type);
+       -- Starts a table. The number of columns is Columns; the first
+       -- column has First_Column_Width times the normal column width, and
+       -- the last column has Last_Column_Width times the normal column width.
+       -- Alignment is the horizontal text alignment within the columns.
+       -- No_Page_Break should be True to keep the table intact on a single
+       -- page; False to allow it to be split across pages.
+       -- Has_Border should be true if a border is desired, false otherwise.
+       -- Small_Text_Size means that the contents will have the AARM size;
+       -- otherwise it will have the normal size.
+       -- Header_Kind determines whether the table has headers.
+       -- This command starts a paragraph; the entire table is a single
+       -- paragraph. Text will be considered part of the caption until the
+       -- next table marker call.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Table_Marker (Output_Object : in out HTML_Output_Type;
+                           Marker : in ARM_Output.Table_Marker_Type);
+       -- Marks the end of an entity in a table.
+       -- If Marker is End_Caption, the table caption ends and the
+       --      future text is part of the table header.
+       -- If Marker is End_Header, the table header ends and the
+       --      future text is part of the table body.
+       -- If Marker is End_Row, a row in the table is completed, and another
+       --      row started.
+       -- If Marker is End_Item, an item in the table header or body is ended,
+       --      and another started.
+       -- If Marker is End_Table, the entire table is finished.
+       -- Raises Not_Valid_Error if not in a table.
+
+    -- Text output: These are only allowed after a Start_Paragraph and
+    -- before any End_Paragraph. Raises Not_Valid_Error if not in a paragraph,
+    -- or another error.
+
+    procedure Ordinary_Text (Output_Object : in out HTML_Output_Type;
+                            Text : in String);
+       -- Output ordinary text.
+       -- The text must end at a word break, never in the middle of a word.
+
+    procedure Ordinary_Character (Output_Object : in out HTML_Output_Type;
+                                 Char : in Character);
+       -- Output an ordinary character.
+       -- Spaces will be used to break lines as needed.
+
+    procedure Hard_Space (Output_Object : in out HTML_Output_Type);
+       -- Output a hard space. No line break should happen at a hard space.
+
+    procedure Line_Break (Output_Object : in out HTML_Output_Type);
+       -- Output a line break. This does not start a new paragraph.
+       -- This corresponds to a "<BR>" in HTML.
+
+    procedure Index_Line_Break (Output_Object : in out HTML_Output_Type;
+                               Clear_Keep_with_Next : in Boolean);
+       -- Output a line break for the index. This does not start a new
+       -- paragraph in terms of spacing. This corresponds to a "<BR>"
+       -- in HTML. If Clear_Keep_with_Next is true, insure that the next
+       -- line does not require the following line to stay with it.
+       -- Raises Not_Valid_Error if the paragraph is not in the index format.
+
+    procedure Soft_Line_Break (Output_Object : in out HTML_Output_Type);
+       -- Output a soft line break. This is a place (in the middle of a
+       -- "word") that we allow a line break. It is usually used after
+       -- underscores in long non-terminals.
+
+    procedure Soft_Hyphen_Break (Output_Object : in out HTML_Output_Type);
+       -- Output a soft line break, with a hyphen. This is a place (in the 
middle of
+       -- a "word") that we allow a line break. If the line break is used,
+       -- a hyphen will be added to the text.
+
+    procedure Tab (Output_Object : in out HTML_Output_Type);
+       -- Output a tab, inserting space up to the next tab stop.
+       -- Raises Not_Valid_Error if the paragraph was created with
+       -- Tab_Stops = ARM_Output.NO_TABS.
+
+    procedure Special_Character (Output_Object : in out HTML_Output_Type;
+                                Char : in ARM_Output.Special_Character_Type);
+       -- Output an special character.
+
+    procedure Unicode_Character (Output_Object : in out HTML_Output_Type;
+                                Char : in ARM_Output.Unicode_Type);
+       -- Output a Unicode character, with code position Char.
+
+    procedure End_Hang_Item (Output_Object : in out HTML_Output_Type);
+       -- Marks the end of a hanging item. Call only once per paragraph.
+       -- Raises Not_Valid_Error if the paragraph style is not in
+       -- Text_Prefixed_Style_Subtype, or if this has already been
+       -- called for the current paragraph, or if the paragraph was started
+       -- with No_Prefix = True.
+
+    procedure Text_Format (Output_Object : in out HTML_Output_Type;
+                          Format : in ARM_Output.Format_Type);
+       -- Change the text format so that all of the properties are as 
specified.
+       -- Note: Changes to these properties ought be stack-like; that is,
+       -- Bold on, Italic on, Italic off, Bold off is OK; Bold on, Italic on,
+       -- Bold off, Italic off should be avoided (as separate commands).
+
+    procedure Clause_Reference (Output_Object : in out HTML_Output_Type;
+                               Text : in String;
+                               Clause_Number : in String);
+       -- Generate a reference to a clause in the standard. The text of
+       -- the reference is "text", and the number of the clause is
+       -- Clause_Number. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure Index_Target (Output_Object : in out HTML_Output_Type;
+                           Index_Key : in Natural);
+       -- Generate a index target. This marks the location where an index
+       -- reference occurs. Index_Key names the index item involved.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, nothing is generated.
+
+    procedure Index_Reference (Output_Object : in out HTML_Output_Type;
+                              Text : in String;
+                              Index_Key : in Natural;
+                              Clause_Number : in String);
+       -- Generate a reference to an index target in the standard. The text
+       -- of the reference is "Text", and Index_Key and Clause_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure DR_Reference (Output_Object : in out HTML_Output_Type;
+                           Text : in String;
+                           DR_Number : in String);
+       -- Generate a reference to an DR from the standard. The text
+       -- of the reference is "Text", and DR_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure AI_Reference (Output_Object : in out HTML_Output_Type;
+                           Text : in String;
+                           AI_Number : in String);
+       -- Generate a reference to an AI from the standard. The text
+       -- of the reference is "Text", and AI_Number denotes
+       -- the target (in folded format). For hyperlinked formats, this should
+       -- generate a link; for other formats, the text alone is generated.
+
+    procedure Local_Target (Output_Object : in out HTML_Output_Type;
+                           Text : in String;
+                           Target : in String);
+       -- Generate a local target. This marks the potential target of local
+       -- links identified by "Target". Text is the text of the target.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link (Output_Object : in out HTML_Output_Type;
+                         Text : in String;
+                         Target : in String;
+                         Clause_Number : in String);
+       -- Generate a local link to the target and clause given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link_Start (Output_Object : in out HTML_Output_Type;
+                               Target : in String;
+                               Clause_Number : in String);
+       -- Generate a local link to the target and clause given.
+       -- The link will surround text until Local_Link_End is called.
+       -- Local_Link_End must be called before this routine can be used again.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link_End (Output_Object : in out HTML_Output_Type;
+                             Target : in String;
+                             Clause_Number : in String);
+       -- End a local link for the target and clause given.
+       -- This must be in the same paragraph as the Local_Link_Start.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure URL_Link (Output_Object : in out HTML_Output_Type;
+                       Text : in String;
+                       URL : in String);
+       -- Generate a link to the URL given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Picture  (Output_Object : in out HTML_Output_Type;
+                       Name  : in String;
+                       Descr : in String;
+                       Alignment : in ARM_Output.Picture_Alignment;
+                       Height, Width : in Natural;
+                       Border : in ARM_Output.Border_Kind);
+       -- Generate a picture.
+       -- Name is the (simple) file name of the picture; Descr is a
+       -- descriptive name for the picture (it will appear in some web
+       -- browsers).
+       -- We assume that it is a .PNG or .JPG and that it will be present
+       -- in the same directory as the output files.
+       -- Alignment specifies the picture alignment.
+       -- Height and Width specify the picture size in pixels.
+       -- Border specifies the kind of border.
+
+private
+
+    type Column_Text_Item_Type;
+    type Column_Text_Ptr is access Column_Text_Item_Type;
+    type Column_Text_Item_Type is record
+       Text : String (1..240);
+       Length : Natural;
+       Item : Natural; -- Which item.
+       End_Para : Boolean; -- True if this item is an end paragraph.
+       Next : Column_Text_Ptr;
+    end record;
+    type Column_Text_Ptrs_Type is array (1..5) of Column_Text_Ptr;
+
+    subtype Prefix_String is String(1..5);
+    type HTML_Output_Type is new ARM_Output.Output_Type with record
+       Is_Valid : Boolean := False;
+
+       -- Global properties:
+       File_Prefix : Prefix_String; -- Blank padded.
+       Output_Path : Ada.Strings.Unbounded.Unbounded_String;
+       Big_Files : Boolean; -- For HTML, this means to generate a single 
monster file.
+       DOS_Filenames : Boolean; -- Generate 8.3 MS-DOS filenames.
+       Title : Ada.Strings.Unbounded.Unbounded_String;
+        HTML_Kind : HTML_Type;
+        Use_Unicode : Boolean;
+        Number_Paragraphs : Boolean;
+        Ref_URL : Ada.Strings.Unbounded.Unbounded_String;
+        Srch_URL : Ada.Strings.Unbounded.Unbounded_String;
+        Index_URL : Ada.Strings.Unbounded.Unbounded_String;
+        Use_Buttons : Boolean := True;
+        Nav_On_Top : Boolean := True;
+        Nav_On_Bottom : Boolean := True;
+       Tab_Emulation : Tab_Emulation_Type;
+        Script_HTML : Ada.Strings.Unbounded.Unbounded_String;
+        Header_HTML : Ada.Strings.Unbounded.Unbounded_String;
+        Footer_HTML : Ada.Strings.Unbounded.Unbounded_String;
+       Body_Font : ARM_Output.Font_Family_Type := ARM_Output.Roman;
+       Force_New_Revision_Colors : Boolean;
+       Text_Color : Color_String;
+       Background_Color : Color_String;
+       Link_Color : Color_String;
+       VLink_Color : Color_String;
+       ALink_Color : Color_String;
+
+       -- Current formatting properties:
+       Is_In_Paragraph  : Boolean := False;
+       Paragraph_Style  : ARM_Output.Paragraph_Style_Type;
+       Paragraph_Indent : ARM_Output.Paragraph_Indent_Type;
+       Had_Prefix : Boolean := False; -- If in paragraph, value of not 
No_Prefix.
+       Column_Count : ARM_Output.Column_Count := 1;
+       Output_File : Ada.Text_IO.File_Type;
+       Section_Name : String(1..3);
+       Char_Count : Natural := 0; -- Characters on current line.
+       Disp_Char_Count : Natural := 0; -- Displayed characters on current line.
+       Disp_Large_Char_Count : Natural := 0; -- Displayed large characters on 
current line (others are "small" characters).
+                       -- Large characters are capitals, 'm', 'w', and numbers.
+       Any_Nonspace : Boolean := False; -- Have we output any non-space on 
this line?
+       Last_was_Space : Boolean := False; -- True if the last visible character
+                               -- output was a space (any kind), or this is the
+                               -- start of a line.
+       Conditional_Space : Boolean := False; -- If True, output a space if the
+                               -- next *visible* character is not a space or
+                               -- punctuation.
+       Saw_Hang_End : Boolean := False; -- If we are in a hanging paragraph,
+                              -- have we seen the end of the hanging part yet?
+       Is_Bold : Boolean; -- Is the text currently bold?
+       Is_Italic : Boolean; -- Is the text current italics?
+       Font : ARM_Output.Font_Family_Type; -- What is the current font family?
+       Size : ARM_Output.Size_Type; -- What is the current relative size?
+       Color : ARM_Output.Color_Type := ARM_Output.Default;
+       Change : ARM_Output.Change_Type := ARM_Output.None;
+       Version : ARM_Contents.Change_Version_Type := '0';
+       Added_Version : ARM_Contents.Change_Version_Type := '0';
+       Location : ARM_Output.Location_Type := ARM_Output.Normal;
+       Tab_Stops : ARM_Output.Tab_Info := ARM_Output.NO_TABS;
+       Can_Emulate_Tabs : Boolean := False; -- Can we emulate tabs in the 
current style?
+
+       Is_In_Table : Boolean := False; -- Are we processing a table?
+       In_Header : Boolean := False; -- If Is_In_Table, are we processing the 
header?
+       Table_Column_Alignment : ARM_Output.Column_Text_Alignment; -- If 
Is_In_Table, specifies the column alignment.
+       Table_Has_Small_Text : Boolean := False; -- If Is_In_Table, specifies 
the text size.
+
+       Current_Column : Natural := 0; -- When processing 4-column+ text, the 
current column number.
+       Current_Item : Natural := 0; -- When processing 4-column+ text, the 
current item within the column.
+       Column_Text : Column_Text_Ptrs_Type := (others => null);
+               -- If we are processing 4-column+ text, the text for the 
columns.
+
+       In_Local_Link : Boolean := False;
+
+       Current_Clause : Ada.Strings.Unbounded.Unbounded_String;
+               -- The name of the clause of the currently open file (for
+               -- Big_Files = False); used to generate the navigation bar.
+    end record;
+
+end ARM_HTML;
diff --git a/packages/ada-ref-man/progs/arm_indx.adb 
b/packages/ada-ref-man/progs/arm_indx.adb
new file mode 100755
index 0000000..8d50b96
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_indx.adb
@@ -0,0 +1,1050 @@
+with -- ARM_Output, redundant with spec
+     ARM_Contents,
+     Ada.Exceptions,
+     Ada.Characters.Handling,
+     Ada.Strings.Fixed,
+     Ada.Text_IO,
+     Ada.Calendar,
+     Ada.Unchecked_Deallocation;
+package body ARM_Index is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the routines to manage and generate the index.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2010, 2011, 2012
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/28/00 - RLB - Created package.
+    --  8/ 7/00 - RLB - Improved sorting of entries.
+    --  1/31/02 - RLB - Added missing with of Unchecked_Deallocation.
+    --  4/11/03 - RLB - Added a hard space in the indexing routine, in order
+    --                 that the empty paragraph isn't ignored.
+    --  9/09/04 - RLB - Removed unused junk noted by Stephen Leake.
+    -- 10/28/05 - RLB - Added key reuse.
+    -- 10/30/05 - RLB - Added subtype declaration.
+    --  1/16/06 - RLB - Fixed so a letter header is output if the first
+    --                 indexed item starts with a letter.
+    --  2/17/06 - RLB - Added Remove_Soft_Hyphens flag to Clean (for output).
+    --  9/22/06 - RLB - Changed to use Clause_Number_Type.
+    --  2/13/07 - RLB - Changed Start_Paragraph to use explicit indents.
+    -- 12/19/07 - RLB - Revised Text_Format calls.
+    --  3/31/10 - RLB - Fixed sorting to ignore embedded commands (like
+    --                 soft hyphens).
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    --  3/12/12 - RLB - Lengthened indexing so that
+    --                 "address@hidden@!Equal_Case_Insensitive"
+    --                 would fit. (Don't ask.)
+    --  8/31/12 - RLB - Fixed to avoid reading uninitialized section numbers.
+
+    Next_Index_Key : Index_Key;
+
+    type Term_Type;
+    type Term_Ptr is access Term_Type;
+    type Term_Type is record
+       Clause : String (1..10);
+       Clause_Len : Natural;
+       Clause_Number : ARM_Contents.Clause_Number_Type;
+       Paragraph : String (1..10);
+       Paragraph_Len : Natural;
+       Term : String (1..72);
+       Term_Len : Natural;
+       Subterm : String (1..80);
+       Subterm_Len : Natural;
+       Kind : Index_Item_Kind_Type;
+       Key : Index_Key;
+       Next : Term_Ptr;
+    end record;
+
+    procedure Free is new Ada.Unchecked_Deallocation (Term_Type, Term_Ptr);
+
+    Index_List : Term_Ptr;
+    Term_Count : Natural := 0;
+
+    procedure Create is
+       -- Initialize this package.
+    begin
+       Index_List := null;
+       Next_Index_Key := 1001;
+       Term_Count := 0;
+    end Create;
+
+
+    procedure Destroy is
+       -- Finalize this package; make sure the index is empty.
+       TTemp : Term_Ptr;
+    begin
+       while Index_List /= null loop
+           TTemp := Index_List;
+           Index_List := TTemp.Next;
+           Free (TTemp);
+       end loop;
+    end Destroy;
+
+
+    function Clean (Item : in String;
+                   Remove_Soft_Hyphens : in Boolean) return String is
+       -- Remove any commands from Item. (Except for soft hyphens
+       -- if Remove_Soft_Hyphens is False.) We keep the contents of any
+       -- commands (we assume the commands are basic formatting).
+       Result : String (1 .. Item'Length);
+       Len : Natural := 0;
+       In_Command : Boolean := False;
+       Skip_Next_Char : Boolean := False;
+       Close_Char : Character := ' ';
+    begin
+       for I in Item'Range loop
+           if Item(I) = '@' then
+               if I < Item'Last and then
+                  (Item(I+1) = '!' or else -- Soft hyphen
+                   Item(I+1) = '|' or else -- Soft linebreak
+                   Item(I+1) = ';' or else -- "nothing"
+                   Item(I+1) = '\' or else -- tab
+                   Item(I+1) = ' ' or else -- hard space
+                   Item(I+1) = '*') then   -- hard return
+                   if Remove_Soft_Hyphens then
+                       Skip_Next_Char := True;
+                   else
+                       -- Allow soft hyphens and other simple commands.
+                       Len := Len + 1;
+                       Result(Len) := Item(I);
+                   end if;
+               elsif I < Item'Last and then
+                  Item(I+1) = '@' then
+                   -- Literal '@' command.
+                   if Remove_Soft_Hyphens then
+                       Len := Len + 1;
+                       Result(Len) := '@';
+                       Skip_Next_Char := True;
+                   else
+                       -- Leave these markers, as we'll format the
+                       -- resulting string.
+                       Len := Len + 1;
+                       Result(Len) := Item(I);
+                   end if;
+               else
+                   In_Command := True;
+                   Close_Char := ' ';
+                   -- Skip it.
+               end if;
+           elsif Skip_Next_Char then
+               Skip_Next_Char := False;
+           elsif In_Command then
+               if Item(I) = '{' then
+                   Close_Char := '}';
+                   In_Command := False; -- Finished command header.
+               elsif Item(I) = '[' then
+                   Close_Char := ']';
+                   In_Command := False;
+               elsif Item(I) = '(' then
+                   Close_Char := ')';
+                   In_Command := False;
+               elsif Item(I) = '<' then
+                   Close_Char := '>';
+                   In_Command := False;
+               elsif Item(I) = '`' then
+                   Close_Char := ''';
+                   In_Command := False;
+               elsif Ada.Characters.Handling.Is_Alphanumeric (Item(I)) then
+                   -- Skip character (part of the command name).
+                   null;
+               else -- End of parameterless command (note: '@' already
+                    -- was recognized).
+                   Close_Char := ' ';
+                   In_Command := False;
+                   Len := Len + 1;
+                   Result(Len) := Item(I);
+               end if;
+           elsif Close_Char /= ' ' and then
+               Close_Char = Item(I) then
+               -- Skip the close character.
+               Close_Char := ' ';
+           elsif Item(I) = Ascii.LF then
+               Len := Len + 1;
+               Result(Len) := ' ';
+           else
+               Len := Len + 1;
+               Result(Len) := Item(I);
+           end if;
+       end loop;
+       return Result (1..Len);
+    end Clean;
+
+
+    function Get_Key return Index_Key is
+       -- Returns a Key value to refer to one or more index entries
+       -- (for a single entity).
+       Temp : Index_Key := Next_Index_Key;
+    begin
+       Next_Index_Key := Next_Index_Key + 1;
+       return Temp;
+    end Get_Key;
+
+
+    procedure Add_Reusing_Key (Term  : in String;
+                              Subterm : in String := "";
+                              Kind : in Index_Item_Kind_Type := Primary_Term;
+                              Clause : in String := "";
+                              Paragraph : in String := "";
+                              Key : in Index_Key) is
+       -- Add an index reference to the index, (re)using the specified Key
+       -- to refer to this index entry. Key must have previously
+       -- returned by Add or Get_Key.
+       Temp_Term : Term_Type;
+       CTerm : constant String := Clean(Term, Remove_Soft_Hyphens => False);
+       CSubterm : constant String := Clean(Subterm, Remove_Soft_Hyphens => 
False);
+    begin
+        Temp_Term.Kind := Kind;
+        Ada.Strings.Fixed.Move (Target => Temp_Term.Term,
+                               Source => CTerm,
+                               Drop   => Ada.Strings.Error,
+                               Pad    => ' ');
+        Temp_Term.Term_Len := CTerm'Length;
+       if Kind /= Primary_Term_and_Subterm and then
+          Kind /= Partial_Term_with_Subterm and then
+          Kind /= Child_Unit_Parent and then
+          Kind /= Declaration_in_Package and then
+          Kind /= Subdeclaration_in_Package and then
+          Kind /= Subtype_Declaration_in_Package and then
+          Kind /= See_Term and then
+          Kind /= See_Also_Term and then
+          Kind /= See_Other_Term and then
+          Kind /= See_Also_Other_Term then
+           if Subterm /= "" then
+               Ada.Exceptions.Raise_Exception (Not_Valid_Error'Identity,
+                   "Subterm used in kind without subterm");
+           else
+               Temp_Term.Subterm_Len := 0;
+           end if;
+       else
+           Ada.Strings.Fixed.Move (Target => Temp_Term.Subterm,
+                                   Source => CSubterm,
+                                   Drop   => Ada.Strings.Error,
+                                   Pad    => ' ');
+           Temp_Term.Subterm_Len := CSubterm'Length;
+       end if;
+       if (Kind = See_Other_Term or else
+           Kind = See_Also_Other_Term) then
+           if Clause /= "" or else Paragraph /= "" then
+               raise Not_Valid_Error with
+                   "Clause used in kind without reference";
+           else
+               Temp_Term.Clause_Len := 0;
+               Temp_Term.Paragraph_Len := 0;
+               -- Note: These have no clause numbers.
+           end if;
+       else
+           Ada.Strings.Fixed.Move (Target => Temp_Term.Clause,
+                                   Source => Clause,
+                                   Drop   => Ada.Strings.Error,
+                                   Pad    => ' ');
+           Temp_Term.Clause_Len := Clause'Length;
+           Ada.Strings.Fixed.Move (Target => Temp_Term.Paragraph,
+                                   Source => Paragraph,
+                                   Drop   => Ada.Strings.Error,
+                                   Pad    => ' ');
+           Temp_Term.Paragraph_Len := Paragraph'Length;
+           ARM_Contents.Make_Clause (Clause, Temp_Term.Clause_Number);
+
+       end if;
+       Temp_Term.Key := Key;
+
+       Temp_Term.Next := Index_List;
+       Index_List := new Term_Type'(Temp_Term);
+       Term_Count := Term_Count + 1;
+    exception
+       when Ada.Strings.Length_Error =>
+           Ada.Text_IO.Put_Line ("**** Index doesn't fit: Term: " & CTerm &
+                                 " [Subterm: " & CSubterm & "]");
+    end Add_Reusing_Key;
+
+
+    procedure Add (Term  : in String;
+                  Subterm : in String := "";
+                  Kind : in Index_Item_Kind_Type := Primary_Term;
+                  Clause : in String := "";
+                  Paragraph : in String := "";
+                   Key : out Index_Key) is
+       -- Add an index reference to the index. Returns a Key value to
+       -- refer to this index entry.
+       -- Raises Not_Valid_Error if Subterm, Clause, or Paragraph is not
+       -- empty when the kind does not use it.
+    begin
+       Key := Get_Key;
+       Add_Reusing_Key (Term, Subterm, Kind, Clause, Paragraph, Key);
+    end Add;
+
+
+    procedure Generate_Index_Body (Output_Object : in out 
ARM_Output.Output_Type'Class;
+                                  Use_Paragraphs : in Boolean := True) is
+       -- Generate the index body. (The section header has already been
+       -- generated). References include paragraph numbers if Use_Paragraphs
+       -- is true.
+       -- Note: This should not leave us in a paragraph.
+
+       Temp : Term_Ptr;
+       Last : Term_Ptr := null;
+       Items : array (1..Term_Count) of Term_Ptr;
+       Keep_Set : Boolean := False;
+
+       Start : Ada.Calendar.Time := Ada.Calendar.Clock;
+
+       function To_Lower (A : in String) return String renames
+           Ada.Characters.Handling.To_Lower;
+       function To_Lower (A : in Character) return Character renames
+           Ada.Characters.Handling.To_Lower;
+
+       procedure Clause_Ref (Item : Term_Ptr) is
+           -- Generate a clause reference:
+       begin
+           if Item.Clause_Len > 5 and then Item.Clause (1..5) = "Annex" then
+               -- Strip off the "Annex".
+               if Use_Paragraphs and then Item.Paragraph_Len /= 0 then
+                   ARM_Output.Index_Reference (Output_Object,
+                       Text => Item.Clause (Item.Clause_Len) & '(' &
+                          Item.Paragraph (1..Item.Paragraph_Len) & ')',
+                       Index_Key => Item.Key,
+                       Clause_Number => Item.Clause (1..Item.Clause_Len));
+               else
+                   ARM_Output.Index_Reference (Output_Object,
+                       Text => Item.Clause (Item.Clause_Len) & "",
+                       Index_Key => Item.Key,
+                       Clause_Number => Item.Clause (1..Item.Clause_Len));
+               end if;
+           elsif Use_Paragraphs and then Item.Paragraph_Len /= 0 then
+               ARM_Output.Index_Reference (Output_Object,
+                   Text => Item.Clause (1..Item.Clause_Len) & '(' &
+                      Item.Paragraph (1..Item.Paragraph_Len) & ')',
+                   Index_Key => Item.Key,
+                   Clause_Number => Item.Clause (1..Item.Clause_Len));
+           else
+               ARM_Output.Index_Reference (Output_Object,
+                   Text => Item.Clause (1..Item.Clause_Len),
+                   Index_Key => Item.Key,
+                   Clause_Number => Item.Clause (1..Item.Clause_Len));
+           end if;
+       end Clause_Ref;
+
+       procedure Italic_Text (Text : in String) is
+       begin
+           ARM_Output.Text_Format (Output_Object,
+                  Format => (Bold => False, Italic => True,
+                             Font => ARM_Output.Default,
+                             Size => 0, Color => ARM_Output.Default,
+                             Change => ARM_Output.None,
+                             Version | Added_Version => '0',
+                             Location => ARM_Output.Normal));
+            ARM_Output.Ordinary_Text (Output_Object, Text);
+           ARM_Output.Text_Format (Output_Object,
+                  Format => (Bold => False, Italic => False,
+                             Font => ARM_Output.Default,
+                             Size => 0, Color => ARM_Output.Default,
+                             Change => ARM_Output.None,
+                             Version | Added_Version => '0',
+                             Location => ARM_Output.Normal));
+       end Italic_Text;
+
+       procedure Term_Text (Text : in String) is
+           A_Soft_Hyphen : Natural := Ada.Strings.Fixed.Index (Text, "@!");
+       begin
+           if A_Soft_Hyphen = 0 then
+               ARM_Output.Ordinary_Text (Output_Object, Text);
+           else
+               ARM_Output.Ordinary_Text (Output_Object, Text(Text'First .. 
A_Soft_Hyphen-1));
+               ARM_Output.Soft_Hyphen_Break (Output_Object);
+               Term_Text (Text(A_Soft_Hyphen+2 .. Text'Last)); -- In case 
there is more than one soft hyphen.
+           end if;
+       end Term_Text;
+
+       procedure New_Kind (Item : Term_Ptr; Reset_Keep : in Boolean) is
+           -- Generate and item of a new kind. Note that the term has already
+           -- been generated (at some point).
+       begin
+          case Item.Kind is
+               when Primary_Term =>
+                   -- ** Must be first, so can't get here.
+                   Italic_Text ("*SORT ERROR*");
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when Partial_Term =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, '[');
+                   Italic_Text ("partial");
+                   ARM_Output.Ordinary_Character (Output_Object, ']');
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when Primary_Term_and_Subterm =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   Term_Text (Item.Subterm (1..Item.Subterm_Len));
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when Partial_Term_with_Subterm =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   Term_Text (Item.Subterm (1..Item.Subterm_Len));
+                   --[The "partial" does not seem to appear on subterms.]
+                   --ARM_Output.Hard_Space (Output_Object);
+                   --ARM_Output.Ordinary_Character (Output_Object, '[');
+                   --Italic_Text ("partial");
+                   --ARM_Output.Ordinary_Character (Output_Object, ']');
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when Syntax_NT_Used =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   Italic_Text ("used");
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when Child_Unit_Parent =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   Italic_Text ("child of");
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Term_Text (Item.Subterm (1..Item.Subterm_Len));
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when Declaration_In_Package =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   Italic_Text ("in");
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Term_Text (Item.Subterm (1..Item.Subterm_Len));
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when SubDeclaration_In_Package =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   declare
+                       In_Loc : Natural :=
+                           Ada.Strings.Fixed.Index (Item.Subterm 
(1..Item.Subterm_Len),
+                               " in ");
+                   begin
+                       if In_Loc = 0 then
+                           -- Weird, "in" not found.
+                           Term_Text (Item.Subterm (1..Item.Subterm_Len));
+                       else
+                           Term_Text (Item.Subterm (1 .. In_Loc));
+                           Italic_Text ("in");
+                           Term_Text (Item.Subterm (In_Loc+3 .. 
Item.Subterm_Len));
+                       end if;
+                   end;
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when Subtype_Declaration_In_Package =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   Italic_Text ("in");
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Term_Text (Item.Subterm (1..Item.Subterm_Len));
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when See_Term =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   Italic_Text ("See");
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Term_Text (Item.Subterm (1..Item.Subterm_Len));
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when See_Also_Term =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   Italic_Text ("See also");
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Term_Text (Item.Subterm (1..Item.Subterm_Len));
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when See_Other_Term =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   Italic_Text ("See");
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Term_Text (Item.Subterm (1..Item.Subterm_Len));
+                   -- No clause reference here.
+
+               when See_Also_Other_Term =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   Italic_Text ("See also");
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Term_Text (Item.Subterm (1..Item.Subterm_Len));
+                   -- No clause reference here.
+           end case;
+       end New_Kind;
+
+       function Is_Last_for_Term (Item : in Term_Ptr) return Boolean is
+           -- Returns True if this is the last line for Item's Term.
+       begin
+           if Item.Next = null then
+               return True;
+           elsif To_Lower (Item.Term (1..Item.Term_Len)) /= To_Lower 
(Item.Next.Term (1..Item.Next.Term_Len)) then
+               -- The next item has a different term.
+               return True;
+           elsif Temp.Kind /= Temp.Next.Kind then
+               -- The next item has a different kind, so another line will
+               -- be generated.
+               return False;
+           elsif To_Lower (Item.Subterm (1..Item.Subterm_Len)) /= To_Lower 
(Item.Next.Subterm (1..Item.Next.Subterm_Len)) then
+               -- The next item has a different subterm, so another line will
+               -- be generated.
+               return False;
+           else
+               -- The following term will just add another clause reference.
+               -- So we must look at the term following that:
+               return Is_Last_for_Term (Item.Next);
+           end if;
+       end Is_Last_for_Term;
+
+    begin
+       Ada.Text_IO.Put_Line ("  -- Start index sorting - " & 
Natural'Image(Term_Count) & " items.");
+
+       -- Sort the items:
+
+       -- Load the items:
+       Temp := Index_List;
+       for I in Items'range loop
+           Items(I) := Temp;
+           Temp := Temp.Next;
+       end loop;
+
+       -- Sort the items array:
+       declare
+
+           function "<" (Left, Right : Term_Ptr) return Boolean is
+               function To_Lower (A : in String) return String renames
+                   Ada.Characters.Handling.To_Lower;
+               use type ARM_Contents.Clause_Number_Type;
+
+               type Compare_Result is (Less, Greater, Equal);
+               function Compare (Left, Right : in String) return 
Compare_Result is
+                   -- Compare two items; the compare is case insensitive and
+                   -- ignores embedded commands.
+               begin
+                   -- Simple cases in order to increase performance.
+                   -- Check for null cases so we don't have to worry about them
+                   -- later.
+                   if Left = Right then
+                       return Equal;
+                   elsif Left'Length = 0 then
+                       return Less; -- Right can't be null or they'd be equal.
+                   elsif Right'Length = 0 then
+                       return Greater;
+                   end if;
+                   -- Both strings are non-null.
+                   if Left(Left'First) in '0'..'9' or else
+                      Left(Left'First) in 'A'..'Z' then
+                       if Right(Right'First) in '0'..'9' or else
+                          Right(Right'First) in 'A'..'Z' then
+                          if Left(Left'First) < Right(Right'First) then
+                              return Less;
+                          elsif Left(Left'First) > Right(Right'First) then
+                              return Greater;
+                          -- else continue below.
+                          end if;
+                       elsif Right(Right'First) in 'a'..'z' then
+                          if Left(Left'First) < 
Character'Val(Character'Pos(Right(Right'First))+Character'Pos('A')-Character'Pos('a'))
 then
+                              return Less;
+                          elsif Left(Left'First) > 
Character'Val(Character'Pos(Right(Right'First))+Character'Pos('A')-Character'Pos('a'))
 then
+                              return Greater;
+                          end if;
+                       -- else continue below.
+                       end if;
+                   elsif Left(Left'First) in 'a'..'z' then
+                       if Right(Right'First) in '0'..'9' or else
+                          Right(Right'First) in 'A'..'Z' then
+                          if 
Character'Val(Character'Pos(Left(Left'First))+Character'Pos('A')-Character'Pos('a'))
 < Right(Right'First) then
+                              return Less;
+                          elsif 
Character'Val(Character'Pos(Left(Left'First))+Character'Pos('A')-Character'Pos('a'))
 > Right(Right'First) then
+                              return Greater;
+                          -- else continue below.
+                          end if;
+                       elsif Right(Right'First) in 'a'..'z' then -- Both lower.
+                          if Left(Left'First) < Right(Right'First) then
+                              return Less;
+                          elsif Left(Left'First) > Right(Right'First) then
+                              return Greater;
+                          end if;
+                       -- else continue below.
+                       end if;
+                   -- else continue below.
+                   end if;
+
+                   -- OK, do a full compare:
+                   declare
+                       -- %% Warning: This has terrible performance, too much 
heap use.
+                       L : constant String := Clean (To_Lower (Left), 
Remove_Soft_Hyphens => True);
+                       R : constant String := Clean (To_Lower (Right), 
Remove_Soft_Hyphens => True);
+                   begin
+--Ada.Text_IO.Put_Line("Full compare: Left=" & Left & "; Right=" & Right);
+--Ada.Text_IO.Put_Line("   Clean Left=" & L & "; Clean Right=" & R);
+                       if L < R then
+--Ada.Text_IO.Put_Line("   Result=Less");
+                           return Less;
+                       elsif L > R then
+--Ada.Text_IO.Put_Line("   Result=Greater");
+                           return Greater;
+                       else
+--Ada.Text_IO.Put_Line("   Result=Equal");
+                           return Equal;
+                       end if;
+                   end;
+               end Compare;
+           begin
+               -- We sort first on "Term", then on "Kind", then on "Subterm",
+               -- then on "Clause", and finally on "Paragraph".
+               case Compare (Left.Term (1..Left.Term_Len), Right.Term 
(1..Right.Term_Len)) is
+                   when Less => return True;
+                   when Greater => return False;
+                   when Equal => null; -- Continue to next compare.
+               end case;
+               -- Partial_Term_with_Subterm and Primary_Term_and_Subterm
+               -- look identical, so they should compare equal for this
+               -- purpose:
+               if Left.Kind = Right.Kind or else
+                 (Left.Kind = Partial_Term_with_Subterm and then
+                  Right.Kind = Primary_Term_and_Subterm) or else
+                  (Left.Kind = Primary_Term_and_Subterm and then
+                  Right.Kind = Partial_Term_with_Subterm) then
+                   null; -- Continue to next compare.
+               elsif Left.Kind < Right.Kind then
+                   return True;
+               else --if Left.Kind > Right.Kind then
+                   return False;
+               end if;
+               case Compare (Left.Subterm (1..Left.Subterm_Len), Right.Subterm 
(1..Right.Subterm_Len)) is
+                   when Less => return True;
+                   when Greater => return False;
+                   when Equal => null; -- Continue to next compare.
+               end case;
+               if Left.Kind = See_Other_Term or else
+                  Left.Kind = See_Also_Other_Term then
+                   -- These have no clause or paragraph number to compare,
+                   -- and the Kinds must match, so they are equal.
+                   -- Since this is "<" and not "<=", the result is False.
+                   return False;
+               end if;
+               -- Note: We use the numbers, because the references don't
+               -- sort right (11.1 comes before 2.8, etc.)
+               if Left.Clause_Number < Right.Clause_Number then
+                   return True;
+               elsif Left.Clause_Number = Right.Clause_Number then
+                   -- Make sure that single digit paragraph numbers sort before
+                   -- multiple digit ones:
+                   if Left.Paragraph_Len <= 1 or else Left.Paragraph(2) = '.' 
or else Left.Paragraph(2) = '/' then
+                       -- Single digit number:
+                       if Right.Paragraph_Len <= 1 or else Right.Paragraph(2) 
= '.' or else Right.Paragraph(2) = '/' then
+                           -- Single digit number, normal compare:
+                           return Left.Paragraph (1..Left.Paragraph_Len) < 
Right.Paragraph (1..Right.Paragraph_Len);
+                       else
+                           -- Single digit is always less than multiple digits:
+                           return True;
+                       end if;
+                   else -- Not single digit number:
+                       if Right.Paragraph_Len <= 1 or else Right.Paragraph(2) 
= '.' or else Right.Paragraph(2) = '/' then
+                           -- Single digit number, always less than multiple 
digits:
+                           return False;
+                       else
+                           -- Else both multiple, use normal compare:
+                           return Left.Paragraph (1..Left.Paragraph_Len) < 
Right.Paragraph (1..Right.Paragraph_Len);
+                       end if;
+                   end if;
+               else -- Left.Clause_Number > Right.Clause_Number
+                   return False;
+               end if;
+           end "<";
+
+           --procedure Final_Sort_Slice (Left, Right : in Natural) is
+           --  -- Use an insertion sort to sort the slice between Left and 
Right.
+           --    Working_Left : Natural;  -- Working Left sorting stop
+           --  Temp : Term_Ptr;
+           --begin
+           --    for Working_Right In Left+1 .. Right loop -- Right sorting 
stop
+           --      Temp := Items(Working_Right);
+           --      Working_Left := Working_Right - 1;
+           --      while Temp < Items(Working_Left) loop -- Switch items
+           --          Items(Working_Left + 1) := Items(Working_Left);
+           --          Working_Left := Working_Left - 1;
+           --          exit when Working_Left = 0;
+           --      end loop;
+           --        Items(Working_Left + 1) := Temp;
+           --    end loop;
+           --end Final_Sort_Slice;
+
+
+           procedure Partition_Sort_Slice (Start_Index, End_Index : Natural) is
+               -- Use quicksort partition sort to sort the slice between
+               -- Start_Index and End_Index.
+               Temp_Item : Term_Ptr;
+           begin
+               case ((End_Index - Start_Index) + 1) is
+                   when 0 | 1 => null; -- A single element is obviously sorted 
(trivially).
+                   when 2 =>
+                       -- Unrolled Insertion Sort.
+                       if Items(Start_Index+1) < Items(Start_Index) then
+                           -- Move the record down.
+                           Temp_Item := Items(Start_Index+1);
+                           Items(Start_Index+1) := Items(Start_Index  );
+                           Items(Start_Index  ) := Temp_Item; -- Put at 
beginning.
+                       -- else Doesn't need to move.
+                       end if;
+                   when 3 =>
+                       -- Unrolled Insertion Sort.
+                       if Items(Start_Index+1) < Items(Start_Index) then
+                           -- Move the record down.
+                           Temp_Item := Items(Start_Index+1);
+                           Items(Start_Index+1) := Items(Start_Index  );
+                           Items(Start_Index  ) := Temp_Item; -- Put at 
beginning.
+                       -- else Doesn't need to move.
+                       end if;
+                       if Items(Start_Index+2) < Items(Start_Index+1) then
+                           -- Move the record down.
+                           Temp_Item := Items(Start_Index+2);
+                           Items(Start_Index+2) := Items(Start_Index+1);
+                           if Temp_Item < Items(Start_Index) then
+                               -- Move the record down.
+                               Items(Start_Index+1) := Items(Start_Index);
+                               Items(Start_Index) := Temp_Item; -- Put at 
beginning.
+                           else
+                               -- Put the record here.
+                               Items(Start_Index+1) := Temp_Item;
+                           end if;
+                       -- else Doesn't need to move.
+                       end if;
+                   when 4 =>
+                       -- Unrolled Insertion Sort.
+                       if Items(Start_Index+1) < Items(Start_Index) then
+                           -- Move the record down.
+                           Temp_Item := Items(Start_Index+1);
+                           Items(Start_Index+1) := Items(Start_Index  );
+                           Items(Start_Index  ) := Temp_Item; -- Put at 
beginning.
+                       -- else Doesn't need to move.
+                       end if;
+                       if Items(Start_Index+2) < Items(Start_Index+1) then
+                           -- Move the record down.
+                           Temp_Item := Items(Start_Index+2);
+                           Items(Start_Index+2) := Items(Start_Index+1);
+                           if Temp_Item < Items(Start_Index) then
+                               -- Move the record down.
+                               Items(Start_Index+1) := Items(Start_Index);
+                               Items(Start_Index) := Temp_Item; -- Put at 
beginning.
+                           else
+                               -- Put the record here.
+                               Items(Start_Index+1) := Temp_Item;
+                           end if;
+                       -- else Doesn't need to move.
+                       end if;
+                       if Items(Start_Index+3) < Items(Start_Index+2) then
+                           -- Move the record down.
+                           Temp_Item := Items(Start_Index+3);
+                           Items(Start_Index+3) := Items(Start_Index+2);
+                           if Temp_Item < Items(Start_Index+1) then
+                               -- Move the record down.
+                               Items(Start_Index+2) := Items(Start_Index+1);
+                               if Temp_Item < Items(Start_Index) then
+                                   -- Move the record down.
+                                   Items(Start_Index+1) := Items(Start_Index);
+                                   Items(Start_Index) := Temp_Item; -- Put at 
beginning.
+                               else -- Put the record here.
+                                   Items(Start_Index+1) := Temp_Item;
+                               end if;
+                           else
+                               -- Put the record here.
+                               Items(Start_Index+2) := Temp_Item;
+                           end if;
+                       -- else Don't move the record.
+                       end if;
+                   when others => -- Longer partitions, quicksort.
+                       declare
+                           Left_Index, Right_Index : Natural;
+                           Pivot_Item : Term_Ptr;
+                       begin
+                           -- Split into partitions, and sort them.
+                           Left_Index := Start_Index;
+                           Right_Index := End_Index;
+                           -- Use the middle element for the pivot, in case 
the items are
+                           -- somewhat sorted.
+                           Pivot_Item := Items ((End_Index - Start_Index) / 2 
+ Start_Index);
+                           loop
+                               loop
+                                   exit when not (Items(Left_Index) < 
Pivot_Item); -- >=
+                                   Left_Index := Left_Index + 1;
+                               end loop;
+                               loop
+                                   exit when not (Pivot_Item < 
Items(Right_Index));
+                                   Right_Index := Right_Index - 1;
+                               end loop;
+                               if Left_Index <= Right_Index then
+                                   if Left_Index < Right_Index then
+                                       Temp_Item := Items(Left_Index);
+                                       Items(Left_Index) := Items(Right_Index);
+                                       Items(Right_Index) := Temp_Item;
+                                   end if;
+                                   Left_Index  := Left_Index + 1;
+                                   Right_Index := Right_Index - 1;
+                               end if;
+                               exit when Left_Index > Right_Index;
+                           end loop; -- Repeat Loop
+                           -- Recursive calls on partitions.
+                           Partition_Sort_Slice (Left_Index, End_Index);
+                           Partition_Sort_Slice (Start_Index, Right_Index);
+                       end;
+               end case;
+           end Partition_Sort_Slice;
+
+       begin
+-- Debug: (This should only print Kinds that have no clause number).
+--for Idx in Items'range loop
+--    if Arm_Contents."=" (Items(Idx).Clause_Number.Section, 
Arm_Contents.UNKNOWN) then
+--        Ada.Text_IO.Put_Line ("For index item" & Natural'Image(Idx) &
+--            " Clause.Section=" & 
Arm_Contents.Section_Number_Type'Image(Items(Idx).Clause_Number.Section) &
+--         " Kind=" & Index_Item_Kind_Type'Image(Items(Idx).Kind));
+--    -- else OK.
+--    end if;
+--end loop;
+
+           -- Use quicksort to handle most of the array, then
+           -- insertion sort for the final slices.
+           Partition_Sort_Slice (Items'First, Items'Last);
+       end;
+
+        -- Relink the items in the sorted order:
+        for I in Items'First .. Items'Last - 1 loop
+           Items(I).Next := Items(I+1);
+        end loop;
+        if Items'Length > 0 then
+           Items(Items'Last).Next := null;
+           Index_List := Items(1);
+        else
+           Index_List := null;
+        end if;
+
+       Ada.Text_IO.Put_Line ("  -- Finish index sorting - " & Duration'Image (
+           Ada.Calendar."-" (Ada.Calendar.Clock, Start)) & " secs.");
+
+       ARM_Output.Start_Paragraph (Output_Object, ARM_Output.Index, Indent => 
0,
+                                   Number => "", No_Breaks => True);
+       Keep_Set := False;
+
+       Temp := Index_List;
+       while Temp /= null loop
+           -- First, check if we've changed to a new group:
+           if (Last /= null and then
+               To_Lower (Last.Term(1)) /= To_Lower(Temp.Term(1))) or else
+               (Last = null and then To_Lower(Temp.Term(1)) in 'a' .. 'z') then
+               -- The first character has changed, or this is the first item.
+               -- We only generate letters, so we try not to come here for
+               -- non-letters.
+               ARM_Output.End_Paragraph (Output_Object);
+               ARM_Output.Start_Paragraph (Output_Object, ARM_Output.Index,
+                                           Indent => 0, Number => "");
+               Keep_Set := False;
+               if To_Lower(Temp.Term(1)) in 'a' .. 'z' then
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => False);
+                   ARM_Output.Text_Format (Output_Object,
+                          Format => (Bold => True, Italic => False,
+                                     Font => ARM_Output.Default,
+                                     Size => 2, Color => ARM_Output.Default,
+                                     Change => ARM_Output.None,
+                                     Version | Added_Version => '0',
+                                     Location => ARM_Output.Normal));
+                   ARM_Output.Ordinary_Character (Output_Object,
+                       Ada.Characters.Handling.To_Upper(Temp.Term(1)));
+                   ARM_Output.Text_Format (Output_Object,
+                          Format => (Bold => False, Italic => False,
+                                     Font => ARM_Output.Default,
+                                     Size => 0, Color => ARM_Output.Default,
+                                     Change => ARM_Output.None,
+                                     Version | Added_Version => '0',
+                                     Location => ARM_Output.Normal));
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => False);
+               else
+                   ARM_Output.Hard_Space (Output_Object);
+                       -- So the paragraph isn't empty (which causes it to be
+                       -- ignored in HTML).
+               end if;
+           end if;
+
+           if Last = null or else
+               To_Lower(Last.Term (1..Last.Term_Len)) /= To_Lower(Temp.Term 
(1..Temp.Term_Len)) then
+               -- New term: (Note that we ignore case differences here. Perhaps
+               -- there ought to be a warning?)
+               if Last /= null then
+                   ARM_Output.End_Paragraph (Output_Object);
+                   if Temp.Kind = Primary_Term then
+                       ARM_Output.Start_Paragraph (Output_Object, 
ARM_Output.Index,
+                                                   Indent => 0, Number => "",
+                                                   No_Breaks => True);
+                       Keep_Set := False;
+                   else -- The item has at least two lines; keep them together.
+                       ARM_Output.Start_Paragraph (Output_Object, 
ARM_Output.Index,
+                                                   Indent => 0, Number => "",
+                                                   No_Breaks => True, 
Keep_with_Next => True);
+                       Keep_Set := True;
+                   end if;
+               end if;
+               if Temp.Kind /= Subtype_Declaration_in_Package then
+                   Term_Text (Temp.Term (1..Temp.Term_Len));
+               else
+                   declare
+                       Of_Loc : Natural :=
+                           Ada.Strings.Fixed.Index (Temp.Term 
(1..Temp.Term_Len),
+                               " subtype of ");
+                   begin
+                       if Of_Loc = 0 then
+                           -- Weird, "subtype of" not found.
+                           Term_Text (Temp.Term (1..Temp.Term_Len));
+                       else
+                           Term_Text (Temp.Term (1 .. Of_Loc));
+                           Italic_Text ("subtype of");
+                           Term_Text (Temp.Term (Of_Loc+11 .. Temp.Term_Len));
+                       end if;
+                   end;
+               end if;
+               if Temp.Kind = Primary_Term then
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Temp);
+               else
+                   if Is_Last_for_Term(Temp) then
+                       -- Last (only) item of this term, always clear Keep:
+                       New_Kind (Temp, Reset_Keep => True);
+                       Keep_Set := False;
+                   else -- Leave keep set:
+                       New_Kind (Temp, Reset_Keep => False);
+                   end if;
+               end if;
+           elsif Last.Kind /= Temp.Kind then
+               New_Kind (Temp, Reset_Keep => Keep_Set);
+               Keep_Set := False;
+           elsif (Temp.Kind = Primary_Term_and_Subterm or else
+                  Temp.Kind = Partial_Term_with_Subterm or else
+                  Temp.Kind = Syntax_NT_Used or else
+                  Temp.Kind = Child_Unit_Parent or else
+                  Temp.Kind = Declaration_in_Package or else
+                  Temp.Kind = SubDeclaration_in_Package or else
+                  Temp.Kind = Subtype_Declaration_in_Package) and then
+               Last.Subterm (1..Last.Subterm_Len) /= Temp.Subterm 
(1..Temp.Subterm_Len) then
+               New_Kind (Temp, Reset_Keep => Keep_Set);
+               Keep_Set := False;
+           elsif (Temp.Kind = See_Other_Term or else
+                  Temp.Kind = See_Also_Other_Term) then
+               -- Just add the next reference.
+               ARM_Output.Ordinary_Character (Output_Object, ',');
+               ARM_Output.Ordinary_Character (Output_Object, ' ');
+               ARM_Output.Ordinary_Text (Output_Object,
+                   Temp.Subterm (1..Temp.Subterm_Len));
+               -- No clause references here.
+           elsif (Temp.Kind = See_Term or else
+                  Temp.Kind = See_Also_Term) then
+               -- Just add the next reference. We'll just use New_Kind for
+               -- this, so we don't get the formats slightly different.
+               New_Kind (Temp, Reset_Keep => Keep_Set);
+               Keep_Set := False;
+           elsif Last.Clause (1..Last.Clause_Len) = Temp.Clause 
(1..Temp.Clause_Len) and then
+                 Last.Paragraph (1..Last.Paragraph_Len) = Temp.Paragraph 
(1..Temp.Paragraph_Len) then
+               -- The reference and everything else is the same, so just
+               -- forget this item.
+               null;
+           else
+               -- Just add the next clause.
+               ARM_Output.Ordinary_Character (Output_Object, ',');
+               ARM_Output.Ordinary_Character (Output_Object, ' ');
+               Clause_Ref (Temp);
+           end if;
+           Last := Temp;
+           Temp := Temp.Next;
+       end loop;
+
+       ARM_Output.End_Paragraph (Output_Object);
+
+    end Generate_Index_Body;
+
+end ARM_Index;
diff --git a/packages/ada-ref-man/progs/arm_indx.ads 
b/packages/ada-ref-man/progs/arm_indx.ads
new file mode 100755
index 0000000..65ef0b5
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_indx.ads
@@ -0,0 +1,110 @@
+with ARM_Output;
+package ARM_Index is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the routines to manage and generate the index.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2005, 2006, 2011
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/28/00 - RLB - Created package.
+    --  8/11/00 - RLB - Made Clean visible.
+    -- 10/28/05 - RLB - Added key reuse.
+    -- 10/30/05 - RLB - Added subtype declaration.
+    --  2/17/06 - RLB - Added Remove_Soft_Hyphens flag to Clean (for output).
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+
+    Not_Valid_Error : exception;
+
+    subtype Index_Key is Natural range 0 .. 20000;
+
+    procedure Create;
+       -- Initialize this package.
+
+    procedure Destroy;
+       -- Finalize this package; make sure the index is empty.
+
+    type Index_Item_Kind_Type is (
+       Primary_Term,                   -- A primary index term.
+       Partial_Term,                   -- A partial index term.
+       Primary_Term_and_Subterm,       -- A primary index term with a subterm.
+       Partial_Term_with_Subterm,      -- A partial index term with a subterm.
+       Syntax_NT_Used,                 -- A non-terminal, with a subterm of 
"Used".
+       Child_Unit_Parent,              -- A child unit, with a subterm of 
"child of <subterm>".
+       Declaration_in_Package,         -- A declaration, with a subterm of "in 
<package>".
+       SubDeclaration_in_Package,      -- A term, with a subterm of "<item> in 
<package>".
+       Subtype_Declaration_in_Package, -- A term (of the form "<item> subtype 
of <item2>, with a subterm of "in <package>".
+       See_Term,                       -- A "see <subterm>" with reference.
+       See_Also_Term,                  -- A "see also <subterm>" with 
reference.
+       See_Other_Term,                 -- A "see <subterm>" without reference.
+       See_Also_Other_Term);           -- A "see also <subterm>" without 
reference.
+       -- Note: These are declared in the sorting order.
+
+    function Get_Key return Index_Key;
+       -- Returns a Key value to refer to one or more index entries
+       -- (for a single entity).
+
+    procedure Add (Term  : in String;
+                  Subterm : in String := "";
+                  Kind : in Index_Item_Kind_Type := Primary_Term;
+                  Clause : in String := "";
+                  Paragraph : in String := "";
+                   Key : out Index_Key);
+       -- Add an index reference to the index. Returns a Key value to
+       -- refer to this index entry.
+       -- Raises Not_Valid_Error if Subterm, Clause, or Paragraph is not
+       -- empty when the kind does not use it.
+
+    procedure Add_Reusing_Key (Term  : in String;
+                              Subterm : in String := "";
+                              Kind : in Index_Item_Kind_Type := Primary_Term;
+                              Clause : in String := "";
+                              Paragraph : in String := "";
+                              Key : in Index_Key);
+       -- Add an index reference to the index, (re)using the specified Key
+       -- to refer to this index entry. Key must have previously
+       -- returned by Add or Get_Key.
+       -- Raises Not_Valid_Error if Subterm, Clause, or Paragraph is not
+       -- empty when the kind does not use it.
+
+    function Clean (Item : in String;
+                   Remove_Soft_Hyphens : in Boolean) return String;
+       -- Remove any commands from Item. (Except for soft hyphens
+       -- if Remove_Soft_Hyphens is False.)
+
+    procedure Generate_Index_Body (Output_Object : in out 
ARM_Output.Output_Type'Class;
+                                  Use_Paragraphs : in Boolean := True);
+       -- Generate the index body. (The section header has already been
+       -- generated). References include paragraph numbers if Use_Paragraphs
+       -- is true.
+
+end ARM_Index;
diff --git a/packages/ada-ref-man/progs/arm_inp.adb 
b/packages/ada-ref-man/progs/arm_inp.adb
new file mode 100755
index 0000000..c7990f1
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_inp.adb
@@ -0,0 +1,444 @@
+with Ada.Text_IO,
+     Ada.Characters.Handling,
+     Ada.Strings.Fixed;
+package body ARM_Input is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the abstract definition of reading an input file
+    -- or other entity, and routines to lex the input entities.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2004, 2005, 2011, 2013
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/15/00 - RLB - Created base package.
+    --  5/16/00 - RLB - Added `' as a open/close pairing.
+    --  7/18/02 - RLB - Added Check_One_of_Parameter_Names.
+    -- 12/06/04 - RLB - Expanded Check_One_of_Parameter_Names to take up to
+    --                 five names.
+    --  1/26/05 - RLB - Fixed so that quoted parameters can be skipped.
+    --  8/16/11 - RLB - Added code so that looping operations stop when
+    --                 the input is empty. (Otherwise, bad comments cause
+    --                 an infinite loop.)
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    --  3/26/13 - RLB - Added %% as a bracket pairing, so the Google
+    --                 Analytics snippett can be inserted.
+
+    function Is_Open_Char (Open_Char : in Character) return Boolean is
+       -- Return True if character is a parameter opening character
+       --    ('<', '[', '{', '(', '`'), and False otherwise.
+    begin
+       case Open_Char is
+           when '<' | '[' | '{' | '(' | '`' | '%' => return True;
+           when others => return False;
+       end case;
+    end Is_Open_Char;
+
+
+    function Get_Close_Char (Open_Char : in Character) return Character is
+       -- Return the parameter closing character for an opening character.
+       -- Raises Not_Valid_Error if Open_Char is not an opening character
+       --    ('<', '[', '{', '(', '`').
+    begin
+       case Open_Char is
+           when '<' => return '>';
+           when '[' => return ']';
+           when '{' => return '}';
+           when '(' => return ')';
+           when '`' => return ''';
+           when '%' => return '%';
+           when others =>
+               Ada.Text_IO.Put_Line ("** Not an Open_Char - " & Open_Char);
+               raise ARM_Input.Not_Valid_Error;
+       end case;
+    end Get_Close_Char;
+
+
+    function Get_Open_Char (Close_Char : in Character) return Character is
+       -- Return the parameter opening character for an closing character.
+       -- Raises Not_Valid_Error if Open_Char is not an closing character
+       --    ('>', ']', '}', ')', ''').
+    begin
+       case Close_Char is
+           when '>' => return '<';
+           when ']' => return '[';
+           when '}' => return '{';
+           when ')' => return '(';
+           when ''' => return '`';
+           when '%' => return '%';
+           when others =>
+               Ada.Text_IO.Put_Line ("** Not a Close_Char - " & Close_Char);
+               raise ARM_Input.Not_Valid_Error;
+       end case;
+    end Get_Open_Char;
+
+
+    procedure Get_Name (Input_Object : in out Input_Type'Class;
+                       Name : out ARM_Input.Command_Name_Type;
+                       Null_Name_Allowed : in Boolean := False) is
+        -- Get a name from the Input_Object. "Names" are sequences of
+        -- alphanumeric characters. If Null_Name_Allowed is False,
+        -- an error is produced if no name is found.
+        Ch : Character;
+        Len : Natural := 0;
+    begin
+        Name := (others => ' ');
+        loop
+           Get_Char (Input_Object, Ch);
+           if Ada.Characters.Handling.Is_Alphanumeric (Ch) then
+               Len := Len + 1;
+               Name(Len) := Ch;
+           else -- End of the name.
+               Replace_Char (Input_Object);
+               if Len = 0 and then (not Null_Name_Allowed) then
+                   Ada.Text_IO.Put_Line ("  ** Failed to find command name on 
line " & Line_String (Input_Object));
+               end if;
+               return;
+           end if;
+        end loop;
+    end Get_Name;
+
+
+    procedure Copy_to_String_until_Close_Char
+            (Input_Object : in out Input_Type'Class;
+             Close_Char : in Character;
+             Buffer : out String;
+             Len : out Natural) is
+        -- Copy text from Input_Object to Buffer until the matching
+        -- Close_Char is found. Len is the number of characters copied.
+        -- Use this when we only need a string; use recording when we
+        -- need the string *and* we still must process the type.
+        -- Note that we watch for matching opening characters, in
+        -- case a nested command uses one.
+        Ch : Character;
+       Start_Ch : Character;
+        Start_Ch_Count : Natural := 0;
+    begin
+       if Close_Char = '"' then
+           Start_Ch := Character'Val(128);
+           -- This character shouldn't occur in input text.
+           -- Buglet: We don't have a way to tell whether this is an inner
+           -- command or just the end; best to avoid nesting of
+           -- quoted parameters.
+       elsif Close_Char = '%' then
+           Start_Ch := Character'Val(129);
+           -- This character shouldn't occur in input text.
+           -- Buglet: We don't have a way to tell whether this is an inner
+           -- command or just the end; best to avoid nesting of
+           -- quoted parameters.
+       else
+           Start_Ch := ARM_Input.Get_Open_Char (Close_Char);
+       end if;
+        ARM_Input.Get_Char (Input_Object, Ch);
+        Len := 0;
+        loop
+           if Ch = Start_Ch then
+               -- In case an inner command uses the same
+               -- start/end character.
+               Start_Ch_Count := Start_Ch_Count + 1;
+           elsif Ch = Close_Char then
+               exit when Start_Ch_Count = 0;
+               Start_Ch_Count := Start_Ch_Count - 1;
+           elsif Ch = Ascii.SUB then -- End of file, quit immediately.
+               Ada.Text_IO.Put_Line ("  ** End of file when recording string 
on line " &
+                       ARM_Input.Line_String (Input_Object));
+               exit;
+           end if;
+           if Len >= Buffer'Length then
+               Ada.Text_IO.Put_Line ("  ** String buffer overflow on line " &
+                       ARM_Input.Line_String (Input_Object));
+----Debug:
+--raise Program_Error; -- Where the heck are we??
+           else
+               Buffer (Buffer'First + Len) := Ch;
+                Len := Len + 1;
+           end if;
+           ARM_Input.Get_Char (Input_Object, Ch);
+        end loop;
+    end Copy_to_String_until_Close_Char;
+
+
+    procedure Skip_until_Close_Char
+            (Input_Object : in out Input_Type'Class;
+             Close_Char : in Character) is
+        -- Skip text from Input_Object until the matching Close_Char is found.
+        -- Note that we watch for matching opening characters, in
+        -- case a nested command uses one.
+        Ch : Character;
+        Start_Ch : Character;
+        Start_Ch_Count : Natural := 0;
+       Start_Line : constant String := ARM_Input.Line_String (Input_Object);
+           -- Save this in case of severe error.
+    begin
+       if Close_Char = '"' then
+           Start_Ch := Character'Val(128);
+           -- This character shouldn't occur in input text.
+           -- Buglet: We don't have a way to tell whether this is an inner
+           -- command or just the end; best to avoid nesting of
+           -- quoted parameters.
+       else
+           Start_Ch := ARM_Input.Get_Open_Char (Close_Char);
+       end if;
+--Ada.Text_IO.Put_Line ("?? Skip: Start=" & Start_Ch & "; Close=" & Close_Char 
& " on line " &
+--   ARM_Input.Line_String (Input_Object));
+        ARM_Input.Get_Char (Input_Object, Ch);
+        loop
+           if Ch = Start_Ch then
+               -- In case an inner command uses the same
+               -- start/end character.
+               Start_Ch_Count := Start_Ch_Count + 1;
+--Ada.Text_IO.Put_Line ("?? Skip: Start found, cnt=" & 
Natural'Image(Start_Ch_Count) & " on line " &
+--   ARM_Input.Line_String (Input_Object));
+           elsif Ch = Close_Char then
+--if Start_Ch_Count = 0 then
+--Ada.Text_IO.Put_Line ("?? Skip: Close found on line " &
+--   ARM_Input.Line_String (Input_Object));
+--end if;
+               exit when Start_Ch_Count = 0;
+               Start_Ch_Count := Start_Ch_Count - 1;
+--Ada.Text_IO.Put_Line ("?? Skip: Close found, cnt=" & 
Natural'Image(Start_Ch_Count) & " on line " &
+--   ARM_Input.Line_String (Input_Object));
+           elsif Ch = Ascii.SUB then -- End of file, quit immediately.
+               Ada.Text_IO.Put_Line ("  ** End of file when skipping to end, 
started on line " &
+                       Start_Line);
+               exit;
+           end if;
+           -- Ignore everything until the end character
+           -- turns up (or the end of file).
+           ARM_Input.Get_Char (Input_Object, Ch);
+        end loop;
+    end Skip_until_Close_Char;
+
+
+    procedure Check_Parameter_Name (Input_Object : in out Input_Type'Class;
+                                   Param_Name : in ARM_Input.Command_Name_Type;
+                                   Is_First : in Boolean;
+                                   Param_Close_Bracket : out Character) is
+        -- Check that the name of a parameter (if any) is Param_Name.
+        -- This is the first parameter is Is_First is True; otherwise
+        -- it is a later parameter. (For a later parameter, we'll skip
+        -- the comma and any whitespace.)
+        -- If the parameter has an argument, the opening character will
+        -- be read, and the closing character will be returned in
+        -- in Param_Close_Bracket. If the parameter wasn't found, an
+        -- error message will be produced, and Param_Close_Bracket will
+        -- be set to ' '.
+        Our_Param_Name : ARM_Input.Command_Name_Type;
+        Ch : Character;
+    begin
+        if not Is_First then
+           -- Skip over the comma and any whitespace:
+           ARM_Input.Get_Char (Input_Object, Ch);
+           if Ch /= ',' then
+               Ada.Text_IO.Put_Line ("  ** Bad parameter separator for " &
+                           Ada.Strings.Fixed.Trim (Param_Name, 
Ada.Strings.Right) &
+                           ": " & Ch & " on line " & ARM_Input.Line_String 
(Input_Object));
+           else
+               ARM_Input.Get_Char (Input_Object, Ch);
+           end if;
+           while (Ch = ' ' or else Ch = Ascii.LF) loop
+               ARM_Input.Get_Char (Input_Object, Ch);
+           end loop;
+           ARM_Input.Replace_Char (Input_Object);
+        -- else nothing to clean up.
+        end if;
+        Arm_Input.Get_Name (Input_Object, Our_Param_Name, Null_Name_Allowed => 
True);
+        if Ada.Characters.Handling.To_Lower (Param_Name) =
+          Ada.Characters.Handling.To_Lower (Our_Param_Name) then
+           ARM_Input.Get_Char (Input_Object, Ch);
+           if Ch /= '=' then
+               Ada.Text_IO.Put_Line ("  ** Bad parameter character for " &
+                   Ada.Strings.Fixed.Trim(Our_Param_Name, Ada.Strings.Right) &
+                   " parameter: " & Ch & " on line " & ARM_Input.Line_String 
(Input_Object));
+           end if;
+        elsif Ada.Strings.Fixed.Trim (Param_Name, Ada.Strings.Right) = "" then
+           null; -- No parameter name.
+        else
+           Ada.Text_IO.Put_Line ("  ** Bad parameter name: " & 
Ada.Strings.Fixed.Trim (Our_Param_Name, Ada.Strings.Right) &
+                                 ", " & Ada.Strings.Fixed.Trim (Param_Name, 
Ada.Strings.Right) & " expected on line " &
+                                 ARM_Input.Line_String (Input_Object));
+        end if;
+        -- Now, open the parameter section:
+        ARM_Input.Get_Char (Input_Object, Ch);
+        if ARM_Input.Is_Open_Char (Ch) then -- Start parameter:
+           Param_Close_Bracket := ARM_Input.Get_Close_Char (Ch);
+        elsif Ch = '"' then -- Start quoted parameter:
+           Param_Close_Bracket := '"';
+        else -- No parameter. Weird.
+           ARM_Input.Replace_Char (Input_Object);
+           Ada.Text_IO.Put_Line ("  ** Failed to find parameter text for " &
+                                 Ada.Strings.Fixed.Trim (Our_Param_Name, 
Ada.Strings.Right) &
+                                 ", line " & ARM_Input.Line_String 
(Input_Object));
+           Param_Close_Bracket := ' ';
+        end if;
+    end Check_Parameter_Name;
+
+
+    procedure Check_One_of_Parameter_Names (
+               Input_Object : in out Input_Type'Class;
+               Param_Name_1 : in ARM_Input.Command_Name_Type;
+               Param_Name_2 : in ARM_Input.Command_Name_Type;
+               Param_Name_3 : in ARM_Input.Command_Name_Type := (others => ' 
');
+               Param_Name_4 : in ARM_Input.Command_Name_Type := (others => ' 
');
+               Param_Name_5 : in ARM_Input.Command_Name_Type := (others => ' 
');
+               Is_First : in Boolean;
+               Param_Close_Bracket : out Character;
+               Param_Found : out Param_Num) is
+        -- Check that the name of a parameter (if any) is one of the given
+       -- names. If the parameter is set to all blanks, it is not used.
+       -- This is the first parameter is Is_First is True;
+       -- otherwise it is a later parameter. (For a later parameter, we'll
+       -- skip the comma and any whitespace.)
+       -- Param_Found will be set to the number of the parameter that was
+       -- found.
+        -- If the parameter has an argument, the opening character will
+        -- be read, and the closing character will be returned in
+        -- in Param_Close_Bracket. If the parameter wasn't found, an
+        -- error message will be produced, Param_Close_Bracket will
+        -- be set to ' ', and Param_Found will be set to 0.
+        Our_Param_Name : ARM_Input.Command_Name_Type;
+        Ch : Character;
+    begin
+        if not Is_First then
+           -- Skip over the comma and any whitespace:
+           ARM_Input.Get_Char (Input_Object, Ch);
+           if Ch /= ',' then
+               Ada.Text_IO.Put_Line ("  ** Bad parameter separator for " &
+                           Ada.Strings.Fixed.Trim (Param_Name_1, 
Ada.Strings.Right) & " or " &
+                           Ada.Strings.Fixed.Trim (Param_Name_2, 
Ada.Strings.Right) &
+                           ": " & Ch & " on line " & ARM_Input.Line_String 
(Input_Object));
+           else
+               ARM_Input.Get_Char (Input_Object, Ch);
+           end if;
+           while (Ch = ' ' or else Ch = Ascii.LF) loop
+               ARM_Input.Get_Char (Input_Object, Ch);
+           end loop;
+           ARM_Input.Replace_Char (Input_Object);
+        -- else nothing to clean up.
+        end if;
+        Arm_Input.Get_Name (Input_Object, Our_Param_Name, Null_Name_Allowed => 
True);
+        if Param_Name_1 /= ARM_Input.Command_Name_Type'(others => ' ') and then
+          Ada.Characters.Handling.To_Lower (Param_Name_1) =
+            Ada.Characters.Handling.To_Lower (Our_Param_Name) then
+           ARM_Input.Get_Char (Input_Object, Ch);
+           if Ch /= '=' then
+               Ada.Text_IO.Put_Line ("  ** Bad parameter character for " &
+                   Ada.Strings.Fixed.Trim(Our_Param_Name, Ada.Strings.Right) &
+                   " parameter: " & Ch & " on line " & ARM_Input.Line_String 
(Input_Object));
+           end if;
+           Param_Found := 1;
+        elsif Param_Name_2 /= ARM_Input.Command_Name_Type'(others => ' ') and 
then
+          Ada.Characters.Handling.To_Lower (Param_Name_2) =
+            Ada.Characters.Handling.To_Lower (Our_Param_Name) then
+           ARM_Input.Get_Char (Input_Object, Ch);
+           if Ch /= '=' then
+               Ada.Text_IO.Put_Line ("  ** Bad parameter character for " &
+                   Ada.Strings.Fixed.Trim(Our_Param_Name, Ada.Strings.Right) &
+                   " parameter: " & Ch & " on line " & ARM_Input.Line_String 
(Input_Object));
+           end if;
+           Param_Found := 2;
+        elsif Param_Name_3 /= ARM_Input.Command_Name_Type'(others => ' ') and 
then
+          Ada.Characters.Handling.To_Lower (Param_Name_3) =
+            Ada.Characters.Handling.To_Lower (Our_Param_Name) then
+           ARM_Input.Get_Char (Input_Object, Ch);
+           if Ch /= '=' then
+               Ada.Text_IO.Put_Line ("  ** Bad parameter character for " &
+                   Ada.Strings.Fixed.Trim(Our_Param_Name, Ada.Strings.Right) &
+                   " parameter: " & Ch & " on line " & ARM_Input.Line_String 
(Input_Object));
+           end if;
+           Param_Found := 3;
+        elsif Param_Name_4 /= ARM_Input.Command_Name_Type'(others => ' ') and 
then
+          Ada.Characters.Handling.To_Lower (Param_Name_4) =
+            Ada.Characters.Handling.To_Lower (Our_Param_Name) then
+           ARM_Input.Get_Char (Input_Object, Ch);
+           if Ch /= '=' then
+               Ada.Text_IO.Put_Line ("  ** Bad parameter character for " &
+                   Ada.Strings.Fixed.Trim(Our_Param_Name, Ada.Strings.Right) &
+                   " parameter: " & Ch & " on line " & ARM_Input.Line_String 
(Input_Object));
+           end if;
+           Param_Found := 4;
+        elsif Param_Name_5 /= ARM_Input.Command_Name_Type'(others => ' ') and 
then
+          Ada.Characters.Handling.To_Lower (Param_Name_5) =
+            Ada.Characters.Handling.To_Lower (Our_Param_Name) then
+           ARM_Input.Get_Char (Input_Object, Ch);
+           if Ch /= '=' then
+               Ada.Text_IO.Put_Line ("  ** Bad parameter character for " &
+                   Ada.Strings.Fixed.Trim(Our_Param_Name, Ada.Strings.Right) &
+                   " parameter: " & Ch & " on line " & ARM_Input.Line_String 
(Input_Object));
+           end if;
+           Param_Found := 5;
+        else
+            if Param_Name_5 /= ARM_Input.Command_Name_Type'(others => ' ') then
+               Ada.Text_IO.Put_Line ("  ** Bad parameter name: " & 
Ada.Strings.Fixed.Trim (Our_Param_Name, Ada.Strings.Right) &
+                                     "; but " & Ada.Strings.Fixed.Trim 
(Param_Name_1, Ada.Strings.Right) & ", " &
+                                     Ada.Strings.Fixed.Trim (Param_Name_2, 
Ada.Strings.Right) & ", " &
+                                     Ada.Strings.Fixed.Trim (Param_Name_3, 
Ada.Strings.Right) & ", " &
+                                     Ada.Strings.Fixed.Trim (Param_Name_4, 
Ada.Strings.Right) & ", or " &
+                                     Ada.Strings.Fixed.Trim (Param_Name_5, 
Ada.Strings.Right) & " expected on line " &
+                                     ARM_Input.Line_String (Input_Object));
+            elsif Param_Name_4 /= ARM_Input.Command_Name_Type'(others => ' ') 
then
+               Ada.Text_IO.Put_Line ("  ** Bad parameter name: " & 
Ada.Strings.Fixed.Trim (Our_Param_Name, Ada.Strings.Right) &
+                                     "; but " & Ada.Strings.Fixed.Trim 
(Param_Name_1, Ada.Strings.Right) & ", " &
+                                     Ada.Strings.Fixed.Trim (Param_Name_2, 
Ada.Strings.Right) & ", " &
+                                     Ada.Strings.Fixed.Trim (Param_Name_3, 
Ada.Strings.Right) & ", or " &
+                                     Ada.Strings.Fixed.Trim (Param_Name_4, 
Ada.Strings.Right) & " expected on line " &
+                                     ARM_Input.Line_String (Input_Object));
+            elsif Param_Name_3 /= ARM_Input.Command_Name_Type'(others => ' ') 
then
+               Ada.Text_IO.Put_Line ("  ** Bad parameter name: " & 
Ada.Strings.Fixed.Trim (Our_Param_Name, Ada.Strings.Right) &
+                                     "; but " & Ada.Strings.Fixed.Trim 
(Param_Name_1, Ada.Strings.Right) & ", " &
+                                     Ada.Strings.Fixed.Trim (Param_Name_2, 
Ada.Strings.Right) & ", or " &
+                                     Ada.Strings.Fixed.Trim (Param_Name_3, 
Ada.Strings.Right) & " expected on line " &
+                                     ARM_Input.Line_String (Input_Object));
+            else
+               Ada.Text_IO.Put_Line ("  ** Bad parameter name: " & 
Ada.Strings.Fixed.Trim (Our_Param_Name, Ada.Strings.Right) &
+                                     "; but " & Ada.Strings.Fixed.Trim 
(Param_Name_1, Ada.Strings.Right) & " or " &
+                                     Ada.Strings.Fixed.Trim (Param_Name_2, 
Ada.Strings.Right) & " expected on line " &
+                                     ARM_Input.Line_String (Input_Object));
+           end if;
+           Param_Found := 0;
+        end if;
+        -- Now, open the parameter section:
+        ARM_Input.Get_Char (Input_Object, Ch);
+        if ARM_Input.Is_Open_Char (Ch) then -- Start parameter:
+           Param_Close_Bracket := ARM_Input.Get_Close_Char (Ch);
+        elsif Ch = '"' then -- Start quoted parameter:
+           Param_Close_Bracket := '"';
+        else -- No parameter. Weird.
+           ARM_Input.Replace_Char (Input_Object);
+           Ada.Text_IO.Put_Line ("  ** Failed to find parameter text for " &
+                                 Ada.Strings.Fixed.Trim (Our_Param_Name, 
Ada.Strings.Right) &
+                                 ", line " & ARM_Input.Line_String 
(Input_Object));
+           Param_Close_Bracket := ' ';
+        end if;
+    end Check_One_of_Parameter_Names;
+
+
+end ARM_Input;
diff --git a/packages/ada-ref-man/progs/arm_inp.ads 
b/packages/ada-ref-man/progs/arm_inp.ads
new file mode 100755
index 0000000..dd12d37
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_inp.ads
@@ -0,0 +1,170 @@
+package ARM_Input is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the abstract definition of reading an input file
+    -- or other entity, and routines to lex the input entities.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2004, 2011
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/15/00 - RLB - Created base package.
+    --  7/18/02 - RLB - Added Check_One_of_Parameter_Names.
+    -- 12/06/04 - RLB - Expanded Check_One_of_Parameter_Names to take up to
+    --                 five names.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+
+    type Input_Type is abstract tagged limited null record;
+
+    MAX_RECORDING_SIZE : constant := 4000;
+
+    Not_Valid_Error : exception; -- The Input_Object is not valid.
+
+    -- procedure Open (Input_Object : in out Input_Type;
+    --                -- Other parameters) is abstract;
+       -- Open an input object for an entity.
+       -- Each concrete type has its own Open routine, with possibly
+       -- different parameters.
+
+    procedure Close (Input_Object : in out Input_Type) is abstract;
+       -- Close the input object (entity).
+       -- May propagate exceptions from the underlying implementation
+       -- (that is, I/O exceptions).
+
+    procedure Get_Char (Input_Object : in out Input_Type;
+                       Char : out Character) is abstract;
+        -- We represent end of line by Ascii.LF, and end of file by
+       -- Ascii.SUB.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+
+    procedure Replace_Char (Input_Object : in out Input_Type) is abstract;
+       -- Replaces the last character read (with Get_Char); the next call
+       -- to Get_Char will return it.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+
+    function Line_String (Input_Object : in Input_Type) return String is 
abstract;
+        -- Returns a string representing the line number and entity.
+       -- Usually used in error messages.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+
+    procedure Start_Recording (Input_Object : in out Input_Type) is abstract;
+        -- Start recording all characters read into a local buffer.
+        -- Use this when text needs to be formatted into the output
+        -- file *and* be saved for future use.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+
+    procedure Stop_Recording_and_Read_Result
+        (Input_Object : in out Input_Type; Result : out String;
+        Len : out Natural) is abstract;
+        -- Stop recording characters read. Put the result into Result,
+        -- and the number of characters written into Len.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+
+    -- Lexical routines:
+
+    subtype Command_Name_Type is String (1 .. 40);
+
+    function Is_Open_Char (Open_Char : in Character) return Boolean;
+       -- Return True if character is a parameter opening character
+       --    ('<', '[', '{', '('), and False otherwise.
+
+    function Get_Close_Char (Open_Char : in Character) return Character;
+       -- Return the parameter closing character for an opening character.
+       -- Raises Not_Valid_Error if Open_Char is not an opening character
+       --    ('<', '[', '{', '(').
+
+    function Get_Open_Char (Close_Char : in Character) return Character;
+       -- Return the parameter opening character for an closing character.
+       -- Raises Not_Valid_Error if Open_Char is not an closing character
+       --    ('>', ']', '}', ')').
+
+
+    procedure Get_Name (Input_Object : in out Input_Type'Class;
+                       Name : out ARM_Input.Command_Name_Type;
+                       Null_Name_Allowed : in Boolean := False);
+        -- Get a name from the Input_Object. "Names" are sequences of
+        -- alphanumeric characters. If Null_Name_Allowed is False,
+        -- an error is produced if no name is found.
+
+    procedure Copy_to_String_until_Close_Char
+            (Input_Object : in out Input_Type'Class;
+             Close_Char : in Character;
+             Buffer : out String;
+             Len : out Natural);
+        -- Copy text from Input_Object to Buffer until the matching
+        -- Close_Char is found. Len is the number of characters copied.
+        -- Use this when we only need a string; use recording when we
+        -- need the string *and* we still must process the type.
+
+    procedure Skip_until_Close_Char
+            (Input_Object : in out Input_Type'Class;
+             Close_Char : in Character);
+        -- Skip text from Input_Object until the matching Close_Char is found.
+
+    procedure Check_Parameter_Name (Input_Object : in out Input_Type'Class;
+                                   Param_Name : in ARM_Input.Command_Name_Type;
+                                   Is_First : in Boolean;
+                                   Param_Close_Bracket : out Character);
+        -- Check that the name of a parameter (if any) is Param_Name.
+        -- This is the first parameter is Is_First is True; otherwise
+        -- it is a later parameter. (For a later parameter, we'll skip
+        -- the comma and any whitespace.)
+        -- If the parameter has an argument, the opening character will
+        -- be read, and the closing character will be returned in
+        -- in Param_Close_Bracket. If the parameter wasn't found, an
+        -- error message will be produced, and Param_Close_Bracket will
+        -- be set to ' '.
+
+    subtype Param_Num is Natural range 0 .. 5;
+    procedure Check_One_of_Parameter_Names (
+               Input_Object : in out Input_Type'Class;
+               Param_Name_1 : in ARM_Input.Command_Name_Type;
+               Param_Name_2 : in ARM_Input.Command_Name_Type;
+               Param_Name_3 : in ARM_Input.Command_Name_Type := (others => ' 
');
+               Param_Name_4 : in ARM_Input.Command_Name_Type := (others => ' 
');
+               Param_Name_5 : in ARM_Input.Command_Name_Type := (others => ' 
');
+               Is_First : in Boolean;
+               Param_Close_Bracket : out Character;
+               Param_Found : out Param_Num);
+        -- Check that the name of a parameter (if any) is one of the given
+       -- names. If the parameter is set to all blanks, it is not used.
+       -- This is the first parameter is Is_First is True;
+       -- otherwise it is a later parameter. (For a later parameter, we'll
+       -- skip the comma and any whitespace.)
+       -- Param_Found will be set to the number of the parameter that was
+       -- found.
+        -- If the parameter has an argument, the opening character will
+        -- be read, and the closing character will be returned in
+        -- in Param_Close_Bracket. If the parameter wasn't found, an
+        -- error message will be produced, Param_Close_Bracket will
+        -- be set to ' ', and Param_Found will be set to 0.
+
+end ARM_Input;
diff --git a/packages/ada-ref-man/progs/arm_mast.adb 
b/packages/ada-ref-man/progs/arm_mast.adb
new file mode 100755
index 0000000..6b74658
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_mast.adb
@@ -0,0 +1,1456 @@
+with Ada.Text_IO,
+     Ada.Characters.Handling,
+     Ada.Strings.Fixed,
+     Ada.Strings.Unbounded;
+with ARM_Input,
+     ARM_File,
+     --ARM_Format, redundant
+     ARM_Output,
+     ARM_Text,
+     ARM_Texinfo,
+     ARM_HTML,
+     ARM_RTF,
+     ARM_Corr;
+     --ARM_Master,
+     --ARM_Contents;
+package body ARM_Master is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the routines to parse the master file, and
+    -- execute it.
+    --
+    -- ---------------------------------------
+    -- Copyright 2006, 2007, 2009, 2011, 2012, 2013, 2016
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  1/05/06 - RLB - Created base package to replace hard-coded main 
program.
+    --  1/11/06 - RLB - Continued expanding this; revised to handle separate
+    --                 creations for the various kinds of output objects.
+    --  1/12/06 - RLB - Added more commands for additional properties.
+    --  1/18/06 - RLB - Added the ExampleFont command.
+    --  1/27/06 - RLB - Added HTMLTabs command.
+    --  2/19/06 - RLB - Set Number_Paragraphs for HTML.
+    --  6/22/06 - RLB - Added LinkNonTerminals command.
+    --  9/21/06 - RLB - Added the Body_Font command.
+    --  9/22/06 - RLB - Added the Note_Format command.
+    --  9/25/06 - RLB - Added the Contents_Format command.
+    -- 10/04/06 - RLB - Added the List_Format command.
+    -- 10/13/06 - RLB - Added specifiable default HTML colors.
+    -- 12/19/07 - RLB - Added MS-DOS file names.
+    --  5/04/09 - RLB - Added the RTFFooter command.
+    --  5/06/09 - RLB - Added the RTFVersionName command.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/19/11 - RLB - Added Texinfo output (from Stephen Leake).
+    --  8/31/12 - RLB - Added Output_Path.
+    -- 11/26/12 - RLB - Added Subdivision_Names.
+    --  3/26/13 - RLB - Added HTMLScript.
+    --  3/17/16 - RLB - Added Base_Change_Version.
+    --  4/20/16 - RLB - Added HTML_New_Revision_Colors.
+
+    type Command_Type is (
+       -- Source commands:
+        Source, TOC,
+       -- Global properties:
+       Show_Index_Entries,
+       Hide_Index_Entries,
+       Show_Annotations,
+       Hide_Annotations,
+       Show_ISO,
+       Hide_ISO,
+       Link_Non_Terminals,
+       Number_Paragraphs,
+       Title,
+       File_Prefix,
+       Example_Font,
+       Body_Font,
+       Note_Format,
+       Contents_Format,
+       List_Format,
+       Subdivision_Names,
+
+       -- HTML properties:
+       Single_HTML_Output_File,
+       Use_MS_DOS_Names,
+       HTML_Kind_Command,
+       HTML_Nav_Bar,
+       HTML_Tabs,
+       HTML_Script,
+       HTML_Header,
+       HTML_Footer,
+       HTML_Color,
+       HTML_New_Revision_Colors,
+       -- RTF properties:
+       Single_RTF_Output_File,
+       RTF_Header_Prefix,
+       RTF_Footer_Text,
+       RTF_Footer,
+       RTF_Page_Size,
+       RTF_Fonts,
+       RTF_Version_Name,
+       -- Other commands:
+       Comment, Unknown);
+
+    type Source_Kind is (A_File, TOC, Empty);
+
+    type Source_Item (Kind : Source_Kind := Empty) is record
+       case Kind is
+           when Empty => null;         -- This item includes no source item.
+            when TOC => null;          -- No info for this, it just holds a
+                                       -- place in the collating order.
+           when A_File =>
+               File_Name          : String(1..80);
+               File_Name_Len      : Natural;
+               Section_Name       : String(1..10);
+               Section_Name_Len   : Natural;
+               Section_Number     : ARM_Contents.Section_Number_Type;
+               Starts_New_Section : Boolean;
+       end case;
+    end record;
+
+    subtype Source_Count is Integer range 0 .. 100;
+    subtype Source_Index is Source_Count range 1 .. Source_Count'Last;
+    Source_Data : array (Source_Index) of Source_Item;
+    Source_Length : Source_Count := 0;
+
+    -- Command line (global) properties:
+    Change_Kind : ARM_Format.Change_Kind; -- Changes to generate.
+    Change_Version : ARM_Contents.Change_Version_Type; -- Change version.
+    Base_Change_Version : ARM_Contents.Change_Version_Type; -- Change version.
+
+    -- Global properties:
+    Display_Index_Entries : Boolean := False; -- Should Index entries be 
displayed?
+    Document_Title : ARM_Contents.Versioned_String; -- Document title.
+    Output_File_Prefix : Ada.Strings.Unbounded.Unbounded_String; -- Output 
file prefix.
+    Include_Annotations : Boolean := False; -- Should annotations be included 
in the output?
+    Include_ISO_Text : Boolean := False; -- Should ISO text be included in the 
output?
+    Should_Link_Non_Terminals : Boolean :=  False; -- Should non-terminals be 
linked?
+    Should_Number_Paragraphs : Boolean := False; -- Should paragraphs be 
numbered?
+    Font_of_Examples : ARM_Output.Font_Family_Type :=
+       ARM_Output.Fixed; -- Which font should be used for examples?
+    Font_of_Body : ARM_Output.Font_Family_Type :=
+       ARM_Output.Roman; -- Which font should be used for the body?
+    Use_ISO_2004_Note_Format : Boolean := True;
+       -- Should we use the ISO 2004 note format, or the one used in the
+       -- Ada 95 standard??
+    Use_ISO_2004_Contents_Format : Boolean := True;
+       -- Should we use the ISO 2004 contents format, or the one used in the
+       -- Ada 95 standard??
+    Use_ISO_2004_List_Format : Boolean := True;
+       -- Should we use the ISO 2004 list format, or the one used in the
+       -- Ada 95 standard??
+    Subdivision_Name_Kind : ARM_Output.Top_Level_Subdivision_Name_Kind :=
+               ARM_Output.Section;
+
+    -- HTML properties:
+    Use_Large_HTML_Files : Boolean := False; -- Use small output files by 
default.
+    Use_MS_DOS_Filenames : Boolean := False; -- Use long file names by default.
+    HTML_Kind : ARM_HTML.HTML_Type := ARM_HTML.HTML_4_Compatible;
+    HTML_Use_Unicode : Boolean := False;
+    HTML_Index_URL : Ada.Strings.Unbounded.Unbounded_String;
+    HTML_Ref_URL : Ada.Strings.Unbounded.Unbounded_String;
+    HTML_Srch_URL : Ada.Strings.Unbounded.Unbounded_String;
+    HTML_Use_Buttons : Boolean := True;
+    HTML_Nav_On_Top : Boolean := True;
+    HTML_Nav_On_Bottom : Boolean := True;
+    HTML_Tab_Emulation : ARM_HTML.Tab_Emulation_Type := 
ARM_HTML.Emulate_Fixed_Only;
+    HTML_Script_Text : Ada.Strings.Unbounded.Unbounded_String; -- Empty by 
default.
+    HTML_Header_Text : Ada.Strings.Unbounded.Unbounded_String; -- Empty by 
default.
+    HTML_Footer_Text : Ada.Strings.Unbounded.Unbounded_String; -- Empty by 
default.
+    HTML_Use_New_Revision_Colors : Boolean := False;
+    HTML_Text_Color : ARM_HTML.Color_String := "#000000";
+    HTML_Background_Color : ARM_HTML.Color_String := "#FFFFF0";
+    HTML_Link_Color : ARM_HTML.Color_String := "#0000FF";
+    HTML_VLink_Color : ARM_HTML.Color_String := "#800080";
+    HTML_ALink_Color : ARM_HTML.Color_String := "#FF0000";
+
+    -- RTF properties:
+    Use_Large_RTF_Files : Boolean := False; -- Use small output files by 
default.
+    Header_Prefix : ARM_Contents.Versioned_String;
+    Footer_Text   : ARM_Contents.Versioned_String;
+    Footer_Use_Date : Boolean := True; -- Use the date by default.
+    Footer_Use_Clause_Name : Boolean := True; -- Use the clause name rather 
than the text above by default.
+    Footer_Use_ISO_Format : Boolean := False; -- Use the normal format.
+    Version_Name  : ARM_Contents.Versioned_String;
+
+    Page_Size : ARM_RTF.Page_Size := ARM_RTF.Letter; -- Use Letter size by 
default.
+    Serif_Font : ARM_RTF.Serif_Fonts := ARM_RTF.Times_New_Roman; -- Use Times 
by default.
+    Sans_Serif_Font : ARM_RTF.Sans_Serif_Fonts := ARM_RTF.Arial; -- Use Arial 
by default.
+
+    function "+" (Source : Ada.Strings.Unbounded.Unbounded_String) return 
String
+        renames Ada.Strings.Unbounded.To_String;
+
+    function "+" (Source : String) return 
Ada.Strings.Unbounded.Unbounded_String
+        renames Ada.Strings.Unbounded.To_Unbounded_String;
+
+    function Decode_Command (Name : in ARM_Input.Command_Name_Type) return 
Command_Type is
+       -- Return the command value for a particular command name:
+       Canonical_Name : constant String :=
+           Ada.Characters.Handling.To_Lower (Ada.Strings.Fixed.Trim (Name, 
Ada.Strings.Right));
+    begin
+       if Canonical_Name = "source" then
+           return Source;
+       elsif Canonical_Name = "toc" then
+           return TOC;
+       elsif Canonical_Name = "showindexentries" then
+           return Show_Index_Entries;
+       elsif Canonical_Name = "hideindexentries" then
+           return Hide_Index_Entries;
+       elsif Canonical_Name = "showannotations" then
+           return Show_Annotations;
+       elsif Canonical_Name = "hideannotations" then
+           return Hide_Annotations;
+       elsif Canonical_Name = "showiso" then
+           return Show_ISO;
+       elsif Canonical_Name = "hideiso" then
+           return Hide_ISO;
+       elsif Canonical_Name = "linknonterminals" then
+           return Link_Non_Terminals;
+       elsif Canonical_Name = "numberparagraphs" then
+           return Number_Paragraphs;
+       elsif Canonical_Name = "title" then
+           return Title;
+       elsif Canonical_Name = "fileprefix" then
+           return File_Prefix;
+       elsif Canonical_Name = "examplefont" then
+           return Example_Font;
+       elsif Canonical_Name = "bodyfont" then
+           return Body_Font;
+       elsif Canonical_Name = "noteformat" then
+           return Note_Format;
+       elsif Canonical_Name = "contentsformat" then
+           return Contents_Format;
+       elsif Canonical_Name = "listformat" then
+           return List_Format;
+       elsif Canonical_Name = "subdivisionnames" then
+           return Subdivision_Names;
+       elsif Canonical_Name = "singlehtmloutputfile" then
+           return Single_HTML_Output_File;
+       elsif Canonical_Name = "usemsdosfilenames" then
+           return Use_MS_DOS_Names;
+       elsif Canonical_Name = "htmlkind" then
+           return HTML_Kind_Command;
+       elsif Canonical_Name = "htmlnavbar" then
+           return HTML_Nav_Bar;
+       elsif Canonical_Name = "htmltabs" then
+           return HTML_Tabs;
+       elsif Canonical_Name = "htmlscript" then
+           return HTML_Script;
+       elsif Canonical_Name = "htmlheader" then
+           return HTML_Header;
+       elsif Canonical_Name = "htmlfooter" then
+           return HTML_Footer;
+       elsif Canonical_Name = "htmlnewrevisioncolors" then
+           return HTML_New_Revision_Colors;
+       elsif Canonical_Name = "htmlcolor" then
+           return HTML_Color;
+       elsif Canonical_Name = "singlertfoutputfile" then
+           return Single_RTF_Output_File;
+       elsif Canonical_Name = "rtfheaderprefix" then
+           return RTF_Header_Prefix;
+       elsif Canonical_Name = "rtffootertext" then
+           return RTF_Footer_Text;
+       elsif Canonical_Name = "rtffooter" then
+           return RTF_Footer;
+       elsif Canonical_Name = "rtfpagesize" then
+           return RTF_Page_Size;
+       elsif Canonical_Name = "rtffonts" then
+           return RTF_Fonts;
+       elsif Canonical_Name = "rtfversionname" then
+           return RTF_Version_Name;
+       elsif Canonical_Name = "comment" then
+           return Comment;
+       else
+           return Unknown;
+       end if;
+    end Decode_Command;
+
+
+    function Get_Versioned_String (Item_Details : in 
ARM_Contents.Versioned_String;
+                                For_Version  : in 
ARM_Contents.Change_Version_Type)
+       return String is
+       -- Get a versioned item for the appropriate version.
+       use type Ada.Strings.Unbounded.Unbounded_String;
+    begin
+       for I in reverse ARM_Contents.Change_Version_Type'First .. For_Version 
loop
+           if Item_Details(I) /= Ada.Strings.Unbounded.Null_Unbounded_String 
then
+               return +Item_Details(I);
+           -- else keep looking, not defined for this version.
+           end if;
+       end loop;
+       return ""; -- Not defined for any version.
+    end Get_Versioned_String;
+
+
+    procedure Read_Master_File (Input_Object : in out 
ARM_Input.Input_Type'Class) is
+       -- Read the master file, saving the information into data structures
+       -- here.
+
+       procedure Process_Command is
+           Command_Name : ARM_Input.Command_Name_Type;
+           Ch : Character;
+           use type ARM_Output.Size_Type;
+           Command : Command_Type;
+
+           Close_Ch : Character;
+           procedure Get_Open_Char is
+               -- Get an open character, setting Close_Ch appropriately;
+               -- generate an error if there isn't one.
+               Ch : Character;
+           begin
+               ARM_Input.Get_Char (Input_Object, Ch);
+               if ARM_Input.Is_Open_Char (Ch) then -- Start parameter:
+                   Close_Ch := ARM_Input.Get_Close_Char (Ch);
+               else
+                   Ada.Text_IO.Put_Line ("** Parameter missing for command on 
line" & ARM_Input.Line_String (Input_Object));
+                   Close_Ch := ' ';
+               end if;
+           end Get_Open_Char;
+
+           function Get_Single_String return String is
+               -- Returns the (single) parameter of a command.
+               Item : String(1..2000);
+               ILen : Natural := 0;
+           begin
+               Get_Open_Char;
+               if Close_Ch /= ' ' then
+                   -- Copy over the string:
+                   ARM_Input.Copy_to_String_until_Close_Char (
+                       Input_Object,
+                       Close_Ch,
+                       Item,
+                       ILen);
+                   return Item(1..ILen);
+               else -- didn't find an opening character.
+                   return "";
+               end if;
+           end Get_Single_String;
+
+           procedure Get_Boolean (Param_Name : in ARM_Input.Command_Name_Type;
+                                  Result : out Boolean;
+                                  Is_First : in Boolean := False) is
+               -- Get a boolean value from a parameter named Param_Name.
+               Ch, Close_Ch : Character;
+           begin
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => Param_Name,
+                   Is_First => Is_First,
+                   Param_Close_Bracket => Close_Ch);
+               if Close_Ch /= ' ' then
+                   -- Get the Boolean character:
+                   ARM_Input.Get_Char (Input_Object, Ch);
+--Ada.Text_IO.Put_Line("  Bool=" & Ch);
+                   case Ch is
+                       when 'F' | 'f' | 'N' | 'n' =>
+                           Result := False;
+                       when 'T' | 't' | 'Y' | 'y' =>
+                           Result := True;
+                       when others =>
+                           Ada.Text_IO.Put_Line ("  ** Bad value for boolean 
parameter " &
+                               Ada.Strings.Fixed.Trim (Param_Name, 
Ada.Strings.Right) &
+                               " on line " & ARM_Input.Line_String 
(Input_Object));
+                   end case;
+                   ARM_Input.Get_Char (Input_Object, Ch);
+                   if Ch /= Close_Ch then
+                       Ada.Text_IO.Put_Line ("  ** Bad close for boolean 
parameter " &
+                           Ada.Strings.Fixed.Trim (Param_Name, 
Ada.Strings.Right) &
+                           " on line " & ARM_Input.Line_String (Input_Object));
+                       ARM_Input.Replace_Char (Input_Object);
+                   end if;
+               -- else no parameter. Weird.
+               end if;
+           end Get_Boolean;
+
+           procedure Process_Versioned_String (Item : in out 
ARM_Contents.Versioned_String) is
+               -- @Command{Version=[<Version>],Text=[<Text>]}
+               Param_Close_Ch, Ch : Character;
+               Text : String(1..80);
+               TLen : Natural := 0;
+               Version : ARM_Contents.Change_Version_Type;
+           begin
+--Ada.Text_IO.Put_Line("Process versioned item command");
+               Get_Open_Char;
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => "Version" & 
(8..ARM_Input.Command_Name_Type'Last => ' '),
+                   Is_First => True,
+                   Param_Close_Bracket => Param_Close_Ch);
+               if Param_Close_Ch /= ' ' then
+                   -- Get the version character:
+                   ARM_Input.Get_Char (Input_Object, Ch);
+                   Version := ARM_Contents.Change_Version_Type(Ch);
+--Ada.Text_IO.Put_Line("  Version=" & Version);
+                   ARM_Input.Get_Char (Input_Object, Ch);
+                   if Ch /= Param_Close_Ch then
+                       Ada.Text_IO.Put_Line ("  ** Bad close for change 
version on line " & ARM_Input.Line_String (Input_Object));
+                       ARM_Input.Replace_Char (Input_Object);
+                   end if;
+               -- else no parameter. Weird.
+               end if;
+
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => "Text" & (5..ARM_Input.Command_Name_Type'Last 
=> ' '),
+                   Is_First => False,
+                   Param_Close_Bracket => Param_Close_Ch);
+               if Param_Close_Ch /= ' ' then
+                   -- Copy over the term:
+                   ARM_Input.Copy_to_String_until_Close_Char (
+                       Input_Object,
+                       Param_Close_Ch,
+                       Text,
+                       TLen);
+--Ada.Text_IO.Put_Line("  Text=" & Text(1..TLen));
+                   Item(Version) := +Text(1..TLen);
+               -- else no parameter, error already produced.
+               end if;
+
+               ARM_Input.Get_Char (Input_Object, Ch);
+               if Ch = Close_Ch then
+                   null;
+               else
+                   Ada.Text_IO.Put_Line ("** Missing closing character for 
command on line" & ARM_Input.Line_String (Input_Object));
+                   ARM_Input.Replace_Char (Input_Object);
+               end if;
+           end Process_Versioned_String;
+
+           procedure Process_RTF_Fonts is
+               -- 
@RTFFonts{Serif=[Times|Souvenir]},SansSerif=[Arial|Helvetica]}
+               Param_Close_Ch : Character;
+               Item : String(1..80);
+               ILen : Natural := 0;
+           begin
+               Get_Open_Char;
+--Ada.Text_IO.Put_Line("Process RTF Fonts");
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => "Serif" & 
(6..ARM_Input.Command_Name_Type'Last => ' '),
+                   Is_First => True,
+                   Param_Close_Bracket => Param_Close_Ch);
+               if Param_Close_Ch /= ' ' then
+                   -- Copy over the font name:
+                   ARM_Input.Copy_to_String_until_Close_Char (
+                       Input_Object,
+                       Param_Close_Ch,
+                       Item,
+                       ILen);
+                   Ada.Text_IO.Put_Line("RTF Serif Font=" & Item(1..ILen));
+                   declare
+                       Name : constant String :=
+                           Ada.Characters.Handling.To_Lower (Item(1..ILen));
+                   begin
+                       if Name = "times" then
+                           Serif_Font := ARM_RTF.Times_New_Roman;
+                       elsif Name = "souvenir" then
+                           Serif_Font := ARM_RTF.Souvenir;
+                       else
+                           Ada.Text_IO.Put_Line ("** Unknown serif font name: 
" & Name &
+                                                 " on line" & 
ARM_Input.Line_String (Input_Object));
+                       end if;
+                   end;
+               -- else no parameter, error already produced.
+               end if;
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => "SansSerif" & 
(10..ARM_Input.Command_Name_Type'Last => ' '),
+                   Is_First => False,
+                   Param_Close_Bracket => Param_Close_Ch);
+               if Param_Close_Ch /= ' ' then
+                   -- Copy over the font name:
+                   ARM_Input.Copy_to_String_until_Close_Char (
+                       Input_Object,
+                       Param_Close_Ch,
+                       Item,
+                       ILen);
+                   Ada.Text_IO.Put_Line("RTF Sans_Serif Font=" & 
Item(1..ILen));
+                   declare
+                       Name : constant String :=
+                           Ada.Characters.Handling.To_Lower (Item(1..ILen));
+                   begin
+                       if Name = "arial" then
+                           Sans_Serif_Font := ARM_RTF.Arial;
+                       elsif Name = "helvetica" then
+                           Sans_Serif_Font := ARM_RTF.Helvetica;
+                       else
+                           Ada.Text_IO.Put_Line ("** Unknown serif font name: 
" & Name &
+                                                 " on line" & 
ARM_Input.Line_String (Input_Object));
+                       end if;
+                   end;
+               -- else no parameter, error already produced.
+               end if;
+               ARM_Input.Get_Char (Input_Object, Ch);
+               if Ch = Close_Ch then
+                   null;
+               else
+                   Ada.Text_IO.Put_Line ("** Missing closing character for 
command on line" & ARM_Input.Line_String (Input_Object));
+                   ARM_Input.Replace_Char (Input_Object);
+               end if;
+           end Process_RTF_Fonts;
+
+           procedure Process_HTML_Kind is
+               -- @HTMLKind{Version=[3|4Comp|4],Unicode=[T|F]}
+               Param_Close_Ch : Character;
+               Item : String(1..80);
+               ILen : Natural := 0;
+           begin
+               Get_Open_Char;
+--Ada.Text_IO.Put_Line("Process HTML Kind");
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => "Version" & 
(8..ARM_Input.Command_Name_Type'Last => ' '),
+                   Is_First => True,
+                   Param_Close_Bracket => Param_Close_Ch);
+               if Param_Close_Ch /= ' ' then
+                   -- Copy over the version:
+                   ARM_Input.Copy_to_String_until_Close_Char (
+                       Input_Object,
+                       Param_Close_Ch,
+                       Item,
+                       ILen);
+                   Ada.Text_IO.Put_Line("HTML version and kind=" & 
Item(1..ILen));
+                   declare
+                       Kind : constant String :=
+                           Ada.Characters.Handling.To_Lower (Item(1..ILen));
+                   begin
+                       if Kind = "3" then
+                           HTML_Kind := ARM_HTML.HTML_3;
+                       elsif Kind = "4comp" then
+                           HTML_Kind := ARM_HTML.HTML_4_Compatible;
+                       elsif Kind = "4" then
+                           HTML_Kind := ARM_HTML.HTML_4_Only;
+                       else
+                           Ada.Text_IO.Put_Line ("** Unknown HTML version: " & 
Kind &
+                                                 " on line" & 
ARM_Input.Line_String (Input_Object));
+                       end if;
+                   end;
+               -- else no parameter, error already produced.
+               end if;
+
+               Get_Boolean ("Unicode" & (8..ARM_Input.Command_Name_Type'Last 
=> ' '),
+                            HTML_Use_Unicode);
+               if HTML_Use_Unicode then
+                   Ada.Text_IO.Put_Line("HTML will use Unicode characters 
where appropriate");
+               else
+                   Ada.Text_IO.Put_Line("HTML will use Unicode characters only 
when explicitly requested");
+               end if;
+
+               ARM_Input.Get_Char (Input_Object, Ch);
+               if Ch = Close_Ch then
+                   null;
+               else
+                   Ada.Text_IO.Put_Line ("** Missing closing character for 
command on line" & ARM_Input.Line_String (Input_Object));
+                   ARM_Input.Replace_Char (Input_Object);
+               end if;
+           end Process_HTML_Kind;
+
+           procedure Process_HTML_Nav_Bar is
+               address@hidden<URL>],SrchName=[<URL>],
+               --    UseButtons=[T|F],OnTop=[T|F],OnBottom=[T|F]}
+               Param_Close_Ch : Character;
+               Item : String(1..80);
+               ILen : Natural := 0;
+           begin
+               Get_Open_Char;
+--Ada.Text_IO.Put_Line("Process HTML Nav Bar");
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => "RefName" & 
(8..ARM_Input.Command_Name_Type'Last => ' '),
+                   Is_First => True,
+                   Param_Close_Bracket => Param_Close_Ch);
+               if Param_Close_Ch /= ' ' then
+                   -- Copy over the version:
+                   ARM_Input.Copy_to_String_until_Close_Char (
+                       Input_Object,
+                       Param_Close_Ch,
+                       Item,
+                       ILen);
+                   Ada.Text_IO.Put_Line("HTML reference URL=" & Item(1..ILen));
+                   HTML_Ref_Url := + Item(1..ILen);
+               -- else no parameter, error already produced.
+               end if;
+
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => "SrchName" & 
(9..ARM_Input.Command_Name_Type'Last => ' '),
+                   Is_First => False,
+                   Param_Close_Bracket => Param_Close_Ch);
+               if Param_Close_Ch /= ' ' then
+                   -- Copy over the version:
+                   ARM_Input.Copy_to_String_until_Close_Char (
+                       Input_Object,
+                       Param_Close_Ch,
+                       Item,
+                       ILen);
+                   Ada.Text_IO.Put_Line("HTML search URL=" & Item(1..ILen));
+                   HTML_Srch_Url := + Item(1..ILen);
+               -- else no parameter, error already produced.
+               end if;
+
+               ARM_Input.Check_Parameter_Name (Input_Object,
+                   Param_Name => "IndexName" & 
(10..ARM_Input.Command_Name_Type'Last => ' '),
+                   Is_First => False,
+                   Param_Close_Bracket => Param_Close_Ch);
+               if Param_Close_Ch /= ' ' then
+                   -- Copy over the version:
+                   ARM_Input.Copy_to_String_until_Close_Char (
+                       Input_Object,
+                       Param_Close_Ch,
+                       Item,
+                       ILen);
+                   Ada.Text_IO.Put_Line("HTML index URL=" & Item(1..ILen));
+                   HTML_Index_Url := + Item(1..ILen);
+               -- else no parameter, error already produced.
+               end if;
+
+               Get_Boolean ("UseButtons" & 
(11..ARM_Input.Command_Name_Type'Last => ' '),
+                            HTML_Use_Buttons);
+               if HTML_Use_Buttons then
+                   Ada.Text_IO.Put_Line("HTML navigation will use buttons");
+               else
+                   Ada.Text_IO.Put_Line("HTML navigation will use text 
labels");
+               end if;
+
+               Get_Boolean ("OnTop" & (6..ARM_Input.Command_Name_Type'Last => 
' '),
+                            HTML_Nav_On_Top);
+               if HTML_Nav_On_Top then
+                   Ada.Text_IO.Put_Line("HTML navigation bar will appear on 
top of pages");
+               end if;
+
+               Get_Boolean ("OnBottom" & (9..ARM_Input.Command_Name_Type'Last 
=> ' '),
+                            HTML_Nav_On_Bottom);
+               if HTML_Nav_On_Bottom then
+                   Ada.Text_IO.Put_Line("HTML navigation bar will appear on 
bottom of pages");
+               end if;
+
+               ARM_Input.Get_Char (Input_Object, Ch);
+               if Ch = Close_Ch then
+                   null;
+               else
+                   Ada.Text_IO.Put_Line ("** Missing closing character for 
command on line" & ARM_Input.Line_String (Input_Object));
+                   ARM_Input.Replace_Char (Input_Object);
+               end if;
+           end Process_HTML_Nav_Bar;
+
+           procedure Process_HTML_Color is
+               address@hidden<Color]>,Background=[<Color>],
+               --  Link=[<Color>],VLink=[<Color>],ALink=[<Color>]}
+
+               procedure Get_Color (Param_Name : in 
ARM_Input.Command_Name_Type;
+                                    Is_First : in Boolean;
+                                    Result : out ARM_HTML.Color_String) is
+                   -- Get a color value from a parameter named Param_Name.
+                   Ch, Close_Ch : Character;
+                   Color : ARM_HTML.Color_String := (others => ' ');
+               begin
+                   ARM_Input.Check_Parameter_Name (Input_Object,
+                       Param_Name => Param_Name,
+                       Is_First => Is_First,
+                       Param_Close_Bracket => Close_Ch);
+                   if Close_Ch /= ' ' then
+                       -- Get the color characters:
+                       for I in ARM_HTML.Color_String'range loop
+                           ARM_Input.Get_Char (Input_Object, Ch);
+                           if Ch = Close_Ch then
+                               Ada.Text_IO.Put_Line ("  ** HTML color too 
short for " &
+                                   Ada.Strings.Fixed.Trim (Param_Name, 
Ada.Strings.Right) &
+                                   " on line " & ARM_Input.Line_String 
(Input_Object));
+                               ARM_Input.Replace_Char (Input_Object);
+                               exit;
+                           end if;
+                           Color(I) := Ch;
+                       end loop;
+--Ada.Text_IO.Put_Line("  Color=" & Color);
+                       Result := Color;
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       if Ch /= Close_Ch then
+                           Ada.Text_IO.Put_Line ("  ** Bad close for color 
parameter " &
+                               Ada.Strings.Fixed.Trim (Param_Name, 
Ada.Strings.Right) &
+                               " on line " & ARM_Input.Line_String 
(Input_Object));
+                           ARM_Input.Replace_Char (Input_Object);
+                       end if;
+                   -- else no parameter. Weird.
+                   end if;
+               end Get_Color;
+
+           begin
+               Get_Open_Char;
+--Ada.Text_IO.Put_Line("Process HTML Color");
+               Get_Color ("Text" & (5..ARM_Input.Command_Name_Type'Last => ' 
'),
+                            Is_First => True, Result => HTML_Text_Color);
+               Ada.Text_IO.Put_Line("HTML text color is " & HTML_Text_Color);
+
+               Get_Color ("Background" & (11..ARM_Input.Command_Name_Type'Last 
=> ' '),
+                            Is_First => False, Result => 
HTML_Background_Color);
+               Ada.Text_IO.Put_Line("HTML background color is " & 
HTML_Background_Color);
+
+               Get_Color ("Link" & (5..ARM_Input.Command_Name_Type'Last => ' 
'),
+                            Is_First => False, Result => HTML_Link_Color);
+               Ada.Text_IO.Put_Line("HTML link color is " & HTML_Link_Color);
+
+               Get_Color ("VLink" & (6..ARM_Input.Command_Name_Type'Last => ' 
'),
+                            Is_First => False, Result => HTML_VLink_Color);
+               Ada.Text_IO.Put_Line("HTML visited link color is " & 
HTML_VLink_Color);
+
+               Get_Color ("ALink" & (6..ARM_Input.Command_Name_Type'Last => ' 
'),
+                            Is_First => False, Result => HTML_ALink_Color);
+               Ada.Text_IO.Put_Line("HTML active link color is " & 
HTML_ALink_Color);
+
+               ARM_Input.Get_Char (Input_Object, Ch);
+               if Ch = Close_Ch then
+                   null;
+               else
+                   Ada.Text_IO.Put_Line ("** Missing closing character for 
command on line" & ARM_Input.Line_String (Input_Object));
+                   ARM_Input.Replace_Char (Input_Object);
+               end if;
+           end Process_HTML_Color;
+
+           procedure Process_Source_Command is
+               -- @Source{Name=<File Name>,SectionName=<Name>,
+               -- SectionNumber=<AlphaNum>,NewSection=[T|F]}
+               Param_Close_Ch : Character;
+               Item : String(1..80);
+               ILen : Natural := 0;
+               use type ARM_Contents.Section_Number_Type;
+           begin
+               Get_Open_Char;
+               if Source_Length = Source_Count'Last then
+                   Ada.Text_IO.Put_Line ("** Too many source files on line" & 
ARM_Input.Line_String (Input_Object));
+               else
+                   Source_Length := Source_Length + 1;
+--Ada.Text_IO.Put_Line("Process source command - Length =" & 
Source_Count'Image(Source_Length));
+                   Source_Data(Source_Length) :=
+                       (Kind => A_File,
+                        File_Name          => (others => ' '),
+                        File_Name_Len      => 0,
+                        Section_Name       => (others => ' '),
+                        Section_Name_Len   => 0,
+                        Section_Number     => 0,
+                        Starts_New_Section => True);
+                   ARM_Input.Check_Parameter_Name (Input_Object,
+                       Param_Name => "Name" & 
(5..ARM_Input.Command_Name_Type'Last => ' '),
+                       Is_First => True,
+                       Param_Close_Bracket => Param_Close_Ch);
+                   if Param_Close_Ch /= ' ' then
+                       -- Copy over the term:
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           Param_Close_Ch,
+                           Item,
+                           ILen);
+--Ada.Text_IO.Put_Line("  Name=" & Item(1..ILen));
+                       if Ada.Strings.Fixed.Index (Item(1..ILen), ".") = 0 then
+                           -- Append the extension:
+                           Source_Data(Source_Length).File_Name_Len := ILen + 
4;
+                           Ada.Strings.Fixed.Move (
+                                       Target => 
Source_Data(Source_Length).File_Name,
+                                       Source => 
Ada.Characters.Handling.To_Lower (Item(1..ILen)) & ".mss");
+                       else
+                           Source_Data(Source_Length).File_Name_Len := ILen;
+                           Ada.Strings.Fixed.Move (
+                                       Target => 
Source_Data(Source_Length).File_Name,
+                                       Source => 
Ada.Characters.Handling.To_Lower (Item(1..ILen)));
+                       end if;
+                   -- else no parameter, error already produced.
+                   end if;
+                   ARM_Input.Check_Parameter_Name (Input_Object,
+                       Param_Name => "SectionName" & 
(12..ARM_Input.Command_Name_Type'Last => ' '),
+                       Is_First => False,
+                       Param_Close_Bracket => Param_Close_Ch);
+                   if Param_Close_Ch /= ' ' then
+                       -- Copy over the term:
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           Param_Close_Ch,
+                           Item,
+                           ILen);
+--Ada.Text_IO.Put_Line("  Section_Name=" & Item(1..ILen));
+                       Source_Data(Source_Length).Section_Name_Len := ILen;
+                       Ada.Strings.Fixed.Move (
+                                   Target => 
Source_Data(Source_Length).Section_Name,
+                                   Source => Item(1..ILen));
+                   -- else no parameter, error already produced.
+                   end if;
+                   ARM_Input.Check_Parameter_Name (Input_Object,
+                       Param_Name => "SectionNumber" & 
(14..ARM_Input.Command_Name_Type'Last => ' '),
+                       Is_First => False,
+                       Param_Close_Bracket => Param_Close_Ch);
+                   if Param_Close_Ch /= ' ' then
+                       -- Copy over the term:
+                       ARM_Input.Copy_to_String_until_Close_Char (
+                           Input_Object,
+                           Param_Close_Ch,
+                           Item,
+                           ILen);
+--Ada.Text_IO.Put_Line("  Section_Number=" & Item(1..ILen));
+                       if ILen = 1 and then Item(1) in 'A'..'Z' then
+                           Source_Data(Source_Length).Section_Number :=
+                               31 + Character'Pos(Item(1)) - 
Character'Pos('A');
+                       elsif ILen = 1 and then Item(1) in 'a'..'z' then
+                           Source_Data(Source_Length).Section_Number :=
+                               31 + Character'Pos(Item(1)) - 
Character'Pos('a');
+                       else
+                           begin
+                               Source_Data(Source_Length).Section_Number :=
+                                   
ARM_Contents.Section_Number_Type'Value(Item(1..Ilen));
+                           exception
+                               when Constraint_Error =>
+                                   Ada.Text_IO.Put_Line ("** Illegal section 
number " &
+                                       Item(1..ILen) & " on line" & 
ARM_Input.Line_String (Input_Object));
+                           end;
+                       end if;
+                   -- else no parameter, error already produced.
+                   end if;
+
+                   Get_Boolean ("NewSection" & 
(11..ARM_Input.Command_Name_Type'Last => ' '),
+                                Source_Data(Source_Length).Starts_New_Section);
+
+                   ARM_Input.Get_Char (Input_Object, Ch);
+                   if Ch = Close_Ch then
+                       null;
+                   else
+                       Ada.Text_IO.Put_Line ("** Missing closing character for 
command on line" & ARM_Input.Line_String (Input_Object));
+                       ARM_Input.Replace_Char (Input_Object);
+                   end if;
+               end if;
+           end Process_Source_Command;
+
+       begin
+           -- We don't have any non-identifier commands here, so we can
+           -- go directly to getting the name:
+           ARM_Input.Get_Name (Input_Object, Command_Name);
+           Command := Decode_Command (Command_Name);
+--Ada.Text_IO.Put_Line("Process command=" & Command_Type'Image(Command));
+--Ada.Text_IO.Put_Line("Process command=" & Command_Type'Image(Command) & " 
Name=" & Command_Name);
+
+           case Command is
+               when Comment =>
+                   -- @Comment{<text>}
+                   -- Skip the parameter.
+                   Get_Open_Char;
+                   if Close_Ch /= ' ' then
+                       ARM_Input.Skip_until_Close_Char (Input_Object, 
Close_Ch);
+                   end if;
+
+               -- Global properties:
+
+               when Show_Index_Entries =>
+                   -- @ShowIndexEntries
+                   Display_Index_Entries := True;
+                   Ada.Text_IO.Put_Line("Show Index Entries");
+
+               when Hide_Index_Entries =>
+                   -- @HideIndexEntries
+                   Display_Index_Entries := False;
+                   Ada.Text_IO.Put_Line("Hide Index Entries");
+
+               when Show_Annotations =>
+                   -- @ShowAnnotations
+                   Include_Annotations := True;
+                   Ada.Text_IO.Put_Line("Show Annotations");
+
+               when Hide_Annotations =>
+                   -- @HideAnnotations
+                   Include_Annotations := False;
+                   Ada.Text_IO.Put_Line("Hide Annotations");
+
+               when Show_ISO =>
+                   -- @ShowISO
+                   Include_ISO_Text := True;
+                   Ada.Text_IO.Put_Line("Show ISO Text");
+
+               when Hide_ISO =>
+                   -- @HideISO
+                   Include_ISO_Text := False;
+                   Ada.Text_IO.Put_Line("Hide ISO Text");
+
+               when Link_Non_Terminals =>
+                   -- @LinkNonTerminals
+                   Should_Link_Non_Terminals := True;
+                   Ada.Text_IO.Put_Line("Link Non-Terminals");
+
+               when Number_Paragraphs =>
+                   -- @NumberParagraphs
+                   Should_Number_Paragraphs := True;
+                   Ada.Text_IO.Put_Line("Number Paragraphs");
+
+               when Title =>
+                   -- @Title{Version=[<version>],Text=[<title_text>]}
+                   Process_Versioned_String (Document_Title);
+
+               when File_Prefix =>
+                   -- @FilePrefix{<File_Prefix>}
+                   Output_File_Prefix := +Ada.Characters.Handling.To_Lower 
(Get_Single_String);
+                   Ada.Text_IO.Put_Line("File Prefix is " &
+                       (+Output_File_Prefix));
+
+               when Example_Font =>
+                   -- @ExampleFont{Swiss|Fixed|Roman}
+                   declare
+                       Font_Name : constant String :=
+                           Ada.Characters.Handling.To_Lower (
+                               Get_Single_String);
+                   begin
+                       if Font_Name = "swiss" then
+                           Font_of_Examples := ARM_Output.Swiss;
+                           Ada.Text_IO.Put_Line("Examples in swiss font");
+                       elsif Font_Name = "fixed" then
+                           Font_of_Examples := ARM_Output.Fixed;
+                           Ada.Text_IO.Put_Line("Examples in fixed-width 
font");
+                       elsif Font_Name = "roman" then
+                           Font_of_Examples := ARM_Output.Roman;
+                           Ada.Text_IO.Put_Line("Examples in roman font");
+                       else
+                           Ada.Text_IO.Put_Line ("** Unknown example font 
name: " & Font_Name &
+                                                 " on line" & 
ARM_Input.Line_String (Input_Object));
+                       end if;
+                   end;
+
+               when Body_Font =>
+                   -- @BodyFont{Swiss|Roman}
+                   declare
+                       Font_Name : constant String :=
+                           Ada.Characters.Handling.To_Lower (
+                               Get_Single_String);
+                   begin
+                       if Font_Name = "swiss" then
+                           Font_of_Body := ARM_Output.Swiss;
+                           Ada.Text_IO.Put_Line("Body in swiss font");
+                       elsif Font_Name = "roman" then
+                           Font_of_Body := ARM_Output.Roman;
+                           Ada.Text_IO.Put_Line("Body in roman font");
+                       else
+                           Ada.Text_IO.Put_Line ("** Unknown body font name: " 
& Font_Name &
+                                                 " on line" & 
ARM_Input.Line_String (Input_Object));
+                       end if;
+                   end;
+
+               when Note_Format =>
+                   -- @NoteFormat{Ada95|ISO2004}
+                   declare
+                       Format_Name : constant String :=
+                           Ada.Characters.Handling.To_Lower (
+                               Get_Single_String);
+                   begin
+                       if Format_Name = "ada95" then
+                           Use_ISO_2004_Note_Format := False;
+                           Ada.Text_IO.Put_Line("Notes in Ada 95 standard 
format");
+                       elsif Format_Name = "iso2004" then
+                           Use_ISO_2004_Note_Format := True;
+                           Ada.Text_IO.Put_Line("Notes in ISO 2004 standard 
format");
+                       else
+                           Ada.Text_IO.Put_Line ("** Unknown note format name: 
" & Format_Name &
+                                                 " on line" & 
ARM_Input.Line_String (Input_Object));
+                       end if;
+                   end;
+
+               when Contents_Format =>
+                   -- @ContentsFormat{Ada95|ISO2004}
+                   declare
+                       Format_Name : constant String :=
+                           Ada.Characters.Handling.To_Lower (
+                               Get_Single_String);
+                   begin
+                       if Format_Name = "ada95" then
+                           Use_ISO_2004_Contents_Format := False;
+                           Ada.Text_IO.Put_Line("Table of Contents in Ada 95 
standard format");
+                       elsif Format_Name = "iso2004" then
+                           Use_ISO_2004_Contents_Format := True;
+                           Ada.Text_IO.Put_Line("Table of Contents in ISO 2004 
standard format");
+                       else
+                           Ada.Text_IO.Put_Line ("** Unknown contents format 
name: " & Format_Name &
+                                                 " on line" & 
ARM_Input.Line_String (Input_Object));
+                       end if;
+                   end;
+
+               when List_Format =>
+                   -- @ListFormat{Ada95|ISO2004}
+                   declare
+                       Format_Name : constant String :=
+                           Ada.Characters.Handling.To_Lower (
+                               Get_Single_String);
+                   begin
+                       if Format_Name = "ada95" then
+                           Use_ISO_2004_List_Format := False;
+                           Ada.Text_IO.Put_Line("Lists in Ada 95 standard 
format");
+                       elsif Format_Name = "iso2004" then
+                           Use_ISO_2004_List_Format := True;
+                           Ada.Text_IO.Put_Line("Lists in ISO 2004 standard 
format");
+                       else
+                           Ada.Text_IO.Put_Line ("** Unknown list format name: 
" & Format_Name &
+                                                 " on line" & 
ARM_Input.Line_String (Input_Object));
+                       end if;
+                   end;
+
+               when Subdivision_Names =>
+                   -- @SubdivisionNames{Chapter|Section|Clause}
+                   declare
+                       SD_Name : constant String :=
+                           Ada.Characters.Handling.To_Lower (
+                               Get_Single_String);
+                   begin
+                       if SD_Name = "chapter" then
+                           Subdivision_Name_Kind := ARM_Output.Chapter;
+                           Ada.Text_IO.Put_Line("Top-level subdivisions known 
as Chapters");
+                       elsif SD_Name = "section" then
+                           Subdivision_Name_Kind := ARM_Output.Section;
+                           Ada.Text_IO.Put_Line("Top-level subdivisions known 
as Sections");
+                       elsif SD_Name = "clause" then
+                           Subdivision_Name_Kind := ARM_Output.Clause;
+                           Ada.Text_IO.Put_Line("Top-level subdivisions known 
as Clauses");
+                       else
+                           Ada.Text_IO.Put_Line ("** Unknown subdivision name: 
" & SD_Name &
+                                                 " on line" & 
ARM_Input.Line_String (Input_Object));
+                       end if;
+                   end;
+
+               -- HTML properties:
+
+               when Single_HTML_Output_File =>
+                   -- @Single_HTML_Output_File
+                   Use_Large_HTML_Files := True;
+                   Ada.Text_IO.Put_Line("Single HTML Output File");
+
+               when Use_MS_DOS_Names =>
+                   -- @UseMSDOSFileNames
+                   Use_MS_DOS_Filenames := True;
+                   Ada.Text_IO.Put_Line("Use MS-DOS (8.3) file names for HTML 
output files");
+
+               when HTML_Kind_Command =>
+                   address@hidden|4Comp|4],Unicode=[T|F]}
+                   Process_HTML_Kind;
+
+               when HTML_Nav_Bar =>
+                   
address@hidden<URL>],SrchName=[<URL>],UseButtons=[T|F],OnTop=[T|F],OnBottom=[T|F]}
+                   Process_HTML_Nav_Bar;
+
+               when HTML_Tabs =>
+                   -- 
@HTMLTabs{[SingleSpace|QuadSpace|EmulateFixedOnly|EmulateFixedOnlyQuad|EmulateAll]}
+                   declare
+                       Tabs : constant String :=
+                           Ada.Characters.Handling.To_Lower 
(Get_Single_String);
+                   begin
+                       if Tabs = "singlespace" then
+                           HTML_Tab_Emulation := ARM_HTML.Single_Space;
+                       elsif Tabs = "quadspace" then
+                           HTML_Tab_Emulation := ARM_HTML.Quad_Space;
+                       elsif Tabs = "emulatefixedonly" then
+                           HTML_Tab_Emulation := ARM_HTML.Emulate_Fixed_Only;
+                       elsif Tabs = "emulatefixedonlyquad" then
+                           HTML_Tab_Emulation := 
ARM_HTML.Emulate_Fixed_Only_Quad;
+                       elsif Tabs = "emulateall" then
+                           HTML_Tab_Emulation := ARM_HTML.Emulate_All;
+                       else
+                           Ada.Text_IO.Put_Line ("** Unknown tab emulation 
name: " & Tabs &
+                                                 " on line" & 
ARM_Input.Line_String (Input_Object));
+                       end if;
+                       Ada.Text_IO.Put_Line("HTML Tab Emulation is " &
+                           
ARM_HTML.Tab_Emulation_Type'Image(HTML_Tab_Emulation));
+                   end;
+
+               when HTML_Script =>
+                   address@hidden<Script>}
+                   HTML_Script_Text := +Get_Single_String;
+                   if Ada.Strings.Unbounded.Length (HTML_Script_Text) /= 0 then
+                       Ada.Text_IO.Put_Line("Non-empty HTML Script seen");
+                   end if;
+
+               when HTML_Header =>
+                   address@hidden<HTML_for_Header>}
+                   HTML_Header_Text := +Get_Single_String;
+                   if Ada.Strings.Unbounded.Length (HTML_Header_Text) /= 0 then
+                       Ada.Text_IO.Put_Line("Non-empty HTML Header seen");
+                   end if;
+
+               when HTML_Footer =>
+                   address@hidden<HTML_for_Footer>}
+                   HTML_Footer_Text := +Get_Single_String;
+                   if Ada.Strings.Unbounded.Length (HTML_Footer_Text) /= 0 then
+                       Ada.Text_IO.Put_Line("Non-empty HTML Footer seen");
+                   end if;
+
+               when HTML_New_Revision_Colors =>
+                   -- @HTMLNewRevisionColors
+                   HTML_Use_New_Revision_Colors := True;
+                   Ada.Text_IO.Put_Line("Unconditionally use new revision 
colors in HTML");
+
+               when HTML_Color =>
+                   address@hidden<Color]>,Background=[<Color>],
+                   --  Link=[<Color>],VLink=[<Color>],ALink=[<Color>]}
+                   Process_HTML_Color;
+
+               -- RTF properties:
+
+               when Single_RTF_Output_File =>
+                   -- @Single_RTF_Output_File
+                   Use_Large_RTF_Files := True;
+                   Ada.Text_IO.Put_Line("Single RTF Output File");
+
+               when RTF_Header_Prefix =>
+                   -- @RTFHeaderPrefix{Version=[<version>],Text=[<title_text>]}
+                   Process_Versioned_String (Header_Prefix);
+
+               when RTF_Footer_Text =>
+                   -- @RTFFooterPrefix{Version=[<version>],Text=[<title_text>]}
+                   Process_Versioned_String (Footer_Text);
+
+               when RTF_Footer =>
+                   -- 
@RTFFooter{UseDate=[T|F],UseClauseName=[T|F],UseISOFormat=[T|F]}
+                   begin
+                       Get_Open_Char;
+--Ada.Text_IO.Put_Line("Process RTF Footer");
+                       Get_Boolean ("UseDate" & 
(8..ARM_Input.Command_Name_Type'Last => ' '),
+                                    Footer_Use_Date, Is_First => True);
+                       if Footer_Use_Date then
+                           Ada.Text_IO.Put_Line("RTF footer will include the 
date");
+                       else
+                           Ada.Text_IO.Put_Line("RTF footer will omit the 
date");
+                       end if;
+
+                       Get_Boolean ("UseClauseName" & 
(14..ARM_Input.Command_Name_Type'Last => ' '),
+                                    Footer_Use_Clause_Name);
+                       if Footer_Use_Clause_Name then
+                           Ada.Text_IO.Put_Line("RTF footer will include the 
name of the clause that starts the page");
+                       else
+                           Ada.Text_IO.Put_Line("RTF footer will include the 
fixed footer text");
+                       end if;
+
+                       Get_Boolean ("UseISOFormat" & 
(13..ARM_Input.Command_Name_Type'Last => ' '),
+                                    Footer_Use_ISO_Format);
+                       if Footer_Use_ISO_Format then
+                           Ada.Text_IO.Put_Line("RTF footer will use the ISO 
format (swiss font, multiple sizes)");
+                       else
+                           Ada.Text_IO.Put_Line("RTF footer will use the 
normal format (body fond, one size)");
+                       end if;
+
+                       ARM_Input.Get_Char (Input_Object, Ch);
+                       if Ch = Close_Ch then
+                           null;
+                       else
+                           Ada.Text_IO.Put_Line ("** Missing closing character 
for command on line" & ARM_Input.Line_String (Input_Object));
+                           ARM_Input.Replace_Char (Input_Object);
+                       end if;
+                   end;
+
+               when RTF_Version_Name =>
+                   -- @RTFVersionName{Version=[<version>],Text=[<title_text>]}
+                   Process_Versioned_String (Version_Name);
+
+               when RTF_Page_Size =>
+                   -- @RTFPageSize{Letter|A4|HalfLetter|Ada95}
+                   declare
+                       Size : constant String :=
+                           Ada.Characters.Handling.To_Lower 
(Get_Single_String);
+                   begin
+                       if Size = "letter" then
+                           Page_Size := ARM_RTF.Letter;
+                       elsif Size = "a4" then
+                           Page_Size := ARM_RTF.A4;
+                       elsif Size = "halfletter" then
+                           Page_Size := ARM_RTF.Half_Letter;
+                       elsif Size = "ada95" then
+                           Page_Size := ARM_RTF.Ada95;
+                       else
+                           Ada.Text_IO.Put_Line ("** Unknown page size name: " 
& Size &
+                                                 " on line" & 
ARM_Input.Line_String (Input_Object));
+                       end if;
+                       Ada.Text_IO.Put_Line("RTF Page Size is " &
+                           ARM_RTF.Page_Size'Image(Page_Size));
+                   end;
+
+               when RTF_Fonts =>
+                   -- 
@RTFFonts{Serif=[Times|Souvenir]},SansSerif=[Arial|Helvetica]}
+                   Process_RTF_Fonts;
+
+               -- Source files:
+
+               when TOC =>
+                   -- @TOC
+                   if Source_Length = Source_Count'Last then
+                       Ada.Text_IO.Put_Line ("** Too many source files on 
line" & ARM_Input.Line_String (Input_Object));
+                   else
+                       Source_Length := Source_Length + 1;
+                       Source_Data(Source_Length) :=
+                           (Kind => TOC);
+                   end if;
+
+               when Source =>
+                   Process_Source_Command;
+
+               when Unknown =>
+                   Ada.Text_IO.Put_Line ("  -- Unknown command (skipped) - " &
+                       Ada.Strings.Fixed.Trim (Command_Name, 
Ada.Strings.Right) &
+                       " on line " & ARM_Input.Line_String (Input_Object));
+           end case;
+       end Process_Command;
+
+    begin
+        Reading_Loop: loop
+           declare
+               Char : Character;
+           begin
+               ARM_Input.Get_Char (Input_Object, Char);
+               case Char is
+                   when '@' =>
+                       Process_Command;
+                   when Ascii.LF | ' ' =>
+                       null;
+                   when Ascii.SUB =>
+                       -- End of file.
+                       exit Reading_Loop;
+                   when others =>
+                       Ada.Text_IO.Put_Line ("** Character(s) not in a command 
in the master file on line" & ARM_Input.Line_String (Input_Object));
+                       while (Char /= ' ' and then Char /= '@' and then
+                               Char /= Ascii.LF and then Char /= Ascii.SUB) 
loop
+                           ARM_Input.Get_Char (Input_Object, Char);
+                       end loop;
+                       ARM_Input.Replace_Char (Input_Object);
+               end case;
+           end;
+        end loop Reading_Loop;
+
+       -- Check for bad combinations:
+       if ARM_Output."="(Font_of_Examples, ARM_Output.Roman) and then
+          ARM_Output."="(Font_of_Body, ARM_Output.Swiss) then
+           -- This doesn't work, since "Roman" examples use the
+           -- body styles, and if they are Swiss...
+           Ada.Text_IO.Put_Line ("  ** Examples cannot be Roman if Body is 
Swiss!! (They will appear in the Swiss font)");
+       end if;
+    end Read_Master_File;
+
+
+    procedure Create_Format (Format_Object : in out ARM_Format.Format_Type) is
+       -- Create an appropriate format object.
+    begin
+       ARM_Format.Create (Format_Object, Change_Kind, Change_Version,
+                Base_Change_Version   => Base_Change_Version,
+               Display_Index_Entries => Display_Index_Entries,
+               Include_Annotations   => Include_Annotations,
+               Include_ISO           => Include_ISO_Text,
+               Link_Non_Terminals    => Should_Link_Non_Terminals,
+               Number_Paragraphs     => Should_Number_Paragraphs,
+               Examples_Font         => Font_of_Examples,
+               Use_ISO_2004_Note_Format => Use_ISO_2004_Note_Format,
+               Use_ISO_2004_Contents_Format => Use_ISO_2004_Contents_Format,
+               Use_ISO_2004_List_Format => Use_ISO_2004_List_Format,
+               Top_Level_Subdivision_Name => Subdivision_Name_Kind);
+    end Create_Format;
+
+
+    procedure Scan_Sources is
+       -- Run the scanning pass on the source files:
+       Format_Object : ARM_Format.Format_Type;
+    begin
+       Create_Format (Format_Object);
+       for Source_Index in Source_Data'First .. Source_Length loop
+           case Source_Data(Source_Index).Kind is
+               when TOC => null;
+               when A_File =>
+                   ARM_Format.Scan (Format_Object,
+                       
Source_Data(Source_Index).File_Name(1..Source_Data(Source_Index).File_Name_Len),
+                       Section_Number => 
Source_Data(Source_Index).Section_Number,
+                       Starts_New_Section => 
Source_Data(Source_Index).Starts_New_Section);
+               when Empty => null;
+           end case;
+       end loop;
+
+       ARM_Format.Destroy (Format_Object);
+    end Scan_Sources;
+
+
+    procedure Generate_Sources (Output_Object : in out 
ARM_Output.Output_Type'Class) is
+       -- Generate the results from the source files:
+       Format_Object : ARM_Format.Format_Type;
+    begin
+       Create_Format (Format_Object);
+
+       for Source_Index in Source_Data'First .. Source_Length loop
+           case Source_Data(Source_Index).Kind is
+               when TOC =>
+                   ARM_Format.Write_Table_of_Contents (Format_Object, 
Output_Object);
+               when A_File =>
+                   ARM_Format.Process (Format_Object,
+                       
Source_Data(Source_Index).File_Name(1..Source_Data(Source_Index).File_Name_Len),
+                       Output_Object,
+                       Section_Name   => 
Source_Data(Source_Index).Section_Name(1..Source_Data(Source_Index).Section_Name_Len),
+                       Section_Number => 
Source_Data(Source_Index).Section_Number,
+                       Starts_New_Section => 
Source_Data(Source_Index).Starts_New_Section);
+               when Empty => null;
+           end case;
+       end loop;
+
+       ARM_Format.Destroy (Format_Object);
+    end Generate_Sources;
+
+
+    procedure Read_and_Process_Master_File (
+       File_Name : in String;
+       The_Change_Kind : ARM_Format.Change_Kind; -- Changes to generate.
+       The_Change_Version : ARM_Contents.Change_Version_Type; -- Change 
version.
+       The_Base_Change_Version : ARM_Contents.Change_Version_Type; -- Base 
change version.
+        Output_Format : in Output_Format_Type;
+        Output_Path : in String) is
+       -- Read and process the master file given.
+       Input_Object : ARM_File.File_Input_Type;
+    begin
+       Ada.Text_IO.Put_Line ("-- Reading master file " & File_Name);
+       begin
+           Arm_File.Open (Input_Object, File_Name);
+       exception
+           when others =>
+               Ada.Text_IO.Put_Line ("** Unable to open master file " & 
File_Name);
+               return;
+       end;
+
+       Change_Kind := The_Change_Kind;
+       Change_Version := The_Change_Version;
+       Base_Change_Version := The_Base_Change_Version;
+
+       Source_Length := 0;
+       Read_Master_File (Input_Object);
+
+       Ada.Text_IO.Put_Line ("  Lines processed: " &
+               ARM_File.Line_String (Input_Object));
+       Arm_File.Close (Input_Object);
+
+       -- Now, execute the commands from the file.
+
+       Scan_Sources; -- Scanning pass.
+
+       -- Create the appropriate output object, then generate the results:
+       case Output_Format is
+           when HTML =>
+               declare
+                   Output : ARM_HTML.HTML_Output_Type;
+               begin
+                   ARM_HTML.Create (Output,
+                                    Big_Files => Use_Large_HTML_Files,
+                                    File_Prefix => +Output_File_Prefix,
+                                    DOS_Filenames => Use_MS_DOS_Filenames,
+                                    Output_Path => Output_Path,
+                                    HTML_Kind => HTML_Kind,
+                                    Use_Unicode => HTML_Use_Unicode,
+                                    Number_Paragraphs => 
Should_Number_Paragraphs,
+                                    Ref_URL => +HTML_Ref_URL,
+                                    Srch_URL => +HTML_Srch_URL,
+                                    Index_URL => +HTML_Index_URL,
+                                    Use_Buttons => HTML_Use_Buttons,
+                                    Nav_On_Top => HTML_Nav_On_Top,
+                                    Nav_On_Bottom => HTML_Nav_On_Bottom,
+                                    Tab_Emulation => HTML_Tab_Emulation,
+                                    Script_HTML => +HTML_Script_Text,
+                                    Header_HTML => +HTML_Header_Text,
+                                    Footer_HTML => +HTML_Footer_Text,
+                                    Title => 
Get_Versioned_String(Document_Title,Change_Version),
+                                    Body_Font => Font_of_Body,
+                                    Force_New_Revision_Colors => 
HTML_Use_New_Revision_Colors and then Change_Version >= '5',
+                                    Text_Color => HTML_Text_Color,
+                                    Background_Color => HTML_Background_Color,
+                                    Link_Color => HTML_Link_Color,
+                                    VLink_Color => HTML_VLink_Color,
+                                    ALink_Color => HTML_ALink_Color);
+                   Generate_Sources (Output);
+                   ARM_HTML.Close (Output);
+               end;
+           when RTF =>
+               declare
+                   Output : ARM_RTF.RTF_Output_Type;
+               begin
+                   if ARM_Format."=" (Change_Kind, ARM_Format.Old_Only) or else
+                      Change_Version = '0' then
+                       ARM_RTF.Create (Output,
+                                       Page_Size => Page_Size,
+                                       Includes_Changes => False,
+                                       Big_Files => Use_Large_RTF_Files,
+                                       Output_Path => Output_Path,
+                                       Primary_Serif_Font => Serif_Font,
+                                       Primary_Sans_Serif_Font => 
Sans_Serif_Font,
+                                       File_Prefix => +Output_File_Prefix,
+                                       Title => 
Get_Versioned_String(Document_Title,Change_Version),
+                                       Header_Prefix => 
Get_Versioned_String(Header_Prefix,Change_Version),
+                                       Footer_Use_Date => Footer_Use_Date,
+                                       Footer_Use_Clause_Name => 
Footer_Use_Clause_Name,
+                                       Footer_Use_ISO_Format=> 
Footer_Use_ISO_Format,
+                                       Footer_Text => Get_Versioned_String 
(Footer_Text, Change_Version),
+                                       Body_Font => Font_of_Body,
+                                       Version_Names => Version_Name);
+                   else
+                       ARM_RTF.Create (Output,
+                                       Page_Size => Page_Size,
+                                       Includes_Changes => True,
+                                       Big_Files => Use_Large_RTF_Files,
+                                       Output_Path => Output_Path,
+                                       Primary_Serif_Font => Serif_Font,
+                                       Primary_Sans_Serif_Font => 
Sans_Serif_Font,
+                                       File_Prefix => +Output_File_Prefix,
+                                       Title => Get_Versioned_String 
(Document_Title, Change_Version),
+                                       Header_Prefix => Get_Versioned_String 
(Header_Prefix, Change_Version),
+                                       Footer_Use_Date => Footer_Use_Date,
+                                       Footer_Use_Clause_Name => 
Footer_Use_Clause_Name,
+                                       Footer_Use_ISO_Format=> 
Footer_Use_ISO_Format,
+                                       Footer_Text => Get_Versioned_String 
(Footer_Text, Change_Version),
+                                       Body_Font => Font_of_Body,
+                                       Version_Names => Version_Name);
+                   end if;
+                   Generate_Sources (Output);
+                   ARM_RTF.Close (Output);
+               end;
+           when Text =>
+               declare
+                   Output : ARM_Text.Text_Output_Type;
+               begin
+                   ARM_Text.Create (Output,
+                                    File_Prefix => +Output_File_Prefix,
+                                    Output_Path => Output_Path,
+                                    Title => Get_Versioned_String 
(Document_Title, Change_Version));
+                   Generate_Sources (Output);
+                   ARM_Text.Close (Output);
+               end;
+           when Corr =>
+               declare
+                   Output : ARM_Corr.Corr_Output_Type;
+               begin
+                   ARM_Corr.Create (Output,
+                                    File_Prefix => +Output_File_Prefix,
+                                    Output_Path => Output_Path,
+                                    Title => Get_Versioned_String 
(Document_Title, Change_Version));
+                   Generate_Sources (Output);
+                   ARM_Corr.Close (Output);
+               end;
+           when Info =>
+               declare
+                   Output : ARM_TexInfo.Texinfo_Output_Type;
+               begin
+                   ARM_TexInfo.Create (Output,
+                                       File_Prefix => +Output_File_Prefix,
+                                       Output_Path => Output_Path,
+                                        Change_Version => Change_Version,
+                                       Title => Get_Versioned_String 
(Document_Title, Change_Version));
+                   Generate_Sources (Output);
+                   ARM_TexInfo.Close (Output);
+               end;
+        end case;
+
+    end Read_and_Process_Master_File;
+
+
+end ARM_Master;
diff --git a/packages/ada-ref-man/progs/arm_mast.ads 
b/packages/ada-ref-man/progs/arm_mast.ads
new file mode 100755
index 0000000..9191a29
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_mast.ads
@@ -0,0 +1,58 @@
+with ARM_Format, ARM_Contents;
+package ARM_Master is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the routines to parse the master file, and
+    -- execute it.
+    --
+    -- ---------------------------------------
+    -- Copyright 2006, 2011, 2012, 2016
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  1/05/06 - RLB - Created base package to replace hard-coded main 
program.
+    --  1/12/06 - RLB - Removed obsolete Document parameter.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    --  8/31/12 - RLB - Added Output_Path.
+    --  3/17/16 - RLB - Added Base_Change_Version.
+
+    type Output_Format_Type is (HTML, RTF, Text, Corr, Info);
+
+    procedure Read_and_Process_Master_File (
+       File_Name : in String;
+       The_Change_Kind : ARM_Format.Change_Kind; -- Changes to generate.
+       The_Change_Version : ARM_Contents.Change_Version_Type; -- Change 
version.
+       The_Base_Change_Version : ARM_Contents.Change_Version_Type; -- Base 
change version.
+        Output_Format : in Output_Format_Type;
+        Output_Path : in String);
+
+       -- Read and process the master file given.
+
+end ARM_Master;
diff --git a/packages/ada-ref-man/progs/arm_out.ads 
b/packages/ada-ref-man/progs/arm_out.ads
new file mode 100755
index 0000000..96648ec
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_out.ads
@@ -0,0 +1,633 @@
+with ARM_Contents;
+package ARM_Output is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package defines the abstract definition of an output object.
+    -- Output objects are responsible for implementing the details of
+    -- a particular format.
+    --
+    -- We use dispatching calls to call the formatter, so the details of
+    -- formatting are insulated from the code that reads the source and
+    -- determines the details of the text.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2004, 2005, 2006, 2007, 2011, 2012
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  4/14/00 - RLB - Created base package.
+    --  4/18/00 - RLB - Added index and contents marker routines.
+    --  4/21/00 - RLB - Added line break and hard space routines.
+    --  4/24/00 - RLB - Added DR references and Insert/Delete text formats.
+    --  4/25/00 - RLB - Added size to format.
+    --  4/29/00 - RLB - Added Indented and Bulleted formats.
+    --  5/10/00 - RLB - Added Syntax and Hanging formats.
+    --         - RLB - Added End_Hang_Item.
+    --  5/12/00 - RLB - Added No_Prefix to Start_Paragraph.
+    --  5/13/00 - RLB - Added Special_Character.
+    --  5/16/00 - RLB - Added more special characters.
+    --  5/17/00 - RLB - Added New_Page.
+    --  5/22/00 - RLB - Added Includes_Changes to Create.
+    --  5/23/00 - RLB - Added Set_Column and New_Column.
+    --               - Added Tab_Info and Tab_Stops.
+    --  5/24/00 - RLB - Added Location to Text_Format.
+    --         - RLB - Added No_Breaks and Keep_with_Next to Start_Paragraph.
+    --  5/25/00 - RLB - Added Big_Files to Create. Added Justification.
+    --         - RLB - Added Separator_Lines and TOC routines.
+    --  5/26/00 - RLB - Added table operations.
+    --  6/ 2/00 - RLB - Added Soft_Line_Break.
+    --  8/ 2/00 - RLB - Added Soft_Hyphen_Break and left and right quote
+    --                 characters.
+    --         - RLB - Added new styles.
+    --  8/ 7/00 - RLB - Added Leading flag to Start_Paragraph, removed 
"Leading"
+    --                 styles.
+    --  8/11/00 - RLB - Added Hanging_in_Bulleted styles.
+    --  8/16/00 - RLB - Added Code_Indented_Nested_Bulleted.
+    --  8/17/00 - RLB - Replaced "Leading" by "Space_After".
+    --                 - RLB - Added Nested_Enumerated.
+    --  8/22/00 - RLB - Added Revised_Clause_Header.
+    --  9/26/00 - RLB - Added Syntax_Summary style.
+    --  7/18/02 - RLB - Removed Document parameter from Create, replaced by
+    --                 three strings and For_ISO boolean.
+    --         - RLB - Added AI_Reference.
+    --         - RLB - Added Change_Version_Type and uses.
+    --  9/10/04 - RLB - Added "Both" to possible changes to handle
+    --                 replacement of changed text.
+    --  9/14/04 - RLB - Moved Change_Version_Type to ARM_Contents to
+    --                 avoid circularities.
+    -- 11/03/04 - RLB - Added Nested_X2_Bulleted.
+    -- 11/15/04 - RLB - Added Indented_Nested_Bulleted.
+    --  1/24/05 - RLB - Added Inner_Indented.
+    --  2/ 1/05 - RLB - Added Turkish chars to allow an AARM note.
+    --  5/27/05 - RLB - Added arbitrary Unicode characters.
+    --  1/11/06 - RLB - Eliminated dispatching Create in favor of tailored
+    --                 versions.
+    --  1/13/06 - RLB - Added new Link operations.
+    --  2/ 8/06 - RLB - Added additional parameters to the table command.
+    --  2/10/06 - RLB - Added even more additional parameters to the
+    --                 table command.
+    --         - RLB - Added picture command.
+    --  3/28/06 - RLB - Updated the comments on the picture command.
+    --  9/25/06 - RLB - Added Last_Column_Width to Start_Table.
+    -- 10/13/06 - RLB - Added Local_Link_Start and Local_Link_End to allow
+    --                 formatting in the linked text.
+    --  2/ 9/07 - RLB - Changed comments on AI_Reference.
+    --  2/13/07 - RLB - Revised to separate style and indent information
+    --                 for paragraphs.
+    --  2/19/07 - RLB - Added Title style to eliminate issues with title
+    --                 pages.
+    -- 12/19/07 - RLB - Added limited colors to Text_Format.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/25/11 - RLB - Added old insertion version to Revised_Clause_Header.
+    -- 10/18/12 - RLB - Added additional hanging styles to reflect additional
+    --                 hang amounts.
+    -- 11/26/12 - RLB - Added subdivision names to Clause_Header and
+    --                 Revised_Clause_Header.
+
+    type Output_Type is abstract tagged limited null record;
+
+    Not_Valid_Error : exception; -- Raised when an operation is invalid.
+
+    -- Creation is handled by the individual output types.
+
+    type Top_Level_Subdivision_Name_Kind is (Chapter, Section, Clause);
+
+
+    procedure Close (Output_Object : in out Output_Type) is abstract;
+       -- Close an Output_Object. No further output to the object is
+       -- allowed after this call.
+
+
+    procedure Section (Output_Object : in out Output_Type;
+                      Section_Title : in String;
+                      Section_Name : in String) is abstract;
+       -- Start a new section. The title is Section_Title (this is
+       -- intended for humans). The name is Section_Name (this is
+       -- intended to be suitable to be a portion of a file name).
+
+    subtype Column_Count is Natural range 1 .. 8;
+    procedure Set_Columns (Output_Object : in out Output_Type;
+                          Number_of_Columns : in ARM_Output.Column_Count) is 
abstract;
+       -- Set the number of columns.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    type Paragraph_Indent_Type is range 0 .. 7;
+       -- The number of units that the text is indented.
+       -- The indentation of paragraphs is described in "units", a mostly
+       -- fixed amount from the left margin.
+
+    type Paragraph_Style_Type is (
+       -- Styles without prefixes:
+       Normal,         -- Normal paragraphs have the style of the body text
+                       -- for the Reference Manual.
+       Wide_Above,     -- Same as Normal, except that there is additional space
+                       -- before the paragraph.
+       Small,          -- Like Normal, except for a smaller font. (Use for
+                       -- notes and annotations, for instance.)
+       Small_Wide_Above, -- Like Small, except that there is additional space
+                       -- before the paragraph.
+       Header,         -- Like Normal, but with no empty space following.
+       Small_Header,   -- Like Small, but with no empty space following. (Use
+                       -- for the header to Notes, for instance).
+       Syntax_Summary, -- The text is in a smaller font, and there is less
+                       -- space than normal between lines.
+       Index,          -- The text is in a smaller font, and if possible,
+                       -- lines that wrap are indented one (additional) unit.
+       Title,          -- The text is in a much larger font (+3 in terms
+                       -- of size units, nearly double the normal size),
+                       -- and with additional space before as in Wide_Above.
+       Examples,       -- The text is in a fixed font.
+       Small_Examples, -- The text is in a smaller fixed font.
+       Swiss_Examples, -- The text is in a swiss (sans-serif) font.
+       Small_Swiss_Examples, -- The text is in a smaller swiss (sans-serif) 
font.
+       -- Styles with prefixes:
+       Bulleted,       -- The text is normal other than that it has a right
+                       -- indent of one unit, and each paragraph is preceeded
+                       -- by a bullet (a solid circle). Indent must be at least
+                       -- one.
+       Small_Bulleted, -- Same as Bulleted, except that a smaller font (same as
+                       -- for Small) is used.
+       Nested_Bulleted,-- Same as Bulleted, except that a small bullet is used.
+       Small_Nested_Bulleted, -- Same as Small_Bulleted, except that a small
+                       -- bullet is used.
+       -- Styles with text prefixes:
+       Enumerated,     -- The text is normal other than it has a right indent
+                       -- of one unit, but the first part of each paragraph (up
+                       -- to the call of End_Hang_Item) hangs out as would a
+                       -- bullet. Indent must be at least one.
+       Small_Enumerated, -- Same as Enumerated, except that a smaller font
+                       -- (same as for Small) is used.
+       Giant_Hanging,  -- The text is normal, but the first part of each
+                       -- paragraph (up to the call of End_Hang_Item) hangs
+                       -- out four units. Indent must be at least four.
+       Small_Giant_Hanging, -- Same as Giant_Hanging, except that the text is
+                       -- in a smaller font (same as Small).
+       Wide_Hanging,   -- The text is normal, but the first part of each
+                       -- paragraph (up to the call of End_Hang_Item) hangs
+                       -- out three units. Indent must be at least three.
+       Small_Wide_Hanging, -- Same as Wide_Hanging, except that the text is
+                       -- in a smaller font (same as Small).
+       Medium_Hanging, -- The text is normal, but the first part of each
+                       -- paragraph (up to the call of End_Hang_Item) hangs
+                       -- out two units. Indent must be at least two.
+       Small_Medium_Hanging, -- Same as Medium_Hanging, except that the text is
+                       -- in a smaller font (same as Small).
+       Narrow_Hanging, -- The text is normal, but the first part of each
+                       -- paragraph (up to the call of End_Hang_Item) hangs
+                       -- out one unit. Indent must be at least one.
+       Small_Narrow_Hanging, -- Same as Narrow_Hanging, except that the text is
+                       -- in a smaller font (same as Small).
+       Hanging_in_Bulleted, -- The text is normal, but it has a right indent
+                       -- of one unit, and the first part of each
+                       -- paragraph (up to the call of End_Hang_Item) hangs
+                       -- out two units. Indent must be at least two.
+       Small_Hanging_in_Bulleted); -- Same as Hanging_in_Bulleted, except that
+                       -- the text is in a smaller font (same as Small).
+
+    subtype Unprefixed_Style_Subtype is
+       Paragraph_Style_Type range Normal .. Small_Swiss_Examples;
+       -- These styles have no prefix at all.
+    subtype Prefixed_Style_Subtype is
+       Paragraph_Style_Type range Bulleted .. Small_Hanging_in_Bulleted;
+       -- These styles have some sort of prefix.
+    subtype Text_Prefixed_Style_Subtype is
+       Paragraph_Style_Type range Enumerated .. Small_Hanging_in_Bulleted;
+       -- These styles have a text prefix.
+    subtype Bullet_Prefixed_Style_Subtype is
+       Paragraph_Style_Type range Bulleted .. Small_Nested_Bulleted;
+       -- These styles have a bullet prefix.
+
+
+    subtype Tab_Location is Natural range 0 .. 200; -- Location of tab stops, 
in picas.
+    type Tab_Kind_Type is (Left_Fixed, Left_Proportional);
+       -- Proportional tabs are adjusted based on the default font size of
+       -- the paragraph; they are given as if the font is 12 points.
+    type Tab_Stop_Type is record
+       Stop : Tab_Location;
+       Kind : Tab_Kind_Type;
+    end record;
+    type Tab_Stops_Type is array (1 .. 20) of Tab_Stop_Type;
+    type Tab_Info is record
+       Number : Natural;
+       Stops : Tab_Stops_Type;
+    end record;
+    NO_TABS : constant Tab_Info := (Number => 0, Stops => (others =>
+       (Kind => Left_Fixed, Stop => 0)));
+
+    type Justification_Type is (Default, Justified, Left, Center, Right);
+       -- Defines the text justification for the paragraph.
+
+    type Space_After_Type is (Normal, Narrow, Wide);
+       -- Defines the space following the paragraph. Narrow is about 30%
+       -- less than normal; Wide is about 50% more than normal.
+
+    type Change_Type is (None, Insertion, Deletion, Both);
+       -- Defines the change state. Both means both an Insertion and Deletion.
+
+    procedure Start_Paragraph (Output_Object : in out Output_Type;
+                              Style     : in ARM_Output.Paragraph_Style_Type;
+                              Indent    : in ARM_Output.Paragraph_Indent_Type;
+                              Number    : in String;
+                              No_Prefix : in Boolean := False;
+                              Tab_Stops : in ARM_Output.Tab_Info := 
ARM_Output.NO_TABS;
+                              No_Breaks : in Boolean := False;
+                              Keep_with_Next : in Boolean := False;
+                              Space_After : in ARM_Output.Space_After_Type
+                                  := ARM_Output.Normal;
+                              Justification : in ARM_Output.Justification_Type
+                                  := ARM_Output.Default) is abstract;
+       -- Start a new paragraph. The style and indent of the paragraph is as
+       -- specified. The (AA)RM paragraph number (which might include update
+       -- and version numbers as well: [12.1/1]) is Number. If the format is
+       -- a type with a prefix (bullets, hangining items), the prefix is
+       -- omitted if No_Prefix is true. Tab_Stops defines the tab stops for
+       -- the paragraph. If No_Breaks is True, we will try to avoid page breaks
+       -- in the paragraph. If Keep_with_Next is true, we will try to avoid
+       -- separating this paragraph and the next one. (These may have no
+       -- effect in formats that don't have page breaks). Space_After
+       -- specifies the amount of space following the paragraph. Justification
+       -- specifies the text justification for the paragraph. Not_Valid_Error
+       -- is raised if Tab_Stops /= NO_TABS for a hanging or bulleted format.
+
+    procedure End_Paragraph (Output_Object : in out Output_Type) is abstract;
+       -- End a paragraph.
+
+    procedure Category_Header (Output_Object : in out Output_Type;
+                              Header_Text : String) is abstract;
+       -- Output a Category header (that is, "Legality Rules",
+       -- "Dynamic Semantics", etc.)
+       -- (Note: We did not use a enumeration here to insure that these
+       -- headers are spelled the same in all output versions).
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Clause_Header (Output_Object     : in out Output_Type;
+                            Header_Text       : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False) is 
abstract;
+       -- Output a Clause header. The level of the header is specified
+       -- in Level. The Clause Number is as specified; the top-level (and
+       -- other) subdivision names are as specified. These should appear in
+       -- the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Revised_Clause_Header
+                           (Output_Object     : in out Output_Type;
+                            New_Header_Text   : in String;
+                            Old_Header_Text   : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Version           : in 
ARM_Contents.Change_Version_Type;
+                            Old_Version       : in 
ARM_Contents.Change_Version_Type;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False) is 
abstract;
+       -- Output a revised clause header. Both the original and new text will
+       -- be output. The level of the header is specified in Level. The Clause
+       -- Number is as specified; the top-level (and other) subdivision names
+       -- are as specified. These should appear in the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- Version is the insertion version of the new text; Old_Version is
+       -- the insertion version of the old text.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure TOC_Marker (Output_Object : in out Output_Type;
+                         For_Start : in Boolean) is abstract;
+       -- Mark the start (if For_Start is True) or end (if For_Start is
+       -- False) of the table of contents data. Output objects that
+       -- auto-generate the table of contents can use this to do needed
+       -- actions.
+
+    type Page_Kind_Type is (Any_Page, Odd_Page_Only, Soft_Page);
+
+    procedure New_Page (Output_Object : in out Output_Type;
+                       Kind : ARM_Output.Page_Kind_Type := 
ARM_Output.Any_Page) is abstract;
+       -- Output a page break.
+       -- Note that this has no effect on non-printing formats.
+       -- Any_Page breaks to the top of the next page (whatever it is);
+       -- Odd_Page_Only breaks to the top of the odd-numbered page;
+       -- Soft_Page allows a page break but does not force one (use in
+       -- "No_Breaks" paragraphs.)
+       -- Raises Not_Valid_Error if in a paragraph if Kind = Any_Page or
+       -- Odd_Page, and if not in a paragraph if Kind = Soft_Page.
+
+    procedure New_Column (Output_Object : in out Output_Type) is abstract;
+       -- Output a column break.
+       -- Raises Not_Valid_Error if in a paragraph, or if the number of
+       -- columns is 1.
+
+    procedure Separator_Line (Output_Object : in out Output_Type;
+                             Is_Thin : Boolean := True) is abstract;
+       -- Output a separator line. It is thin if "Is_Thin" is true.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    type Column_Text_Alignment is (Center_All, Left_All, Center_except_First);
+    type Header_Kind_Type is (Both_Caption_and_Header, Header_Only, 
No_Headers);
+
+    procedure Start_Table (Output_Object : in out Output_Type;
+                          Columns : in ARM_Output.Column_Count;
+                          First_Column_Width : in ARM_Output.Column_Count;
+                          Last_Column_Width : in ARM_Output.Column_Count;
+                          Alignment : in ARM_Output.Column_Text_Alignment;
+                          No_Page_Break : in Boolean;
+                          Has_Border : in Boolean;
+                          Small_Text_Size : in Boolean;
+                          Header_Kind : in ARM_Output.Header_Kind_Type) is 
abstract;
+       -- Starts a table. The number of columns is Columns; the first
+       -- column has First_Column_Width times the normal column width, and
+       -- the last column has Last_Column_Width times the normal column width.
+       -- Alignment is the horizontal text alignment within the columns.
+       -- No_Page_Break should be True to keep the table intact on a single
+       -- page; False to allow it to be split across pages.
+       -- Has_Border should be true if a border is desired, false otherwise.
+       -- Small_Text_Size means that the contents will have the AARM size;
+       -- otherwise it will have the normal size.
+       -- Header_Kind determines whether the table has headers.
+       -- This command starts a paragraph; the entire table is a single
+       -- paragraph. Text will be considered part of the caption until the
+       -- next table marker call.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    type Table_Marker_Type is (End_Caption, End_Item, End_Header,
+       End_Row, End_Row_Next_Is_Last, End_Table);
+    procedure Table_Marker (Output_Object : in out Output_Type;
+                           Marker : in ARM_Output.Table_Marker_Type) is 
abstract;
+       -- Marks the end of an entity in a table.
+       -- If Marker is End_Caption, the table caption ends and the
+       --      future text is part of the table header.
+       -- If Marker is End_Header, the table header ends and the
+       --      future text is part of the table body.
+       -- If Marker is End_Row, a row in the table is completed, and another
+       --      row started.
+       -- If Marker is End_Row_Next_Is_Last, a row in the table is completed,
+       --      and another row started. That row is the last row in the table.
+       -- If Marker is End_Item, an item in the table header or body is ended,
+       --      and another started.
+       -- If Marker is End_Table, the entire table is finished.
+       -- Raises Not_Valid_Error if not in a table.
+
+    -- Text output: These are only allowed after a Start_Paragraph and
+    -- before any End_Paragraph. Raises Not_Valid_Error if not allowed.
+
+    procedure Ordinary_Text (Output_Object : in out Output_Type;
+                            Text : in String) is abstract;
+       -- Output ordinary text.
+       -- The text must end at a word break, never in the middle of a word.
+
+    procedure Ordinary_Character (Output_Object : in out Output_Type;
+                                 Char : in Character) is abstract;
+       -- Output an ordinary (Latin-1) character.
+       -- Spaces will be used to break lines as needed.
+
+    procedure Hard_Space (Output_Object : in out Output_Type) is abstract;
+       -- Output a hard space. No line break should happen at a hard space.
+
+    procedure Line_Break (Output_Object : in out Output_Type) is abstract;
+       -- Output a line break. This does not start a new paragraph.
+       -- This corresponds to a "<BR>" in HTML.
+
+    procedure Index_Line_Break (Output_Object : in out Output_Type;
+                               Clear_Keep_with_Next : in Boolean) is abstract;
+       -- Output a line break for the index. This does not start a new
+       -- paragraph in terms of spacing. This corresponds to a "<BR>"
+       -- in HTML. If Clear_Keep_with_Next is true, insure that the next
+       -- line does not require the following line to stay with it.
+       -- Raises Not_Valid_Error if the paragraph is not in the index format.
+
+    procedure Soft_Line_Break (Output_Object : in out Output_Type) is abstract;
+       -- Output a soft line break. This is a place (in the middle of a
+       -- "word") that we allow a line break. It is usually used after
+       -- underscores in long non-terminals.
+
+    procedure Soft_Hyphen_Break (Output_Object : in out Output_Type) is 
abstract;
+       -- Output a soft line break, with a hyphen. This is a place (in the 
middle of
+       -- a "word") that we allow a line break. If the line break is used,
+       -- a hyphen will be added to the text.
+
+    procedure Tab (Output_Object : in out Output_Type) is abstract;
+       -- Output a tab, inserting space up to the next tab stop.
+       -- Raises Not_Valid_Error if the paragraph was created with
+       -- Tab_Stops = ARM_Output.NO_TABS.
+
+    type Special_Character_Type is (EM_Dash, -- EM (very long) dash.
+                                   EN_Dash, -- EN (long) dash
+                                   GEQ, -- Greater than or equal symbol.
+                                   LEQ, -- Less than or equal symbol.
+                                   NEQ, -- Not equal symbol.
+                                   PI,  -- PI.
+                                   Left_Ceiling, -- Left half of ceiling.
+                                   Right_Ceiling, -- Right half of ceiling.
+                                   Left_Floor, -- Left half of floor.
+                                   Right_Floor, -- Right half of floor.
+                                   Thin_Space, -- A thinner than usual space.
+                                   Left_Quote, -- A left facing single quote.
+                                   Right_Quote, -- A right facing single quote.
+                                   Left_Double_Quote, -- A left facing double 
quote.
+                                   Right_Double_Quote, -- A right facing 
double quote.
+                                   Small_Dotless_I, -- A small i without a dot 
(Unicode(16#0131#).
+                                   Capital_Dotted_I -- A large I with a dot 
(Unicode(16#0130#).
+                                  );
+
+    procedure Special_Character (Output_Object : in out Output_Type;
+                                Char : in ARM_Output.Special_Character_Type) 
is abstract;
+       -- Output an special character.
+
+    type Unicode_Type is range 0 .. 2**31-2;
+
+    procedure Unicode_Character (Output_Object : in out Output_Type;
+                                Char : in ARM_Output.Unicode_Type) is abstract;
+       -- Output a Unicode character, with code position Char.
+
+    procedure End_Hang_Item (Output_Object : in out Output_Type) is abstract;
+       -- Marks the end of a hanging item. Call only once per paragraph.
+       -- Raises Not_Valid_Error if the paragraph style is not in
+       -- Text_Prefixed_Style_Subtype, or if this has already been
+       -- called for the current paragraph, or if the paragraph was started
+       -- with No_Prefix = True.
+
+
+    type Font_Family_Type is (Roman, Swiss, Fixed, Default);
+       -- Determines the font family. "Default" is the font family
+       -- of a paragraph before it is changed.
+
+    type Size_Type is range -9 .. 9;
+       -- Determines the relative size. This is the change in size. For
+       -- formats that allow it, this is the change in size in points.
+       -- Otherwise, this is a relative change.
+
+    type Color_Type is (Default, Black, Red, Green, Blue);
+       -- Determines the text color. "Default" is usually black,
+       -- although some formats may use color to indicate changes.
+
+    type Location_Type is (Normal, Subscript, Superscript);
+       -- Determines the location (vertical position) of the text: in the
+       -- normal position, subscripted (below the normal position), or
+       -- superscripted (above the normal position).
+
+    type Format_Type is record
+       -- A grouping of all of the format parameters.
+       Bold    : Boolean;
+       Italic  : Boolean;
+       Font    : ARM_Output.Font_Family_Type;
+       Size    : ARM_Output.Size_Type;
+       Color   : ARM_Output.Color_Type;
+        Change  : ARM_Output.Change_Type;
+        Version : ARM_Contents.Change_Version_Type;
+        Added_Version : ARM_Contents.Change_Version_Type;
+           -- Only used when Change = Both; this is then the version
+           -- of the insertion, and Version is then the version of the 
deletion.
+        Location : ARM_Output.Location_Type;
+    end record;
+    NORMAL_FORMAT : constant Format_Type :=
+       (Bold => False, Italic => False, Font => Default,
+        Size => 0, Color => Default, Change => None, Version => '0',
+        Added_Version => '0', Location => Normal);
+       -- The format of utterly normal text. Usually used to reset
+       -- the format or for initialization.
+
+    procedure Text_Format (Output_Object : in out Output_Type;
+                          Format : in ARM_Output.Format_Type) is abstract;
+       -- Change the text format so that all of the properties are as 
specified.
+       -- Note: Changes to these properties ought be stack-like; that is,
+       -- Bold on, Italic on, Italic off, Bold off is OK; Bold on, Italic on,
+       -- Bold off, Italic off should be avoided (as separate commands).
+
+    procedure Clause_Reference (Output_Object : in out Output_Type;
+                               Text : in String;
+                               Clause_Number : in String) is abstract;
+       -- Generate a reference to a clause in the standard. The text of
+       -- the reference is "Text", and the number of the clause is
+       -- Clause_Number. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure Index_Target (Output_Object : in out Output_Type;
+                           Index_Key : in Natural) is abstract;
+       -- Generate a index target. This marks the location where an index
+       -- reference occurs. Index_Key names the index item involved.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, nothing is generated.
+
+    procedure Index_Reference (Output_Object : in out Output_Type;
+                              Text : in String;
+                              Index_Key : in Natural;
+                              Clause_Number : in String) is abstract;
+       -- Generate a reference to an index target in the standard. The text
+       -- of the reference is "Text", and Index_Key and Clause_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure DR_Reference (Output_Object : in out Output_Type;
+                           Text : in String;
+                           DR_Number : in String) is abstract;
+       -- Generate a reference to a DR from the standard. The text
+       -- of the reference is "Text", and DR_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure AI_Reference (Output_Object : in out Output_Type;
+                           Text : in String;
+                           AI_Number : in String) is abstract;
+       -- Generate a reference to an AI from the standard. The text
+       -- of the reference is "Text", and AI_Number denotes
+       -- the target (in unfolded format). For hyperlinked formats, this
+       -- should generate a link; for other formats, the text alone is
+       -- generated.
+
+    procedure Local_Target (Output_Object : in out Output_Type;
+                           Text : in String;
+                           Target : in String) is abstract;
+       -- Generate a local target. This marks the potential target of local
+       -- links identified by "Target". Text is the text of the target.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link (Output_Object : in out Output_Type;
+                         Text : in String;
+                         Target : in String;
+                         Clause_Number : in String) is abstract;
+       -- Generate a local link to the target and clause given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link_Start (Output_Object : in out Output_Type;
+                               Target : in String;
+                               Clause_Number : in String) is abstract;
+       -- Generate a local link to the target and clause given.
+       -- The link will surround text until Local_Link_End is called.
+       -- Local_Link_End must be called before this routine can be used again.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link_End (Output_Object : in out Output_Type;
+                             Target : in String;
+                             Clause_Number : in String) is abstract;
+       -- End a local link for the target and clause given.
+       -- This must be in the same paragraph as the Local_Link_Start.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure URL_Link (Output_Object : in out Output_Type;
+                       Text : in String;
+                       URL : in String) is abstract;
+       -- Generate a link to the URL given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    type Picture_Alignment is (Inline, Float_Left, Float_Right,
+       Alone_Left, Alone_Right, Alone_Center);
+       -- Inline puts the picture as part of a paragraph;
+       -- Alone styles put the picture as the only things on the line;
+       -- Float styles wrap text around the picture. Alone styles are
+       -- *not* part of paragraphs.
+
+    type Border_Kind is (None, Thin, Thick);
+
+    procedure Picture  (Output_Object : in out Output_Type;
+                       Name  : in String;
+                       Descr : in String;
+                       Alignment : in ARM_Output.Picture_Alignment;
+                       Height, Width : in Natural;
+                       Border : in ARM_Output.Border_Kind) is abstract;
+       -- Generate a picture.
+       -- Name is the (simple) file name of the picture; Descr is a
+       -- descriptive name for the picture (it will appear in some web
+       -- browsers).
+       -- We assume that it is a .PNG or .JPG and that it will be present
+       -- in the same directory as the output files.
+       -- Alignment specifies the picture alignment.
+       -- Height and Width specify the picture size in pixels.
+       -- Border specifies the kind of border.
+
+end ARM_Output;
diff --git a/packages/ada-ref-man/progs/arm_rtf.adb 
b/packages/ada-ref-man/progs/arm_rtf.adb
new file mode 100755
index 0000000..fa2ed02
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_rtf.adb
@@ -0,0 +1,6242 @@
+with --ARM_Output,
+     --ARM_Contents,
+     --Ada.Text_IO,
+     Ada.Exceptions,
+     Ada.Streams.Stream_IO,
+     Ada.Strings.Maps,
+     Ada.Strings.Fixed,
+     Ada.Characters.Handling,
+     Ada.Calendar,
+     Ada.Unchecked_Conversion;
+package body ARM_RTF is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package defines the RTF output object.
+    -- Output objects are responsible for implementing the details of
+    -- a particular format.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2004, 2005, 2006, 2007, 2009, 2010, 2011, 2012,
+    --     2013, 2016
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/18/00 - RLB - Created package.
+    --  5/22/00 - RLB - Added Includes_Changes to Create.
+    --  5/23/00 - RLB - Added Set_Column and New_Column.
+    --               - Added Tab_Info and Tab_Stops.
+    --  5/24/00 - RLB - Added Location to Text_Format.
+    --         - RLB - Added No_Breaks and Keep_with_Next to Start_Paragraph.
+    --  5/25/00 - RLB - Added Big_Files to Create. Added Justification.
+    --         - RLB - Added Separator_Lines and TOC routines.
+    --  5/26/00 - RLB - Added table operations.
+    --  5/27/00 - RLB - Implemented table operations.
+    --  5/28/00 - RLB - Added index style.
+    --  6/ 2/00 - RLB - Added Soft_Line_Break.
+    --         - RLB - Changed back to mostly "after" spacing, so paragraph
+    --                 numbers format correctly on tops of pages.
+    --  8/ 2/00 - RLB - Added Soft_Hyphen_Break and left and right quote
+    --                 characters.
+    --         - RLB - Added additional styles.
+    --          - RLB - Fixed bulleted styles to have a right indent as well.
+    --  8/ 4/00 - RLB - Added additional styles.
+    --         - RLB - Fixed table text size.
+    --  8/ 7/00 - RLB - Added Leading flag to Start_Paragraph, removed 
"Leading"
+    --                 styles.
+    --  8/ 8/00 - RLB - Added "Hang_Width" in order to get more accurate
+    --                 hang prefix determination.
+    --  8/10/00 - RLB - Style corrections.
+    --  8/11/00 - RLB - Fixed footers for clauses with very long titles.
+    --         - RLB - Added Hanging_in_Bulleted styles.
+    --  8/16/00 - RLB - Adjusted so captial 'I' is not a large character.
+    --         - RLB - Added Code_Indented_Nested_Bulleted and 
Notes_Nested_Bulleted.
+    --  8/17/00 - RLB - Replaced "Leading" by "Space_After".
+    --                 - RLB - Added Nested_Enumerated.
+    --  8/21/00 - RLB - Moved paragraph numbers in a bit for AARM.
+    --  8/22/00 - RLB - Added Revised_Clause_Header.
+    --  8/23/00 - RLB - Revised widths of AARM text to be more like RM.
+    --  8/31/00 - RLB - Moved paragraphs in again.
+    --  9/26/00 - RLB - Added Syntax_Summary style.
+    --  9/27/00 - RLB - Cut the lower margin for the AARM pages.
+    --  7/18/02 - RLB - Removed Document parameter, replaced by three
+    --                 strings.
+    --         - RLB - Added AI_Reference.
+    --         - RLB - Added Change_Version_Type and uses.
+    --  9/10/04 - RLB - Added "Both" to possible changes to handle
+    --                 replacement of changed text.
+    --  9/14/04 - RLB - Moved Change_Version_Type to contents.
+    --  9/15/04 - RLB - Completely rewrote Text_Format to avoid problems
+    --                 with ordering of calls.
+    -- 11/03/04 - RLB - Added Nested_X2_Bulleted.
+    -- 11/15/04 - RLB - Added Indented_Nested_Bulleted.
+    -- 11/16/04 - RLB - Experimented with changes to avoid the hot pink
+    --                 revision markers.
+    -- 12/15/04 - RLB - Added Pascal's workaround to formatting bugs in
+    --                 Word 2000/XP/2003.
+    -- 12/16/04 - RLB - Removed it after it proved not to help.
+    --  1/24/05 - RLB - Added Inner_Indent.
+    --  2/ 1/05 - RLB - Added Turkish chars to allow an AARM note.
+    --  5/27/05 - RLB - Added arbitrary Unicode characters.
+    --  1/11/06 - RLB - Eliminated dispatching Create in favor of tailored
+    --                 versions.
+    --  1/18/06 - RLB - Added additional styles.
+    --  2/ 8/06 - RLB - Added additional parameters to the table command.
+    --  2/10/06 - RLB - Added even more additional parameters to the
+    --                 table command.
+    --         - RLB - Added picture command.
+    --  9/21/06 - RLB - Added Body_Font; revised styles to handle that.
+    --  9/22/06 - RLB - Added Subsubclause.
+    --  9/25/06 - RLB - Handled optional renaming of TOC.
+    --         - RLB - Added Last_Column_Width to Start_Table.
+    -- 10/10/06 - RLB - Widened bulleted and enumerated hanging a bit to make
+    --                 room for wider numbers for ISO 2004 format.
+    -- 10/13/06 - RLB - Added Local_Link_Start and Local_Link_End to allow
+    --                 formatting in the linked text.
+    -- 12/22/06 - RLB - Fixed glitch in number of column units.
+    --  2/ 9/07 - RLB - Changed comments on AI_Reference.
+    --  2/14/07 - RLB - Revised to separate style and indent information
+    --                 for paragraphs.
+    --  2/16/07 - RLB - Added example styles for additional nesting levels.
+    --  2/19/07 - RLB - Added Standard Title style.
+    -- 12/18/07 - RLB - Fixed silly table bug.
+    --         - RLB - Added Plain_Annex.
+    -- 12/19/07 - RLB - Added limited colors to Text_Format.
+    -- 12/21/07 - RLB - Removed extra "not" from "large" character counter
+    --                 in Ordinary_Character.
+    --  5/ 4/09 - RLB - Added the footer information.
+    --  5/ 6/09 - RLB - Added ISO format footer and version names.
+    -- 10/28/09 - RLB - Added missing with.
+    --  3/31/10 - RLB - Adjusted picture scaling to be closer to reality.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/20/11 - RLB - Updated to handle extra-wide paragraph numbers
+    --                 automatically (there are too many to hand-fix now).
+    -- 10/25/11 - RLB - Added old insertion version to Revised_Clause_Header.
+    --  4/ 3/12 - RLB - Eliminated redundancy.
+    --  8/31/12 - RLB - Added Output_Path.
+    -- 10/18/12 - RLB - Added additional hanging styles.
+    -- 11/05/12 - RLB - Added various additional styles.
+    -- 11/26/12 - RLB - Added subdivision names to Clause_Header and
+    --                 Revised_Clause_Header.
+    -- 12/13/12 - RLB - Added style needed by AARM (only in deleted text).
+    --  8/16/13 - RLB - Added missing style needed by recent RM change.
+    --  6/28/16 - RLB - Added missing style needed by recent ACATS
+    --                 documentation change.
+    --  8/19/16 - RLB - Nasty bug in End_Hang_Item: it loses any open styles
+    --                 if a line break has to be inserted.
+
+
+    -- Note: We assume a lot about the Section_Names passed into
+    -- Section in order to get the proper headers/footers/page numbers.
+    -- Someday, that ought to be changed somehow.
+
+    LINE_LENGTH : constant := 78;
+       -- Maximum intended line length.
+
+    LEADING_PERCENT : constant := 70;
+       -- Leading is 70% of normal height.
+    TRAILING_PERCENT : constant := 150;
+       -- Leading is 150% of normal height.
+
+    type Format_Info_Type is record
+       Defined : Boolean := False;
+       Size : Natural; -- In 1/2 pts.
+       Indent : Natural; -- In Twips (.1 pt = 1/120th pica = 1/1440th inch).
+       Hang_Width : Natural; -- In Twips (.1 pt = 1/120th pica = 1/1440th 
inch).
+       Before : Natural; -- Vertical space before in Twips. (\sb)
+       After : Natural; -- Vertical space after in Twips. (\sa)
+       Is_Justified : Boolean; -- True if the format is justified. (\qj vs. 
\qc or \ql)
+       Number : Natural; -- Style number.
+       Format_String : String(1 .. 200);
+       Format_Len : Natural := 0;
+    end record;
+
+    Paragraph_Info : array (ARM_Output.Paragraph_Style_Type,
+                           ARM_Output.Paragraph_Indent_Type) of 
Format_Info_Type;
+       -- Set by Start_RTF_File.
+    Heading_1_Info : Format_Info_Type;
+    Heading_2_Info : Format_Info_Type;
+    Heading_3_Info : Format_Info_Type;
+    Heading_4_Info : Format_Info_Type;
+    Category_Header_Info : Format_Info_Type;
+    Normal_Paragraph_Number_Info : Format_Info_Type;
+    Wide_Paragraph_Number_Info : Format_Info_Type;
+    Header_Info : Format_Info_Type;
+    Footer_Info : Format_Info_Type;
+    TOC_1_Info : Format_Info_Type;
+    TOC_2_Info : Format_Info_Type;
+    TOC_3_Info : Format_Info_Type;
+    TOC_4_Info : Format_Info_Type;
+
+    Table_C_Text_Info : Format_Info_Type;
+    Table_L_Text_Info : Format_Info_Type;
+    Table_C_Sml_Text_Info : Format_Info_Type;
+    Table_L_Sml_Text_Info : Format_Info_Type;
+
+    procedure Set_Style (Into : in out Format_Info_Type;
+                        Font : in ARM_Output.Font_Family_Type; -- Default 
means use Body_Font.
+                        Body_Font : in ARM_Output.Font_Family_Type;
+                        Font_Size : in Natural;
+                        Style_Indent : in Natural;
+                        Style_Hang_Width : in Natural := 0;
+                        Style_Before : in Natural;
+                        Style_After : in Natural;
+                        Style_Justified : in Boolean;
+                        Style_String_Prefix : in String;
+                        Style_String_Suffix : in String) is
+       -- Internal routine.
+       -- Set the indicated style information.
+       -- The two part of the Style String includes all of the information
+       -- except Font (\fn), Font_Size (\fsnn), Indent (\linn), Hang (\fi-nn),
+       -- Before (\sbnn), and After (\sann) -- these are added appropriately
+       -- between the halves of the string.
+       Font_String : String(1..3) := "\f0";
+
+       function Make (Code : in String; Value : in Natural) return String is
+           Val : constant String := Natural'Image(Value);
+       begin
+           if Value /= 0 then
+               return '\' & Code & Val(2..Val'Last);
+           else
+               return ""; -- Make nothing.
+           end if;
+       end Make;
+
+    begin
+       Into.Defined := True;
+       Into.Size := Font_Size;
+       case Font is
+           when ARM_Output.Default =>
+               if ARM_Output."=" (Body_Font, ARM_Output.Swiss) then
+                   Font_String(3) := '1';
+                   Into.Size := Into.Size - 1;
+               else -- Roman.
+                   Font_String(3) := '0';
+               end if;
+           when ARM_Output.Roman =>
+               Font_String(3) := '0';
+           when ARM_Output.Swiss =>
+               Font_String(3) := '1';
+           when ARM_Output.Fixed =>
+               Font_String(3) := '2';
+       end case;
+       Into.Indent := Style_Indent;
+       Into.Hang_Width := Style_Hang_Width;
+       Into.Before := Style_Before;
+       Into.After  := Style_After;
+       Into.Is_Justified := Style_Justified;
+       declare
+           Style : constant String :=
+                       Style_String_Prefix & " " &
+                       Font_String &
+                       Make ("fs", Into.Size) &
+                       Make ("li", Into.Indent) &
+                       Make ("fi-", Into.Hang_Width) &
+                       Make ("sb", Into.Before) &
+                       Make ("sa", Into.After) &
+                       Style_String_Suffix;
+       begin
+           Ada.Strings.Fixed.Move (Source => Style,
+                                   Target => Into.Format_String);
+            Into.Format_Len := Style'Length;
+       end;
+    end Set_Style;
+
+
+    procedure Write_Style (Fyle : in Ada.Text_IO.File_Type;
+                          Style : in Format_Info_Type) is
+       -- Internal routine.
+       -- Write a header to start a style definition for Style.
+    begin
+       if not Style.Defined then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Undefined Style in style table");
+       end if;
+        Ada.Text_IO.Put (Fyle, "{" &
+           Style.Format_String(1 .. Style.Format_Len));
+    end Write_Style;
+
+
+    procedure Write_Style_for_Paragraph (Fyle : in Ada.Text_IO.File_Type;
+                                        Style : in Format_Info_Type;
+                                        Count : out Natural) is
+       -- Internal routine.
+       -- Write a header to start a paragraph in Style. Count is set to
+       -- the characters written.
+    begin
+       if not Style.Defined then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Undefined Style in paragraph");
+       end if;
+        Ada.Text_IO.Put (Fyle, "{\pard\plain " &
+           Style.Format_String(1 .. Style.Format_Len));
+       Count := Style.Format_Len + 13;
+    end Write_Style_for_Paragraph;
+
+
+    procedure Write_Headers (Output_Object : in out RTF_Output_Type) is
+       -- Write the page headers for this object into the current file.
+       Junk : Natural;
+    begin
+        -- Default header/footer:
+        Ada.Text_IO.Put (Output_Object.Output_File, "{\headerl ");
+        Write_Style_for_Paragraph (Output_Object.Output_File, Header_Info, 
Junk);
+       if Ada.Strings.Unbounded.Length (Output_Object.Header_Prefix) = 0 then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\b\f1 " &
+               Ada.Strings.Unbounded.To_String (Output_Object.Title) &
+               "\par}}}");
+       elsif Ada.Strings.Unbounded.Length (Output_Object.Title) = 0 then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\b\f1 " &
+               Ada.Strings.Unbounded.To_String (Output_Object.Header_Prefix) &
+               "\par}}}");
+       else
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\b\f1 " &
+               Ada.Strings.Unbounded.To_String (Output_Object.Header_Prefix) &
+               " \emdash  " &
+               Ada.Strings.Unbounded.To_String (Output_Object.Title) &
+               "\par}}}");
+       end if;
+        Ada.Text_IO.Put (Output_Object.Output_File, "{\headerr ");
+        Write_Style_for_Paragraph (Output_Object.Output_File, Header_Info, 
Junk);
+       if Ada.Strings.Unbounded.Length (Output_Object.Header_Prefix) = 0 then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\qr\b\f1 " &
+               Ada.Strings.Unbounded.To_String (Output_Object.Title) &
+               "\par}}}");
+       elsif Ada.Strings.Unbounded.Length (Output_Object.Title) = 0 then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\qr\b\f1 " &
+               Ada.Strings.Unbounded.To_String (Output_Object.Header_Prefix) &
+               "\par}}}");
+       else
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\qr\b\f1 " &
+               Ada.Strings.Unbounded.To_String (Output_Object.Header_Prefix) &
+               " \emdash  " &
+               Ada.Strings.Unbounded.To_String (Output_Object.Title) &
+               "\par}}}");
+       end if;
+-- Note: We don't need the default footers; none probably work better, anyway.
+--     Ada.Text_IO.Put (Output_Object.Output_File, "{\footerl ");
+--     Write_Style_for_Paragraph (Output_Object.Output_File, Footer_Info, 
Junk);
+--     if Name = "00" or else Name = "TOC" or else Name = "Ttl" then
+--         -- No section number.
+--         Ada.Text_IO.Put (Output_Object.Output_File, "{\f0 ");
+--     else
+--            Ada.Text_IO.Put (Output_Object.Output_File, "{\b\f1 ");
+--         if Name(1) = '0' then -- Strip leading zero...
+--                Ada.Text_IO.Put (Output_Object.Output_File, 
Name(2..Name'Last));
+--         else
+--                Ada.Text_IO.Put (Output_Object.Output_File, Name);
+--         end if;
+--         Ada.Text_IO.Put (Output_Object.Output_File, "}\~\~\~{\f0 ");
+--     end if;
+--        Ada.Text_IO.Put (Output_Object.Output_File, Title);
+--        Ada.Text_IO.Put_Line (Output_Object.Output_File, "\tab 
\tab{\field{\*\fldinst { PAGE }}{\fldrslt {\lang1024 x}}}\par}}}");
+--     Ada.Text_IO.Put (Output_Object.Output_File, "{\footerr ");
+--     Write_Style_for_Paragraph (Output_Object.Output_File, Footer_Info, 
Junk);
+--     Ada.Text_IO.Put (Output_Object.Output_File, "{\f0 {\field{\*\fldinst { 
PAGE }}{\fldrslt {\lang1024 x}}}\tab \tab ");
+--        Ada.Text_IO.Put (Output_Object.Output_File, Title);
+--     if Name = "00" or else Name = "TOC" or else Name = "Ttl" then
+--         null; -- No section number.
+--     else
+--         Ada.Text_IO.Put (Output_Object.Output_File, "\~\~\~\b\f1 ");
+--         if Name(1) = '0' then -- Strip leading zero...
+--                Ada.Text_IO.Put (Output_Object.Output_File, 
Name(2..Name'Last));
+--         else
+--                Ada.Text_IO.Put (Output_Object.Output_File, Name);
+--         end if;
+--     end if;
+--     Ada.Text_IO.Put_Line (Output_Object.Output_File, "\par}}}");
+    end Write_Headers;
+
+
+    procedure Start_RTF_File (Output_Object : in out RTF_Output_Type;
+                             File_Name : in String;
+                             Title : in String;
+                             Name : in String) is
+       -- Internal routine.
+       -- Create an RTF file, and generate the needed text to start an RTF
+       -- file. The file name is just the name portion, not the path or
+       -- extension. "Name" is a short identifier, typically the clause
+       -- number or letter.
+
+       INDENT_UNIT : constant := 360;
+
+       subtype PWidth is String(1..4);
+       function Paper_Width return PWidth is
+           -- Return the paper width in twips:
+       begin
+           case Output_Object.Page_Size is
+               when ARM_RTF.A4 =>
+                   return "9030";
+               when ARM_RTF.Letter =>
+                   return "9360";
+               when ARM_RTF.Half_Letter =>
+                   return "5760";
+               when ARM_RTF.Ada95 =>
+                   return "7740";
+           end case;
+       end Paper_Width;
+
+       function Half_Paper_Width return PWidth is
+           -- Return the center of the paper width in twips:
+       begin
+           case Output_Object.Page_Size is
+               when ARM_RTF.A4 =>
+                   return "4515";
+               when ARM_RTF.Letter =>
+                   return "4680";
+               when ARM_RTF.Half_Letter =>
+                   return "2880";
+               when ARM_RTF.Ada95 =>
+                   return "3870";
+           end case;
+       end Half_Paper_Width;
+
+
+    begin
+       Ada.Text_IO.Create (Output_Object.Output_File, Ada.Text_IO.Out_File,
+           Ada.Strings.Unbounded.To_String (Output_Object.Output_Path) &
+           File_Name & ".RTF");
+
+
+       -- Note: This header (simplified) is from a Word 97 created file.
+       -- File introduction:
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033");
+           -- rtf1=RTF file marker;
+           -- ansi=character set is ansi;
+           -- ansicpg=code page for ansi-Unicode conversion (1252);
+           -- uc1=One character replacement for Unicode characters;
+           -- deff0=Default font to use (Font 0);
+           -- deflang=default language (1033 - American English);
+           -- deflangfe=default language (asian text) (1033 - American 
English).
+
+       -- Font table:
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\fonttbl");
+       case Output_Object.Primary_Serif_Font is
+           when Times_New_Roman =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"{\f0\froman\fcharset0 Times New Roman;}");
+           when Souvenir =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"{\f0\froman\fcharset0 Souvenir{\*\falt Souvienne};}");
+       end case;
+       case Output_Object.Primary_Sans_Serif_Font is
+           when Helvetica =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"{\f1\fswiss\fcharset0 Helvetica{\*\falt Arial};}"); -- Usually Arial on most 
Windows machines.
+           when Arial =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"{\f1\fswiss\fcharset0 Arial{\*\falt Helvetica};}"); -- Give Arial preference, 
because otherwise it screwed up Jim Moore's machine.
+       end case;
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"{\f2\fmodern\fcharset0\fprq1 Courier New;}");
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\f3\ftech\fcharset0 
Symbol;}}");
+           -- f=Font number;
+           -- fswiss,froman,fmodern,gtech=font family;
+           -- fcharset=character set (0=Ansi);
+           -- fprq=pitch (0=anything (default); 1=fixed; 2=variable);
+           -- falt=alternative font name;
+           -- followed by the font name
+
+       -- File table: (None used.)
+
+       -- Color table:
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\colortbl;");
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red0\green0\blue0;"); -- Color 1
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red0\green0\blue255;"); -- Color 2
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red0\green255\blue255;"); -- Color 3
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red0\green255\blue0;"); -- Color 4
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red255\green0\blue255;"); -- Color 5
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red255\green0\blue0;"); -- Color 6
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red255\green255\blue0;"); -- Color 7
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red255\green255\blue255;"); -- Color 8
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red0\green0\blue128;"); -- Color 9
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red0\green128\blue128;"); -- Color 10
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red0\green128\blue0;"); -- Color 11
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red128\green0\blue128;"); -- Color 12
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red128\green0\blue0;"); -- Color 13
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red128\green128\blue0;"); -- Color 14
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red128\green128\blue128;"); -- Color 15
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\red192\green192\blue192;}"); -- Color 16
+
+       -- Style sheet:
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\stylesheet");
+
+       if Output_Object.Page_Size = ARM_RTF.Ada95 or else
+          Output_Object.Page_Size = ARM_RTF.Half_Letter then
+           -- These are smaller page sizes than the other sizes.
+           -- ** TBD: Consider putting this into a separate parameter (there is
+           -- ** little reason for the font size to depend on the page size).
+           Set_Style (Paragraph_Info(ARM_Output.Normal, 0),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => 0,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s0\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-220\slmult0 \snext0 
");
+           Set_Style (Heading_1_Info,
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 28,
+                      Style_Indent => 0,
+                      Style_Before => 0,
+                      Style_After => 210,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s1\keepn\widctlpar\outlinelevel0\adjustright",
+                      Style_String_Suffix => "\b\kerning28\qc\cgrid \sbasedon0 
\snext0 ");
+           Set_Style (Heading_2_Info,
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 24,
+                      Style_Indent => 0,
+                      Style_Before => 240,
+                      Style_After => 120,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s2\keepn\widctlpar\outlinelevel1\adjustright",
+                      Style_String_Suffix => "\b\ql\cgrid \sbasedon0 \snext0 
");
+           Set_Style (Heading_3_Info,
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 23,
+                      Style_Indent => 0,
+                      Style_Before => 210,
+                      Style_After => 90,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s3\keepn\widctlpar\outlinelevel2\adjustright",
+                      Style_String_Suffix => "\b\ql\cgrid \sbasedon0 \snext0 
");
+           Set_Style (Category_Header_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => 0,
+                      Style_Before => 100,
+                      Style_After => 60,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s4\keepn\adjustright",
+                      Style_String_Suffix => "\cgrid\qc\i \snext0 ");
+           Set_Style (Normal_Paragraph_Number_Info,
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 12,
+                      Style_Indent => 0,
+                      Style_Before => 0,
+                      Style_After =>  0,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s5\keepn\widctlpar\adjustright " &
+                        
"\pvpara\phpg\posxo\posy0\absw450\dxfrtext100\dfrmtxtx120\dfrmtxty120"&
+                        "\cgrid\qc",
+                      Style_String_Suffix => "\snext0 "); -- Note: We adjust 
the space before on use.
+           Set_Style (Wide_Paragraph_Number_Info,
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 12,
+                      Style_Indent => 0,
+                      Style_Before => 0,
+                      Style_After =>  0,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s5\keepn\widctlpar\adjustright " &
+                        
"\pvpara\phpg\posxo\posy0\absw490\dxfrtext100\dfrmtxtx120\dfrmtxty120"&
+                        "\cgrid\qc",
+                      Style_String_Suffix => "\snext0 "); -- Note: We adjust 
the space before on use.
+           Set_Style (Paragraph_Info(ARM_Output.Small, 1), -- Notes
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s6\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-180\slmult0 \snext6 
");
+           Set_Style (Paragraph_Info(ARM_Output.Small, 2), -- Annotations
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s7\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-180\slmult0 \snext7 
");
+           Set_Style (Paragraph_Info(ARM_Output.Examples, 1),
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s8\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\sl-160\ql \snext8 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 3),
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Before => 0,
+                      Style_After => 70,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s9\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\sl-140\ql \snext9 ");
+           Set_Style (Paragraph_Info(ARM_Output.Normal, 1), -- Syntax indent
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s10\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-200 \snext10 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Normal, 3), -- Regular indent
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s11\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-220\slmult0 
\snext11 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small, 5), -- Regular 
annotation indent
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s12\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-180\slmult0 
\snext12 ");
+           Set_Style (Paragraph_Info(ARM_Output.Wide_Hanging, 3),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 1080,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s13\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext13 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Narrow_Hanging, 1),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s14\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext14 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Wide_Hanging, 5),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 1080,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s15\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-170\slmult0 
\snext15 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Narrow_Hanging, 3),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s16\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-170\slmult0 
\snext16 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Bulleted, 1),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Hang_Width => 240,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s17\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-200\slmult0\tx360 \snext17 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Nested_Bulleted, 2),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Hang_Width => 220,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s18\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-200\slmult0\tx720 \snext18 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Bulleted, 3),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 220,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s19\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-170\slmult0\tx1080 \snext19 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Nested_Bulleted, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 200,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s20\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-170\slmult0\tx1440 \snext20 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Bulleted, 4), -- Indented 
bullets
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 240,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s21\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-200\slmult0\tx1080 \snext21 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Bulleted, 2), -- Syntax indent 
bullets
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Hang_Width => 240,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s22\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-200\slmult0\tx720 \snext22 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Bulleted, 3), -- Code indented 
bullets
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 240,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s23\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-200\slmult0\tx1080 \snext23 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Normal, 2), -- Code indented
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s24\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-220\slmult0 
\snext24 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small, 4), -- Code indented 
annotations.
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s25\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-180\slmult0 
\snext25 ");
+           Set_Style (Paragraph_Info(ARM_Output.Examples, 4), -- Indented 
examples
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s26\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-160 \snext26 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 6), -- 
Indented annotation examples.
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => INDENT_UNIT*6,
+                      Style_Before => 0,
+                      Style_After => 70,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s27\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-140 \snext27 ");
+
+            Set_Style (Header_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 17,
+                      Style_Indent => 0,
+                      Style_Before => 0,
+                      Style_After => 0,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s28\widctlpar\tqc\tx" & Half_Paper_Width &
+                        "\tqr\tx" & Paper_Width & "\adjustright",
+                      Style_String_Suffix => "\cgrid \sbasedon0 \snext28 ");
+            Set_Style (Footer_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 17,
+                      Style_Indent => 0,
+                      Style_Before => 0,
+                      Style_After => 0,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s29\widctlpar" & -- "\tqc\tx" & Half_Paper_Width & 
-- We don't use or define the center tab; it causes problems with very long 
titles.
+                        "\tqr\tx" & Paper_Width & "\adjustright",
+                      Style_String_Suffix => "\cgrid \sbasedon0 \snext29 ");
+           Set_Style (Paragraph_Info(ARM_Output.Index, 0),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => 225,
+                      Style_Hang_Width => 225,
+                      Style_Before => 0,
+                      Style_After => 0,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s31\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-180\slmult0 
\snext31 ");
+           Set_Style (Paragraph_Info(ARM_Output.Wide_Above, 0),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => 0,
+                      Style_Before => 120,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s32\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-220\slmult0 \snext0 
");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Wide_Above, 2), -- Wide 
above annotations.
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Before => 90,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s33\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-180\slmult0 \snext7 
");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Header, 1), -- Notes 
header
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 0,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s34\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-180\slmult0 \snext6 
");
+                         -- Note: No extra space afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Bulleted, 2), -- Bullets 
in notes
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Hang_Width => 240,
+                      Style_Before => 0,
+                      Style_After => 60,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s35\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-170\slmult0\tx720 \snext35 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Nested_Bulleted, 3), -- 
Nested bullets in notes
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 230,
+                      Style_Before => 0,
+                      Style_After => 60,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s36\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-170\slmult0\tx1080 \snext36 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Hanging_in_Bulleted, 3),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s37\widctlpar\adjustright",
+                      Style_String_Suffix => "\ri360\cgrid\qj\sl-200\slmult0 
\snext14 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Hanging_in_Bulleted, 5),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s38\widctlpar\adjustright",
+                      Style_String_Suffix => "\ri360\cgrid\qj\sl-170\slmult0 
\snext16 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Nested_Bulleted, 4), -- Code 
indent nested bullets
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 220,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s39\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-200\slmult0\tx1440 \snext39 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Syntax_Summary, 1),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 65,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s40\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-170\slmult0 
\snext40 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Enumerated, 1),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Hang_Width => 240,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s41\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-200\slmult0\tx360 \snext41 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Enumerated, 3),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 220,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s42\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-170\slmult0\tx1080 \snext42 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Enumerated, 2),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Hang_Width => 260,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s43\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-200\slmult0\tx360 \snext43 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Enumerated, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 240,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s44\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-170\slmult0\tx1080 \snext44 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Nested_Bulleted, 3), -- Doubly 
nested bullets
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 220,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s45\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-200\slmult0\tx720 \snext45 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Nested_Bulleted, 5), -- 
Doubly nested bullets
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 200,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s46\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-170\slmult0\tx1440 \snext46 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Nested_Bulleted, 5), -- 
Indented nested bullets.
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 240,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s47\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-200\slmult0\tx1080 \snext47 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Normal, 4), -- Inner indented
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s48\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-220\slmult0 
\snext48 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small, 6), -- Inner indented
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*6,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s49\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-180\slmult0 
\snext49 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small, 3), -- Annotations in 
syntax indentation
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s50\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-180\slmult0 
\snext50 ");
+           Set_Style (Paragraph_Info(ARM_Output.Swiss_Examples, 1),
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s51\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\sl-180\ql \snext51 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Swiss_Examples, 3),
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Before => 0,
+                      Style_After => 70,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s52\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\sl-160\ql \snext52 ");
+           Set_Style (Paragraph_Info(ARM_Output.Swiss_Examples, 4), -- Indented
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s53\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-180 \snext53 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Swiss_Examples, 6), -- 
Indented
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => INDENT_UNIT*6,
+                      Style_Before => 0,
+                      Style_After => 70,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s54\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-160 \snext54 ");
+           Set_Style (Paragraph_Info(ARM_Output.Enumerated, 3), -- Doubly 
nested enumerations
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 260,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s55\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-200\slmult0\tx360 \snext43 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Enumerated, 5), -- 
Doubly nested enumerations
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 240,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s56\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-170\slmult0\tx1080 \snext56 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Examples, 2), -- Syntax 
Indented examples
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s57\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-160 \snext57 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 4), -- Syntax 
Indented annotation examples.
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Before => 0,
+                      Style_After => 70,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s58\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-140 \snext58 ");
+           Set_Style (Paragraph_Info(ARM_Output.Swiss_Examples, 2), -- Syntax 
Indented
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s59\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-180 \snext59 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Swiss_Examples, 4), -- 
Syntax Indented
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Before => 0,
+                      Style_After => 70,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s60\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-160 \snext60 ");
+           Set_Style (Paragraph_Info(ARM_Output.Examples, 3), -- Code Indented 
examples
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s61\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-160 \snext61 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 5), -- Code 
Indented annotation examples.
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Before => 0,
+                      Style_After => 70,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s62\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-140 \snext62 ");
+           Set_Style (Paragraph_Info(ARM_Output.Swiss_Examples, 3), -- Code 
Indented
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s63\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-180 \snext63 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Swiss_Examples, 5), -- 
Code Indented
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Before => 0,
+                      Style_After => 70,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s64\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-160 \snext64 ");
+           Set_Style (Paragraph_Info(ARM_Output.Title, 0),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 34, -- Slightly less than double.
+                      Style_Indent => 0,
+                      Style_Before => 120,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s65\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-360\slmult0 \snext0 
");
+           Set_Style (Paragraph_Info(ARM_Output.Giant_Hanging, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 1440,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s66\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext66 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Medium_Hanging, 2),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s67\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext67 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Giant_Hanging, 6),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*6,
+                      Style_Hang_Width => 1440,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s68\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-170\slmult0 
\snext68 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Medium_Hanging, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s69\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-170\slmult0 
\snext69 ");
+                         -- Note: Narrower space between and afterwards.
+
+           -- The following are indented one extra level:
+           Set_Style (Paragraph_Info(ARM_Output.Narrow_Hanging, 2),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s70\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext70 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Medium_Hanging, 3),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s71\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext71 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Wide_Hanging, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 1080,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s72\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext72 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Narrow_Hanging, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s73\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-170\slmult0 
\snext73 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Medium_Hanging, 5),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s74\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-170\slmult0 
\snext74 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Wide_Hanging, 6),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*6,
+                      Style_Hang_Width => 1080,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s75\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-170\slmult0 
\snext75 ");
+                         -- Note: Narrower space between and afterwards.
+
+           -- The following are indented two extra levels:
+           Set_Style (Paragraph_Info(ARM_Output.Narrow_Hanging, 3),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s76\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext76 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Medium_Hanging, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s77\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext77 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Narrow_Hanging, 5),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s78\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-170\slmult0 
\snext78 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Medium_Hanging, 6),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => INDENT_UNIT*6,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s79\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-170\slmult0 
\snext79 ");
+                         -- Note: Narrower space between and afterwards.
+
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 2), -- Notes 
indent
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Before => 0,
+                      Style_After => 70,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s80\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\sl-140\ql \snext80 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Swiss_Examples, 1),
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 70,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s81\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\sl-160\ql \snext81 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Swiss_Examples, 2),
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 70,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s82\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\sl-160\ql \snext82 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 1),
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 70,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s83\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\sl-140\ql \snext83 ");
+           Set_Style (Paragraph_Info(ARM_Output.Examples, 5), -- Child 
Indented examples
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s84\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-160 \snext84 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 7), -- Child 
Indented annotation examples.
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => INDENT_UNIT*7,
+                      Style_Before => 0,
+                      Style_After => 70,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s85\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-140 \snext85 ");
+
+           -- The following are indented three extra levels:
+           Set_Style (Paragraph_Info(ARM_Output.Narrow_Hanging, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s86\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext86 ");
+                         -- Note: Narrower space between and afterwards.
+
+           -- New styles should be added here, following numbers will need 
adjustments.
+           Set_Style (Heading_4_Info,
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => 0,
+                      Style_Before => 210,
+                      Style_After => 90,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s87\keepn\widctlpar\outlinelevel3\adjustright",
+                      Style_String_Suffix => "\b\ql\cgrid \sbasedon0 \snext0 
");
+           if Output_Object.Big_Files then
+               -- Define the TOC styles:
+                Set_Style (TOC_1_Info,
+                          Font => ARM_Output.Swiss,
+                          Body_Font => Output_Object.Body_Font,
+                          Font_Size => 20,
+                          Style_Indent => 0,
+                          Style_Before => 45,
+                          Style_After => 45,
+                          Style_Justified => FALSE,
+                          Style_String_Prefix =>
+                            "\s88\widctlpar\tqr\tldot\tx" & Paper_Width & 
"\adjustright",
+                          Style_String_Suffix => "\b\cgrid \sbasedon0 \snext0 
");
+                Set_Style (TOC_2_Info,
+                          Font => ARM_Output.Swiss,
+                          Body_Font => Output_Object.Body_Font,
+                          Font_Size => 17,
+                          Style_Indent => 200,
+                          Style_Before => 0,
+                          Style_After => 0,
+                          Style_Justified => FALSE,
+                          Style_String_Prefix =>
+                            "\s89\widctlpar\tqr\tldot\tx" & Paper_Width & 
"\adjustright",
+                          Style_String_Suffix => "\b\cgrid \sbasedon0 \snext0 
");
+                Set_Style (TOC_3_Info,
+                          Font => ARM_Output.Swiss,
+                          Body_Font => Output_Object.Body_Font,
+                          Font_Size => 17,
+                          Style_Indent => 400,
+                          Style_Before => 0,
+                          Style_After => 0,
+                          Style_Justified => FALSE,
+                          Style_String_Prefix =>
+                            "\s90\widctlpar\tqr\tldot\tx" & Paper_Width & 
"\adjustright",
+                          Style_String_Suffix => "\b\cgrid \sbasedon0 \snext0 
");
+                Set_Style (TOC_4_Info,
+                          Font => ARM_Output.Swiss,
+                          Body_Font => Output_Object.Body_Font,
+                          Font_Size => 17,
+                          Style_Indent => 600,
+                          Style_Before => 0,
+                          Style_After => 0,
+                          Style_Justified => FALSE,
+                          Style_String_Prefix =>
+                            "\s91\widctlpar\tqr\tldot\tx" & Paper_Width & 
"\adjustright",
+                          Style_String_Suffix => "\b\cgrid \sbasedon0 \snext0 
");
+           end if;
+           Set_Style (Table_C_Text_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => 0,
+                      Style_Before => 20,
+                      Style_After => 20,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix => "",
+                      Style_String_Suffix => "\qc ");
+               -- We use a bit of space above and below to avoid overrunning
+               -- the borders of the cells.
+           Set_Style (Table_L_Text_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => 0,
+                      Style_Before => 20,
+                      Style_After => 20,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix => "",
+                      Style_String_Suffix => "\ql ");
+           Set_Style (Table_C_Sml_Text_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => 0,
+                      Style_Before => 20,
+                      Style_After => 20,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix => "",
+                      Style_String_Suffix => "\qc ");
+           Set_Style (Table_L_Sml_Text_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 15,
+                      Style_Indent => 0,
+                      Style_Before => 20,
+                      Style_After => 20,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix => "",
+                      Style_String_Suffix => "\ql ");
+       else
+           Set_Style (Paragraph_Info(ARM_Output.Normal, 0),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => 0,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s0\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-260\slmult0 \snext0 
");
+           Set_Style (Heading_1_Info,
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 36,
+                      Style_Indent => 0,
+                      Style_Before => 0,
+                      Style_After => 210,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s1\keepn\widctlpar\outlinelevel0\adjustright",
+                      Style_String_Suffix => "\b\kerning36\qc\cgrid \sbasedon0 
\snext0 ");
+           Set_Style (Heading_2_Info,
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 28,
+                      Style_Indent => 0,
+                      Style_Before => 240,
+                      Style_After => 120,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s2\keepn\widctlpar\outlinelevel1\adjustright",
+                      Style_String_Suffix => "\b\ql\cgrid \sbasedon0 \snext0 
");
+           Set_Style (Heading_3_Info,
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 28,
+                      Style_Indent => 0,
+                      Style_Before => 210,
+                      Style_After => 100,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s3\keepn\widctlpar\outlinelevel2\adjustright",
+                      Style_String_Suffix => "\b\ql\cgrid \sbasedon0 \snext0 
");
+           Set_Style (Category_Header_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => 0,
+                      Style_Before => 120,
+                      Style_After => 120,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s4\keepn\adjustright",
+                      Style_String_Suffix => "\cgrid\qc\i \snext0 ");
+           Set_Style (Normal_Paragraph_Number_Info,
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => 0,
+                      Style_Before => 0,
+                      Style_After => 0,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s5\keepn\widctlpar\adjustright " &
+                        
"\pvpara\phpg\posxo\posy0\absw580\dxfrtext100\dfrmtxtx150\dfrmtxty150"&
+                        "\cgrid\qc",
+                      Style_String_Suffix => "\snext0 "); -- We adjust the 
space before for each number.
+               -- Frame commands:
+               -- \pvpara - positions the frame vertically with the next 
paragraph;
+               -- \phpg - positions the frame horizonatally within the page;
+               -- \posxo - positions the paragraph outside of the frame;
+               -- \posy0 - positions the paragraph at the top of the frame;
+               -- \absw - frame width in twips (640);
+               -- \dxfrtext - distance of frame from text in all directions 
(twips);
+               -- \dfrmtxtx - horizontal distance of text from frame (twips);
+               -- \dfrmtxty - vertical distance of text from frame (twips).
+
+           Set_Style (Wide_Paragraph_Number_Info,
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 14,
+                      Style_Indent => 0,
+                      Style_Before => 0,
+                      Style_After => 0,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s5\keepn\widctlpar\adjustright " &
+                        
"\pvpara\phpg\posxo\posy0\absw640\dxfrtext100\dfrmtxtx150\dfrmtxty150"&
+                        "\cgrid\qc",
+                      Style_String_Suffix => "\snext0 "); -- We adjust the 
space before for each number.
+
+
+           Set_Style (Paragraph_Info(ARM_Output.Small, 1), -- Notes
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s6\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 \snext6 
");
+           Set_Style (Paragraph_Info(ARM_Output.Small, 2), -- Annotations
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s7\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 \snext7 
");
+           Set_Style (Paragraph_Info(ARM_Output.Examples, 1),
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s8\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-190\slmult0 \snext8 
");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 3),
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s9\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-170\slmult0 \snext9 
");
+           Set_Style (Paragraph_Info(ARM_Output.Normal, 1), -- Syntax indented
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s10\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-240 \snext10 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Normal, 3), -- Indented
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s11\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-260\slmult0 
\snext11 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small, 5), -- Indented 
annotations
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s12\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext12 ");
+           Set_Style (Paragraph_Info(ARM_Output.Wide_Hanging, 3),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 1080,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s13\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-240\slmult0 
\snext13 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Narrow_Hanging, 1),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s14\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-240\slmult0 
\snext14 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Wide_Hanging, 5), -- 
Indented two levels for use in indented text.
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 1080,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s15\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-190\slmult0 
\snext15 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Narrow_Hanging, 3), -- 
Indented two levels for use in indented text.
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s16\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-190\slmult0 
\snext16 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Bulleted, 1),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Hang_Width => 250,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s17\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-240\slmult0\tx360 \snext17 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Nested_Bulleted, 2),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Hang_Width => 220,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s18\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-240\slmult0\tx720 \snext18 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Bulleted, 3),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 220,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s19\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-190\slmult0\tx1080 \snext19 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Nested_Bulleted, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 200,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s20\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-190\slmult0\tx1440 \snext20 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Bulleted, 4), -- Indented 
bulleted
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 250,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s21\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-240\slmult0\tx1080 \snext21 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Bulleted, 2), -- Bullets in 
syntax indenting
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Hang_Width => 250,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s22\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-240\slmult0\tx720 \snext22 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Bulleted, 3), -- Bullets in 
syntax indenting
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 250,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s23\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-240\slmult0\tx1080 \snext23 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Normal, 2), -- Code indenting
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s24\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-260\slmult0 
\snext24 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small, 4), -- Annotations in 
code indenting
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s25\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext25 ");
+           Set_Style (Paragraph_Info(ARM_Output.Examples, 4), -- Indented 
examples
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s26\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-190\slmult0 
\snext26 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 6), -- 
Indented examples in annotations.
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*6,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s27\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-170\slmult0 
\snext27 ");
+
+            Set_Style (Header_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 20,
+                      Style_Indent => 0,
+                      Style_Before => 0,
+                      Style_After => 0,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s28\widctlpar\tqc\tx" & Half_Paper_Width &
+                        "\tqr\tx" & Paper_Width & "\adjustright",
+                      Style_String_Suffix => "\cgrid \sbasedon0 \snext28 ");
+            Set_Style (Footer_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 20,
+                      Style_Indent => 0,
+                      Style_Before => 0,
+                      Style_After => 0,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s29\widctlpar" & -- "\tqc\tx" & Half_Paper_Width & 
-- We don't use or define the center tab; it causes problems with very long 
titles.
+                        "\tqr\tx" & Paper_Width & "\adjustright",
+                      Style_String_Suffix => "\cgrid \sbasedon0 \snext29 ");
+           Set_Style (Paragraph_Info(ARM_Output.Index, 0),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => 270,
+                      Style_Hang_Width => 270,
+                      Style_Before => 0,
+                      Style_After => 0,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s31\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-200\slmult0 
\snext31 ");
+           Set_Style (Paragraph_Info(ARM_Output.Wide_Above, 0),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => 0,
+                      Style_Before => 120,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s32\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-260\slmult0 \snext0 
");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Wide_Above, 2), -- Wide 
above annotations.
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Before => 90,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s33\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 \snext7 
");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Header, 1), -- Notes 
header
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 0,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s34\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 \snext6 
");
+                     -- Note: No space afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Bulleted, 2), -- Bullets 
in notes
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Hang_Width => 250,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s35\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-190\slmult0\tx720 \snext35 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Nested_Bulleted, 3), -- 
Nested bullets in notes
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 220,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s36\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-190\slmult0\tx1080 \snext36 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Hanging_in_Bulleted, 3),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s37\widctlpar\adjustright",
+                      Style_String_Suffix => "\ri360\cgrid\qj\sl-240\slmult0 
\snext14 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Hanging_in_Bulleted, 5),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s38\widctlpar\adjustright",
+                      Style_String_Suffix => "\ri360\cgrid\qj\sl-190\slmult0 
\snext16 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Nested_Bulleted, 4), -- Nested 
bullets in code indenting
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 220,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s39\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-240\slmult0\tx1440 \snext39 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Syntax_Summary, 1),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s40\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-200\slmult0 
\snext40 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Enumerated, 1),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Hang_Width => 250,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s41\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-240\slmult0\tx360 \snext41 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Enumerated, 3),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 220,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s42\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-190\slmult0\tx1080 \snext42 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Enumerated, 2), -- Nested 
enumerations.
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Hang_Width => 270,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s43\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-240\slmult0\tx360 \snext43 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Enumerated, 4), -- Small 
nested enumerations.
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 240,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s44\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-190\slmult0\tx1080 \snext44 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Nested_Bulleted, 3), -- Doubly 
nested bullets
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 220,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s45\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-240\slmult0\tx720 \snext45 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Nested_Bulleted, 5), -- 
Doubly nested bullets
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 200,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s46\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-190\slmult0\tx1440 \snext46 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Nested_Bulleted, 5), -- 
Indented nested bullets
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 250,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s47\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-240\slmult0\tx1080 \snext47 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Normal, 4), -- Inner indented
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s48\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-260\slmult0 
\snext48 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small, 6), -- Inner indented
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*6,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s49\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext49 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small, 3), -- Annotations in 
syntax indenting
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s50\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-200\slmult0 
\snext50 ");
+           Set_Style (Paragraph_Info(ARM_Output.Swiss_Examples, 1),
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 20,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s51\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-240\slmult0 
\snext51 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Swiss_Examples, 3),
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s52\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-180\slmult0 
\snext52 ");
+           Set_Style (Paragraph_Info(ARM_Output.Swiss_Examples, 4), -- 
Indented examples
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 20,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s53\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-240\slmult0 
\snext53 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Swiss_Examples, 6), -- 
Indented examples
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*6,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s54\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-180\slmult0 
\snext54 ");
+           Set_Style (Paragraph_Info(ARM_Output.Enumerated, 3), -- Doubly 
nested enumerations.
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 270,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s55\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-240\slmult0\tx360 \snext55 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Enumerated, 5), -- Small 
doubly nested enumerations.
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 240,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s56\widctlpar\adjustright",
+                      Style_String_Suffix => 
"\ri360\cgrid\qj\sl-190\slmult0\tx1080 \snext56 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Examples, 2), -- Syntax 
Indented examples
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s57\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-190\slmult0 
\snext57 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 4), -- Syntax 
Indented examples in annotations.
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s58\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-170\slmult0 
\snext58 ");
+           Set_Style (Paragraph_Info(ARM_Output.Swiss_Examples, 2), -- Syntax 
Indented examples
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 20,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s59\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-240\slmult0 
\snext59 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Swiss_Examples, 4), -- 
Syntax Indented examples
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s60\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-180\slmult0 
\snext60 ");
+           Set_Style (Paragraph_Info(ARM_Output.Examples, 3), -- Code Indented 
examples
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s61\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-190\slmult0 
\snext61 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 5), -- Code 
Indented examples in annotations.
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s62\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-170\slmult0 
\snext62 ");
+           Set_Style (Paragraph_Info(ARM_Output.Swiss_Examples, 3), -- Code 
Indented examples
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 20,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s63\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-240\slmult0 
\snext63 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Swiss_Examples, 5), -- 
Code Indented examples
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s64\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-180\slmult0 
\snext64 ");
+           Set_Style (Paragraph_Info(ARM_Output.Title, 0),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 42, -- Slight less than double (3 pts 
larger than Heading_1).
+                      Style_Indent => 0,
+                      Style_Before => 120,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s65\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-440\slmult0 \snext0 
");
+           Set_Style (Paragraph_Info(ARM_Output.Giant_Hanging, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 1440,
+                      Style_Before => 0,
+                      Style_After => 110,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s66\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-240\slmult0 
\snext66 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Medium_Hanging, 2),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s67\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-240\slmult0 
\snext67 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Giant_Hanging, 6),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*6,
+                      Style_Hang_Width => 1440,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s68\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-190\slmult0 
\snext68 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Medium_Hanging, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s69\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-190\slmult0 
\snext69 ");
+                         -- Note: Narrower space between.
+
+           -- The following are indented one extra level:
+           Set_Style (Paragraph_Info(ARM_Output.Narrow_Hanging, 2),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s70\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-240\slmult0 
\snext70 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Medium_Hanging, 3),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s71\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-240\slmult0 
\snext71 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Wide_Hanging, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 1080,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s72\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-240\slmult0 
\snext72 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Narrow_Hanging, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s73\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-190\slmult0 
\snext73 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Medium_Hanging, 5),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s74\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-190\slmult0 
\snext74 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Wide_Hanging, 6),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*6,
+                      Style_Hang_Width => 1080,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s75\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-190\slmult0 
\snext75 ");
+                         -- Note: Narrower space between.
+           -- The following are indented two extra levels:
+           Set_Style (Paragraph_Info(ARM_Output.Narrow_Hanging, 3),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*3,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s76\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-240\slmult0 
\snext76 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Medium_Hanging, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s77\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-240\slmult0 
\snext77 ");
+                         -- Note: Narrower space between and afterwards.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Narrow_Hanging, 5),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s78\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-190\slmult0 
\snext78 ");
+                         -- Note: Narrower space between.
+           Set_Style (Paragraph_Info(ARM_Output.Small_Medium_Hanging, 6),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*6,
+                      Style_Hang_Width => 720,
+                      Style_Before => 0,
+                      Style_After => 90,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s79\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-190\slmult0 
\snext79 ");
+                         -- Note: Narrower space between.
+
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 2), -- 
Indented for notes.
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s80\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-170\slmult0 
\snext80 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Swiss_Examples, 1),
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s81\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-180\slmult0 
\snext81 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Swiss_Examples, 2),
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*2,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s82\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-180\slmult0 
\snext82 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 1),
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*1,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s83\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-170\slmult0 
\snext83 ");
+           Set_Style (Paragraph_Info(ARM_Output.Examples, 5), -- Child 
Indented examples
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => INDENT_UNIT*5,
+                      Style_Before => 0,
+                      Style_After => 100,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s84\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-190\slmult0 
\snext84 ");
+           Set_Style (Paragraph_Info(ARM_Output.Small_Examples, 7), -- Child 
Indented examples in annotations.
+                      Font => ARM_Output.Fixed,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 16,
+                      Style_Indent => INDENT_UNIT*7,
+                      Style_Before => 0,
+                      Style_After => 80,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s85\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\ql\sl-170\slmult0 
\snext85 ");
+
+           -- The following are indented three extra levels:
+           Set_Style (Paragraph_Info(ARM_Output.Narrow_Hanging, 4),
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => INDENT_UNIT*4,
+                      Style_Hang_Width => 360,
+                      Style_Before => 0,
+                      Style_After => 120,
+                      Style_Justified => TRUE,
+                      Style_String_Prefix =>
+                        "\s86\widctlpar\adjustright",
+                      Style_String_Suffix => "\cgrid\qj\sl-240\slmult0 
\snext86 ");
+                         -- Note: Narrower space between and afterwards.
+
+           -- New styles should be added here, following numbers will need 
adjustments.
+           Set_Style (Heading_4_Info,
+                      Font => ARM_Output.Swiss,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 27,
+                      Style_Indent => 0,
+                      Style_Before => 210,
+                      Style_After => 100,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix =>
+                        "\s87\keepn\widctlpar\outlinelevel3\adjustright",
+                      Style_String_Suffix => "\b\ql\cgrid \sbasedon0 \snext0 
");
+           if Output_Object.Big_Files then
+               -- Define the TOC styles:
+                Set_Style (TOC_1_Info,
+                          Font => ARM_Output.Swiss,
+                          Body_Font => Output_Object.Body_Font,
+                          Font_Size => 24,
+                          Style_Indent => 0,
+                          Style_Before => 60,
+                          Style_After => 60,
+                          Style_Justified => FALSE,
+                          Style_String_Prefix =>
+                            "\s88\widctlpar\tqr\tldot\tx" & Paper_Width & 
"\adjustright",
+                          Style_String_Suffix => "\b\cgrid \sbasedon0 \snext0 
");
+                Set_Style (TOC_2_Info,
+                          Font => ARM_Output.Swiss,
+                          Body_Font => Output_Object.Body_Font,
+                          Font_Size => 22,
+                          Style_Indent => 200,
+                          Style_Before => 0,
+                          Style_After => 0,
+                          Style_Justified => FALSE,
+                          Style_String_Prefix =>
+                            "\s89\widctlpar\tqr\tldot\tx" & Paper_Width & 
"\adjustright",
+                          Style_String_Suffix => "\b\cgrid \sbasedon0 \snext0 
");
+                Set_Style (TOC_3_Info,
+                          Font => ARM_Output.Swiss,
+                          Body_Font => Output_Object.Body_Font,
+                          Font_Size => 22,
+                          Style_Indent => 400,
+                          Style_Before => 0,
+                          Style_After => 0,
+                          Style_Justified => FALSE,
+                          Style_String_Prefix =>
+                            "\s90\widctlpar\tqr\tldot\tx" & Paper_Width & 
"\adjustright",
+                          Style_String_Suffix => "\b\cgrid \sbasedon0 \snext0 
");
+                Set_Style (TOC_4_Info,
+                          Font => ARM_Output.Swiss,
+                          Body_Font => Output_Object.Body_Font,
+                          Font_Size => 22,
+                          Style_Indent => 600,
+                          Style_Before => 0,
+                          Style_After => 0,
+                          Style_Justified => FALSE,
+                          Style_String_Prefix =>
+                            "\s91\widctlpar\tqr\tldot\tx" & Paper_Width & 
"\adjustright",
+                          Style_String_Suffix => "\b\cgrid \sbasedon0 \snext0 
");
+           end if;
+           Set_Style (Table_C_Text_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => 0,
+                      Style_Before => 10,
+                      Style_After => 10,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix => "",
+                      Style_String_Suffix => "\qc ");
+               -- We use a bit of space above and below to avoid overrunning
+               -- the borders of the cells.
+           Set_Style (Table_L_Text_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 22,
+                      Style_Indent => 0,
+                      Style_Before => 20,
+                      Style_After => 20,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix => "",
+                      Style_String_Suffix => "\ql ");
+           Set_Style (Table_C_Sml_Text_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => 0,
+                      Style_Before => 20,
+                      Style_After => 20,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix => "",
+                      Style_String_Suffix => "\qc ");
+           Set_Style (Table_L_Sml_Text_Info,
+                      Font => ARM_Output.Default,
+                      Body_Font => Output_Object.Body_Font,
+                      Font_Size => 18,
+                      Style_Indent => 0,
+                      Style_Before => 20,
+                      Style_After => 20,
+                      Style_Justified => FALSE,
+                      Style_String_Prefix => "",
+                      Style_String_Suffix => "\ql ");
+       end if;
+
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Normal, 0));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Normal;}");
+           -- Normal style.
+       Write_Style (Output_Object.Output_File, Heading_1_Info);
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Heading 1;}");
+       Write_Style (Output_Object.Output_File, Heading_2_Info);
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Heading 2;}");
+       Write_Style (Output_Object.Output_File, Heading_3_Info);
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Heading 3;}");
+       Write_Style (Output_Object.Output_File, Category_Header_Info);
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Category Header;}");
+       Write_Style (Output_Object.Output_File, Normal_Paragraph_Number_Info);
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Paragraph Number;}");
+       Write_Style (Output_Object.Output_File, Wide_Paragraph_Number_Info);
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Large Paragraph 
Number;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small, 1));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Notes;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small, 2));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Annotations;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Examples, 1));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Examples, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Normal, 1));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Syntax Indented;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Normal, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Normal Indented;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small, 5));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Indented;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Wide_Hanging, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Narrow_Hanging, 1));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Narrow Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Wide_Hanging, 5));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Narrow_Hanging, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Narrow 
Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Bulleted, 1));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Bulleted;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Nested_Bulleted, 2));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Nested Bulleted;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Bulleted, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Bulleted;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Nested_Bulleted, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Nested 
Bulleted;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Bulleted, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Indented 
Bulleted;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Bulleted, 2));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Syntax Indented 
Bulleted;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Bulleted, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Code Indented 
Bulleted;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Normal, 2));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Code Indented;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Code 
Indented;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Examples, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Indented 
Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Examples, 6));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Indented 
Examples;}");
+       Write_Style (Output_Object.Output_File, Header_Info);
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "header;}");
+       Write_Style (Output_Object.Output_File, Footer_Info);
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "footer;}");
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\*\cs30 \additive 
\sbasedon30 page number;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Index, 0));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Index;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Wide_Above, 0));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Wide;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Wide_Above, 2));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Wide Annotations;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Header, 1));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Notes Header;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Bulleted, 2));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Notes Bulleted;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Nested_Bulleted, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Notes Nested 
Bulleted;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Hanging_in_Bulleted, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Hanging in 
Bulleted;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Hanging_in_Bulleted, 5));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Hanging in 
Bulleted;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Nested_Bulleted, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Code Indented 
Bulleted;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Syntax_Summary, 1));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Syntax Summary;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Enumerated, 1));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Enumerated;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Enumerated, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Enumerated;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Enumerated, 2));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Nested 
Enumerated;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Enumerated, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Nested 
Enumerated;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Nested_Bulleted, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Nested X2 
Bulleted;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Nested_Bulleted, 5));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Nested X2 
Bulleted;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Nested_Bulleted, 5));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Indented Nested 
Bulleted;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Normal, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Inner Indented;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small, 6));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Inner 
Indented;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Syntax 
Indented;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Swiss_Examples, 1));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Swiss Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Swiss_Examples, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Swiss 
Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Swiss_Examples, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Swiss Indented 
Examples;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Swiss_Examples, 6));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Swiss Indented 
Examples;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Enumerated, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Nested X2 
Enumerated;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Enumerated, 5));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Nested X2 
Enumerated;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Examples, 2));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Syntax Indented 
Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Examples, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Syntax 
Indented Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Swiss_Examples, 2));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Swiss Syntax 
Indented Examples;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Swiss_Examples, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Swiss Syntax 
Indented Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Examples, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Code Indented 
Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Examples, 5));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Code Indented 
Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Swiss_Examples, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Swiss Code Indented 
Examples;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Swiss_Examples, 5));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Swiss Code 
Indented Examples;}");
+        Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Title, 0));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Standard Title;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Giant_Hanging, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Giant Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Medium_Hanging, 2));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Medium Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Giant_Hanging, 6));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Giant 
Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Medium_Hanging, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Medium 
Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Narrow_Hanging, 2));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Indented Narrow 
Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Medium_Hanging, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Indented Narrow 
Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Wide_Hanging, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Indented Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Narrow_Hanging, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Indented 
Narrow Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Medium_Hanging, 5));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Indented 
Medium Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Wide_Hanging, 6));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Indented 
Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Narrow_Hanging, 3));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Dbl Indented Narrow 
Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Medium_Hanging, 4));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Dbl Indented Narrow 
Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Narrow_Hanging, 5));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Dbl Indented 
Narrow Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Medium_Hanging, 6));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Dbl Indented 
Medium Hanging;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Examples, 2));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Notes Indented 
Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Swiss_Examples, 1));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Swiss Basic 
Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Swiss_Examples, 2));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Swiss Indented 
Basic Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Examples, 1));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Basic 
Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Examples, 5));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Child Indented 
Examples;}");
+       Write_Style (Output_Object.Output_File, 
Paragraph_Info(ARM_Output.Small_Examples, 6));
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "Small Child Indented 
Examples;}");
+        if Output_Object.Big_Files then
+           Write_Style (Output_Object.Output_File, Heading_4_Info);
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "Heading 4;}");
+           -- Define the TOC styles:
+           Write_Style (Output_Object.Output_File, TOC_1_Info);
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "toc 1;}");
+           Write_Style (Output_Object.Output_File, TOC_2_Info);
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "toc 2;}");
+           Write_Style (Output_Object.Output_File, TOC_3_Info);
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "toc 3;}");
+           Write_Style (Output_Object.Output_File, TOC_4_Info);
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "toc 4;}}");
+       else
+           Write_Style (Output_Object.Output_File, Heading_4_Info);
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "Heading 4;}}");
+       end if;
+            -- \additive means that the style inherits from the previous style.
+           -- \basedon defines the style that the style was inherited from.
+           -- \snext defines the next style to use (if omitted, use same 
style).
+           -- \shidden - Don't show the style in the drop down menu.
+
+           -- Formatting properties:
+           -- \widctlpar - Widow/orphan control in this paragraph;
+           -- \adjustright - adjust right indent for document properties;
+           -- \fs - font size in halfpoints (.5 pt);
+           -- \f - font number;
+           -- \q - text alignment (j - justified, c - centered, l - left, r 
-right);
+           -- \cgrid - set the character grid(?) to the default;
+           -- \li - left indent, in twips (.1 pt);
+           -- \fi - first line indent, in twips (.1 pt);
+           -- \sa - space after paragraph, in twips (.1 pt);
+           -- \sb - space before paragraph, in twips (.1 pt);
+           -- \sl - space between lines, in twips. "Exactly" if negative, "At 
least" if positive.
+           -- \slmult0 - line space multiple - 0 - Exactly or "At least"/.
+           -- \pard - reset to default paragraph properties;
+           -- \plain - reset to default font/character properties;
+           -- \tx - set tab at location, in twips (.1 pt);
+           -- \tqc - set following tab as a centered tab;
+           -- \tqr - set following tab as a right tab.
+
+       -- Revision table:
+       Ada.Text_IO.Put (Output_Object.Output_File, "{\*\revtbl ");
+        if Ada.Strings.Unbounded.Length (Output_Object.Version_Names('0')) = 0 
then
+           Ada.Text_IO.Put (Output_Object.Output_File, "{Original Text;}");
+       else
+            Ada.Text_IO.Put (Output_Object.Output_File, "{" &
+              
Ada.Strings.Unbounded.To_String(Output_Object.Version_Names('0')) &
+               ";}");
+       end if;
+       for Version in Character range '1' .. '9' loop
+            if Ada.Strings.Unbounded.Length 
(Output_Object.Version_Names(Version)) /= 0 then
+                Ada.Text_IO.Put (Output_Object.Output_File, "{" &
+                  
Ada.Strings.Unbounded.To_String(Output_Object.Version_Names(Version)) &
+                   ";}");
+           else exit; -- No more after the first empty one.
+           end if;
+       end loop;
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "}");
+
+       -- Information (truncated):
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\info{\title " &
+           Ada.Strings.Unbounded.To_String (Output_Object.Title) & "}");
+
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "\version2");
+
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\author AXE 
Consultants}"); -- Working.
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\operator Randall 
Brukardt, Principle Technician}}");
+       --Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\author 
JTC1/SC22/WG9/ARG}"); -- Final.
+       --Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\operator Randall 
Brukardt, ARG Editor}}");
+
+       -- Initial setup (document properties):
+       -- Paper size:
+       -- Note: If changing the page size or margins, be sure to change the
+       -- header and footer tab settings as well.
+       case Output_Object.Page_Size is
+           when ARM_RTF.A4 =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\paperw11909\paperh16834"); -- Set paper to A4.
+           when ARM_RTF.Letter =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\paperw12240\paperh15840"); -- Set paper to US Letter.
+           when ARM_RTF.Half_Letter =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\paperw7920\paperh12240");  -- Set paper to 5.5x8.5.
+           when ARM_RTF.Ada95 =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\paperw10080\paperh12960"); -- Set paper to 7x9.
+       end case;
+
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\facingp\margmirror"); -- Set to facing pages and mirrored margins.
+       -- Margins.
+       case Output_Object.Page_Size is
+           when ARM_RTF.Ada95 | ARM_RTF.Half_Letter =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\margl1440\margr900\margt1080\margb1080");
+           when ARM_RTF.Letter | ARM_RTF.A4 =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\margl1800\margr1080\margt1440\margb1440");
+       end case;
+       -- Revisions:
+       if Output_Object.Includes_Changes then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\revisions\revprop3 \revbar0 ");
+               -- \revisions - Revisions marking is on;
+               -- \revprop3 - Show revisions as underlined.
+               -- \revbar0 - No revision bars.
+                   -- Alternatively, use \revprop0\revbar3, using the infamous
+                   -- vertical bar on the outside, and no other highlighting.
+       -- else not changes, thus no revisions.
+       end if;
+       -- Other properties:
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\widowctrl\ftnbj\aenddoc\lytprtmet\formshade\viewkind1\viewscale100");
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\pgbrdrhead\pgbrdrfoot\fet0");
+           -- \widowctrl - Enable widow and orphan control;
+           -- \ftnbj - Footnotes at bottom of page;
+           -- \aenddoc - Endnotes at end of document;
+           -- \lytprtmet - Layout using printer metrics;
+           -- \formshade - Form field shading is on;
+           -- \viewkind - Default view of the document (1-Page Layout; 
4-Normal);
+           -- \viewscale100 - Percentage zoom of the document (100%);
+           -- \pgbrdrhead - Page border surrounds header;
+           -- \pgbrdrfoot - Page border surrounds footer;
+           -- \fet0    - Footnote/endnote control: 0 - Footnotes only (or 
none);
+       -- Section properties:
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\sectd\linex0\endnhere\sectdefaultcl\sbkodd\headery540\footery540");
+           -- \sectd   - Default section properties;
+           -- \linex0  - Line number spacing (0 - none);
+           -- \endnhere- Endnotes included;
+           -- \sectdefaultcl - Default character layout for section.
+           -- \sbkodd - Start at top of odd page.
+           -- \headery - Distance (in twips) of header from top of page.
+           -- \footery - Distance (in twips) of footerr from bottom of page.
+       if Name = "Ttl" or else -- Title page
+          Name = "All" then -- Single giant file
+           -- No page numbers, headers, or footers here.
+           null;
+       else
+           if Name = "00" or else Name = "TOC" then
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\pgnlcrm\pgncont "); -- Lower-case roman numeral, numbers continue.
+           elsif Name = "01" then
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\pgndec\pgnstart1\pgnrestart "); -- Decimal page number; starts at 1 here.
+           else
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\pgndec\pgncont "); -- Decimal page number, numbers continue.
+           end if;
+           -- Write the page headers:
+           Write_Headers (Output_Object);
+       end if;
+        Output_Object.Wrote_into_Section := False;
+    end Start_RTF_File;
+
+
+    procedure End_RTF_File (Output_Object : in out RTF_Output_Type) is
+       -- Internal routine.
+       -- Generate the needed text to end an RTF file. Also closes the file.
+    begin
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "}");
+       Ada.Text_IO.Close (Output_Object.Output_File);
+    end End_RTF_File;
+
+
+    procedure Create (Output_Object : in out RTF_Output_Type;
+                     Page_Size : in ARM_RTF.Page_Size;
+                     Includes_Changes : in Boolean;
+                     Big_Files : in Boolean;
+                     File_Prefix : in String;
+                     Output_Path : in String;
+                     Primary_Sans_Serif_Font : in Sans_Serif_Fonts := Arial;
+                     Primary_Serif_Font : in Serif_Fonts := Times_New_Roman;
+                     Body_Font : in ARM_Output.Font_Family_Type := 
ARM_Output.Roman;
+                     Header_Prefix : in String := "";
+                     Footer_Use_Date : in Boolean;
+                     Footer_Use_Clause_Name : in Boolean;
+                     Footer_Use_ISO_Format : in Boolean;
+                     Footer_Text : in String := "";
+                     Version_Names : in ARM_Contents.Versioned_String;
+                     Title : in String := "") is
+       -- Create an Output_Object for a document with the specified page
+       -- size. Changes from the base document are included if
+       -- Includes_Changes is True (otherwise no revisions are generated).
+       -- Generate a few large output files if
+       -- Big_Files is True; otherwise generate smaller output files.
+       -- The prefix of the output file names is File_Prefix - this
+       -- should be no more then 4 characters allowed in file names.
+       -- The files will be written into Output_Path.
+       -- The title of the document is Title.
+       -- The header prefix appears in the header (if any) before the title,
+       -- separated by a dash.
+       -- The footer consists of the page number, the date if Footer_Use_Date
+       -- is true, and the clause name if Footer_Use_Clase_Name is True, and
+       -- the Footer_Text otherwise. The font and size of the footer is as
+       -- an ISO standard if Footer_Use_ISO_Format is True, and as the
+       -- Ada Reference Manual otherwise.
+       -- The primary font used for the Sans_Serif text, and for the Serif
+       -- text, is as specified.
+       -- Which font is used for the body is specified by Body_Font.
+       -- The author names of the various versions is specified by the
+       -- Version_Names.
+    begin
+       if Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Already valid object");
+       end if;
+       Output_Object.Is_Valid := True;
+       Output_Object.Page_Size := Page_Size;
+       Output_Object.Includes_Changes := Includes_Changes;
+       Output_Object.Big_Files := Big_Files;
+       Ada.Strings.Fixed.Move (Target => Output_Object.File_Prefix,
+                               Source => File_Prefix);
+       Output_Object.Output_Path :=
+               Ada.Strings.Unbounded.To_Unbounded_String (Output_Path);
+       Output_Object.Primary_Sans_Serif_Font := Primary_Sans_Serif_Font;
+       Output_Object.Primary_Serif_Font := Primary_Serif_Font;
+       Output_Object.Body_Font := Body_Font;
+       Output_Object.Title := Ada.Strings.Unbounded.To_Unbounded_String 
(Title);
+       Output_Object.Header_Prefix :=
+               Ada.Strings.Unbounded.To_Unbounded_String (Header_Prefix);
+       Output_Object.Footer_Text :=
+               Ada.Strings.Unbounded.To_Unbounded_String (Footer_Text);
+       Output_Object.Footer_Use_Date := Footer_Use_Date;
+       Output_Object.Footer_Use_Clause_Name := Footer_Use_Clause_Name;
+       Output_Object.Footer_Use_ISO_Format := Footer_Use_ISO_Format;
+       Output_Object.Version_Names := Version_Names;
+       if Big_Files then
+           -- We're going to generate a single giant file. Open it now.
+           Start_RTF_File (Output_Object,
+                           Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right),
+                           Ada.Strings.Unbounded.To_String 
(Output_Object.Title),
+                           "All");
+           Ada.Text_IO.New_Line (Output_Object.Output_File);
+       end if;
+    end Create;
+
+
+    procedure Close (Output_Object : in out RTF_Output_Type) is
+       -- Close an Output_Object. No further output to the object is
+       -- allowed after this call.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Ada.Text_IO.Is_Open (Output_Object.Output_File) then
+           End_RTF_File (Output_Object);
+       end if;
+       Output_Object.Is_Valid := False;
+    end Close;
+
+
+    procedure Section (Output_Object : in out RTF_Output_Type;
+                      Section_Title : in String;
+                      Section_Name : in String) is
+       -- Start a new section. The title is Section_Title (this is
+       -- intended for humans). The name is Section_Name (this is
+       -- intended to be suitable to be a portion of a file name).
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Section in paragraph");
+       end if;
+       if not Output_Object.Big_Files then
+           if Ada.Text_IO.Is_Open (Output_Object.Output_File) then
+               End_RTF_File (Output_Object);
+           end if;
+
+           -- Create a new file for this section:
+           Start_RTF_File (Output_Object,
+                           Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right) &
+                               "-" & Section_Name,
+                           Section_Title,
+                           Section_Name);
+           Ada.Text_IO.New_Line (Output_Object.Output_File);
+       else
+           if Output_Object.Wrote_into_Section then
+               -- Just a new section header (odd page break) and page number 
setup:
+               if Section_Name = "TOC" then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\sect\sbkodd\pgnlcrm\pgnstart1\pgnrestart ");
+                       -- Lower-case roman number page number; reset to 1.
+               elsif Section_Name = "00" then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\sect\sbkodd\pgnlcrm\pgncont ");
+                       -- Lower-case roman numeral, numbers continue.
+               elsif Section_Name = "01" then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\sect\sbkodd\pgndec\pgnstart1\pgnrestart ");
+                       -- Decimal page number; starts at 1 here.
+               else
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\sect\sbkodd\pgndec\pgncont ");
+                       -- Decimal page number, numbers continue.
+               end if;
+               -- Write the page headers:
+               Write_Headers (Output_Object);
+           -- else Probably the title page: no headers or footers.
+           end if;
+           Output_Object.Wrote_into_Section := False;
+       end if;
+    end Section;
+
+
+    procedure Set_Columns (Output_Object : in out RTF_Output_Type;
+                          Number_of_Columns : in ARM_Output.Column_Count) is
+       -- Set the number of columns.
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "In paragraph");
+       end if;
+       if Number_of_Columns = Output_Object.Column_Count then
+           return;
+       end if;
+       if Output_Object.Wrote_into_Section then
+           Ada.Text_IO.Put (Output_Object.Output_File, "\sect\sbknone");
+       end if;
+       case Number_of_Columns is
+           when 1 => Ada.Text_IO.Put_Line (Output_Object.Output_File, "\cols1 
");
+           when 2 => Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\cols2\colsx0 ");
+                       -- Two columns, no space between. (Paragraph formatting
+                       -- will take care of that.)
+           when 3 => Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\cols3\colsx0 ");
+           when 4 => Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\cols4\colsx0 ");
+           when 5 => Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\cols5\colsx0 ");
+           when 6 => Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\cols6\colsx0 ");
+           when 7 => Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\cols7\colsx0 ");
+           when 8 => Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\cols8\colsx0 ");
+       end case;
+       Output_Object.Column_Count := Number_of_Columns;
+    end Set_Columns;
+
+
+    procedure Set_Tabs (Output_Object : in out RTF_Output_Type;
+                       Style         : in ARM_Output.Paragraph_Style_Type;
+                       Indent        : in ARM_Output.Paragraph_Indent_Type) is
+       -- Set tabs in the current (just started) paragraph.
+    begin
+       case Style is
+           when ARM_Output.Normal | ARM_Output.Wide_Above |
+                ARM_Output.Small | ARM_Output.Small_Wide_Above |
+                ARM_Output.Header | ARM_Output.Small_Header |
+                ARM_Output.Index | ARM_Output.Syntax_Summary |
+                ARM_Output.Title |
+                ARM_Output.Examples | ARM_Output.Small_Examples |
+                ARM_Output.Swiss_Examples | ARM_Output.Small_Swiss_Examples =>
+               if Output_Object.Tab_Stops.Number /= 0 then
+                   if (Output_Object.Tab_Stops.Number * 8) + 
Output_Object.Char_Count >
+                       LINE_LENGTH then
+                       Ada.Text_IO.New_Line (Output_Object.Output_File);
+                       Output_Object.Char_Count := 0;
+                   end if;
+                   declare
+                       function Stop_in_Twips (Stop : 
ARM_Output.Tab_Stop_Type) return Natural is
+                           -- Return the value of a tab stop in Twips:
+                       begin
+                           if ARM_Output."="(Stop.Kind, ARM_Output.Left_Fixed) 
then
+                               return Stop.Stop*120 +
+                                   Paragraph_Info(Style, Indent).Indent;
+                                   -- *120 is to convert picas to Twips.
+                           else
+                               -- Scale with font size. (Stop assumes 12 pt
+                               -- type).
+                               -- Raw formula:
+                               -- (Stop.Stop * 120) -- Stop in twips.
+                               -- * (Paragraph_Info(Format).Size / 24) -- Font 
scale.
+                               -- After rearranging, we get:
+                               return
+                                   Stop.Stop * Paragraph_Info(Style, 
Indent).Size * 5 +
+                                   Paragraph_Info(Style, Indent).Indent;
+                           end if;
+                       end Stop_in_Twips;
+
+                   begin
+                       for I in 1 .. Output_Object.Tab_Stops.Number loop
+                           -- Define tab stops.
+                           declare
+                               Num : String := Integer'Image (Stop_in_Twips (
+                                           Output_Object.Tab_Stops.Stops(I)));
+                           begin
+                               Ada.Text_IO.Put (Output_Object.Output_File, 
"\tx");
+                               Ada.Text_IO.Put (Output_Object.Output_File, 
Num(2..Num'Length));
+                               Ada.Text_IO.Put (Output_Object.Output_File, " 
");
+                               Output_Object.Char_Count := 
Output_Object.Char_Count + 4 + Num'Length-1;
+                           end;
+                       end loop;
+                   end;
+               -- else no tabs defined.
+               end if;
+
+           when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted |
+                ARM_Output.Small_Bulleted | ARM_Output.Small_Nested_Bulleted |
+                ARM_Output.Giant_Hanging | ARM_Output.Wide_Hanging |
+                ARM_Output.Medium_Hanging | ARM_Output.Narrow_Hanging |
+                ARM_Output.Hanging_in_Bulleted |
+                ARM_Output.Small_Giant_Hanging | ARM_Output.Small_Wide_Hanging 
|
+                ARM_Output.Small_Medium_Hanging | 
ARM_Output.Small_Narrow_Hanging |
+                ARM_Output.Small_Hanging_in_Bulleted |
+                ARM_Output.Enumerated | ARM_Output.Small_Enumerated =>
+               if Output_Object.Tab_Stops.Number /= 0 then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Tabs in hanging/bulleted paragraph");
+               end if;
+       end case;
+    end Set_Tabs;
+
+
+    procedure Start_Paragraph (Output_Object : in out RTF_Output_Type;
+                              Style     : in ARM_Output.Paragraph_Style_Type;
+                              Indent    : in ARM_Output.Paragraph_Indent_Type;
+                              Number    : in String;
+                              No_Prefix : in Boolean := False;
+                              Tab_Stops : in ARM_Output.Tab_Info := 
ARM_Output.NO_TABS;
+                              No_Breaks : in Boolean := False;
+                              Keep_with_Next : in Boolean := False;
+                              Space_After : in ARM_Output.Space_After_Type
+                                  := ARM_Output.Normal;
+                              Justification : in ARM_Output.Justification_Type
+                                  := ARM_Output.Default) is
+       -- Start a new paragraph. The style and indent of the paragraph is as
+       -- specified. The (AA)RM paragraph number (which might include update
+       -- and version numbers as well: [12.1/1]) is Number. If the format is
+       -- a type with a prefix (bullets, hangining items), the prefix is
+       -- omitted if No_Prefix is true. Tab_Stops defines the tab stops for
+       -- the paragraph. If No_Breaks is True, we will try to avoid page breaks
+       -- in the paragraph. If Keep_with_Next is true, we will try to avoid
+       -- separating this paragraph and the next one. (These may have no
+       -- effect in formats that don't have page breaks). Space_After
+       -- specifies the amount of space following the paragraph. Justification
+       -- specifies the text justification for the paragraph. Not_Valid_Error
+       -- is raised if Tab_Stops /= NO_TABS for a hanging or bulleted format.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Already in paragraph");
+       end if;
+       if not Paragraph_Info(Style, Indent).Defined then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Undefined Style " & 
ARM_Output.Paragraph_Style_Type'Image(Style) &
+               " and Indent:" & 
ARM_Output.Paragraph_Indent_Type'Image(Indent));
+       end if;
+       Output_Object.Is_In_Paragraph := True;
+       Output_Object.Had_Prefix := not No_Prefix;
+       Output_Object.Char_Count := 0;
+       Output_Object.Saw_Hang_End := False;
+       Output_Object.Wrote_into_Section := True;
+
+       -- First, write the paragraph number, if any. This has its own style.
+       if Number /= "" then -- We have a paragraph number.
+           -- Most paragraph numbers are 7 or fewer characters. The box is
+           -- sized for 7 characters. If we have 8 characters (as in 277.10/2),
+           -- we need a wider box.
+           if Number'Length > 7 then
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Wide_Paragraph_Number_Info, Output_Object.Char_Count);
+           else
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Normal_Paragraph_Number_Info, Output_Object.Char_Count);
+           end if;
+           -- Figure the space above: (We use a variable space above so the
+           -- numbers align with the bottom of the text, not the top).
+           declare
+               Diff : Natural := (Paragraph_Info(Style, Indent).Size -
+                                  Normal_Paragraph_Number_Info.Size) +
+                                 (Paragraph_Info(Style, Indent).Before/10);
+               -- This would seem to be double the required adjustment for the
+               -- size, but it works. So why question it?
+           begin
+               if Diff >= 30 then
+                  Ada.Text_IO.Put (Output_Object.Output_File, "\sb3" &
+                       Character'Val(Diff mod 10 + Character'Pos('0')) & "0 ");
+               elsif Diff >= 20 then
+                  Ada.Text_IO.Put (Output_Object.Output_File, "\sb2" &
+                       Character'Val(Diff mod 10 + Character'Pos('0')) & "0 ");
+               elsif Diff >= 10 then
+                  Ada.Text_IO.Put (Output_Object.Output_File, "\sb1" &
+                       Character'Val(Diff mod 10 + Character'Pos('0')) & "0 ");
+               else
+                  Ada.Text_IO.Put (Output_Object.Output_File, "\sb" &
+                       Character'Val(Diff + Character'Pos('0')) & "0 ");
+               end if;
+           end;
+--*** Box width??
+
+           Ada.Text_IO.Put (Output_Object.Output_File, Number);
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "\par}");
+           Output_Object.Char_Count := 0;
+       -- else no paragraph number.
+       end if;
+       -- Now, write the paragraph header:
+       case Style is
+           when ARM_Output.Normal | ARM_Output.Wide_Above |
+                ARM_Output.Small | ARM_Output.Small_Wide_Above |
+                ARM_Output.Header | ARM_Output.Small_Header |
+                ARM_Output.Index | ARM_Output.Syntax_Summary |
+                ARM_Output.Title |
+                ARM_Output.Examples | ARM_Output.Small_Examples |
+                ARM_Output.Swiss_Examples | ARM_Output.Small_Swiss_Examples =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Paragraph_Info(Style, Indent),
+                   Output_Object.Char_Count);
+--Ada.Text_IO.Put_Line ("Start paragraph - full style");
+           when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted |
+                ARM_Output.Small_Bulleted | ARM_Output.Small_Nested_Bulleted =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Paragraph_Info(Style, Indent),
+                   Output_Object.Char_Count);
+--Ada.Text_IO.Put_Line ("Start paragraph - full style (bullet)");
+               if No_Prefix then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "\tab ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 5;
+               else
+                   if ARM_Output."=" (Style, ARM_Output.Nested_Bulleted) or 
else
+                      ARM_Output."=" (Style, ARM_Output.Small_Nested_Bulleted) 
then
+                       -- Make a smaller bullet.
+                       if Paragraph_Info(Style, Indent).Size = 15 then
+                           Ada.Text_IO.Put (Output_Object.Output_File, 
"{\f3\fs12\'b7}\tab ");
+                       elsif Paragraph_Info(Style, Indent).Size = 16 then
+                           Ada.Text_IO.Put (Output_Object.Output_File, 
"{\f3\fs12\'b7}\tab ");
+                       elsif Paragraph_Info(Style, Indent).Size = 18 then
+                           Ada.Text_IO.Put (Output_Object.Output_File, 
"{\f3\fs14\'b7}\tab ");
+                       elsif Paragraph_Info(Style, Indent).Size = 20 then
+                           Ada.Text_IO.Put (Output_Object.Output_File, 
"{\f3\fs16\'b7}\tab ");
+                       else --if Paragraph_Info(Style, Indent).Size = 22 then
+                           Ada.Text_IO.Put (Output_Object.Output_File, 
"{\f3\fs18\'b7}\tab ");
+                       end if;
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
19;
+                   else -- Normal bullet.
+                       Ada.Text_IO.Put (Output_Object.Output_File, 
"{\f3\'b7}\tab ");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
14;
+                   end if;
+               end if;
+
+           when ARM_Output.Giant_Hanging | ARM_Output.Wide_Hanging |
+                ARM_Output.Medium_Hanging | ARM_Output.Narrow_Hanging |
+                ARM_Output.Hanging_in_Bulleted |
+                ARM_Output.Small_Giant_Hanging | ARM_Output.Small_Wide_Hanging 
|
+                ARM_Output.Small_Medium_Hanging | 
ARM_Output.Small_Narrow_Hanging |
+                ARM_Output.Small_Hanging_in_Bulleted |
+                ARM_Output.Enumerated | ARM_Output.Small_Enumerated =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Paragraph_Info(Style, Indent),
+                   Output_Object.Char_Count);
+--Ada.Text_IO.Put_Line ("Start paragraph - full style (hang)");
+               if No_Prefix then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "\tab ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 5;
+                   Output_Object.Saw_Hang_End := True;
+               else -- Has prefix.
+                   Output_Object.Saw_Hang_End := False;
+                   Output_Object.Prefix_Large_Char_Count := 0;
+               end if;
+       end case;
+
+       Output_Object.Paragraph_Style := Style;
+       Output_Object.Paragraph_Indent := Indent;
+       Output_Object.Font := ARM_Output.Default;
+       Output_Object.Is_Bold := False;
+       Output_Object.Is_Italic := False;
+       Output_Object.Size := 0;
+       Output_Object.Color := ARM_Output.Default;
+       Output_Object.Real_Size := Paragraph_Info(Style,Indent).Size;
+       Output_Object.Tab_Stops := Tab_Stops;
+       Output_Object.Current_Space_After := Space_After;
+
+       Set_Tabs (Output_Object, Style, Indent);
+
+       if No_Breaks or Keep_with_Next then
+           if Output_Object.Char_Count + 13 >
+               LINE_LENGTH then
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Output_Object.Char_Count := 0;
+           end if;
+           if No_Breaks then
+               Ada.Text_IO.Put (Output_Object.Output_File, "\keep ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 6;
+           end if;
+           if Keep_with_Next then
+               Ada.Text_IO.Put (Output_Object.Output_File, "\keepn ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 7;
+           end if;
+       end if;
+       if ARM_Output."=" (Space_After, ARM_Output.Narrow) then
+           -- Reduce the following space by 30%:
+           declare
+               SA : constant String := Natural'Image((Paragraph_Info(Style, 
Indent).After*(LEADING_PERCENT/10))/10);
+           begin
+               if Output_Object.Char_Count + 4 + SA'Length - 1 >
+                   LINE_LENGTH then
+                   Ada.Text_IO.New_Line (Output_Object.Output_File);
+                   Output_Object.Char_Count := 0;
+               end if;
+                Ada.Text_IO.Put (Output_Object.Output_File, "\sa");
+                Ada.Text_IO.Put (Output_Object.Output_File, SA(2..SA'Last));
+                Ada.Text_IO.Put (Output_Object.Output_File, " ");
+                Output_Object.Char_Count := 4 + SA'Length - 1;
+           end;
+       elsif ARM_Output."=" (Space_After, ARM_Output.Wide) then
+           -- Increase the following space by 50%:
+           declare
+               SA : constant String := Natural'Image((Paragraph_Info(Style, 
Indent).After*(TRAILING_PERCENT/10))/10);
+           begin
+               if Output_Object.Char_Count + 4 + SA'Length - 1 >
+                   LINE_LENGTH then
+                   Ada.Text_IO.New_Line (Output_Object.Output_File);
+                   Output_Object.Char_Count := 0;
+               end if;
+                Ada.Text_IO.Put (Output_Object.Output_File, "\sa");
+                Ada.Text_IO.Put (Output_Object.Output_File, SA(2..SA'Last));
+                Ada.Text_IO.Put (Output_Object.Output_File, " ");
+                Output_Object.Char_Count := 4 + SA'Length - 1;
+           end;
+       end if;
+       if ARM_Output."/=" (Justification, ARM_Output.Default) then
+           if Output_Object.Char_Count + 4 >
+               LINE_LENGTH then
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Output_Object.Char_Count := 0;
+           end if;
+           case Justification is
+               when ARM_Output.Default => null; -- Can't get here.
+               when ARM_Output.Left =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "\ql ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 4;
+               when ARM_Output.Center =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "\qc ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 4;
+               when ARM_Output.Right =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "\qr ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 4;
+               when ARM_Output.Justified =>
+                   Ada.Text_IO.Put (Output_Object.Output_File, "\qj ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 4;
+           end case;
+       end if;
+       -- Start hang (last), so we get a clean count of prefix characters:
+       case Style is
+           when ARM_Output.Giant_Hanging | ARM_Output.Wide_Hanging |
+                ARM_Output.Medium_Hanging | ARM_Output.Narrow_Hanging |
+                ARM_Output.Small_Giant_Hanging | ARM_Output.Small_Wide_Hanging 
|
+                ARM_Output.Small_Medium_Hanging | 
ARM_Output.Small_Narrow_Hanging |
+                ARM_Output.Hanging_in_Bulleted | 
ARM_Output.Small_Hanging_in_Bulleted |
+                ARM_Output.Enumerated | ARM_Output.Small_Enumerated =>
+               if not No_Prefix then
+                   Ada.Text_IO.New_Line (Output_Object.Output_File);
+                   Output_Object.Char_Count := 0;
+--Ada.Text_Io.Put ("Start Hang:");
+               -- else no prefix, no need to count.
+               end if;
+           when others => null;
+       end case;
+    end Start_Paragraph;
+
+
+    procedure End_Paragraph (Output_Object : in out RTF_Output_Type) is
+       -- End a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       Output_Object.Is_In_Paragraph := False;
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "\par}");
+       Output_Object.Char_Count := 0;
+--Ada.Text_IO.Put_Line ("End paragraph '}'");
+    end End_Paragraph;
+
+
+    procedure Category_Header (Output_Object : in out RTF_Output_Type;
+                              Header_Text : String) is
+       -- Output a Category header (that is, "Legality Rules",
+       -- "Dynamic Semantics", etc.)
+       -- (Note: We did not use a enumeration here to insure that these
+       -- headers are spelled the same in all output versions).
+       -- Raises Not_Valid_Error if in a paragraph.
+       Count : Natural; -- Not used after being set.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Header in paragraph");
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+       Write_Style_for_Paragraph (Output_Object.Output_File,
+           Category_Header_Info, Count);
+       Ada.Text_IO.Put_Line (Output_Object.Output_File,
+           Header_Text & "\par}");
+       Output_Object.Char_Count := 0;
+       Output_Object.Wrote_into_Section := True;
+    end Category_Header;
+
+
+    function Current_Date return String is
+        -- Local routine:
+       Date : Ada.Calendar.Time := Ada.Calendar.Clock;
+        Day : constant String := 
Ada.Calendar.Day_Number'Image(Ada.Calendar.Day(Date));
+        Year : constant String := 
Ada.Calendar.Year_Number'Image(Ada.Calendar.Year(Date));
+        Month : constant Ada.Calendar.Month_Number := Ada.Calendar.Month(Date);
+    begin
+        case Month is
+           when  1 => return Day(2..Day'Last) & " January" & Year;
+           when  2 => return Day(2..Day'Last) & " February" & Year;
+           when  3 => return Day(2..Day'Last) & " March" & Year;
+           when  4 => return Day(2..Day'Last) & " April" & Year;
+           when  5 => return Day(2..Day'Last) & " May" & Year;
+           when  6 => return Day(2..Day'Last) & " June" & Year;
+           when  7 => return Day(2..Day'Last) & " July" & Year;
+           when  8 => return Day(2..Day'Last) & " August" & Year;
+           when  9 => return Day(2..Day'Last) & " September" & Year;
+           when 10 => return Day(2..Day'Last) & " October" & Year;
+           when 11 => return Day(2..Day'Last) & " November" & Year;
+           when 12 => return Day(2..Day'Last) & " December" & Year;
+        end case;
+    end Current_Date;
+
+
+    procedure Clause_Footer (Output_Object : in out RTF_Output_Type;
+                            Header_Text : in String;
+                            Level : in ARM_Contents.Level_Type;
+                            Clause_Number : in String;
+                            No_Page_Break : in Boolean := False) is
+        -- Local routine: Set up the footer for the header.
+       Count : Natural; -- Not used after being set.
+    begin
+       -- Adjust footer.
+       if Output_Object.Wrote_into_Section then
+           -- Start a new section:
+           if No_Page_Break or else
+              ARM_Contents."="(Level, ARM_Contents.Clause) or else
+              ARM_Contents."="(Level, ARM_Contents.Subclause) or else
+              ARM_Contents."="(Level, ARM_Contents.Subsubclause) then
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\sect\sbknone\pgncont ");
+           else
+               -- Start sections on a new page. (Should only happen in the
+               -- introduction).
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\sect\sbkpage\pgncont ");
+           end if;
+       -- else just use the existing section.
+       end if;
+       if Clause_Number = "" or else
+          ARM_Contents."="(Level, ARM_Contents.Unnumbered_Section) then
+           Ada.Text_IO.Put (Output_Object.Output_File, "{\footerl ");
+           Write_Style_for_Paragraph (Output_Object.Output_File, Footer_Info, 
Count);
+           if Output_Object.Footer_Use_ISO_Format then
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f1\fs16 ");
+           elsif ARM_Output."="(Output_Object.Body_Font, ARM_Output.Swiss) then
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f1 ");
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f0 ");
+           end if;
+           if Output_Object.Footer_Use_Clause_Name then
+                Ada.Text_IO.Put (Output_Object.Output_File, Header_Text);
+           else
+                Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Unbounded.To_String 
(Output_Object.Footer_Text));
+           end if;
+            Ada.Text_IO.Put (Output_Object.Output_File, "\tab ");
+           if Output_Object.Footer_Use_Date then
+               Ada.Text_IO.Put (Output_Object.Output_File, Current_Date);
+           -- else no date.
+           end if;
+           if Output_Object.Footer_Use_ISO_Format then
+                Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\~\~\~\~\~\~{\f1\fs22\b {\field{\*\fldinst { PAGE }}{\fldrslt {\lang1024 
x}}}}\par}}}");
+           else
+                Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\~\~\~\~\~\~{\field{\*\fldinst { PAGE }}{\fldrslt {\lang1024 x}}}\par}}}");
+           end if;
+           Ada.Text_IO.Put (Output_Object.Output_File, "{\footerr ");
+           Write_Style_for_Paragraph (Output_Object.Output_File, Footer_Info, 
Count);
+           if Output_Object.Footer_Use_ISO_Format then
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f1\fs22\b 
{\field{\*\fldinst { PAGE }}{\fldrslt {\lang1024 x}}}}\~\~\~\~\~\~");
+           elsif ARM_Output."="(Output_Object.Body_Font, ARM_Output.Swiss) then
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f1 
{\field{\*\fldinst { PAGE }}{\fldrslt {\lang1024 x}}}}\~\~\~\~\~\~");
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f0 
{\field{\*\fldinst { PAGE }}{\fldrslt {\lang1024 x}}}}\~\~\~\~\~\~");
+           end if;
+           if Output_Object.Footer_Use_Date then
+               Ada.Text_IO.Put (Output_Object.Output_File, Current_Date);
+           -- else no date.
+           end if;
+           Ada.Text_IO.Put (Output_Object.Output_File, "\tab ");
+           if Output_Object.Footer_Use_ISO_Format then
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f1\fs16 ");
+           end if;
+           if Output_Object.Footer_Use_Clause_Name then
+                Ada.Text_IO.Put (Output_Object.Output_File, Header_Text);
+           else
+                Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Unbounded.To_String 
(Output_Object.Footer_Text));
+           end if;
+           if Output_Object.Footer_Use_ISO_Format then
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "\par}}}");
+           else
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "\par}}");
+           end if;
+       else
+           Ada.Text_IO.Put (Output_Object.Output_File, "{\footerl ");
+           Write_Style_for_Paragraph (Output_Object.Output_File, Footer_Info, 
Count);
+           if Output_Object.Footer_Use_Clause_Name then
+                Ada.Text_IO.Put (Output_Object.Output_File, "{\b\f1 ");
+               if Level in ARM_Contents.Plain_Annex .. 
ARM_Contents.Normative_Annex then
+                   -- Clause Number includes "Annex". Just use the letter.
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
Clause_Number(Clause_Number'Last));
+               else
+                   Ada.Text_IO.Put (Output_Object.Output_File, Clause_Number);
+               end if;
+               if Output_Object.Footer_Use_ISO_Format then
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
"}\~\~\~{\f1\fs16 ");
+               elsif ARM_Output."="(Output_Object.Body_Font, ARM_Output.Swiss) 
then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "}\~\~\~{\f1 ");
+               else
+                   Ada.Text_IO.Put (Output_Object.Output_File, "}\~\~\~{\f0 ");
+               end if;
+                Ada.Text_IO.Put (Output_Object.Output_File, Header_Text);
+           else
+               if Output_Object.Footer_Use_ISO_Format then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "{\f1\fs16 ");
+               elsif ARM_Output."="(Output_Object.Body_Font, ARM_Output.Swiss) 
then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "{\f1 ");
+               else
+                   Ada.Text_IO.Put (Output_Object.Output_File, "{\f0 ");
+               end if;
+                Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Unbounded.To_String 
(Output_Object.Footer_Text));
+           end if;
+            Ada.Text_IO.Put (Output_Object.Output_File, "\tab ");
+           if Output_Object.Footer_Use_Date then
+               Ada.Text_IO.Put (Output_Object.Output_File, Current_Date);
+           -- else no date.
+           end if;
+           if Output_Object.Footer_Use_ISO_Format then
+                Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\~\~\~\~\~\~{\f1\fs22\b {\field{\*\fldinst { PAGE }}{\fldrslt {\lang1024 
x}}}}\par}}}");
+           else
+                Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\~\~\~\~\~\~{\field{\*\fldinst { PAGE }}{\fldrslt {\lang1024 x}}}\par}}}");
+           end if;
+           Ada.Text_IO.Put (Output_Object.Output_File, "{\footerr ");
+           Write_Style_for_Paragraph (Output_Object.Output_File, Footer_Info, 
Count);
+           if Output_Object.Footer_Use_ISO_Format then
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f1\fs22\b 
{\field{\*\fldinst { PAGE }}{\fldrslt {\lang1024 x}}}}\~\~\~\~\~\~");
+           elsif ARM_Output."="(Output_Object.Body_Font, ARM_Output.Swiss) then
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f1 
{\field{\*\fldinst { PAGE }}{\fldrslt {\lang1024 x}}}}\~\~\~\~\~\~");
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f0 
{\field{\*\fldinst { PAGE }}{\fldrslt {\lang1024 x}}}}\~\~\~\~\~\~");
+           end if;
+           if Output_Object.Footer_Use_Date then
+               Ada.Text_IO.Put (Output_Object.Output_File, Current_Date);
+           -- else no date.
+           end if;
+           Ada.Text_IO.Put (Output_Object.Output_File, "\tab ");
+           if Output_Object.Footer_Use_ISO_Format then
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f1\fs16 ");
+           elsif ARM_Output."="(Output_Object.Body_Font, ARM_Output.Swiss) then
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f1 ");
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f0 ");
+           end if;
+           if Output_Object.Footer_Use_Clause_Name then
+                Ada.Text_IO.Put (Output_Object.Output_File, Header_Text);
+               Ada.Text_IO.Put (Output_Object.Output_File, "}\~\~\~\b\f1 ");
+               if Level in ARM_Contents.Plain_Annex .. 
ARM_Contents.Normative_Annex then
+                   -- Clause Number includes "Annex". Just use the letter.
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
Clause_Number(Clause_Number'Last));
+               else
+                   Ada.Text_IO.Put (Output_Object.Output_File, Clause_Number);
+               end if;
+           else
+                Ada.Text_IO.Put (Output_Object.Output_File,
+                   Ada.Strings.Unbounded.To_String 
(Output_Object.Footer_Text));
+               Ada.Text_IO.Put (Output_Object.Output_File, "}");
+           end if;
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "\par}}");
+       end if;
+       Output_Object.Wrote_into_Section := True;
+    end Clause_Footer;
+
+
+    procedure Clause_Header (Output_Object     : in out RTF_Output_Type;
+                            Header_Text       : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False) is
+       -- Output a Clause header. The level of the header is specified
+       -- in Level. The Clause Number is as specified; the top-level (and
+       -- other) subdivision names are as specified. These should appear in
+       -- the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+       Count : Natural; -- Not used after being set.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Header in paragraph");
+       end if;
+        Ada.Text_IO.New_Line (Output_Object.Output_File);
+
+       -- Adjust footer.
+       Clause_Footer (Output_Object, Header_Text, Level, Clause_Number, 
No_Page_Break);
+
+       -- Special for table of contents:
+       if Clause_Number = "" and then
+               (Header_Text = "Table of Contents" or else -- Ada 95 format
+                Header_Text = "Contents") then -- ISO 2004 format.
+           if Header_Text = "Table of Contents" then
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\pard\plain 
\s1\sb240\sa60\keepn\widctlpar\outlinelevel0\adjustright 
\b\f1\fs36\kerning36\qc\cgrid Table of Contents\par}");
+           else
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\pard\plain 
\s1\sb240\sa60\keepn\widctlpar\outlinelevel0\adjustright 
\b\f1\fs36\kerning36\qc\cgrid Contents\par}");
+           end if;
+           Output_Object.Char_Count := 0;
+           return;
+       end if;
+
+       case Level is
+           when ARM_Contents.Plain_Annex =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Heading_1_Info, Count);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                   Clause_Number & ": " & Header_Text & "\par}");
+                               -- Note: Clause_Number includes "Annex"
+           when ARM_Contents.Normative_Annex =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Heading_1_Info, Count);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, Clause_Number 
& "\line ");
+                               -- Note: Clause_Number includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\b0 
(normative)}\line ");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, Header_Text & 
"\par}");
+           when ARM_Contents.Informative_Annex =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Heading_1_Info, Count);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, Clause_Number 
& "\line ");
+                               -- Note: Clause_Number includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\b0 
(informative)}\line ");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, Header_Text & 
"\par}");
+           when ARM_Contents.Unnumbered_Section =>
+               if Header_Text /= "" then
+                   Write_Style_for_Paragraph (Output_Object.Output_File,
+                       Heading_1_Info, Count);
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
Header_Text & "\par}");
+               end if;
+           when ARM_Contents.Section =>
+               case Top_Level_Subdivision_Name is
+                   when ARM_Output.Chapter =>
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                           Heading_1_Info, Count);
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"Chapter " &
+                            Clause_Number & ": " & Header_Text & "\par}");
+                   when ARM_Output.Section =>
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                           Heading_1_Info, Count);
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"Section " &
+                            Clause_Number & ": " & Header_Text & "\par}");
+                   when ARM_Output.Clause =>
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                           Heading_1_Info, Count);
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                            Clause_Number & "\~\~\~" & Header_Text & "\par}");
+               end case;
+           when ARM_Contents.Clause =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Heading_2_Info, Count);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                    Clause_Number & " " & Header_Text & "\par}");
+           when ARM_Contents.Subclause =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Heading_3_Info, Count);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                    Clause_Number & " " & Header_Text & "\par}");
+           when ARM_Contents.Subsubclause =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Heading_4_Info, Count);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                    Clause_Number & " " & Header_Text & "\par}");
+           when ARM_Contents.Dead_Clause =>
+               raise Program_Error; -- No headers for dead clauses.
+       end case;
+       Output_Object.Char_Count := 0;
+    end Clause_Header;
+
+
+    procedure Revised_Clause_Header
+                           (Output_Object     : in out RTF_Output_Type;
+                            New_Header_Text   : in String;
+                            Old_Header_Text   : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Version           : in 
ARM_Contents.Change_Version_Type;
+                            Old_Version       : in 
ARM_Contents.Change_Version_Type;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False) is
+       -- Output a revised clause header. Both the original and new text will
+       -- be output. The level of the header is specified in Level. The Clause
+       -- Number is as specified; the top-level (and other) subdivision names
+       -- are as specified. These should appear in the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- Version is the insertion version of the new text; Old_Version is
+       -- the insertion version of the old text.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+       Count : Natural; -- Not used after being set.
+       function Header_Text return String is
+       begin
+           if Old_Version = '0' then -- Old is original text
+               return "{\revised\revauth" & Version & " " & New_Header_Text & 
"}{\deleted\revauthdel" & Version & " " & Old_Header_Text & "}";
+           else
+               return "{\revised\revauth" & Version & " " & New_Header_Text &
+                       "}{\deleted\revauthdel" & Version &
+                          "\revised\revauth" & Old_Version &  " " &
+                          Old_Header_Text & "}";
+           end if;
+       end Header_Text;
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Header in paragraph");
+       end if;
+        Ada.Text_IO.New_Line (Output_Object.Output_File);
+
+       -- Adjust footer.
+       Clause_Footer (Output_Object, New_Header_Text, Level,
+                      Clause_Number, No_Page_Break);
+
+       case Level is
+           when ARM_Contents.Plain_Annex =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Heading_1_Info, Count);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                   Clause_Number & ": " & Header_Text & "\par}");
+                               -- Note: Clause_Number includes "Annex"
+           when ARM_Contents.Normative_Annex =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Heading_1_Info, Count);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, Clause_Number 
& "\line ");
+                               -- Note: Clause_Number includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\b0 
(normative)}\line ");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, Header_Text & 
"\par}");
+           when ARM_Contents.Informative_Annex =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Heading_1_Info, Count);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, Clause_Number 
& "\line ");
+                               -- Note: Clause_Number includes "Annex"
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\b0 
(informative)}\line ");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, Header_Text & 
"\par}");
+           when ARM_Contents.Unnumbered_Section =>
+               if Header_Text /= "" then
+                   Write_Style_for_Paragraph (Output_Object.Output_File,
+                       Heading_1_Info, Count);
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, 
Header_Text & "\par}");
+               end if;
+           when ARM_Contents.Section =>
+               case Top_Level_Subdivision_Name is
+                   when ARM_Output.Chapter =>
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                           Heading_1_Info, Count);
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"Chapter " &
+                            Clause_Number & ": " & Header_Text & "\par}");
+                   when ARM_Output.Section =>
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                           Heading_1_Info, Count);
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"Section " &
+                            Clause_Number & ": " & Header_Text & "\par}");
+                   when ARM_Output.Clause =>
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                           Heading_1_Info, Count);
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                            Clause_Number & "\~\~\~" & Header_Text & "\par}");
+               end case;
+           when ARM_Contents.Clause =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Heading_2_Info, Count);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                    Clause_Number & " " & Header_Text & "\par}");
+           when ARM_Contents.Subclause =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Heading_3_Info, Count);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                    Clause_Number & " " & Header_Text & "\par}");
+           when ARM_Contents.Subsubclause =>
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Heading_4_Info, Count);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                    Clause_Number & " " & Header_Text & "\par}");
+           when ARM_Contents.Dead_Clause =>
+               raise Program_Error; -- No headers for dead clauses.
+       end case;
+       Output_Object.Char_Count := 0;
+    end Revised_Clause_Header;
+
+
+    procedure TOC_Marker (Output_Object : in out RTF_Output_Type;
+                         For_Start : in Boolean) is
+       -- Mark the start (if For_Start is True) or end (if For_Start is
+       -- False) of the table of contents data. Output objects that
+       -- auto-generate the table of contents can use this to do needed
+       -- actions.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "TOC in paragraph");
+       end if;
+       if Output_Object.Big_Files then
+           if For_Start then
+               -- Create a Table of contents field:
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                   Paragraph_Info(ARM_Output.Normal, 0),
+                   Output_Object.Char_Count);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                   "{\field\fldedit{\*\fldinst  TOC \\o ""1-3"" }{\fldrslt ");
+               Output_Object.Char_Count := 0;
+           else -- End.
+               -- Close the field:
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "}}\par}");
+           end if;
+       else -- Small files:
+           null; -- We're not generating a table of contents.
+       end if;
+    end TOC_Marker;
+
+
+    procedure New_Page (Output_Object : in out RTF_Output_Type;
+                       Kind : ARM_Output.Page_Kind_Type := 
ARM_Output.Any_Page) is
+       -- Output a page break.
+       -- Note that this has no effect on non-printing formats.
+       -- Any_Page breaks to the top of the next page (whatever it is);
+       -- Odd_Page_Only breaks to the top of the odd-numbered page;
+       -- Soft_Page allows a page break but does not force one (use in
+       -- "No_Breaks" paragraphs.)
+       -- Raises Not_Valid_Error if in a paragraph if Kind = Any_Page or
+       -- Odd_Page, and if not in a paragraph if Kind = Soft_Page.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       case Kind is
+           when ARM_Output.Any_Page =>
+               if Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Page in paragraph");
+               end if;
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\sect\sbkpage\pgncont ");
+                   -- A section break and start on a new page, with page 
numbers continuing.
+                   -- All other section properties are inherited.
+                   -- We use a section break here, and not
+                   -- "\page", because that gives the wrong footers if the next
+                   -- item is a clause header (as it usually is).
+               Output_Object.Wrote_into_Section := False;
+           when ARM_Output.Odd_Page_Only =>
+               if Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Page in paragraph");
+               end if;
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\sect\sbkodd\pgncont ");
+                   -- A section break and start on an odd page, with page 
numbers continuing.
+                   -- All other section properties are inherited.
+               Output_Object.Wrote_into_Section := False;
+           when ARM_Output.Soft_Page =>
+               if not Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Soft page not in paragraph");
+               end if;
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "\softpage ");
+       end case;
+    end New_Page;
+
+
+    procedure New_Column (Output_Object : in out RTF_Output_Type) is
+       -- Output a column break.
+       -- Raises Not_Valid_Error if in a paragraph, or if the number of
+       -- columns is 1.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "New Column in paragraph");
+       end if;
+       if Output_Object.Column_Count <= 1 then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Column break, but no columns");
+       end if;
+       -- Set the font size to the most recently used one, because
+       -- otherwise this takes a 12 pt. space, much too large in some cases:
+       declare
+           FS : constant String := Natural'Image(
+               Paragraph_Info(Output_Object.Paragraph_Style,
+                              Output_Object.Paragraph_Indent).Size);
+       begin
+            Ada.Text_IO.Put (Output_Object.Output_File, "\fs");
+            Ada.Text_IO.Put (Output_Object.Output_File, FS(2..FS'Last));
+       end;
+       Ada.Text_IO.Put_Line (Output_Object.Output_File, "\column ");
+    end New_Column;
+
+
+    procedure Separator_Line (Output_Object : in out RTF_Output_Type;
+                             Is_Thin : Boolean := True) is
+       -- Output a separator line. It is thin if "Is_Thin" is true.
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Separator in paragraph");
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+       if Is_Thin then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\pard 
\widctlpar\brdrb\brdrs\brdrw15\brsp20 \adjustright \fs4\par }");
+               -- \brdrb - Bottom border; \brdrs - Single thickness;
+               -- \brdrw15 - thickness of 15 twips (max 75);
+               -- \brsp20 - spacing between border and text.
+       else
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "{\pard 
\widctlpar\brdrb\brdrs\brdrw30\brsp20 \adjustright \fs4\par }");
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+    end Separator_Line;
+
+
+    function Format_Value (Value : in Integer) return String is
+       Str : constant String := Natural'Image(Value);
+    begin
+       if Value < 0 then
+           return Str;
+       else
+           return Str(2..Str'Last);
+       end if;
+    end Format_Value;
+
+
+    type Table_Info_Kind is (Caption, Header, Header_no_Caption, First_Row, 
Row, Last_Row);
+
+    procedure RTF_Table_Info (Output_Object : in out RTF_Output_Type;
+                             Kind : in Table_Info_Kind) is
+       -- Output the current table definition (Word needs this on every row):
+       use type ARM_Output.Column_Text_Alignment;
+    begin
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "\trowd \trgaph108 ");
+
+        Ada.Text_IO.Put_Line (Output_Object.Output_File, "\trrh" &
+           Format_Value(Paragraph_Info(ARM_Output.Normal,0).Size * 16) &
+           "\trleft" & Format_Value(Output_Object.Table_Indent) & " ");
+
+       if Output_Object.Table_Has_Border then
+           -- Set all of the borders to the normal:
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\trbrdrt\brdrs\brdrw10 " &
+               "\trbrdrl\brdrs\brdrw10 " & "\trbrdrb\brdrs\brdrw10 " &
+               "\trbrdrr\brdrs\brdrw10 " & "\trbrdrh\brdrs\brdrw10 " &
+               "\trbrdrv\brdrs\brdrw10 ");
+       -- else nothing.
+       end if;
+
+       if Output_Object.Table_No_Page_Break then
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\trkeep\trkeepfollow ");
+       elsif Kind = Header_no_Caption then
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "\trhdr\trkeep ");
+       else
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "\trkeep ");
+       end if;
+
+       case Kind is
+           when Caption =>
+               -- Now, define the cell borders:
+               if Output_Object.Table_Has_Border then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                       "\clvertalc \clbrdrt\brdrs\brdrw10 " &
+                       "\clbrdrl\brdrs\brdrw10 " &
+                       "\clbrdrb\brdrs\brdrw10 " &
+                       "\clbrdrr\brdrs\brdrw10 ");
+               else
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                       "\clvertalc ");
+               end if;
+
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\cltxlrtb\cellx" &
+                   Format_Value(Output_Object.Table_Indent + 
Output_Object.Table_Width) & " ");
+                   -- Caption cell crosses entire line.
+
+               -- Now, set up text (normal, centered):
+               if Output_Object.Table_Has_Small_Text then
+                   Write_Style_for_Paragraph (Output_Object.Output_File,
+                                              Table_C_Sml_Text_Info,
+                                              Output_Object.Char_Count);
+                   Output_Object.Real_Size := Table_C_Sml_Text_Info.Size;
+                   Output_Object.Size := 0;
+               else
+                   Write_Style_for_Paragraph (Output_Object.Output_File,
+                                              Table_C_Text_Info,
+                                              Output_Object.Char_Count);
+                   Output_Object.Real_Size := Table_C_Text_Info.Size;
+                   Output_Object.Size := 0;
+               end if;
+               Ada.Text_IO.Put (Output_Object.Output_File, "\intbl ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 6;
+
+           when Header | Header_No_Caption =>
+               -- Now, define the cell borders for each cell:
+               for I in 1 .. Output_Object.Column_Count loop
+                   if Output_Object.Table_Has_Border then
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                           "\clvertalc \clbrdrt\brdrs\brdrw10 " &
+                           "\clbrdrl\brdrs\brdrw10 " &
+                           "\clbrdrb\brdrs\brdrw10 " &
+                           "\clbrdrr\brdrs\brdrw10 ");
+                   else
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                           "\clvertalc ");
+                   end if;
+--Ada.Text_IO.Put_Line("Header:");
+--Ada.Text_IO.Put_Line("Indent:" & Natural'Image(Output_Object.Table_Indent) &
+--     " Count:" & Natural'Image(I+Output_Object.Table_First_Column_Mult-1));
+                   if I /= Output_Object.Column_Count then
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\cltxlrtb\cellx" &
+                           Format_Value(Output_Object.Table_Indent +
+                               
Output_Object.Table_Column_Width*(Integer(I+Output_Object.Table_First_Column_Mult-1)))
 & " ");
+                   else -- Last cell, full width.
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\cltxlrtb\cellx" &
+                           Format_Value(Output_Object.Table_Indent + 
Output_Object.Table_Width) & " ");
+                   end if;
+               end loop;
+
+               -- Now, define text format:
+               if Output_Object.Table_Alignment = ARM_Output.Center_All then
+                   if Output_Object.Table_Has_Small_Text then
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                                                  Table_C_Sml_Text_Info,
+                                                  Output_Object.Char_Count);
+                       Output_Object.Real_Size := Table_C_Sml_Text_Info.Size;
+                       Output_Object.Size := 0;
+                   else
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                                                  Table_C_Text_Info,
+                                                  Output_Object.Char_Count);
+                       Output_Object.Real_Size := Table_C_Text_Info.Size;
+                       Output_Object.Size := 0;
+                   end if;
+               else
+                   if Output_Object.Table_Has_Small_Text then
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                                                  Table_L_Sml_Text_Info,
+                                                  Output_Object.Char_Count);
+                       Output_Object.Real_Size := Table_L_Sml_Text_Info.Size;
+                       Output_Object.Size := 0;
+                   else
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                                                  Table_L_Text_Info,
+                                                  Output_Object.Char_Count);
+                       Output_Object.Real_Size := Table_L_Text_Info.Size;
+                       Output_Object.Size := 0;
+                   end if;
+               end if;
+               Ada.Text_IO.Put (Output_Object.Output_File, "\intbl ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 6;
+
+           when First_Row | Row | Last_Row =>
+               -- Now, define the cell borders for each cell:
+               for I in 1 .. Output_Object.Column_Count loop
+                   if Output_Object.Table_Has_Border then
+                       if Kind = First_Row then
+                           Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                               "\clvertalc \clbrdrt\brdrs\brdrw10 " &
+                               "\clbrdrl\brdrs\brdrw10 " &
+                               "\clbrdrb\brdrs\brdrw10 " &
+                               "\clbrdrr\brdrs\brdrw10 ");
+                       elsif Kind = Row then
+                           --Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                           --    "\clvertalc \clbrdrl\brdrs\brdrw10 " &
+                           --    "\clbrdrr\brdrs\brdrw10 ");
+                           -- Why no bottom border??
+
+                           -- No top border!
+                           Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                               "\clvertalc \clbrdrl\brdrs\brdrw10 " &
+                               "\clbrdrb\brdrs\brdrw10 " &
+                               "\clbrdrr\brdrs\brdrw10 ");
+                       else -- Kind = Last_Row then
+                           -- No top border!
+                           Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                               "\clvertalc \clbrdrl\brdrs\brdrw10 " &
+                               "\clbrdrb\brdrs\brdrw10 " &
+                               "\clbrdrr\brdrs\brdrw10 ");
+                       end if;
+                   else
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                           "\clvertalc ");
+                   end if;
+
+                   if I /= Output_Object.Column_Count then
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\cltxlrtb\cellx" &
+                           Format_Value(Output_Object.Table_Indent +
+                               
Output_Object.Table_Column_Width*(Integer(I+Output_Object.Table_First_Column_Mult-1)))
 & " ");
+                   else -- Last cell, full width.
+                       Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"\cltxlrtb\cellx" &
+                           Format_Value(Output_Object.Table_Indent + 
Output_Object.Table_Width) & " ");
+                   end if;
+               end loop;
+
+               -- Now, define text format:
+               if Output_Object.Table_Alignment = ARM_Output.Center_All then
+                   if Output_Object.Table_Has_Small_Text then
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                                                  Table_C_Sml_Text_Info,
+                                                  Output_Object.Char_Count);
+                       Output_Object.Real_Size := Table_C_Sml_Text_Info.Size;
+                       Output_Object.Size := 0;
+                   else
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                                                  Table_C_Text_Info,
+                                                  Output_Object.Char_Count);
+                       Output_Object.Real_Size := Table_C_Text_Info.Size;
+                       Output_Object.Size := 0;
+                   end if;
+               else
+                   if Output_Object.Table_Has_Small_Text then
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                                                  Table_L_Sml_Text_Info,
+                                                  Output_Object.Char_Count);
+                       Output_Object.Real_Size := Table_L_Sml_Text_Info.Size;
+                       Output_Object.Size := 0;
+                   else
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                                                  Table_L_Text_Info,
+                                                  Output_Object.Char_Count);
+                       Output_Object.Real_Size := Table_L_Text_Info.Size;
+                       Output_Object.Size := 0;
+                   end if;
+               end if;
+               Ada.Text_IO.Put (Output_Object.Output_File, "\intbl ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 6;
+
+       end case;
+
+       -- \trowd - Start a table row.
+       -- \row - End a table row.
+       -- \trgaph - Half of of the gap between cells, in twips.
+       -- \trhdr - Repeat line as header on following pages.
+       -- \trkeep - Keep the row together (no page break).
+       -- \trkeepfollow - Keep the row with the following (no page break).
+       -- \trleft - Left edge of table row (in twips).
+       -- \trrh - Row height (minimum if positive, absolute if negative).
+
+       -- \clveralc - Text is centered vertically in cell.
+       -- \cltxlrtb - Text flows top to bottom and left to right.
+       -- \cellx - Right edge of cell, in Twips. (This is an absolute 
position).
+
+       -- \intbl - Required marker for each cell.
+       -- \cell - Ends cell (use instead of \par).
+
+       -- \trbrdrt - Row Top border
+       -- \trbrdrl - Row Left border
+       -- \trbrdrb - Row Bottom border
+       -- \trbrdrr - Row Right border
+       -- \trbrdrh - Row Horizontal border
+       -- \trbrdrv - Row Vertical border
+       -- \clbrdrt - Cell Top border
+       -- \clbrdrl - Cell Left border
+       -- \clbrdrb - Cell Bottom border
+       -- \clbrdrr - Cell Right border
+       -- \brdrs - Single width border
+       -- \brdrw - Width of the pen (can't be more than 75).
+
+    end RTF_Table_Info;
+
+
+    procedure Start_Table (Output_Object : in out RTF_Output_Type;
+                          Columns : in ARM_Output.Column_Count;
+                          First_Column_Width : in ARM_Output.Column_Count;
+                          Last_Column_Width : in ARM_Output.Column_Count;
+                          Alignment : in ARM_Output.Column_Text_Alignment;
+                          No_Page_Break : in Boolean;
+                          Has_Border : in Boolean;
+                          Small_Text_Size : in Boolean;
+                          Header_Kind : in ARM_Output.Header_Kind_Type) is
+       -- Starts a table. The number of columns is Columns; the first
+       -- column has First_Column_Width times the normal column width, and
+       -- the last column has Last_Column_Width times the normal column width.
+       -- Alignment is the horizontal text alignment within the columns.
+       -- No_Page_Break should be True to keep the table intact on a single
+       -- page; False to allow it to be split across pages.
+       -- Has_Border should be true if a border is desired, false otherwise.
+       -- Small_Text_Size means that the contents will have the AARM size;
+       -- otherwise it will have the normal size.
+       -- Header_Kind determines whether the table has headers.
+       -- This command starts a paragraph; the entire table is a single
+       -- paragraph. Text will be considered part of the caption until the
+       -- next table marker call.
+       -- Raises Not_Valid_Error if in a paragraph.
+       Page_Width : Natural;
+       Column_Units : constant Natural :=
+           Natural(Columns+First_Column_Width+Last_Column_Width-2);
+           -- The number of column units (a unit being a regular width column).
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Table in paragraph");
+       end if;
+
+       Output_Object.Is_In_Paragraph := True;
+       Output_Object.Is_In_Table := True;
+       Output_Object.Table_No_Page_Break := No_Page_Break;
+       Output_Object.Table_Alignment := Alignment;
+       Output_Object.Table_First_Column_Mult := First_Column_Width;
+       Output_Object.Table_Last_Column_Mult := Last_Column_Width;
+       Output_Object.Table_Has_Border := Has_Border;
+       Output_Object.Table_Has_Small_Text := Small_Text_Size;
+
+       case Output_Object.Page_Size is
+           when ARM_RTF.A4 =>
+               Page_Width := 9030;
+           when ARM_RTF.Letter =>
+               Page_Width := 9360;
+           when ARM_RTF.Half_Letter =>
+               Page_Width := 5040;
+           when ARM_RTF.Ada95 =>
+               Page_Width := 7740;
+        end case;
+       if Column_Units <= 3 then
+           Output_Object.Table_Indent := Page_Width / 6;
+       elsif Column_Units <= 8 then
+           Output_Object.Table_Indent := Page_Width / 16;
+       else
+           Output_Object.Table_Indent := 0;
+       end if;
+        Output_Object.Table_Width  := Page_Width - 
Output_Object.Table_Indent*2;
+        Output_Object.Table_Column_Width  := Output_Object.Table_Width / 
(Column_Units);
+       Output_Object.Column_Count := Columns;
+--Ada.Text_IO.Put_Line("Table information");
+--Ada.Text_IO.Put_Line("Columns:" & Natural'Image(Columns) &
+--     " 1st column mult:" & Natural'Image(First_Column_Width) &
+--     " last column mult:" & Natural'Image(Last_Column_Width));
+--Ada.Text_IO.Put_Line("Width (twips):" & 
Natural'Image(Output_Object.Table_Width) &
+--     " Column width:" & Natural'Image(Output_Object.Table_Column_Width));
+
+       -- Make a blank line before, of the right size:
+       Write_Style_for_Paragraph (Output_Object.Output_File,
+                                  Table_L_Text_Info,
+                                  Output_Object.Char_Count);
+        Ada.Text_IO.Put (Output_Object.Output_File, "\par }");
+       Output_Object.Char_Count := 0;
+
+       case Header_Kind is
+           when ARM_Output.Both_Caption_and_Header =>
+               RTF_Table_Info (Output_Object, Kind => Caption);
+           when ARM_Output.Header_Only =>
+               RTF_Table_Info (Output_Object, Kind => Header_no_Caption);
+           when ARM_Output.No_Headers =>
+               RTF_Table_Info (Output_Object, Kind => Row);
+       end case;
+
+    end Start_Table;
+
+
+    procedure Table_Marker (Output_Object : in out RTF_Output_Type;
+                           Marker : in ARM_Output.Table_Marker_Type) is
+       -- Marks the end of an entity in a table.
+       -- If Marker is End_Caption, the table caption ends and the
+       --      future text is part of the table header.
+       -- If Marker is End_Header, the table header ends and the
+       --      future text is part of the table body.
+       -- If Marker is End_Row, a row in the table is completed, and another
+       --      row started.
+       -- If Marker is End_Row_Next_Is_Last, a row in the table is completed,
+       --      and another row started. That row is the last row in the table.
+       -- If Marker is End_Item, an item in the table header or body is ended,
+       --      and another started.
+       -- If Marker is End_Table, the entire table is finished.
+       -- Raises Not_Valid_Error if not in a table.
+       use type ARM_Output.Column_Text_Alignment;
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if (not Output_Object.Is_In_Paragraph) or (not 
Output_Object.Is_In_Table) then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Table marker not in table");
+       end if;
+       case Marker is
+           when ARM_Output.End_Item =>
+               if Output_Object.Table_Alignment = 
ARM_Output.Center_except_First then
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, "\cell }");
+                   Output_Object.Char_Count := 0;
+                   -- Now, define text format:
+                   if Output_Object.Table_Has_Small_Text then
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                                                  Table_C_Sml_Text_Info,
+                                                  Output_Object.Char_Count);
+                       Output_Object.Real_Size := Table_C_Sml_Text_Info.Size;
+                       Output_Object.Size := 0;
+                   else
+                       Write_Style_for_Paragraph (Output_Object.Output_File,
+                                                  Table_C_Text_Info,
+                                                  Output_Object.Char_Count);
+                       Output_Object.Real_Size := Table_C_Text_Info.Size;
+                       Output_Object.Size := 0;
+                   end if;
+               else -- Text format stays the same.
+                   Ada.Text_IO.Put_Line (Output_Object.Output_File, "\cell ");
+                   Output_Object.Char_Count := 0;
+               end if;
+
+           when ARM_Output.End_Caption =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "\cell }");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "\row "); -- 
End row.
+
+               -- Start header row:
+               RTF_Table_Info (Output_Object, Kind => Header); -- Repeat table 
definition.
+
+           when ARM_Output.End_Header =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "\cell }");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "\row "); -- 
End row.
+
+               -- Start 1st body row:
+               RTF_Table_Info (Output_Object, Kind => First_Row); -- Repeat 
table definition.
+
+           when ARM_Output.End_Row =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "\cell }");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "\row "); -- 
End row.
+
+               -- Start other body rows (no top border!):
+               RTF_Table_Info (Output_Object, Kind => Row); -- Repeat table 
definition.
+
+           when ARM_Output.End_Row_Next_Is_Last =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "\cell }");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "\row "); -- 
End row.
+
+               -- Start other body rows (no top border!):
+               RTF_Table_Info (Output_Object, Kind => Last_Row); -- Repeat 
table definition.
+
+           when ARM_Output.End_Table =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "\cell }");
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "\row "); -- 
End last row of table.
+
+               Output_Object.Is_In_Paragraph := False;
+               Output_Object.Is_In_Table := False;
+               Output_Object.Column_Count := 1;
+
+               -- Make a blank line after, of the right size:
+               Write_Style_for_Paragraph (Output_Object.Output_File,
+                                          Table_L_Text_Info,
+                                          Output_Object.Char_Count);
+               Ada.Text_IO.Put (Output_Object.Output_File, "\par }");
+               Output_Object.Char_Count := 0;
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+       end case;
+    end Table_Marker;
+
+
+    -- Text output: These are only allowed after a Start_Paragraph and
+    -- before any End_Paragraph. Raises Not_Valid_Error if not allowed.
+
+    Special_Set : constant Ada.Strings.Maps.Character_Set :=
+         Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('\'),
+           Ada.Strings.Maps."or" (Ada.Strings.Maps.To_Set ('{'),
+                                  Ada.Strings.Maps.To_Set ('}')));
+
+    procedure Ordinary_Text (Output_Object : in out RTF_Output_Type;
+                            Text : in String) is
+       -- Output ordinary text.
+       -- The text must end at a word break, never in the middle of a word.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Ada.Strings.Fixed.Count (Text, Special_Set) = 0 and then
+          (Output_Object.Paragraph_Style not in
+             ARM_Output.Text_Prefixed_Style_Subtype or else
+               Output_Object.Saw_Hang_End) then
+               -- The second condition so that prefixes have their
+               -- characters counted properly...
+           if Output_Object.Char_Count + Text'Length > LINE_LENGTH then
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Ada.Text_IO.Put (Output_Object.Output_File, Text);
+               Output_Object.Char_Count := Text'Length;
+           elsif Output_Object.Char_Count + Text'Length >= LINE_LENGTH - 10 
then
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, Text);
+               Output_Object.Char_Count := 0;
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, Text);
+               Output_Object.Char_Count := Output_Object.Char_Count + 
Text'Length;
+           end if;
+       else
+           for I in Text'range loop
+               Ordinary_Character (Output_Object, Text(I));
+           end loop;
+       end if;
+    end Ordinary_Text;
+
+
+    procedure Ordinary_Character (Output_Object : in out RTF_Output_Type;
+                                 Char : in Character) is
+       -- Output an ordinary character.
+       -- Spaces will be used to break lines as needed.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Char = ' ' and then Output_Object.Char_Count >= LINE_LENGTH - 5 then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, " ");
+           Output_Object.Char_Count := 0;
+       else
+           if Char = '\' then
+               Ada.Text_IO.Put (Output_Object.Output_File, "\\");
+               Output_Object.Char_Count := Output_Object.Char_Count + 2;
+           elsif Char = '{' then
+               Ada.Text_IO.Put (Output_Object.Output_File, "\{");
+               Output_Object.Char_Count := Output_Object.Char_Count + 2;
+           elsif Char = '}' then
+               Ada.Text_IO.Put (Output_Object.Output_File, "\}");
+               Output_Object.Char_Count := Output_Object.Char_Count + 2;
+           elsif Char >= Character'Val(126) then -- All higher Latin-1 
characters.
+               declare
+                   Code : constant Natural := Character'Pos(Char);
+               begin
+                   if Code mod 16 >= 10 then
+                       if Code / 16 >= 10 then
+                           Ada.Text_IO.Put (Output_Object.Output_File, "\'" &
+                               Character'Val((Code / 16 - 10) + 
Character'Pos('a')) &
+                               Character'Val((Code mod 16 - 10) + 
Character'Pos('a')));
+                       else
+                           Ada.Text_IO.Put (Output_Object.Output_File, "\'" &
+                               Character'Val((Code / 16) + Character'Pos('0')) 
&
+                               Character'Val((Code mod 16 - 10) + 
Character'Pos('a')));
+                       end if;
+                   else
+                       if Code / 16 >= 10 then
+                           Ada.Text_IO.Put (Output_Object.Output_File, "\'" &
+                               Character'Val((Code / 16 - 10) + 
Character'Pos('a')) &
+                               Character'Val((Code mod 16) + 
Character'Pos('0')));
+                       else
+                           Ada.Text_IO.Put (Output_Object.Output_File, "\'" &
+                               Character'Val((Code / 16) + Character'Pos('0')) 
&
+                               Character'Val((Code mod 16) + 
Character'Pos('0')));
+                       end if;
+                   end if;
+                   Output_Object.Char_Count := Output_Object.Char_Count + 5;
+               end;
+               if Output_Object.Paragraph_Style in
+                     ARM_Output.Text_Prefixed_Style_Subtype and then
+                  (not Output_Object.Saw_Hang_End) then
+                   if not Ada.Characters.Handling.Is_Lower (Char) then
+                       Output_Object.Prefix_Large_Char_Count :=
+                          Output_Object.Prefix_Large_Char_Count + 1;
+                   -- else small character. (This isn't perfectly accurate, but
+                   -- these aren't used much in prefixes.)
+                   end if;
+               end if;
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, Char);
+               Output_Object.Char_Count := Output_Object.Char_Count + 1;
+               if Output_Object.Paragraph_Style in
+                       ARM_Output.Text_Prefixed_Style_Subtype and then
+                  (not Output_Object.Saw_Hang_End) then
+--Ada.Text_Io.Put (Char);
+                   if Char in 'A' .. 'H' or else Char in 'J' .. 'Z' or else -- 
Capital 'I' is narrow.
+                      Char in '0' .. '9' or else
+                       Char = '+' or else Char = '_' or else Char = '@' or else
+                       Char = '#' or else Char = '$' or else Char = '%' or else
+                       Char = '&' or else Char = '*' or else Char = '<' or else
+                       Char = '>' then
+                       Output_Object.Prefix_Large_Char_Count :=
+                          Output_Object.Prefix_Large_Char_Count + 1;
+                   elsif Char = '.' then
+                       -- '.' is extra narrow; treat it as canceling out a
+                       -- a large character.
+                       if Output_Object.Prefix_Large_Char_Count > 0 then
+                           Output_Object.Prefix_Large_Char_Count :=
+                              Output_Object.Prefix_Large_Char_Count - 1;
+                       end if;
+                   -- else small character.
+                   end if;
+               end if;
+           end if;
+       end if;
+    end Ordinary_Character;
+
+
+    procedure Hard_Space (Output_Object : in out RTF_Output_Type) is
+       -- Output a hard space. No line break should happen at a hard space.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.Paragraph_Style in ARM_Output.Examples ..
+               ARM_Output.Small_Examples then
+           -- Fixed width fonts; hard spaces seem to be a different width
+           -- than regular ones. So use regular spaces.
+            Ada.Text_IO.Put (Output_Object.Output_File, " ");
+            Output_Object.Char_Count := Output_Object.Char_Count + 1;
+       else
+            Ada.Text_IO.Put (Output_Object.Output_File, "\~");
+            Output_Object.Char_Count := Output_Object.Char_Count + 2;
+       end if;
+    end Hard_Space;
+
+
+    procedure Line_Break (Output_Object : in out RTF_Output_Type) is
+       -- Output a line break. This does not start a new paragraph.
+       -- This corresponds to a "<BR>" in HTML.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.Is_In_Table then
+           -- We can't use \Par in a table, or Word deadlocks.
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "\line ");
+            Output_Object.Char_Count := 0;
+       elsif not Paragraph_Info(Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent).Is_Justified then
+           -- We can't use \Par, as that inserts paragraph spacing.
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "\line ");
+            Output_Object.Char_Count := 0;
+       else
+           -- We can't use \Line, as that will cause the line to be justified.
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "\sa0\par ");
+               -- We have to turn off the inter-paragraph spacing.
+               -- Now, reset the \sa setting.
+           declare
+               SA_Width : Natural := 
Paragraph_Info(Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent).After;
+           begin
+               if ARM_Output."="(Output_Object.Current_Space_After,
+                  ARM_Output.Narrow) then
+                  SA_Width := SA_Width*(LEADING_PERCENT/10)/10;
+               elsif ARM_Output."="(Output_Object.Current_Space_After,
+                      ARM_Output.Wide) then
+                  SA_Width := SA_Width*(TRAILING_PERCENT/10)/10;
+               end if;
+               declare
+                   SA : constant String := Natural'Image(SA_Width);
+               begin
+                    Ada.Text_IO.Put (Output_Object.Output_File, "\sa");
+                    Ada.Text_IO.Put (Output_Object.Output_File, 
SA(2..SA'Last));
+                    Ada.Text_IO.Put (Output_Object.Output_File, " ");
+                    Output_Object.Char_Count := 4 + SA'Length - 1;
+               end;
+           end;
+           if (Output_Object.Paragraph_Style in ARM_Output.Bulleted ..
+                   ARM_Output.Small_Hanging_in_Bulleted) then -- Always 
"NoPrefix" here.
+                Ada.Text_IO.Put (Output_Object.Output_File, "\tab ");
+                Output_Object.Char_Count := Output_Object.Char_Count + 5;
+           end if;
+       end if;
+    end Line_Break;
+
+
+    procedure Index_Line_Break (Output_Object : in out RTF_Output_Type;
+                               Clear_Keep_with_Next : in Boolean) is
+       -- Output a line break for the index. This does not start a new
+       -- paragraph in terms of spacing. This corresponds to a "<BR>"
+       -- in HTML. If Clear_Keep_with_Next is true, insure that the next
+       -- line does not require the following line to stay with it.
+       -- Raises Not_Valid_Error if the paragraph is not in the index format.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if ARM_Output."/=" (Output_Object.Paragraph_Style, ARM_Output.Index) or 
else
+          ARM_Output."/=" (Output_Object.Paragraph_Indent, 0) then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in index paragraph");
+       end if;
+       -- We have to use /par here, because otherwise we don't get the "undent"
+       -- at the start of the paragraph.
+
+       if Clear_Keep_with_Next then
+           -- Note: We need this special routine, because ending the paragraph
+           -- would add blank lines to the HTML.
+           End_Paragraph (Output_Object);
+           Start_Paragraph (Output_Object, ARM_Output.Index, Indent => 0,
+               Number => "", No_Breaks => True, Keep_with_Next => False,
+               Tab_Stops => Output_Object.Tab_Stops);
+       else
+            Ada.Text_IO.Put_Line (Output_Object.Output_File, "\par ");
+               -- Inherits the paragraph properties.
+       end if;
+        Output_Object.Char_Count := 0;
+    end Index_Line_Break;
+
+
+    procedure Soft_Line_Break (Output_Object : in out RTF_Output_Type) is
+       -- Output a soft line break. This is a place (in the middle of a
+       -- "word") that we allow a line break. It is usually used after
+       -- underscores in long non-terminals.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+        Ada.Text_IO.Put (Output_Object.Output_File, "\softline ");
+        --Ada.Text_IO.Put (Output_Object.Output_File, "\zwbo ");
+       --    -- Zero-width break opportunity. (Word 7.0 [Word 95] or later).
+       --    (Doesn't work).
+        Output_Object.Char_Count := Output_Object.Char_Count + 10;
+    end Soft_Line_Break;
+
+
+    procedure Soft_Hyphen_Break (Output_Object : in out RTF_Output_Type) is
+       -- Output a soft line break, with a hyphen. This is a place (in the 
middle of
+       -- a "word") that we allow a line break. If the line break is used,
+       -- a hyphen will be added to the text.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+        Ada.Text_IO.Put (Output_Object.Output_File, "\-");
+        Output_Object.Char_Count := Output_Object.Char_Count + 2;
+    end Soft_Hyphen_Break;
+
+
+    procedure Tab (Output_Object : in out RTF_Output_Type) is
+       -- Output a tab, inserting space up to the next tab stop.
+       -- Raises Not_Valid_Error if the paragraph was created with
+       -- Tab_Stops = ARM_Output.NO_TABS.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if ARM_Output."="(Output_Object.Tab_Stops, ARM_Output.NO_TABS) then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Tab, but none set");
+       end if;
+        Ada.Text_IO.Put (Output_Object.Output_File, "\tab ");
+        Output_Object.Char_Count := Output_Object.Char_Count + 5;
+    end Tab;
+
+
+    procedure Special_Character (Output_Object : in out RTF_Output_Type;
+                                Char : in ARM_Output.Special_Character_Type) is
+       -- Output an special character.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       case Char is
+           when ARM_Output.EM_Dash =>
+               Ada.Text_IO.Put (Output_Object.Output_File, "\emdash ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 8;
+           when ARM_Output.EN_Dash =>
+               Ada.Text_IO.Put (Output_Object.Output_File, "\endash ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 8;
+           when ARM_Output.GEQ =>
+               --Unicode: Doesn't work on Windows 98:
+               --Ada.Text_IO.Put (Output_Object.Output_File, "\uc2\u8805 >=");
+               --Output_Object.Char_Count := Output_Object.Char_Count + 13;
+               -- Character 179, Symbol font.
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f3\'B3}");
+               Output_Object.Char_Count := Output_Object.Char_Count + 9;
+           when ARM_Output.LEQ =>
+               --Unicode: Doesn't work on Windows 98:
+               --Ada.Text_IO.Put (Output_Object.Output_File, "\uc2\u8804 <=");
+               --Output_Object.Char_Count := Output_Object.Char_Count + 13;
+               -- Character 163, Symbol font.
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f3\'A3}");
+               Output_Object.Char_Count := Output_Object.Char_Count + 9;
+           when ARM_Output.NEQ =>
+               --Unicode: Doesn't work on Windows 98:
+               --Ada.Text_IO.Put (Output_Object.Output_File, "\uc2\u8800 /=");
+               --Output_Object.Char_Count := Output_Object.Char_Count + 13;
+               -- Character 185, Symbol font.
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f3\'B9}");
+               Output_Object.Char_Count := Output_Object.Char_Count + 9;
+           when ARM_Output.PI =>
+               --Unicode: Doesn't work on Windows 98:
+               --Ada.Text_IO.Put (Output_Object.Output_File, "\uc2\u960 PI");
+               --Output_Object.Char_Count := Output_Object.Char_Count + 12;
+               -- Character 112, Symbol font.
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f3\'70}");
+               Output_Object.Char_Count := Output_Object.Char_Count + 9;
+           when ARM_Output.Left_Ceiling =>
+               --Unicode: Doesn't work on Windows 98:
+               --Ada.Text_IO.Put (Output_Object.Output_File, "\uc8\u8968 
Ceiling(");
+               --Output_Object.Char_Count := Output_Object.Char_Count + 19;
+               -- Character 233, Symbol font.
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f3\'E9}");
+               Output_Object.Char_Count := Output_Object.Char_Count + 9;
+           when ARM_Output.Right_Ceiling =>
+               --Unicode: Doesn't work on Windows 98:
+               --Ada.Text_IO.Put (Output_Object.Output_File, "\uc1\u8969 )");
+               --Output_Object.Char_Count := Output_Object.Char_Count + 11;
+               -- Character 249, Symbol font.
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f3\'F9}");
+               Output_Object.Char_Count := Output_Object.Char_Count + 9;
+           when ARM_Output.Left_Floor =>
+               --Unicode: Doesn't work on Windows 98:
+               --Ada.Text_IO.Put (Output_Object.Output_File, "\uc6\u8970 
Floor(");
+               --Output_Object.Char_Count := Output_Object.Char_Count + 17;
+               -- Character 235, Symbol font.
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f3\'EB}");
+               Output_Object.Char_Count := Output_Object.Char_Count + 9;
+           when ARM_Output.Right_Floor =>
+               --Unicode: Doesn't work on Windows 98:
+               --Ada.Text_IO.Put (Output_Object.Output_File, "\uc1\u8971 )");
+               --Output_Object.Char_Count := Output_Object.Char_Count + 11;
+               -- Character 251, Symbol font.
+               Ada.Text_IO.Put (Output_Object.Output_File, "{\f3\'FB}");
+               Output_Object.Char_Count := Output_Object.Char_Count + 9;
+           when ARM_Output.Thin_Space =>
+               Ada.Text_IO.Put (Output_Object.Output_File, "\qmspace ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 9;
+           when ARM_Output.Left_Quote =>
+               Ada.Text_IO.Put (Output_Object.Output_File, "\lquote ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 8;
+           when ARM_Output.Right_Quote =>
+               Ada.Text_IO.Put (Output_Object.Output_File, "\rquote ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 8;
+           when ARM_Output.Left_Double_Quote =>
+               Ada.Text_IO.Put (Output_Object.Output_File, "\ldblquote ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 11;
+           when ARM_Output.Right_Double_Quote =>
+               Ada.Text_IO.Put (Output_Object.Output_File, "\rdblquote ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 11;
+           when ARM_Output.Small_Dotless_I =>
+               --Unicode: Doesn't work on Windows 98: but we have no choice 
here:
+               Ada.Text_IO.Put (Output_Object.Output_File, "\uc1\u305 i");
+               -- Note: \uc1 means ASCII version has one character;
+               -- \u305 means use Unicode character 305.
+               Output_Object.Char_Count := Output_Object.Char_Count + 11;
+           when ARM_Output.Capital_Dotted_I =>
+               --Unicode: Doesn't work on Windows 98: but we have no choice 
here:
+               Ada.Text_IO.Put (Output_Object.Output_File, "\uc1\u304 I");
+               Output_Object.Char_Count := Output_Object.Char_Count + 11;
+       end case;
+       if Output_Object.Paragraph_Style in
+             ARM_Output.Text_Prefixed_Style_Subtype and then
+          (not Output_Object.Saw_Hang_End) then
+               Output_Object.Prefix_Large_Char_Count :=
+                  Output_Object.Prefix_Large_Char_Count + 1;
+       end if;
+    end Special_Character;
+
+
+    procedure Unicode_Character (Output_Object : in out RTF_Output_Type;
+                                Char : in ARM_Output.Unicode_Type) is
+       -- Output a Unicode character, with code position Char.
+       Char_Code : constant String := ARM_Output.Unicode_Type'Image(Char);
+       Len : constant String := Natural'Image(Char_Code'Length+2);
+    begin
+       -- We don't check this, we just output it.
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+        Ada.Text_IO.Put (Output_Object.Output_File, "\uc" & Len(2..Len'Last) &
+          "\u" & Char_Code(2..Char_Code'Last) & " <U" &
+          Char_Code(2..Char_Code'Last) & ">");
+        Output_Object.Char_Count := Output_Object.Char_Count + 9 + Len'Last-1 +
+          (Char_Code'Last-1)*2;
+       if Output_Object.Paragraph_Style in
+               ARM_Output.Text_Prefixed_Style_Subtype and then
+          (not Output_Object.Saw_Hang_End) then
+               Output_Object.Prefix_Large_Char_Count :=
+                  Output_Object.Prefix_Large_Char_Count + 1;
+       end if;
+    end Unicode_Character;
+
+
+    procedure End_Hang_Item (Output_Object : in out RTF_Output_Type) is
+       -- Marks the end of a hanging item. Call only once per paragraph.
+       -- Raises Not_Valid_Error if the paragraph style is not in
+       -- Text_Prefixed_Style_Subtype, or if this has already been
+       -- called for the current paragraph, or if the paragraph was started
+       -- with No_Prefix = True.
+       Current_Format : ARM_Output.Format_Type;
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.Paragraph_Style not in 
ARM_Output.Text_Prefixed_Style_Subtype then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not a hanging paragraph");
+       end if;
+       if Output_Object.Saw_Hang_End then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Already saw the end of the hanging part");
+       end if;
+       Output_Object.Saw_Hang_End := True;
+
+--Ada.Text_Io.Put (": Cnt=" & Natural'Image(Output_Object.Char_Count) & " 
Lrg=" &
+--   Natural'Image(Output_Object.Prefix_Large_Char_Count));
+--Ada.Text_Io.Put (" Style=" & 
ARM_Output.Paragraph_Style_Type'Image(Output_Object.Paragraph_Style));
+--Ada.Text_Io.Put (" Indent=" & 
ARM_Output.Paragraph_Indent_Type'Image(Output_Object.Paragraph_Indent));
+--Ada.Text_Io.Put (" Count=" & Natural'Image(
+--      ((Paragraph_Info(Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent).Hang_Width * 6 * 2) /
+--       (Paragraph_Info(Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent).Size * 5   * 5)) - 1));
+--Ada.Text_Io.Put (" Hang_Width=" & 
Natural'Image(Paragraph_Info(Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent).Hang_Width));
+--Ada.Text_Io.Put (" Size=" & 
Natural'Image(Paragraph_Info(Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent).Size));
+
+        if Output_Object.Char_Count*2 + Output_Object.Prefix_Large_Char_Count
+           <= ((Paragraph_Info(Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent).Hang_Width * 6 * 2) /
+               (Paragraph_Info(Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent).Size * 5   * 5)) - 1 then
+           -- No line break needed. (I can't find a way to get Word to do
+           -- this properly, so we have to do it. We assume large characters
+           -- are about 1 1/2 times normal characters, and that normal
+           -- characters are about 5/6 the pt. size in width. Note that "Size"
+           -- is in 1/2 pts., while "Hang_Width" is in .1 pts., so we need
+           -- the "5" to correct the units.) The "- 1" is to allow space
+           -- for the trailing space/tab. (Running into the text looks bad!).
+           Ada.Text_IO.Put (Output_Object.Output_File, "\tab ");
+           Output_Object.Char_Count := Output_Object.Char_Count + 5;
+--Ada.Text_Io.Put_Line (" No_Break");
+        else -- Line break needed.
+           -- Just writing a line break clobbers any open styles.
+           -- We have to save the current style, close it properly,
+           -- do the line break stuff, and then reopen it. This showed as
+           -- a bug only in RM-All, 3.3.1(19) [which should be shown as
+           -- deleted, but was not.]
+           -- Note that the HTML version does this save and restore dance,
+           -- why we didn't do it here I'm not sure - RLB - 8/19/16.
+           Current_Format :=  (Bold    => Output_Object.Is_Bold,
+                               Italic  => Output_Object.Is_Italic,
+                               Font    => Output_Object.Font,
+                               Size    => Output_Object.Size,
+                               Color   => Output_Object.Color,
+                               Change  => Output_Object.Change,
+                               Version => Output_Object.Version,
+                               Added_Version => Output_Object.Added_Version,
+                               Location=> Output_Object.Location);
+           Text_Format (Output_Object, ARM_Output.NORMAL_FORMAT);
+               -- Clear the existing format.
+           --Ada.Text_IO.Put_Line (Output_Object.Output_File, "\line ");
+           --Output_Object.Char_Count := 0;
+           --This idiot program JUSTIFIES the text fragment, so a line
+           --break cannot be used if the text is justified.
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "\sa0\keepn\par 
}");
+           Write_Style_for_Paragraph (Output_Object.Output_File,
+               Paragraph_Info(Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent),
+               Output_Object.Char_Count);
+           Set_Tabs (Output_Object, Output_Object.Paragraph_Style,
+                               Output_Object.Paragraph_Indent);
+
+           -- Reset after spacing:
+           if ARM_Output."="(Output_Object.Current_Space_After,
+              ARM_Output.Narrow) then
+               declare
+                   SA_Width : Natural := 
Paragraph_Info(Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent).After*(LEADING_PERCENT/10)/10;
+                   SA : constant String := Natural'Image(SA_Width);
+               begin
+                    Ada.Text_IO.Put (Output_Object.Output_File, "\sa");
+                    Ada.Text_IO.Put (Output_Object.Output_File, 
SA(2..SA'Last));
+                    Ada.Text_IO.Put (Output_Object.Output_File, " ");
+                    Output_Object.Char_Count := 4 + SA'Length - 1;
+               end;
+           elsif ARM_Output."="(Output_Object.Current_Space_After,
+                 ARM_Output.Wide) then
+               declare
+                   SA_Width : Natural := 
Paragraph_Info(Output_Object.Paragraph_Style, 
Output_Object.Paragraph_Indent).After*(TRAILING_PERCENT/10)/10;
+                   SA : constant String := Natural'Image(SA_Width);
+               begin
+                    Ada.Text_IO.Put (Output_Object.Output_File, "\sa");
+                    Ada.Text_IO.Put (Output_Object.Output_File, 
SA(2..SA'Last));
+                    Ada.Text_IO.Put (Output_Object.Output_File, " ");
+                    Output_Object.Char_Count := 4 + SA'Length - 1;
+               end;
+           end if;
+           Ada.Text_IO.Put (Output_Object.Output_File, "\tab ");
+           Output_Object.Char_Count := Output_Object.Char_Count + 5;
+--Ada.Text_Io.Put_Line (" Break");
+           -- Reset the format:
+           Text_Format (Output_Object, Current_Format);
+        end if;
+    end End_Hang_Item;
+
+
+    procedure Text_Format (Output_Object : in out RTF_Output_Type;
+                          Format : in ARM_Output.Format_Type) is
+       -- Change the text format so that all of the properties are as 
specified.
+       -- Note: Changes to these properties ought be stack-like; that is,
+       -- Bold on, Italic on, Italic off, Bold off is OK; Bold on, Italic on,
+       -- Bold off, Italic off should be avoided (as separate commands).
+       TRACE_TF : constant Boolean := FALSE;
+       use type ARM_Output.Change_Type;
+       use type ARM_Contents.Change_Version_Type;
+       use type ARM_Output.Location_Type;
+       use type ARM_Output.Size_Type;
+       use type ARM_Output.Color_Type;
+
+       procedure Make_Size_Command (Size : in Natural) is
+           -- Write a \fs command to the file for Size.
+           -- Max 29.5 pt, min 5 pt.
+       begin
+           if Output_Object.Real_Size >= 50 then
+               Ada.Text_IO.Put (Output_Object.Output_File, "\fs5" &
+                   Character'Val(Output_Object.Real_Size mod 10 + 
Character'Pos('0')));
+           elsif Output_Object.Real_Size >= 40 then
+               Ada.Text_IO.Put (Output_Object.Output_File, "\fs4" &
+                   Character'Val(Output_Object.Real_Size mod 10 + 
Character'Pos('0')));
+           elsif Output_Object.Real_Size >= 30 then
+               Ada.Text_IO.Put (Output_Object.Output_File, "\fs3" &
+                   Character'Val(Output_Object.Real_Size mod 10 + 
Character'Pos('0')));
+           elsif Output_Object.Real_Size >= 20 then
+               Ada.Text_IO.Put (Output_Object.Output_File, "\fs2" &
+                   Character'Val(Output_Object.Real_Size mod 10 + 
Character'Pos('0')));
+           elsif Output_Object.Real_Size >= 10 then
+               Ada.Text_IO.Put (Output_Object.Output_File, "\fs1" &
+                   Character'Val(Output_Object.Real_Size mod 10 + 
Character'Pos('0')));
+           else
+               Ada.Text_IO.Put (Output_Object.Output_File, "\fs10");
+           end if;
+           Output_Object.Char_Count := Output_Object.Char_Count + 6;
+       end Make_Size_Command;
+
+
+       procedure Close_Basic_Format is
+           -- Close any open basic format (Bold/Italic/Size/Font) command.
+       begin
+           if (not Output_Object.Is_Bold) and (not Output_Object.Is_Italic) and
+               ARM_Output."=" (Output_Object.Font, ARM_Output.Default) and
+               Output_Object.Color =  ARM_Output.Default and
+               Output_Object.Size = 0 then
+               -- No format previously set, so none to close (default).
+               return;
+           end if;
+           if TRACE_TF then
+               Ada.Text_Io.Put (" Close basic format [");
+               if Output_Object.Is_Bold then
+                   Ada.Text_Io.Put ('B');
+               end if;
+               if Output_Object.Is_Italic then
+                   Ada.Text_Io.Put ('I');
+               end if;
+               if Output_Object.Size /= 0 then
+                   Ada.Text_Io.Put ('S');
+               end if;
+               if Output_Object.Color /= ARM_Output.Default then
+                   Ada.Text_Io.Put ('C');
+               end if;
+               if ARM_Output."/=" (Output_Object.Font, ARM_Output.Default) then
+                   Ada.Text_Io.Put ('F');
+               end if;
+               Ada.Text_Io.Put (']');
+           end if;
+           Ada.Text_IO.Put (Output_Object.Output_File, "}");
+           Output_Object.Char_Count := Output_Object.Char_Count + 1;
+           Output_Object.Real_Size := Output_Object.Real_Size -
+                                   (Integer(Output_Object.Size)*2);
+           Output_Object.Size := 0;
+           Output_Object.Is_Bold := False;
+           Output_Object.Is_Italic := False;
+           Output_Object.Color := ARM_Output.Default;
+           case Output_Object.Font is
+               when ARM_Output.Default => null;
+               when ARM_Output.Fixed => null;
+               when ARM_Output.Roman => null;
+               when ARM_Output.Swiss =>
+                   -- Undo the size adjustment, if any.
+                   if ARM_Output."/=" (Output_Object.Body_Font, 
ARM_Output.Swiss) then
+                       Output_Object.Real_Size := Output_Object.Real_Size + 1;
+                   -- else no adjustment.
+                   end if;
+           end case;
+           Output_Object.Font := ARM_Output.Default;
+       end Close_Basic_Format;
+
+
+       procedure Make_Basic_Format is
+           -- Make any needed Bold/Italic/Size/Font command.
+       begin
+           if (not Format.Bold) and (not Format.Italic) and
+               ARM_Output."=" (Format.Font, ARM_Output.Default) and
+               Format.Color = ARM_Output.Default and
+               Format.Size = 0 then
+               -- No format needed (default).
+               return;
+           end if;
+           Ada.Text_IO.Put (Output_Object.Output_File, "{");
+           Output_Object.Char_Count := Output_Object.Char_Count + 1;
+            if TRACE_TF then
+               Ada.Text_Io.Put (" Make basic {");
+            end if;
+
+           -- Bold:
+           if Format.Bold then
+               if TRACE_TF then
+                   Ada.Text_Io.Put (" Change bold");
+               end if;
+               Ada.Text_IO.Put (Output_Object.Output_File, "\b");
+               Output_Object.Char_Count := Output_Object.Char_Count + 2;
+               Output_Object.Is_Bold := True;
+           end if;
+           -- Italic:
+           if Format.Italic then
+               if TRACE_TF then
+                   Ada.Text_Io.Put (" Change italics");
+               end if;
+               Ada.Text_IO.Put (Output_Object.Output_File, "\i");
+               Output_Object.Char_Count := Output_Object.Char_Count + 2;
+               Output_Object.Is_Italic := True;
+           end if;
+           -- Size:
+           if Format.Size /= 0 then
+               if TRACE_TF then
+                   Ada.Text_Io.Put (" Change size " & 
ARM_Output.Size_Type'Image(Format.Size));
+               end if;
+               Output_Object.Real_Size := Output_Object.Real_Size +
+                                                   Integer(Format.Size)*2;
+               if ARM_Output."/=" (Format.Font, ARM_Output.Swiss)
+                   or else ARM_Output."=" (Output_Object.Body_Font, 
ARM_Output.Swiss) then
+                   Make_Size_Command (Output_Object.Real_Size);
+               -- else it will be done by the Font, below.
+               end if;
+           end if;
+           Output_Object.Size := Format.Size;
+           -- Color:
+           if Format.Color /= ARM_Output.Default then
+               if TRACE_TF then
+                   Ada.Text_Io.Put (" Change color " & 
ARM_Output.Color_Type'Image(Format.Color));
+               end if;
+               case Format.Color is
+                   when ARM_Output.Default => null;
+                   when ARM_Output.Black => -- Color 1
+                       Ada.Text_IO.Put (Output_Object.Output_File, "\cf1");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
4;
+                   when ARM_Output.Red   => -- Color 13
+                       Ada.Text_IO.Put (Output_Object.Output_File, "\cf13");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
5;
+                   when ARM_Output.Green => -- Color 11
+                       Ada.Text_IO.Put (Output_Object.Output_File, "\cf11");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
5;
+                   when ARM_Output.Blue  => -- Color 9
+                       Ada.Text_IO.Put (Output_Object.Output_File, "\cf9");
+                       Output_Object.Char_Count := Output_Object.Char_Count + 
4;
+               end case;
+           end if;
+           Output_Object.Color := Format.Color;
+
+           -- Font:
+           case Format.Font is
+               when ARM_Output.Default => null;
+               when ARM_Output.Fixed =>
+                   if TRACE_TF then
+                       Ada.Text_Io.Put (" Change font fixed");
+                   end if;
+                   Ada.Text_IO.Put (Output_Object.Output_File, "\f2");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 4;
+               when ARM_Output.Roman =>
+                   if TRACE_TF then
+                       Ada.Text_Io.Put (" Change font roman");
+                   end if;
+                   Ada.Text_IO.Put (Output_Object.Output_File, "\f0");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 4;
+               when ARM_Output.Swiss =>
+                   if TRACE_TF then
+                       Ada.Text_Io.Put (" Change font swiss");
+                   end if;
+                   Ada.Text_IO.Put (Output_Object.Output_File, "\f1");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 3;
+                   -- Swiss fonts always appear too large, so shrink it a bit,
+                   -- but not if the main body is a Swiss font.
+                   if ARM_Output."/=" (Output_Object.Body_Font, 
ARM_Output.Swiss) then
+                       Output_Object.Real_Size := Output_Object.Real_Size - 1;
+                       Make_Size_Command (Output_Object.Real_Size);
+                   end if;
+           end case;
+           Ada.Text_IO.Put (Output_Object.Output_File, " ");
+           Output_Object.Char_Count := Output_Object.Char_Count + 1;
+           Output_Object.Font := Format.Font;
+       end Make_Basic_Format;
+
+
+       procedure Make_Revision is
+           -- Make any needed revision:
+       begin
+           -- We could "improve" this by keeping similar changes together,
+           -- especially for changes to/from Both, but its a lot more work
+           -- and unnecessary.
+           case Format.Change is
+               when ARM_Output.Insertion =>
+                   if TRACE_TF then
+                       Ada.Text_Io.Put (" Change insertion");
+                   end if;
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
"{\revised\revauth" & Format.Version & ' ');
+                   Output_Object.Char_Count := Output_Object.Char_Count + 18;
+                       -- Note: \revauthN indicates the author. Each version
+                       -- that we'll use needs an entry in the \revtbl.
+                       -- We could include a date with \revddtm??, but that's 
messy.
+               when ARM_Output.Deletion =>
+                   if TRACE_TF then
+                       Ada.Text_Io.Put (" Change deletion");
+                   end if;
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
"{\deleted\revauthdel" & Format.Version & ' ');
+                   Output_Object.Char_Count := Output_Object.Char_Count + 21;
+                       -- Note: \revauthdelN indicates the author. Each version
+                       -- that we'll use needs an entry in the \revtbl.
+                       -- We could include a date with \revddtmdel??, but 
that's messy.
+               when ARM_Output.Both =>
+                   if TRACE_TF then
+                       Ada.Text_Io.Put (" Change both");
+                   end if;
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
"{\revised\revauth" & Format.Added_Version & ' ');
+                   Output_Object.Char_Count := Output_Object.Char_Count + 18;
+                   Ada.Text_IO.Put (Output_Object.Output_File, 
"{\deleted\revauthdel" & Format.Version & ' ');
+                   Output_Object.Char_Count := Output_Object.Char_Count + 21;
+                       -- Note: \revauthdelN indicates the author. Each version
+                       -- that we'll use needs an entry in the \revtbl.
+                       -- We could include a date with \revddtmdel??, but 
that's messy.
+               when ARM_Output.None =>
+                   null;
+           end case;
+           Output_Object.Change := Format.Change;
+           Output_Object.Version := Format.Version;
+           Output_Object.Added_Version := Format.Added_Version;
+       end Make_Revision;
+
+
+       procedure Close_Revision is
+           -- Close any open revision:
+       begin
+           -- We could "improve" this by keeping similar changes together,
+           -- especially for changes to/from Both, but its a lot more work
+           -- and unnecessary.
+           case Output_Object.Change is
+               when ARM_Output.Insertion =>
+                   if TRACE_TF then
+                       Ada.Text_Io.Put (" Unchange insertion");
+                   end if;
+                   Ada.Text_IO.Put (Output_Object.Output_File, "}");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 1;
+               when ARM_Output.Deletion =>
+                   if TRACE_TF then
+                       Ada.Text_Io.Put (" Unchange deletion");
+                   end if;
+                   Ada.Text_IO.Put (Output_Object.Output_File, "}");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 1;
+               when ARM_Output.None =>
+                   null;
+               when ARM_Output.Both =>
+                   if TRACE_TF then
+                       Ada.Text_Io.Put (" Unchange both");
+                   end if;
+                   Ada.Text_IO.Put (Output_Object.Output_File, "}}");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 2;
+           end case;
+       end Close_Revision;
+
+
+       procedure Make_Location is
+           -- Make any needed location:
+       begin
+           case Format.Location is
+               when ARM_Output.Subscript =>
+                   if TRACE_TF then
+                       Ada.Text_Io.Put (" Change sub");
+                   end if;
+                   Ada.Text_IO.Put (Output_Object.Output_File, "{\sub ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 6;
+               when ARM_Output.Superscript =>
+                   if TRACE_TF then
+                       Ada.Text_Io.Put (" Change sup");
+                   end if;
+                   Ada.Text_IO.Put (Output_Object.Output_File, "{\super ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 8;
+               when ARM_Output.Normal =>
+                   null;
+           end case;
+           Output_Object.Location := Format.Location;
+       end Make_Location;
+
+
+       procedure Close_Location is
+           -- Close any open location:
+       begin
+           case Output_Object.Location is
+               when ARM_Output.Subscript =>
+                   if TRACE_TF then
+                       Ada.Text_Io.Put (" Unchange sub");
+                   end if;
+                   Ada.Text_IO.Put (Output_Object.Output_File, "}");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 1;
+               when ARM_Output.Superscript =>
+                   if TRACE_TF then
+                       Ada.Text_Io.Put (" Unchange sup");
+                   end if;
+                   Ada.Text_IO.Put (Output_Object.Output_File, "}");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 1;
+               when ARM_Output.Normal =>
+                   null;
+           end case;
+       end Close_Location;
+
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+
+        if TRACE_TF then
+           Ada.Text_Io.Put ("Text format");
+        end if;
+       -- We always make changes in the order:
+       -- Revision;
+       -- Location;
+       -- Basic_Format (Bold, Italic, Font, Size, Color).
+       -- Thus, we have to unstack them in the reverse order. And, if we want
+       -- to change an outer one, we have to close and redo any inner
+       -- ones.
+
+       -- We do these in this order so that the changes are stacked properly.
+       if Format.Change /= Output_Object.Change or else
+           Format.Version /= Output_Object.Version or else
+           Format.Added_Version /= Output_Object.Added_Version then
+           Close_Basic_Format;
+           Close_Location;
+           Close_Revision;
+           Make_Revision;
+           Make_Location;
+           Make_Basic_Format;
+       elsif Format.Location /= Output_Object.Location then
+           -- We don't need to change the revision, leave it alone.
+           Close_Basic_Format;
+           Close_Location;
+           Make_Location;
+           Make_Basic_Format;
+       elsif Format.Color /= Output_Object.Color or else
+          Format.Size /= Output_Object.Size or else
+          ARM_Output."/=" (Format.Font, Output_Object.Font) or else
+          Format.Bold /= Output_Object.Is_Bold or else
+          Format.Italic /= Output_Object.Is_Italic then
+           Close_Basic_Format;
+           Make_Basic_Format;
+       -- else no change at all.
+       end if;
+        if TRACE_TF then
+           Ada.Text_Io.New_Line;
+        end if;
+    end Text_Format;
+
+
+    procedure Clause_Reference (Output_Object : in out RTF_Output_Type;
+                               Text : in String;
+                               Clause_Number : in String) is
+       -- Generate a reference to a clause in the standard. The text of
+       -- the reference is "Text", and the number of the clause is
+       -- Clause_Number. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+           -- Note: We could generate genuine clause references for Word,
+           -- but that wouldn't buy us anything for the RM.
+    end Clause_Reference;
+
+
+    procedure Index_Target (Output_Object : in out RTF_Output_Type;
+                           Index_Key : in Natural) is
+       -- Generate a index target. This marks the location where an index
+       -- reference occurs. Index_Key names the index item involved.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, nothing is generated.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       null; -- Nothing to do for RTF. We could have let Word make the
+             -- index, but then we'd still have to build it for HTML, and
+             -- we couldn't get paragraph numbers in the index.
+    end Index_Target;
+
+
+    procedure Index_Reference (Output_Object : in out RTF_Output_Type;
+                              Text : in String;
+                              Index_Key : in Natural;
+                              Clause_Number : in String) is
+       -- Generate a reference to an index target in the standard. The text
+       -- of the reference is "Text", and Index_Key and Clause_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end Index_Reference;
+
+
+    procedure DR_Reference (Output_Object : in out RTF_Output_Type;
+                           Text : in String;
+                           DR_Number : in String) is
+       -- Generate a reference to an DR from the standard. The text
+       -- of the reference is "Text", and DR_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end DR_Reference;
+
+
+    procedure AI_Reference (Output_Object : in out RTF_Output_Type;
+                           Text : in String;
+                           AI_Number : in String) is
+       -- Generate a reference to an AI from the standard. The text
+       -- of the reference is "Text", and AI_Number denotes
+       -- the target (in unfolded format). For hyperlinked formats, this should
+       -- generate a link; for other formats, the text alone is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end AI_Reference;
+
+
+    procedure Local_Target (Output_Object : in out RTF_Output_Type;
+                           Text : in String;
+                           Target : in String) is
+       -- Generate a local target. This marks the potential target of local
+       -- links identified by "Target". Text is the text of the target.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, only the text is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end Local_Target;
+
+
+    procedure Local_Link (Output_Object : in out RTF_Output_Type;
+                         Text : in String;
+                         Target : in String;
+                         Clause_Number : in String) is
+       -- Generate a local link to the target and clause given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end Local_Link;
+
+
+    procedure Local_Link_Start (Output_Object : in out RTF_Output_Type;
+                               Target : in String;
+                               Clause_Number : in String) is
+       -- Generate a local link to the target and clause given.
+       -- The link will surround text until Local_Link_End is called.
+       -- Local_Link_End must be called before this routine can be used again.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       null; -- No link, nothing to do.
+    end Local_Link_Start;
+
+
+    procedure Local_Link_End (Output_Object : in out RTF_Output_Type;
+                             Target : in String;
+                             Clause_Number : in String) is
+       -- End a local link for the target and clause given.
+       -- This must be in the same paragraph as the Local_Link_Start.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       null; -- No link, nothing to do.
+    end Local_Link_End;
+
+
+    procedure URL_Link (Output_Object : in out RTF_Output_Type;
+                       Text : in String;
+                       URL : in String) is
+       -- Generate a link to the URL given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end URL_Link;
+
+
+    procedure Picture  (Output_Object : in out RTF_Output_Type;
+                       Name  : in String;
+                       Descr : in String;
+                       Alignment : in ARM_Output.Picture_Alignment;
+                       Height, Width : in Natural;
+                       Border : in ARM_Output.Border_Kind) is
+       -- Generate a picture.
+       -- Name is the (simple) file name of the picture; Descr is a
+       -- descriptive name for the picture (it will appear in some web
+       -- browsers).
+       -- We assume that it is a .PNG or .JPG and that it will be present
+       -- in the same directory as the output files.
+       -- Alignment specifies the picture alignment.
+       -- Height and Width specify the picture size in pixels.
+       -- Border specifies the kind of border.
+       use type ARM_Output.Picture_Alignment;
+       use type ARM_Output.Border_Kind;
+
+       HORIZONTAL_TWIPS_PER_PIXEL : constant := 16; -- By experiment.
+       VERTICAL_TWIPS_PER_PIXEL : constant := 16; -- By experiment.
+           -- These values give us Pixels/90 = box size in inches.
+
+       -- For reasons that I don't understand, the supposed "raw" picture
+       -- size is Pixels/120. So a scaling of 75% gives exact pixels.
+
+
+       type Kind is (PNG, JPEG, Unknown);
+       type DWord is mod 2**32;
+       Picture_Width  : DWord;
+       Picture_Height : DWord;
+       Picture_Kind : Kind := Unknown;
+       Picture_Scaling : Natural;
+
+       procedure Get_Picture_Dimensions is
+           -- Get the picture dimensions from the graphic file.
+           use type Ada.Streams.Stream_Element_Offset;
+           Fyle : Ada.Streams.Stream_IO.File_Type;
+           type PNG_Header is record
+               Signature_1 : DWord; -- Fixed value
+               Signature_2 : DWord; -- Fixed value
+               Header_Len  : DWord; -- Fixed value (13)
+               Header_Type : DWord; -- Fixed value ("IHDR")
+               Width       : DWord; -- In pixels.
+               Height      : DWord; -- In pixels.
+               -- Other stuff is not important here.
+           end record;
+           subtype PNG_Stream is Ada.Streams.Stream_Element_Array(1..6*4);
+           function Convert is new Ada.Unchecked_Conversion (Source => 
PNG_Stream,
+                                                             Target => 
PNG_Header);
+           Buffer : PNG_Stream;
+           Last : Ada.Streams.Stream_Element_Offset;
+           Temp : Ada.Streams.Stream_Element;
+       begin
+           begin
+               Ada.Streams.Stream_IO.Open (Fyle,
+                   Mode => Ada.Streams.Stream_IO.In_File,
+                   Name => Ada.Strings.Unbounded.To_String 
(Output_Object.Output_Path) &
+                           Name);
+           exception
+               when Oops:others =>
+                   Ada.Text_IO.Put_Line ("** Unable to open picture file: " &
+                       Ada.Exceptions.Exception_Message(Oops));
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Unable to open picture file");
+           end;
+           -- Read a PNG header, to see if it is a PNG:
+           Ada.Streams.Stream_IO.Read (Fyle, Buffer, Last);
+           if Last /= 24 then
+               Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                   "Picture file too short");
+           end if;
+           if Convert(Buffer).Signature_1 = 16#89_50_4e_47# and then
+              Convert(Buffer).Signature_2 = 16#0d_0a_1a_0a# then
+               -- This is a PNG file:
+               Picture_Kind := PNG;
+               Picture_Width := Convert(Buffer).Width;
+               Picture_Height := Convert(Buffer).Height;
+               Ada.Text_IO.Put_Line ("Forward PNG: Width=" &
+                   DWord'Image(Picture_Width) & " Height=" &
+                   DWord'Image(Picture_Height));
+           elsif Convert(Buffer).Signature_1 = 16#47_4e_50_89# and then
+              Convert(Buffer).Signature_2 = 16#0a_1a_0a_0d# then
+               -- This is a byte-swapped PNG file.
+               -- Swap the bytes in the buffer, then get the width and height:
+               Temp := Buffer(17);
+               Buffer(17) := Buffer(20);
+               Buffer(20) := Temp;
+               Temp := Buffer(18);
+               Buffer(18) := Buffer(19);
+               Buffer(19) := Temp;
+               Temp := Buffer(21);
+               Buffer(21) := Buffer(24);
+               Buffer(24) := Temp;
+               Temp := Buffer(22);
+               Buffer(22) := Buffer(23);
+               Buffer(23) := Temp;
+               Picture_Kind := PNG;
+               Picture_Width := Convert(Buffer).Width;
+               Picture_Height := Convert(Buffer).Height;
+               Ada.Text_IO.Put_Line ("Reversed PNG: Width=" &
+                   DWord'Image(Picture_Width) & " Height=" &
+                   DWord'Image(Picture_Height));
+
+
+--         elsif Name'Length > 5 and then
+--            (Name(Name'Last-3..Name'Last) = ".JPG" or else
+--             Name(Name'Last-3..Name'Last) = ".jpg" or else
+--             Name(Name'Last-4..Name'Last) = ".JPEG" or else
+--             Name(Name'Last-4..Name'Last) = ".Jpeg" or else
+--             Name(Name'Last-4..Name'Last) = ".jpeg") then
+--             Picture_Kind := JPEG;
+
+
+           else
+               Ada.Text_IO.Put_Line ("** Unimplemented picture formatting: 
File type");
+               Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                   "Do not recognize picture file");
+           end if;
+       end Get_Picture_Dimensions;
+
+
+       function Format_Twips (Twips : in Natural) return String is
+           Flab : constant String := Natural'Image(Twips);
+       begin
+           return Flab(2..Flab'Last);
+       end Format_Twips;
+
+
+       procedure Dump_File_in_Hex is
+           -- Read and output the graphics file to the output file
+           -- in Hexadecimal.
+           Fyle : Ada.Streams.Stream_IO.File_Type;
+           Buffer : Ada.Streams.Stream_Element_Array(1..32);
+           Last : Ada.Streams.Stream_Element_Offset;
+           use type Ada.Streams.Stream_Element;
+           use type Ada.Streams.Stream_Element_Offset;
+           Temp : Ada.Streams.Stream_Element;
+       begin
+           begin
+               Ada.Streams.Stream_IO.Open (Fyle,
+                   Mode => Ada.Streams.Stream_IO.In_File,
+                   Name => Ada.Strings.Unbounded.To_String 
(Output_Object.Output_Path) &
+                           Name);
+           exception
+               when Oops:others =>
+                   Ada.Text_IO.Put_Line ("** Unable to open picture file: " &
+                       Ada.Exceptions.Exception_Message(Oops));
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Unable to open picture file");
+           end;
+           loop
+               Ada.Streams.Stream_IO.Read (Fyle, Buffer, Last);
+               exit when Last = 0; -- Nothing read equals end of file.
+               for I in 1 .. Last loop
+                   Temp := Buffer(I) / 16;
+                   if Temp > 9 then
+                       Ada.Text_IO.Put (Output_Object.Output_File,
+                           Character'Val(Character'Pos('A') + (Temp - 10)));
+                   else
+                       Ada.Text_IO.Put (Output_Object.Output_File,
+                           Character'Val(Character'Pos('0') + Temp));
+                   end if;
+                   Temp := Buffer(I) mod 16;
+                   if Temp > 9 then
+                       Ada.Text_IO.Put (Output_Object.Output_File,
+                           Character'Val(Character'Pos('A') + (Temp - 10)));
+                   else
+                       Ada.Text_IO.Put (Output_Object.Output_File,
+                           Character'Val(Character'Pos('0') + Temp));
+                   end if;
+               end loop;
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+           end loop;
+           Ada.Streams.Stream_IO.Close (Fyle);
+       end Dump_File_in_Hex;
+
+    begin
+       Get_Picture_Dimensions;
+
+       -- Calculate scaling needed:
+       declare
+           Width_Scale, Height_Scale : Float;
+           Word_Scaling : constant Float := 6.0;
+               -- Scaling so that the HTML pixel and Word pixel
+               -- have the same approximate size. Word's pixels
+               -- seem to be about 6 times smaller than HTML's.
+
+           -- Word's box size is
+       begin
+           Width_Scale := Float(Width) / Float(Picture_Width) * 100.0 * 
Word_Scaling;
+           Height_Scale := Float(Height) / Float(Picture_Height) * 100.0 * 
Word_Scaling;
+
+           -- Then, use the smaller scale:
+           if Width_Scale < Height_Scale then
+               Picture_Scaling := Natural(Width_Scale);
+           else
+               Picture_Scaling := Natural(Height_Scale);
+           end if;
+           Ada.Text_IO.Put_Line ("Picture scaling (%):" & 
Natural'Image(Picture_Scaling));
+           Ada.Text_IO.Put_Line ("Box width=" &
+               Natural'Image(Width) & " Height=" &
+               Natural'Image(Height));
+           -- Note: Word 2000/2003 seems to ignore this scaling; it seems to
+           -- use the "picwgoal" and "pichgoal" exclusively.
+           -- As noted above, that naturally gives a 75% scaling when the
+           -- picture size and box size are the same. We remove that for this
+           -- information. (Note: The smaller the scaling the better.)
+           Ada.Text_IO.Put_Line ("Word 2003 scaling: Width=" &
+               Natural'Image(Natural(Float(Width) / Float(Picture_Width) * 
100.0 / 0.75)) & " Height=" &
+               Natural'Image(Natural(Float(Height) / Float(Picture_Height) * 
100.0 / 0.75)));
+
+       end;
+
+       -- Wrap the picture in a shape, so we can set the properties:
+
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "{\shp{\*\shpinst"); -- Start a shape.
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\shpleft0\shptop0"); -- Left and top are the origin.
+       Ada.Text_IO.Put (Output_Object.Output_File,
+           "\shpright" & Format_Twips(Width * HORIZONTAL_TWIPS_PER_PIXEL)); -- 
Right edge in twips.
+        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+           "\shpbottom" & Format_Twips(Height * VERTICAL_TWIPS_PER_PIXEL)); -- 
Bottom edge in twips.
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\shpfhdr0"); -- Shape is in the main document.
+
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\shpbxcolumn"); -- Shape is positioned relative to the column.
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\shpbxignore"); -- But use posrelh instead (column is the default).
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\shpbypara"); -- Shape is positioned relative to the paragraph.
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\shpbyignore"); -- But use posrelv instead (paragraph is the 
default).
+       case Alignment is
+          when ARM_Output.Inline =>
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "\shpwr2\shpwrk0"); -- Wrap text around shape (rectangle), 
on both sides.
+          when ARM_Output.Float_Left =>
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "\shpwr2\shpwrk2"); -- Wrap text around shape (rectangle), 
on right only.
+          when ARM_Output.Float_Right =>
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "\shpwr2\shpwrk1"); -- Wrap text around shape (rectangle), 
on left only.
+          when ARM_Output.Alone_Left | ARM_Output.Alone_Center |
+               ARM_Output.Alone_Right =>
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "\shpwr1"); -- Don't allow text alongside shape.
+       end case;
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\shpfblwtxt0"); -- Text is below shape.
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\shpz0"); -- Z-order for shape (these don't overlap, I hope).
+
+       Output_Object.Last_Shape_Id := Output_Object.Last_Shape_Id + 1;
+           -- These need to be unique, but the value doesn't matter much.
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\shplid" & Format_Twips(Output_Object.Last_Shape_Id));
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "{\sp{\sn shapeType}{\sv 75}}"); -- "Picture frame" type.
+        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+           "{\sp{\sn fFlipH}{\sv 0}}{\sp{\sn fFlipV}{\sv 0}}"); -- No flipping.
+
+        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+           "{\sp{\sn pib}{\sv {\pict"); -- Start the picture data
+
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\picscalex" & Format_Twips(Picture_Scaling)); -- X scaling (%).
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\picscaley" & Format_Twips(Picture_Scaling)); -- Y scaling (%).
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\piccropl0"); -- Left crop (twips) [Should be zero].
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\piccropr0"); -- Right crop (twips) [Should be zero].
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\piccropt0"); -- Top crop (twips) [Should be zero].
+        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+           "\piccropb0"); -- Bottom crop (twips) [Should be zero].
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\picw" & Format_Twips(Natural(Picture_Width) * 5)); -- Raw picture 
width in ??? (doesn't seem to be used).
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "\pich" & Format_Twips(Natural(Picture_Height) * 5)); -- Raw 
picture height in ??? (doesn't seem to be used).
+       Ada.Text_IO.Put (Output_Object.Output_File,
+           "\picwgoal" & Format_Twips(Width * HORIZONTAL_TWIPS_PER_PIXEL)); -- 
Picture width goal in twips.
+        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+           "\pichgoal" & Format_Twips(Height * VERTICAL_TWIPS_PER_PIXEL)); -- 
Picture height goal in twips.
+
+       -- Figure out file type, using the correct type here:
+       if Picture_Kind = PNG then
+            Ada.Text_IO.Put_Line (Output_Object.Output_File,
+               "\pngblip"); -- Specifies that the file is a PNG.
+       elsif Picture_Kind = JPEG then
+            Ada.Text_IO.Put_Line (Output_Object.Output_File,
+               "\jpegblip"); -- Specifies that the file is a JPEG.
+       else
+           null; -- We should have already bombed.
+       end if;
+
+       -- Should use:
+       -- \bliptagnnn - Picture ID.
+       -- \blipuid XXXX - Picture Unique ID.
+       -- How these are calculated is unclear (it appears to be a hash of
+       -- some kind). So I left these out.
+
+       Dump_File_in_Hex;
+
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "}}}"); -- End the picture data.
+
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "{\sp{\sn pibName}{\sv " & Name & "}}"); -- Picture file name
+        Ada.Text_IO.Put (Output_Object.Output_File,
+           "{\sp{\sn pibFlags}{\sv 2}}"); -- No idea, a flag of "2" is not 
documented.
+       case Border is
+           when ARM_Output.None =>
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn fLine}{\sv 0}}"); -- No line here.
+           when ARM_Output.Thin =>
+               -- Default lineType of 0, solid.
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn lineWidth}{\sv 9525}}"); -- Line size (single - 
0.75pt).
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn fLine}{\sv 1}}"); -- Show line here.
+           when ARM_Output.Thick =>
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn lineWidth}{\sv 19050}}"); -- Line size (double - 
1.5pt).
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn fLine}{\sv 1}}"); -- Show line here.
+       end case;
+       case Alignment is
+          when ARM_Output.Inline =>
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn posh}{\sv 1}}"); -- Position to the left.
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn posrelh}{\sv 3}}"); -- Position to the character.
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn posh}{\sv 2}}"); -- Position to the top.
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn posrelh}{\sv 3}}"); -- Position to the line.
+          when ARM_Output.Float_Left =>
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn posh}{\sv 1}}"); -- Position to the left.
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn posrelh}{\sv 2}}"); -- Position to the column.
+          when ARM_Output.Float_Right =>
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn posh}{\sv 3}}"); -- Position to the right.
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn posrelh}{\sv 2}}"); -- Position to the column.
+          when ARM_Output.Alone_Left =>
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn posh}{\sv 1}}"); -- Position to the left.
+          when ARM_Output.Alone_Center =>
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn posh}{\sv 2}}"); -- Position to the center.
+          when ARM_Output.Alone_Right =>
+               Ada.Text_IO.Put (Output_Object.Output_File,
+                   "{\sp{\sn posh}{\sv 3}}"); -- Position to the right.
+       end case;
+        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+           "{\sp{\sn fLayoutInCell}{\sv 0}}"); -- No nested use.
+
+       -- Here we find {\shprslt followed by metafile junk. Not doing that.
+       ---- Fake Word 95 output (it shouldn't be used, but...):
+        --Ada.Text_IO.Put_Line (Output_Object.Output_File,
+       --    "{\shprslt\par\pard \ql 
\pvpara\posxr\dxfrtext180\dfrmtxtx180\dfrmtxty0\nowrap\adjustright\ \par}");
+
+        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+           "}}"); -- End the shape.
+        Output_Object.Char_Count := 0;
+
+       -- Original code:
+--
+--     case Alignment is
+--        when ARM_Output.Inline =>
+--             null;
+--        when ARM_Output.Float_Left =>
+--             null; --***??
+--        when ARM_Output.Float_Right =>
+--             Ada.Text_IO.Put_Line ("** Unimplemented picture formatting: 
Float Right");
+--        when ARM_Output.Alone_Left =>
+--             Ada.Text_IO.Put (Output_Object.Output_File,
+--                 "{\pard\plain\sb" & Format_Twips(Height * 
VERTICAL_TWIPS_PER_PIXEL) & " ");
+--                     -- Set up a normal left-justified paragraph that is 
high enough for this picture.
+--        when ARM_Output.Alone_Center =>
+--             Ada.Text_IO.Put (Output_Object.Output_File,
+--                 "{\pard\plain\qc\sb" & Format_Twips(Height * 
VERTICAL_TWIPS_PER_PIXEL) & " ");
+--                     -- Set up a normal centered paragraph that is high 
enough for this picture.
+--        when ARM_Output.Alone_Right =>
+--             Ada.Text_IO.Put (Output_Object.Output_File,
+--                 "{\pard\plain\qr\sb" & Format_Twips(Height * 
VERTICAL_TWIPS_PER_PIXEL) & " ");
+--                     -- Set up a normal right-justified paragraph that is 
high enough for this picture.
+--     end case;
+--
+--     -- Picture setup:
+--        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+--         "{\*\shppict {\pict "); -- Defines a picture (Word 97 and newer).
+--
+--     -- Shape Properties:
+--     Output_Object.Last_Shape_Id := Output_Object.Last_Shape_Id + 1;
+--         -- These need to be unique, but what they are doesn't matter much.
+--        Ada.Text_IO.Put (Output_Object.Output_File,
+--         "{\*\picprop\shplid" & Format_Twips(Output_Object.Last_Shape_Id));
+--        Ada.Text_IO.Put (Output_Object.Output_File,
+--         "{\sp{\sn shapeType}{\sv 75}}"); -- "Picture frame" type.
+--        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+--         "{\sp{\sn fFlipH}{\sv 0}}{\sp{\sn fFlipV}{\sv 0}}"); -- No flipping.
+--        Ada.Text_IO.Put (Output_Object.Output_File,
+--         "{\sp{\sn pibName}{\sv " & Name & "}}"); -- Picture file name
+--        Ada.Text_IO.Put (Output_Object.Output_File,
+--         "{\sp{\sn pibFlags}{\sv 2}}"); -- No idea, a flag of "2" is not 
documented.
+--        Ada.Text_IO.Put (Output_Object.Output_File,
+--         "{\sp{\sn fLine}{\sv 0}}"); -- No line here.
+--        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+--         "{\sp{\sn fLayoutInCell}{\sv 1}}}"); -- Allow nested use..
+--
+--
+--        Ada.Text_IO.Put (Output_Object.Output_File,
+--         "\picscalex" & Format_Twips(Picture_Scaling)); -- X scaling (%).
+--        Ada.Text_IO.Put (Output_Object.Output_File,
+--         "\picscaley" & Format_Twips(Picture_Scaling)); -- Y scaling (%).
+--        Ada.Text_IO.Put (Output_Object.Output_File,
+--         "\piccropl0"); -- Left crop (twips) [Should be zero].
+--        Ada.Text_IO.Put (Output_Object.Output_File,
+--         "\piccropr0"); -- Right crop (twips) [Should be zero].
+--        Ada.Text_IO.Put (Output_Object.Output_File,
+--         "\piccropt0"); -- Top crop (twips) [Should be zero].
+--        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+--         "\piccropb0"); -- Bottom crop (twips) [Should be zero].
+--        Ada.Text_IO.Put (Output_Object.Output_File,
+--         "\picw" & Format_Twips(Width * HORIZONTAL_TWIPS_PER_PIXEL)); -- Raw 
picture width in twips.
+--        Ada.Text_IO.Put (Output_Object.Output_File,
+--         "\pich" & Format_Twips(Height * VERTICAL_TWIPS_PER_PIXEL)); -- Raw 
picture height in twips.
+--     Ada.Text_IO.Put (Output_Object.Output_File,
+--         "\picwgoal" & Format_Twips(Width * HORIZONTAL_TWIPS_PER_PIXEL)); -- 
Picture width goal in twips.
+--        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+--         "\pichgoal" & Format_Twips(Height * VERTICAL_TWIPS_PER_PIXEL)); -- 
Picture height goal in twips.
+--
+--     case Border is
+--         when ARM_Output.None =>
+--             null;
+--         when ARM_Output.Thin =>
+--             Ada.Text_IO.Put (Output_Object.Output_File,
+--                 "\brdrs\brdrw15 "); -- Single thickness border (value is in 
twips).
+--         when ARM_Output.Thick =>
+--             Ada.Text_IO.Put (Output_Object.Output_File,
+--                 "\brdrs\brdrw30 "); -- Double thickness border (value is in 
twips).
+--     end case;
+--
+--     -- Figure out file type, using the correct type here:
+--     if Picture_Kind = PNG then
+--            Ada.Text_IO.Put (Output_Object.Output_File,
+--             "\pngblip "); -- Specifies that the file is a PNG.
+--     elsif Picture_Kind = JPEG then
+--            Ada.Text_IO.Put (Output_Object.Output_File,
+--             "\jpegblip "); -- Specifies that the file is a JPEG.
+--     else
+--         null; -- We should have already bombed.
+--     end if;
+--
+--     -- Should use:
+--     -- \bliptagnnn - Picture ID.
+--     -- \blipuid XXXX - Picture Unique ID.
+--     -- How these are calculated is unclear (it appears to be a hash of
+--     -- some kind). So I left these out.
+--
+--     Dump_File_in_Hex;
+--
+--        Ada.Text_IO.Put_Line (Output_Object.Output_File,
+--         "}}"); -- End the picture.
+--        Output_Object.Char_Count := 0;
+--
+--     -- This should be followed by:
+--     -- {\*\nonshppict {\pict - Defines an old format picture. This has
+--     -- the graphic in metafile format. I have no idea how to convert that;
+--     -- forget it.
+--
+--     -- An easy but incredibly crappy implementation follows. But this
+--     -- needs height information in a dedicated paragraph to work at all
+--     -- (without it, it ends up one line high). If we have the height
+--     -- information, why bother with this; just generate it correctly.
+--     -- Then we can be sure that the height and width are specified.
+--        --Ada.Text_IO.Put_Line (Output_Object.Output_File,
+--     --    "{\field\fldedit{\*\fldinst { INCLUDEPICTURE "".\" & Name & """ 
\\* MERGEFORMAT \\d }}{\fldrslt {}}}");
+--        --Output_Object.Char_Count := 0;
+--
+--     -- Close anything opened for alignment:
+--     case Alignment is
+--        when ARM_Output.Inline =>
+--             null;
+--        when ARM_Output.Float_Left =>
+--             null;
+--        when ARM_Output.Float_Right =>
+--             null;
+--        when ARM_Output.Alone_Left =>
+--             Ada.Text_IO.Put_Line (Output_Object.Output_File, "\par}");
+--        when ARM_Output.Alone_Center =>
+--             Ada.Text_IO.Put_Line (Output_Object.Output_File, "\par}");
+--        when ARM_Output.Alone_Right =>
+--             Ada.Text_IO.Put_Line (Output_Object.Output_File, "\par}");
+--     end case;
+
+    end Picture;
+
+
+-- Notes:
+-- "\_" is a non-breaking hyphen.
+
+end ARM_RTF;
diff --git a/packages/ada-ref-man/progs/arm_rtf.ads 
b/packages/ada-ref-man/progs/arm_rtf.ads
new file mode 100755
index 0000000..e46779f
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_rtf.ads
@@ -0,0 +1,524 @@
+with ARM_Output,
+     ARM_Contents,
+     Ada.Text_IO;
+-- private
+with Ada.Strings.Unbounded;
+package ARM_RTF is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package defines the RTF output object.
+    -- Output objects are responsible for implementing the details of
+    -- a particular format.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2004, 2005, 2006, 2007, 2009, 2011, 2012
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/18/00 - RLB - Created package.
+    --  5/22/00 - RLB - Added Includes_Changes to Create.
+    --  5/23/00 - RLB - Added Set_Column and New_Column.
+    --               - Added Tab_Info and Tab_Stops.
+    --  5/24/00 - RLB - Added Location to Text_Format.
+    --         - RLB - Added No_Breaks and Keep_with_Next to Start_Paragraph.
+    --  5/25/00 - RLB - Added Big_Files to Create. Added Justification.
+    --         - RLB - Added Separator_Lines and TOC routines.
+    --  5/26/00 - RLB - Added table operations.
+    --  6/ 2/00 - RLB - Added Soft_Line_Break.
+    --  8/ 2/00 - RLB - Added Soft_Hyphen_Break.
+    --  8/ 7/00 - RLB - Added Leading flag to Start_Paragraph.
+    --  8/17/00 - RLB - Replaced "Leading" by "Space_After".
+    --  8/22/00 - RLB - Added Revised_Clause_Header.
+    --  7/18/02 - RLB - Removed Document parameter from Create, replaced by
+    --                 three strings and For_ISO boolean.
+    --         - RLB - Added AI_Reference.
+    --         - RLB - Added Change_Version_Type and uses.
+    --  9/10/04 - RLB - Added "Both" to possible changes to handle
+    --                 replacement of changed text.
+    --  9/14/04 - RLB - Moved Change_Version_Type to ARM_Contents.
+    --  5/27/05 - RLB - Added arbitrary Unicode characters.
+    --  1/11/06 - RLB - Eliminated dispatching Create in favor of tailored
+    --                 versions.
+    --  1/13/06 - RLB - Added new Link operations.
+    --  2/ 8/06 - RLB - Added additional parameters to the table command.
+    --  2/10/06 - RLB - Added even more additional parameters to the
+    --                 table command.
+    --         - RLB - Added picture command.
+    --  3/30/06 - RLB - Added shape id counter.
+    --  9/21/06 - RLB - Added Body_Font.
+    --  9/25/06 - RLB - Added Last_Column_Width to Start_Table.
+    -- 10/13/06 - RLB - Added Local_Link_Start and Local_Link_End to allow
+    --                 formatting in the linked text.
+    --  2/ 9/07 - RLB - Changed comments on AI_Reference.
+    --  2/13/07 - RLB - Revised to separate style and indent information
+    --                 for paragraphs.
+    -- 12/19/07 - RLB - Added limited colors to Text_Format.
+    --  5/ 4/09 - RLB - Added footer commands.
+    --  5/ 6/09 - RLB - Added version names.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/25/11 - RLB - Added old insertion version to Revised_Clause_Header.
+    --  8/31/12 - RLB - Added Output_Path.
+    -- 11/26/12 - RLB - Added subdivision names to Clause_Header and
+    --                 Revised_Clause_Header.
+
+    type RTF_Output_Type is new ARM_Output.Output_Type with private;
+
+    type Page_Size is (A4, Letter, Ada95, Half_Letter);
+       -- A4 is standard European letter size.
+       -- Letter is standard American letter size (8.5x11).
+       -- Half_Letter is standard America half size (5.5x8.5).
+       -- Ada95 is the size of the existing Ada 95 standard (7x9).
+
+    type Serif_Fonts is (Times_New_Roman, Souvenir);
+    type Sans_Serif_Fonts is (Arial, Helvetica);
+
+    procedure Create (Output_Object : in out RTF_Output_Type;
+                     Page_Size : in ARM_RTF.Page_Size;
+                     Includes_Changes : in Boolean;
+                     Big_Files : in Boolean;
+                     File_Prefix : in String;
+                     Output_Path : in String;
+                     Primary_Sans_Serif_Font : in Sans_Serif_Fonts := Arial;
+                     Primary_Serif_Font : in Serif_Fonts := Times_New_Roman;
+                     Body_Font : in ARM_Output.Font_Family_Type := 
ARM_Output.Roman;
+                     Header_Prefix : in String := "";
+                     Footer_Use_Date : in Boolean;
+                     Footer_Use_Clause_Name : in Boolean;
+                     Footer_Use_ISO_Format : in Boolean;
+                     Footer_Text : in String := "";
+                     Version_Names : in ARM_Contents.Versioned_String;
+                     Title : in String := "");
+       -- Create an Output_Object for a document with the specified page
+       -- size. Changes from the base document are included if
+       -- Includes_Changes is True (otherwise no revisions are generated).
+       -- Generate a few large output files if
+       -- Big_Files is True; otherwise generate smaller output files.
+       -- The prefix of the output file names is File_Prefix - this
+       -- should be no more then 5 characters allowed in file names.
+       -- The files will be written into Output_Path.
+       -- The title of the document is Title.
+       -- The header prefix appears in the header (if any) before the title,
+       -- separated by a dash.
+       -- The footer consists of the page number, the date if Footer_Use_Date
+       -- is true, and the clause name if Footer_Use_Clase_Name is True, and
+       -- the Footer_Text otherwise. The font and size of the footer is as
+       -- an ISO standard if Footer_Use_ISO_Format is True, and as the
+       -- Ada Reference Manual otherwise.
+       -- The primary font used for the Sans_Serif text, and for the Serif
+       -- text, is as specified.
+       -- Which font is used for the body is specified by Body_Font.
+       -- The author names of the various versions is specified by the
+       -- Version_Names.
+
+    procedure Close (Output_Object : in out RTF_Output_Type);
+       -- Close an Output_Object. No further output to the object is
+       -- allowed after this call.
+
+
+    procedure Section (Output_Object : in out RTF_Output_Type;
+                      Section_Title : in String;
+                      Section_Name : in String);
+       -- Start a new section. The title is Section_Title (this is
+       -- intended for humans). The name is Section_Name (this is
+       -- intended to be suitable to be a portion of a file name).
+
+    procedure Set_Columns (Output_Object : in out RTF_Output_Type;
+                          Number_of_Columns : in ARM_Output.Column_Count);
+       -- Set the number of columns.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Start_Paragraph (Output_Object : in out RTF_Output_Type;
+                              Style     : in ARM_Output.Paragraph_Style_Type;
+                              Indent    : in ARM_Output.Paragraph_Indent_Type;
+                              Number    : in String;
+                              No_Prefix : in Boolean := False;
+                              Tab_Stops : in ARM_Output.Tab_Info := 
ARM_Output.NO_TABS;
+                              No_Breaks : in Boolean := False;
+                              Keep_with_Next : in Boolean := False;
+                              Space_After : in ARM_Output.Space_After_Type
+                                  := ARM_Output.Normal;
+                              Justification : in ARM_Output.Justification_Type
+                                  := ARM_Output.Default);
+       -- Start a new paragraph. The style and indent of the paragraph is as
+       -- specified. The (AA)RM paragraph number (which might include update
+       -- and version numbers as well: [12.1/1]) is Number. If the format is
+       -- a type with a prefix (bullets, hangining items), the prefix is
+       -- omitted if No_Prefix is true. Tab_Stops defines the tab stops for
+       -- the paragraph. If No_Breaks is True, we will try to avoid page breaks
+       -- in the paragraph. If Keep_with_Next is true, we will try to avoid
+       -- separating this paragraph and the next one. (These may have no
+       -- effect in formats that don't have page breaks). Space_After
+       -- specifies the amount of space following the paragraph. Justification
+       -- specifies the text justification for the paragraph. Not_Valid_Error
+       -- is raised if Tab_Stops /= NO_TABS for a hanging or bulleted format.
+
+    procedure End_Paragraph (Output_Object : in out RTF_Output_Type);
+       -- End a paragraph.
+
+    procedure Category_Header (Output_Object : in out RTF_Output_Type;
+                              Header_Text : String);
+       -- Output a Category header (that is, "Legality Rules",
+       -- "Dynamic Semantics", etc.)
+       -- (Note: We did not use a enumeration here to insure that these
+       -- headers are spelled the same in all output versions).
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Clause_Header (Output_Object     : in out RTF_Output_Type;
+                            Header_Text       : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False);
+       -- Output a Clause header. The level of the header is specified
+       -- in Level. The Clause Number is as specified; the top-level (and
+       -- other) subdivision names are as specified. These should appear in
+       -- the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Revised_Clause_Header
+                           (Output_Object     : in out RTF_Output_Type;
+                            New_Header_Text   : in String;
+                            Old_Header_Text   : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Version           : in 
ARM_Contents.Change_Version_Type;
+                            Old_Version       : in 
ARM_Contents.Change_Version_Type;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False);
+       -- Output a revised clause header. Both the original and new text will
+       -- be output. The level of the header is specified in Level. The Clause
+       -- Number is as specified; the top-level (and other) subdivision names
+       -- are as specified. These should appear in the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- Version is the insertion version of the new text; Old_Version is
+       -- the insertion version of the old text.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure TOC_Marker (Output_Object : in out RTF_Output_Type;
+                         For_Start : in Boolean);
+       -- Mark the start (if For_Start is True) or end (if For_Start is
+       -- False) of the table of contents data. Output objects that
+       -- auto-generate the table of contents can use this to do needed
+       -- actions.
+
+    procedure New_Page (Output_Object : in out RTF_Output_Type;
+                       Kind : ARM_Output.Page_Kind_Type := 
ARM_Output.Any_Page);
+       -- Output a page break.
+       -- Note that this has no effect on non-printing formats.
+       -- Any_Page breaks to the top of the next page (whatever it is);
+       -- Odd_Page_Only breaks to the top of the odd-numbered page;
+       -- Soft_Page allows a page break but does not force one (use in
+       -- "No_Breaks" paragraphs.)
+       -- Raises Not_Valid_Error if in a paragraph if Kind = Any_Page or
+       -- Odd_Page, and if not in a paragraph if Kind = Soft_Page.
+
+    procedure New_Column (Output_Object : in out RTF_Output_Type);
+       -- Output a column break.
+       -- Raises Not_Valid_Error if in a paragraph, or if the number of
+       -- columns is 1.
+
+    procedure Separator_Line (Output_Object : in out RTF_Output_Type;
+                             Is_Thin : Boolean := True);
+       -- Output a separator line. It is thin if "Is_Thin" is true.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Start_Table (Output_Object : in out RTF_Output_Type;
+                          Columns : in ARM_Output.Column_Count;
+                          First_Column_Width : in ARM_Output.Column_Count;
+                          Last_Column_Width : in ARM_Output.Column_Count;
+                          Alignment : in ARM_Output.Column_Text_Alignment;
+                          No_Page_Break : in Boolean;
+                          Has_Border : in Boolean;
+                          Small_Text_Size : in Boolean;
+                          Header_Kind : in ARM_Output.Header_Kind_Type);
+       -- Starts a table. The number of columns is Columns; the first
+       -- column has First_Column_Width times the normal column width, and
+       -- the last column has Last_Column_Width times the normal column width.
+       -- Alignment is the horizontal text alignment within the columns.
+       -- No_Page_Break should be True to keep the table intact on a single
+       -- page; False to allow it to be split across pages.
+       -- Has_Border should be true if a border is desired, false otherwise.
+       -- Small_Text_Size means that the contents will have the AARM size;
+       -- otherwise it will have the normal size.
+       -- Header_Kind determines whether the table has headers.
+       -- This command starts a paragraph; the entire table is a single
+       -- paragraph. Text will be considered part of the caption until the
+       -- next table marker call.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Table_Marker (Output_Object : in out RTF_Output_Type;
+                           Marker : in ARM_Output.Table_Marker_Type);
+       -- Marks the end of an entity in a table.
+       -- If Marker is End_Caption, the table caption ends and the
+       --      future text is part of the table header.
+       -- If Marker is End_Header, the table header ends and the
+       --      future text is part of the table body.
+       -- If Marker is End_Row, a row in the table is completed, and another
+       --      row started.
+       -- If Marker is End_Item, an item in the table header or body is ended,
+       --      and another started.
+       -- If Marker is End_Table, the entire table is finished.
+       -- Raises Not_Valid_Error if not in a table.
+
+    -- Text output: These are only allowed after a Start_Paragraph and
+    -- before any End_Paragraph. Raises Not_Valid_Error if not in a paragraph,
+    -- or another error.
+
+    procedure Ordinary_Text (Output_Object : in out RTF_Output_Type;
+                            Text : in String);
+       -- Output ordinary text.
+       -- The text must end at a word break, never in the middle of a word.
+
+    procedure Ordinary_Character (Output_Object : in out RTF_Output_Type;
+                                 Char : in Character);
+       -- Output an ordinary character.
+       -- Spaces will be used to break lines as needed.
+
+    procedure Hard_Space (Output_Object : in out RTF_Output_Type);
+       -- Output a hard space. No line break should happen at a hard space.
+
+    procedure Line_Break (Output_Object : in out RTF_Output_Type);
+       -- Output a line break. This does not start a new paragraph.
+       -- This corresponds to a "<BR>" in RTF.
+
+    procedure Index_Line_Break (Output_Object : in out RTF_Output_Type;
+                               Clear_Keep_with_Next : in Boolean);
+       -- Output a line break for the index. This does not start a new
+       -- paragraph in terms of spacing. This corresponds to a "<BR>"
+       -- in HTML. If Clear_Keep_with_Next is true, insure that the next
+       -- line does not require the following line to stay with it.
+       -- Raises Not_Valid_Error if the paragraph is not in the index format.
+
+    procedure Soft_Line_Break (Output_Object : in out RTF_Output_Type);
+       -- Output a soft line break. This is a place (in the middle of a
+       -- "word") that we allow a line break. It is usually used after
+       -- underscores in long non-terminals.
+
+    procedure Soft_Hyphen_Break (Output_Object : in out RTF_Output_Type);
+       -- Output a soft line break, with a hyphen. This is a place (in the 
middle of
+       -- a "word") that we allow a line break. If the line break is used,
+       -- a hyphen will be added to the text.
+
+    procedure Tab (Output_Object : in out RTF_Output_Type);
+       -- Output a tab, inserting space up to the next tab stop.
+       -- Raises Not_Valid_Error if the paragraph was created with
+       -- Tab_Stops = ARM_Output.NO_TABS.
+
+    procedure Special_Character (Output_Object : in out RTF_Output_Type;
+                                Char : in ARM_Output.Special_Character_Type);
+       -- Output an special character.
+
+    procedure Unicode_Character (Output_Object : in out RTF_Output_Type;
+                                Char : in ARM_Output.Unicode_Type);
+       -- Output a Unicode character, with code position Char.
+
+    procedure End_Hang_Item (Output_Object : in out RTF_Output_Type);
+       -- Marks the end of a hanging item. Call only once per paragraph.
+       -- Raises Not_Valid_Error if the paragraph style is not in
+       -- Text_Prefixed_Style_Subtype, or if this has already been
+       -- called for the current paragraph, or if the paragraph was started
+       -- with No_Prefix = True.
+
+    procedure Text_Format (Output_Object : in out RTF_Output_Type;
+                          Format : in ARM_Output.Format_Type);
+       -- Change the text format so that all of the properties are as 
specified.
+       -- Note: Changes to these properties ought be stack-like; that is,
+       -- Bold on, Italic on, Italic off, Bold off is OK; Bold on, Italic on,
+       -- Bold off, Italic off should be avoided (as separate commands).
+
+    procedure Clause_Reference (Output_Object : in out RTF_Output_Type;
+                               Text : in String;
+                               Clause_Number : in String);
+       -- Generate a reference to a clause in the standard. The text of
+       -- the reference is "text", and the number of the clause is
+       -- Clause_Number. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure Index_Target (Output_Object : in out RTF_Output_Type;
+                           Index_Key : in Natural);
+       -- Generate a index target. This marks the location where an index
+       -- reference occurs. Index_Key names the index item involved.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, nothing is generated.
+
+    procedure Index_Reference (Output_Object : in out RTF_Output_Type;
+                              Text : in String;
+                              Index_Key : in Natural;
+                              Clause_Number : in String);
+       -- Generate a reference to an index target in the standard. The text
+       -- of the reference is "Text", and Index_Key and Clause_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure DR_Reference (Output_Object : in out RTF_Output_Type;
+                           Text : in String;
+                           DR_Number : in String);
+       -- Generate a reference to an DR from the standard. The text
+       -- of the reference is "Text", and DR_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure AI_Reference (Output_Object : in out RTF_Output_Type;
+                           Text : in String;
+                           AI_Number : in String);
+       -- Generate a reference to an AI from the standard. The text
+       -- of the reference is "Text", and AI_Number denotes
+       -- the target (in unfolded format). For hyperlinked formats, this should
+       -- generate a link; for other formats, the text alone is generated.
+
+    procedure Local_Target (Output_Object : in out RTF_Output_Type;
+                           Text : in String;
+                           Target : in String);
+       -- Generate a local target. This marks the potential target of local
+       -- links identified by "Target". Text is the text of the target.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link (Output_Object : in out RTF_Output_Type;
+                         Text : in String;
+                         Target : in String;
+                         Clause_Number : in String);
+       -- Generate a local link to the target and clause given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link_Start (Output_Object : in out RTF_Output_Type;
+                               Target : in String;
+                               Clause_Number : in String);
+       -- Generate a local link to the target and clause given.
+       -- The link will surround text until Local_Link_End is called.
+       -- Local_Link_End must be called before this routine can be used again.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link_End (Output_Object : in out RTF_Output_Type;
+                             Target : in String;
+                             Clause_Number : in String);
+       -- End a local link for the target and clause given.
+       -- This must be in the same paragraph as the Local_Link_Start.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure URL_Link (Output_Object : in out RTF_Output_Type;
+                       Text : in String;
+                       URL : in String);
+       -- Generate a link to the URL given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Picture  (Output_Object : in out RTF_Output_Type;
+                       Name  : in String;
+                       Descr : in String;
+                       Alignment : in ARM_Output.Picture_Alignment;
+                       Height, Width : in Natural;
+                       Border : in ARM_Output.Border_Kind);
+       -- Generate a picture.
+       -- Name is the (simple) file name of the picture; Descr is a
+       -- descriptive name for the picture (it will appear in some web
+       -- browsers).
+       -- We assume that it is a .PNG or .JPG and that it will be present
+       -- in the same directory as the output files.
+       -- Alignment specifies the picture alignment.
+       -- Height and Width specify the picture size in pixels.
+       -- Border specifies the kind of border.
+
+private
+
+    subtype Prefix_String is String(1..5);
+    type RTF_Output_Type is new ARM_Output.Output_Type with record
+       Is_Valid : Boolean := False;
+       Is_In_Paragraph  : Boolean := False;
+       Paragraph_Style  : ARM_Output.Paragraph_Style_Type := ARM_Output.Normal;
+       Paragraph_Indent : ARM_Output.Paragraph_Indent_Type := 0;
+       Had_Prefix : Boolean := False; -- If in paragraph, value of (not 
No_Prefix).
+       Wrote_into_Section : Boolean := False; -- Have we written into the
+               -- current section yet?
+       Column_Count : ARM_Output.Column_Count := 1; -- Number of columns in 
current section.
+
+       Output_File : Ada.Text_IO.File_Type;
+       Big_Files : Boolean; -- For RTF, this means to generate a single 
monster file.
+       File_Prefix : Prefix_String; -- Blank padded.
+       Output_Path : Ada.Strings.Unbounded.Unbounded_String;
+
+       Title : Ada.Strings.Unbounded.Unbounded_String;
+       Header_Prefix : Ada.Strings.Unbounded.Unbounded_String;
+        Footer_Use_Date : Boolean;
+        Footer_Use_Clause_Name : Boolean;
+        Footer_Use_ISO_Format : Boolean;
+       Footer_Text : Ada.Strings.Unbounded.Unbounded_String;
+       Page_Size : ARM_RTF.Page_Size;
+       Version_Names : ARM_Contents.Versioned_String;
+       Includes_Changes : Boolean;
+       Primary_Sans_Serif_Font : Sans_Serif_Fonts;
+       Primary_Serif_Font : Serif_Fonts;
+       Body_Font : ARM_Output.Font_Family_Type;
+       For_ISO : Boolean;
+       Char_Count : Natural := 0; -- Characters on current line.
+       Saw_Hang_End : Boolean := False; -- If we are in a hanging paragraph,
+                              -- have we seen the end of the hanging part yet?
+       Current_Space_After : ARM_Output.Space_After_Type := ARM_Output.Normal;
+                               -- The value of Space_After for the current
+                               -- paragraph.
+       Prefix_Large_Char_Count : Natural := 0;
+               -- If we're in a hanging paragraph, and Saw_Hang_End is False,
+               -- this is a count of the large (capitals, mostly) characters
+               -- visible in the prefix.
+       Is_Bold : Boolean; -- Is the text currently bold?
+       Is_Italic : Boolean; -- Is the text current italics?
+       Font : ARM_Output.Font_Family_Type; -- What is the current font family?
+       Size : ARM_Output.Size_Type; -- What is the current relative size?
+       Real_Size : Natural; -- What is the current size in halfpoints?
+       Color : ARM_Output.Color_Type; -- What is the current text color?
+       Change : ARM_Output.Change_Type := ARM_Output.None;
+       Version : ARM_Contents.Change_Version_Type := '0';
+       Added_Version : ARM_Contents.Change_Version_Type := '0';
+       Location : ARM_Output.Location_Type := ARM_Output.Normal;
+       Tab_Stops : ARM_Output.Tab_Info := ARM_Output.NO_TABS;
+       -- Tables:
+       Is_In_Table : Boolean := False; -- Are we processing a table?
+       Table_Width : Natural := 0; -- The width of the table, in twips.
+       Table_Indent : Natural := 0; -- The indent of the table, in twips.
+       Table_Column_Width : Natural := 0; -- The column width of the table, in 
twips.
+       Table_First_Column_Mult : ARM_Output.Column_Count := 1; -- The multiple 
of the first column.
+       Table_Last_Column_Mult : ARM_Output.Column_Count := 1; -- The multiple 
of the last column.
+       Table_Alignment : ARM_Output.Column_Text_Alignment := 
ARM_Output.Center_All;
+       Table_No_Page_Break : Boolean := False; -- Is a page break allowed in 
the table?
+       Table_Has_Border : Boolean := False; -- Does the table have a border?
+       Table_Has_Small_Text : Boolean := False; -- Does the table have small 
text?
+       -- Pictures:
+       Last_Shape_Id : Natural := 1024; -- Shape ids.
+    end record;
+
+end ARM_RTF;
diff --git a/packages/ada-ref-man/progs/arm_str.adb 
b/packages/ada-ref-man/progs/arm_str.adb
new file mode 100755
index 0000000..e21e1bc
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_str.adb
@@ -0,0 +1,172 @@
+with --ARM_Input,
+     Ada.Text_IO;
+package body ARM_String is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the definition of reading input from a string.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2011
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/15/00 - RLB - Created package.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+
+    procedure Open (Input_Object : in out String_Input_Type;
+                   Text : in String;
+                   Text_Name : in String) is
+       -- Open an input object for a file.
+    begin
+        Input_Object.Line_Counter := 0;
+       if Text'Length > Input_Object.Buffer'Length then
+           Ada.Text_IO.Put_Line ("  ** Text too long for string input object 
for " & Text_Name);
+       else
+           Input_Object.Buffer(1..Text'Length) := Text;
+           Input_Object.Buffer_Len := Text'Length;
+       end if;
+        Input_Object.Buffer_Index := 0;
+        Input_Object.Is_Valid := True;
+       if Text_Name'Length > Input_Object.Name'Length then
+           Input_Object.Name := Text_Name(Text_Name'First .. Text_Name'First + 
Input_Object.Name'Length - 1);
+           Input_Object.Name_Len := Input_Object.Name'Length;
+       else
+           Input_Object.Name(1..Text_Name'Length) := Text_Name;
+           Input_Object.Name_Len := Text_Name'Length;
+       end if;
+    end Open;
+
+
+    procedure Close (Input_Object : in out String_Input_Type) is
+       -- Close the input object (entity).
+       -- May propagate exceptions from the underlying implementation
+       -- (that is, I/O exceptions).
+    begin
+       if not Input_Object.Is_Valid then
+           raise ARM_Input.Not_Valid_Error;
+       end if;
+       Input_Object.Is_Valid := False;
+    end Close;
+
+
+    procedure Get_Char (Input_Object : in out String_Input_Type;
+                       Char : out Character) is
+        -- We represent end of line by Ascii.LF.
+        -- Raises: End_Error when the end of file is reached.
+       --         Not_Valid_Error if Input_Object is not valid (open).
+    begin
+       if not Input_Object.Is_Valid then
+           raise ARM_Input.Not_Valid_Error;
+       end if;
+        Input_Object.Buffer_Index := Input_Object.Buffer_Index + 1;
+        if Input_Object.Buffer_Index > Input_Object.Buffer_Len then
+--Ada.Text_IO.Put_Line ("Get_Char EOS, index=" & 
Natural'Image(Input_Object.Buffer_Index));
+           Char := ASCII.Sub;
+           return;
+        end if;
+        Char := Input_Object.Buffer(Input_Object.Buffer_Index);
+       if Char = Ascii.LF then
+           Input_Object.Line_Counter := Input_Object.Line_Counter + 1;
+--Ada.Text_IO.Put_Line ("Get_Char EOL, index=" & 
Natural'Image(Input_Object.Buffer_Index));
+--else Ada.Text_IO.Put_Line ("Get_Char " & Char & ", index=" & 
Natural'Image(Input_Object.Buffer_Index));
+       end if;
+    end Get_Char;
+
+
+    procedure Replace_Char (Input_Object : in out String_Input_Type) is
+       -- Replaces the last character read (with Get_Char); the next call
+       -- to Get_Char will return it.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+    begin
+       if not Input_Object.Is_Valid then
+           raise ARM_Input.Not_Valid_Error;
+       end if;
+        if Input_Object.Buffer_Index = 0 then
+           raise Program_Error; -- Called twice or before any calls to 
Get_Char.
+        end if;
+        if Input_Object.Buffer_Index <= Input_Object.Buffer_Len and then
+          Input_Object.Buffer(Input_Object.Buffer_Index) = Ascii.LF then
+           Input_Object.Line_Counter := Input_Object.Line_Counter - 1;
+       end if;
+--Ada.Text_IO.Put_Line ("Replace_Char");
+        Input_Object.Buffer_Index := Input_Object.Buffer_Index - 1;
+    end Replace_Char;
+
+
+    function Line_String (Input_Object : in String_Input_Type) return String is
+        -- Returns a string representing the line number and entity.
+       -- Usually used in error messages.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+    begin
+       if not Input_Object.Is_Valid then
+           raise ARM_Input.Not_Valid_Error;
+       end if;
+        return Natural'Image(Input_Object.Line_Counter) & " - " &
+               Input_Object.Name(1..Input_Object.Name_Len);
+    end Line_String;
+
+
+    procedure Start_Recording (Input_Object : in out String_Input_Type) is
+        -- Start recording all characters read into a local buffer.
+        -- Use this when text needs to be formatted into the output
+        -- file *and* be saved for future use.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+    begin
+       if not Input_Object.Is_Valid then
+           raise ARM_Input.Not_Valid_Error;
+       end if;
+        Input_Object.Recording := True;
+        Input_Object.Recording_Start := Input_Object.Buffer_Index + 1;
+    end Start_Recording;
+
+
+    procedure Stop_Recording_and_Read_Result
+        (Input_Object : in out String_Input_Type; Result : out String;
+        Len : out Natural) is
+        -- Stop recording characters read. Put the result into Result,
+        -- and the number of characters written into Len.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+    begin
+       if not Input_Object.Is_Valid then
+           raise ARM_Input.Not_Valid_Error;
+       end if;
+        if Input_Object.Buffer_Index - Input_Object.Recording_Start + 1 >
+           Result'Length then
+           Ada.Text_IO.Put_Line ("  ** Too many characters recorded on line " 
& Line_String (Input_Object));
+           Len := 0;
+        else
+           Len := (Input_Object.Buffer_Index - Input_Object.Recording_Start) + 
1;
+           Result (Result'First .. Result'First + Len - 1) :=
+                Input_Object.Buffer (Input_Object.Recording_Start .. 
Input_Object.Buffer_Index);
+        end if;
+        Input_Object.Recording := False;
+    end Stop_Recording_and_Read_Result;
+
+end ARM_String;
diff --git a/packages/ada-ref-man/progs/arm_str.ads 
b/packages/ada-ref-man/progs/arm_str.ads
new file mode 100755
index 0000000..ed9eb1a
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_str.ads
@@ -0,0 +1,98 @@
+with ARM_Input;
+package ARM_String is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the definition of reading input from a string.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2011
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/15/00 - RLB - Created package.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+
+    type String_Input_Type is new ARM_Input.Input_Type with private;
+
+    procedure Open (Input_Object : in out String_Input_Type;
+                   Text : in String;
+                   Text_Name : in String);
+       -- Open an input object for a string (Text), with a name of Text_Name.
+       -- (The name is used for error messages).
+
+    procedure Close (Input_Object : in out String_Input_Type);
+       -- Close the input object (entity).
+       -- May propagate exceptions from the underlying implementation
+       -- (that is, I/O exceptions).
+
+    procedure Get_Char (Input_Object : in out String_Input_Type;
+                       Char : out Character);
+        -- We represent end of line by Ascii.LF.
+        -- Raises: End_Error when the end of file is reached.
+       --         Not_Valid_Error if Input_Object is not valid (open).
+
+    procedure Replace_Char (Input_Object : in out String_Input_Type);
+       -- Replaces the last character read (with Get_Char); the next call
+       -- to Get_Char will return it.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+
+    function Line_String (Input_Object : in String_Input_Type) return String;
+        -- Returns a string representing the line number and entity.
+       -- Usually used in error messages.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+
+    procedure Start_Recording (Input_Object : in out String_Input_Type);
+        -- Start recording all characters read into a local buffer.
+        -- Use this when text needs to be formatted into the output
+        -- file *and* be saved for future use.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+
+    procedure Stop_Recording_and_Read_Result
+        (Input_Object : in out String_Input_Type; Result : out String;
+        Len : out Natural);
+        -- Stop recording characters read. Put the result into Result,
+        -- and the number of characters written into Len.
+        -- Raises: Not_Valid_Error if Input_Object is not valid (open).
+
+private
+    type String_Input_Type is new ARM_Input.Input_Type with record
+       Is_Valid : Boolean := False;
+       Line_Counter : Natural := 0;
+       Buffer : String(1..4000);
+       Buffer_Len : Natural := 0;
+       Buffer_Index : Natural := 0; -- Last character read from buffer.
+       -- For recording:
+       Recording : Boolean := False;
+       Recording_Start : Natural := 0; -- First character of recorded section.
+       -- Name:
+       Name : String(1..120);
+       Name_Len : Natural;
+    end record;
+end ARM_String;
diff --git a/packages/ada-ref-man/progs/arm_sub.adb 
b/packages/ada-ref-man/progs/arm_sub.adb
new file mode 100755
index 0000000..3512ab3
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_sub.adb
@@ -0,0 +1,773 @@
+--with ARM_Output;
+--with ARM_Index;
+with ARM_Contents;
+with Ada.Characters.Handling;
+with Ada.Strings.Fixed;
+with Ada.Unchecked_Deallocation;
+--with Ada.Text_IO; -- ** Temp.
+package body ARM_Subindex is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the database to store subindex items for
+    -- non-normative appendixes.
+    --
+    -- ---------------------------------------
+    -- Copyright 2005, 2006, 2007, 2011, 2012
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    -- 10/28/05 - RLB - Created package.
+    --  8/ 4/06 - RLB - Fixed problems if unit was missing.
+    --  9/22/06 - RLB - Changed to use Clause_Number_Type.
+    --  2/13/07 - RLB - Changed Start_Paragraph to use explicit indents.
+    -- 12/19/07 - RLB - Revised Text_Format calls.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    --  4/ 3/12 - RLB - Removed unused declaration.
+
+    type String_Ptr is access String;
+    type Item is record
+       Next : Item_List;
+       Entity        : String_Ptr := null;
+       From_Unit     : String_Ptr := null;
+       Kind          : Subindex_Item_Kind_Type := Top_Level;
+       Clause        : String (1..10);
+       Clause_Len    : Natural;
+       Clause_Number : ARM_Contents.Clause_Number_Type;
+       Paragraph     : String (1..10);
+       Paragraph_Len : Natural;
+        Key          : ARM_Index.Index_Key;
+    end record;
+
+    procedure Free is new Ada.Unchecked_Deallocation (Item, Item_List);
+    procedure Free is new Ada.Unchecked_Deallocation (String, String_Ptr);
+
+
+    procedure Create (Subindex_Object : in out Subindex_Type) is
+       -- Initialize a Subindex object.
+    begin
+       Subindex_Object.Is_Valid := True;
+       Subindex_Object.List := null;
+       Subindex_Object.Item_Count := 0;
+    end Create;
+
+
+    procedure Destroy (Subindex_Object : in out Subindex_Type) is
+       -- Destroy a Subindex object, freeing any resources used.
+       Temp : Item_List;
+    begin
+       if not Subindex_Object.Is_Valid then
+           raise Not_Valid_Error;
+       end if;
+       while Subindex_Object.List /= null loop
+           Temp := Subindex_Object.List;
+           Subindex_Object.List := Temp.Next;
+           Free (Temp.Entity);
+           Free (Temp.From_Unit);
+           Free (Temp);
+       end loop;
+       Subindex_Object.Is_Valid := False;
+    end Destroy;
+
+
+    procedure Insert (Subindex_Object : in out Subindex_Type;
+                     Entity          : in String;
+                     From_Unit       : in String := "";
+                     Kind            : in Subindex_Item_Kind_Type := Top_Level;
+                     Clause          : in String := "";
+                     Paragraph       : in String := "";
+                      Key            : in ARM_Index.Index_Key) is
+       -- Insert an item into the Subindex object.
+       -- The Key must be one returned by ARM_Index.Add or ARM_Index.Get_Key.
+       -- Raises Not_Valid_Error if From_Unit, Clause, or Paragraph is not
+       -- empty when the kind does not use it; or if From_Unit is empty
+       -- when the kind requires it.
+       Temp_Item : Item;
+    begin
+       if not Subindex_Object.Is_Valid then
+           raise Not_Valid_Error;
+       end if;
+       if Kind = Top_Level and then From_Unit'Length /= 0 then
+           raise Not_Valid_Error; -- No subterm here.
+       end if;
+        Ada.Strings.Fixed.Move (Target => Temp_Item.Clause,
+                               Source => Clause,
+                               Drop   => Ada.Strings.Error,
+                               Pad    => ' ');
+        Temp_Item.Clause_Len := Clause'Length;
+        Ada.Strings.Fixed.Move (Target => Temp_Item.Paragraph,
+                               Source => Paragraph,
+                               Drop   => Ada.Strings.Error,
+                               Pad    => ' ');
+        Temp_Item.Paragraph_Len := Paragraph'Length;
+        ARM_Contents.Make_Clause (Clause, Temp_Item.Clause_Number);
+       Temp_Item.Kind := Kind;
+       Temp_Item.Key  := Key;
+       Temp_Item.Entity := new String'(Entity);
+       if From_Unit'Length /= 0 then
+           Temp_Item.From_Unit := new String'(From_Unit);
+       else
+           if Kind = In_Unit or else
+              Kind = Child_of_Parent or else
+              Kind = Subtype_In_Unit or else
+              Kind = Description_In_Unit or else
+              Kind = Raised_Belonging_to_Unit then
+               -- There must be a unit here.
+               raise Not_Valid_Error;
+           end if;
+       end if;
+       Temp_Item.Next := Subindex_Object.List;
+        Subindex_Object.List := new Item'(Temp_Item);
+       Subindex_Object.Item_Count := Subindex_Object.Item_Count + 1;
+    end Insert;
+
+
+    procedure Write_Subindex (
+               Subindex_Object : in out Subindex_Type;
+               Output_Object   : in out ARM_Output.Output_Type'Class;
+               Use_Paragraphs : in Boolean := True;
+               Minimize_Lines : in Boolean := False) is
+       -- Generate the given subindex to Output_Object.
+       -- References include paragraph numbers if Use_Paragraphs is true.
+       -- Try to minimize lines if Minimize_Lines is True.
+       -- Note: This should not leave us in a paragraph.
+       Temp : Item_List;
+       Last : Item_List := null;
+       Items : array (1..Subindex_Object.Item_Count) of Item_List;
+
+       Keep_Set : Boolean := False;
+
+       CHARS_ON_SINGLE_LINE : constant := 38;
+           -- The number of characters allowed on a single line if
+           -- "Minimize_Lines" is True.
+
+       function To_Lower (A : in String) return String renames
+           Ada.Characters.Handling.To_Lower;
+
+
+        function "<" (Left, Right : Item_List) return Boolean is
+        use type ARM_Contents.Clause_Number_Type;
+
+           type Compare_Result is (Less, Greater, Equal);
+           function Compare (Left, Right : in String) return Compare_Result is
+               -- By binding the arguments, we cut the heap usage by
+               -- nearly half, and thus the runtime of the compare routine.
+           begin
+               if Left < Right then
+                   return Less;
+               elsif Left > Right then
+                   return Greater;
+               else
+                   return Equal;
+               end if;
+           end Compare;
+        begin
+           -- We sort first on "Entity", then on "Kind", then on "From_Unit",
+           -- then on "Clause", and finally on "Paragraph".
+           case Compare (To_Lower (Left.Entity.all), To_Lower 
(Right.Entity.all)) is
+               when Less => return True;
+               when Greater => return False;
+               when Equal => null; -- Continue to next compare.
+           end case;
+           if Left.Kind = Right.Kind then
+               null; -- Continue to next compare.
+           elsif Left.Kind < Right.Kind then
+               return True;
+           else --if Left.Kind > Right.Kind then
+               return False;
+           end if;
+           if Left.From_Unit = null then
+               null; -- No string to compare (Kind=Top_Level)
+           else
+               case Compare (To_Lower (Left.From_Unit.all), To_Lower 
(Right.From_Unit.all)) is
+                   when Less => return True;
+                   when Greater => return False;
+                   when Equal => null; -- Continue to next compare.
+               end case;
+           end if;
+
+           -- Note: We use the numbers, because the references don't
+           -- sort right (11.1 comes before 2.8, etc.)
+           if Left.Clause_Number < Right.Clause_Number then
+               return True;
+           elsif Left.Clause_Number = Right.Clause_Number then
+               -- Make sure that single digit paragraph numbers sort before
+               -- multiple digit ones:
+               if Left.Paragraph_Len <= 1 or else Left.Paragraph(2) = '.' or 
else Left.Paragraph(2) = '/' then
+                   -- Single digit number:
+                   if Right.Paragraph_Len <= 1 or else Right.Paragraph(2) = 
'.' or else Right.Paragraph(2) = '/' then
+                       -- Single digit number, normal compare:
+                       return Left.Paragraph (1..Left.Paragraph_Len) < 
Right.Paragraph (1..Right.Paragraph_Len);
+                   else
+                       -- Single digit is always less than multiple digits:
+                       return True;
+                   end if;
+               else -- Not single digit number:
+                   if Right.Paragraph_Len <= 1 or else Right.Paragraph(2) = 
'.' or else Right.Paragraph(2) = '/' then
+                       -- Single digit number, always less than multiple 
digits:
+                       return False;
+                   else
+                       -- Else both multiple, use normal compare:
+                       return Left.Paragraph (1..Left.Paragraph_Len) < 
Right.Paragraph (1..Right.Paragraph_Len);
+                   end if;
+               end if;
+           else -- Left.Clause_Number > Right.Clause_Number then
+               return False;
+           end if;
+        end "<";
+
+
+        procedure Partition_Sort_Slice (Start_Index, End_Index : Natural) is
+           -- Use quicksort partition sort to sort the slice between
+           -- Start_Index and End_Index.
+           Temp_Item : Item_List;
+        begin
+           case ((End_Index - Start_Index) + 1) is
+               when 0 | 1 => null; -- A single element is obviously sorted 
(trivially).
+               when 2 =>
+                   -- Unrolled Insertion Sort.
+                   if Items(Start_Index+1) < Items(Start_Index) then
+                       -- Move the record down.
+                       Temp_Item := Items(Start_Index+1);
+                       Items(Start_Index+1) := Items(Start_Index  );
+                       Items(Start_Index  ) := Temp_Item; -- Put at beginning.
+                   -- else Doesn't need to move.
+                   end if;
+               when 3 =>
+                   -- Unrolled Insertion Sort.
+                   if Items(Start_Index+1) < Items(Start_Index) then
+                       -- Move the record down.
+                       Temp_Item := Items(Start_Index+1);
+                       Items(Start_Index+1) := Items(Start_Index  );
+                       Items(Start_Index  ) := Temp_Item; -- Put at beginning.
+                   -- else Doesn't need to move.
+                   end if;
+                   if Items(Start_Index+2) < Items(Start_Index+1) then
+                       -- Move the record down.
+                       Temp_Item := Items(Start_Index+2);
+                       Items(Start_Index+2) := Items(Start_Index+1);
+                       if Temp_Item < Items(Start_Index) then
+                           -- Move the record down.
+                           Items(Start_Index+1) := Items(Start_Index);
+                           Items(Start_Index) := Temp_Item; -- Put at 
beginning.
+                       else
+                           -- Put the record here.
+                           Items(Start_Index+1) := Temp_Item;
+                       end if;
+                   -- else Doesn't need to move.
+                   end if;
+               when 4 =>
+                   -- Unrolled Insertion Sort.
+                   if Items(Start_Index+1) < Items(Start_Index) then
+                       -- Move the record down.
+                       Temp_Item := Items(Start_Index+1);
+                       Items(Start_Index+1) := Items(Start_Index  );
+                       Items(Start_Index  ) := Temp_Item; -- Put at beginning.
+                   -- else Doesn't need to move.
+                   end if;
+                   if Items(Start_Index+2) < Items(Start_Index+1) then
+                       -- Move the record down.
+                       Temp_Item := Items(Start_Index+2);
+                       Items(Start_Index+2) := Items(Start_Index+1);
+                       if Temp_Item < Items(Start_Index) then
+                           -- Move the record down.
+                           Items(Start_Index+1) := Items(Start_Index);
+                           Items(Start_Index) := Temp_Item; -- Put at 
beginning.
+                       else
+                           -- Put the record here.
+                           Items(Start_Index+1) := Temp_Item;
+                       end if;
+                   -- else Doesn't need to move.
+                   end if;
+                   if Items(Start_Index+3) < Items(Start_Index+2) then
+                       -- Move the record down.
+                       Temp_Item := Items(Start_Index+3);
+                       Items(Start_Index+3) := Items(Start_Index+2);
+                       if Temp_Item < Items(Start_Index+1) then
+                           -- Move the record down.
+                           Items(Start_Index+2) := Items(Start_Index+1);
+                           if Temp_Item < Items(Start_Index) then
+                               -- Move the record down.
+                               Items(Start_Index+1) := Items(Start_Index);
+                               Items(Start_Index) := Temp_Item; -- Put at 
beginning.
+                           else -- Put the record here.
+                               Items(Start_Index+1) := Temp_Item;
+                           end if;
+                       else
+                           -- Put the record here.
+                           Items(Start_Index+2) := Temp_Item;
+                       end if;
+                   -- else Don't move the record.
+                   end if;
+               when others => -- Longer partitions, quicksort.
+                   declare
+                       Left_Index, Right_Index : Natural;
+                       Pivot_Item : Item_List;
+                   begin
+                       -- Split into partitions, and sort them.
+                       Left_Index := Start_Index;
+                       Right_Index := End_Index;
+                       -- Use the middle element for the pivot, in case the 
items are
+                       -- somewhat sorted.
+                       Pivot_Item := Items ((End_Index - Start_Index) / 2 + 
Start_Index);
+                       loop
+                           loop
+                               exit when not (Items(Left_Index) < Pivot_Item); 
-- >=
+                               Left_Index := Left_Index + 1;
+                           end loop;
+                           loop
+                               exit when not (Pivot_Item < Items(Right_Index));
+                               Right_Index := Right_Index - 1;
+                           end loop;
+                           if Left_Index <= Right_Index then
+                               if Left_Index < Right_Index then
+                                   Temp_Item := Items(Left_Index);
+                                   Items(Left_Index) := Items(Right_Index);
+                                   Items(Right_Index) := Temp_Item;
+                               end if;
+                               Left_Index  := Left_Index + 1;
+                               Right_Index := Right_Index - 1;
+                           end if;
+                           exit when Left_Index > Right_Index;
+                       end loop; -- Repeat Loop
+                       -- Recursive calls on partitions.
+                       Partition_Sort_Slice (Left_Index, End_Index);
+                       Partition_Sort_Slice (Start_Index, Right_Index);
+                   end;
+           end case;
+        end Partition_Sort_Slice;
+
+
+       procedure Term_Text (Text : in String) is
+           A_Soft_Hyphen : Natural := Ada.Strings.Fixed.Index (Text, "@!");
+       begin
+           if A_Soft_Hyphen = 0 then
+               ARM_Output.Ordinary_Text (Output_Object, Text);
+           else
+               ARM_Output.Ordinary_Text (Output_Object, Text(Text'First .. 
A_Soft_Hyphen-1));
+               ARM_Output.Soft_Hyphen_Break (Output_Object);
+               Term_Text (Text(A_Soft_Hyphen+2 .. Text'Last)); -- In case 
there is more than one soft hyphen.
+           end if;
+       end Term_Text;
+
+
+       procedure Clause_Ref (Item : Item_List) is
+           -- Generate a clause reference:
+       begin
+           if Item.Clause_Len > 5 and then Item.Clause (1..5) = "Annex" then
+               -- Strip off the "Annex".
+               if Use_Paragraphs and then Item.Paragraph_Len /= 0 then
+                   ARM_Output.Index_Reference (Output_Object,
+                       Text => Item.Clause (Item.Clause_Len) & '(' &
+                          Item.Paragraph (1..Item.Paragraph_Len) & ')',
+                       Index_Key => Item.Key,
+                       Clause_Number => Item.Clause (1..Item.Clause_Len));
+               else
+                   ARM_Output.Index_Reference (Output_Object,
+                       Text => Item.Clause (Item.Clause_Len) & "",
+                       Index_Key => Item.Key,
+                       Clause_Number => Item.Clause (1..Item.Clause_Len));
+               end if;
+           elsif Use_Paragraphs and then Item.Paragraph_Len /= 0 then
+               ARM_Output.Index_Reference (Output_Object,
+                   Text => Item.Clause (1..Item.Clause_Len) & '(' &
+                      Item.Paragraph (1..Item.Paragraph_Len) & ')',
+                   Index_Key => Item.Key,
+                   Clause_Number => Item.Clause (1..Item.Clause_Len));
+           else
+               ARM_Output.Index_Reference (Output_Object,
+                   Text => Item.Clause (1..Item.Clause_Len),
+                   Index_Key => Item.Key,
+                   Clause_Number => Item.Clause (1..Item.Clause_Len));
+           end if;
+       end Clause_Ref;
+
+
+       procedure Italic_Text (Text : in String) is
+       begin
+           ARM_Output.Text_Format (Output_Object,
+                  Format => (Bold => False, Italic => True,
+                             Font => ARM_Output.Default,
+                             Size => 0, Color => ARM_Output.Default,
+                             Change => ARM_Output.None,
+                             Version | Added_Version => '0',
+                             Location => ARM_Output.Normal));
+            ARM_Output.Ordinary_Text (Output_Object, Text);
+           ARM_Output.Text_Format (Output_Object,
+                  Format => (Bold => False, Italic => False,
+                             Font => ARM_Output.Default,
+                             Size => 0, Color => ARM_Output.Default,
+                             Change => ARM_Output.None,
+                             Version | Added_Version => '0',
+                             Location => ARM_Output.Normal));
+       end Italic_Text;
+
+
+       procedure New_Kind (Item : Item_List; Reset_Keep : in Boolean;
+           Last_Had_Same_Unit : Boolean := False) is
+           -- Generate and item of a new kind. Note that the term has already
+           -- been generated (at some point).
+       begin
+          case Item.Kind is
+               when Top_Level =>
+                   -- ** Must be first, so can't get here.
+                   Italic_Text ("*SORT ERROR*");
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when In_Unit =>
+                   if Last_Had_Same_Unit then
+                       -- ** Must be before any other items with a unit,
+                       -- so can't get here.
+                       Italic_Text ("*SORT ERROR*");
+                   end if;
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   if Item.From_Unit /= null then
+                       Italic_Text ("in");
+                       ARM_Output.Ordinary_Character (Output_Object, ' ');
+                       Term_Text (Item.From_Unit.all);
+                   -- else shouldn't be empty, but why crash?
+                   end if;
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when Child_of_Parent =>
+                   if Last_Had_Same_Unit then
+                       -- ** Must be before any other items with a unit,
+                       -- so can't get here.
+                       Italic_Text ("*SORT ERROR*");
+                   end if;
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   if Item.From_Unit /= null then
+                       Italic_Text ("child of");
+                       ARM_Output.Ordinary_Character (Output_Object, ' ');
+                       Term_Text (Item.From_Unit.all);
+                   -- else shouldn't be empty, but why crash?
+                   end if;
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when Subtype_In_Unit =>
+                   if Last_Had_Same_Unit then
+                       -- ** Must be before any other items with a unit,
+                       -- so can't get here.
+                       Italic_Text ("*SORT ERROR*");
+                   end if;
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   if Item.From_Unit /= null then
+                       Italic_Text ("in");
+                       ARM_Output.Ordinary_Character (Output_Object, ' ');
+                       Term_Text (Item.From_Unit.all);
+                   -- else shouldn't be empty, but why crash?
+                   end if;
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when Description_In_Unit =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   if not Last_Had_Same_Unit then
+                       ARM_Output.Hard_Space (Output_Object);
+                       ARM_Output.Hard_Space (Output_Object);
+                       ARM_Output.Hard_Space (Output_Object);
+                       if Item.From_Unit /= null then
+                           Italic_Text ("in");
+                           ARM_Output.Ordinary_Character (Output_Object, ' ');
+                           Term_Text (Item.From_Unit.all);
+                       -- else shouldn't be empty, but why crash?
+                       end if;
+                       ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => False);
+                   end if;
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   Italic_Text ("description");
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+               when Raised_Belonging_to_Unit =>
+                   ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => Reset_Keep);
+                   if not Last_Had_Same_Unit then
+                       ARM_Output.Hard_Space (Output_Object);
+                       ARM_Output.Hard_Space (Output_Object);
+                       ARM_Output.Hard_Space (Output_Object);
+                       if Item.From_Unit /= null then
+                           Italic_Text ("in");
+                           ARM_Output.Ordinary_Character (Output_Object, ' ');
+                           Term_Text (Item.From_Unit.all);
+                       -- else shouldn't be empty, but why crash?
+                       end if;
+                       ARM_Output.Index_Line_Break (Output_Object, 
Clear_Keep_with_Next => False);
+                   end if;
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   Italic_Text ("raised");
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Item);
+
+           end case;
+       end New_Kind;
+
+       function Is_Last_for_Entity (Item : in Item_List) return Boolean is
+           -- Returns True if this is the last line for Item's Entity.
+       begin
+--Ada.Text_IO.Put_Line("Enter Is_Last");
+           if Item.Next = null then
+--Ada.Text_IO.Put_Line("  No follower (True)");
+               return True;
+           elsif To_Lower (Item.Entity.all) /= To_Lower(Item.Next.Entity.all) 
then
+               -- The next item has a different entity.
+--Ada.Text_IO.Put_Line("  Different entity (True)");
+               return True;
+           elsif Item.Kind /= Item.Next.Kind then
+               -- The next item has a different kind, so another line will
+               -- be generated.
+--Ada.Text_IO.Put_Line("  Different kind (False)");
+               return False;
+           elsif Item.Kind /= Top_Level and then
+                 Item.From_Unit.all /= Item.Next.From_Unit.all then
+               -- The next item has a different unit, so another line will
+               -- be generated.
+--Ada.Text_IO.Put_Line("  Different unit (False)");
+               return False;
+           else
+               -- The following entity will just add another clause reference.
+               -- So we must look at the entity following that:
+--Ada.Text_IO.Put_Line("  Recurse");
+               return Is_Last_for_Entity (Item.Next);
+           end if;
+       end Is_Last_for_Entity;
+
+    begin
+        if not Subindex_Object.Is_Valid then
+            raise Not_Valid_Error;
+        end if;
+
+       Keep_Set := False;
+
+       -- Load the items:
+       Temp := Subindex_Object.List;
+       for I in Items'range loop
+           Items(I) := Temp;
+           Temp := Temp.Next;
+       end loop;
+
+       -- Sort the items:
+       Partition_Sort_Slice (Items'First, Items'Last);
+
+        -- Relink the items in the sorted order:
+        for I in Items'First .. Items'Last - 1 loop
+           Items(I).Next := Items(I+1);
+        end loop;
+        if Items'Length > 0 then
+           Items(Items'Last).Next := null;
+           Subindex_Object.List := Items(1);
+        else
+           Subindex_Object.List := null;
+        end if;
+
+       ARM_Output.Start_Paragraph (Output_Object, ARM_Output.Index,
+               Indent => 0, Number => "", No_Breaks => True);
+
+       Temp := Subindex_Object.List;
+       while Temp /= null loop
+           -- First, check for the new entity:
+           if Last = null or else
+               To_Lower(Last.Entity.all) /= To_Lower(Temp.Entity.all) then
+               -- New term: (Note that we ignore case differences here.
+               -- Perhaps there ought to be a warning?)
+               if Last /= null then
+                   ARM_Output.End_Paragraph (Output_Object);
+                   if Temp.Kind = Top_Level then
+                       ARM_Output.Start_Paragraph (Output_Object, 
ARM_Output.Index,
+                                                   Indent => 0, Number => "",
+                                                   No_Breaks => True);
+                       Keep_Set := False;
+--Ada.Text_IO.Put_Line("New Item: Entity=" & Temp.Entity.all &
+--" Kind=" & Subindex_Item_Kind_Type'Image(Temp.Kind) &
+--" Keep_Set=" & Boolean'Image(Keep_Set));
+                   elsif Minimize_Lines and then
+                         Temp.Kind = In_Unit and then
+                         Temp.Entity'Length + 4 + Temp.From_Unit'Length < 
CHARS_ON_SINGLE_LINE then
+                       -- Write as a single line.
+                       ARM_Output.Start_Paragraph (Output_Object, 
ARM_Output.Index,
+                                                   Indent => 0, Number => "",
+                                                   No_Breaks => True);
+                       Keep_Set := False;
+--Ada.Text_IO.Put_Line("New Item: Entity=" & Temp.Entity.all &
+--" Kind=" & Subindex_Item_Kind_Type'Image(Temp.Kind) &
+--" From_Unit=" & Temp.From_Unit.all & " Keep_Set=" & Boolean'Image(Keep_Set));
+                   else -- The item has at least two lines; keep them together.
+                       ARM_Output.Start_Paragraph (Output_Object, 
ARM_Output.Index,
+                                                   Indent => 0, Number => "",
+                                                   No_Breaks => True, 
Keep_with_Next => True);
+                       Keep_Set := True;
+--Ada.Text_IO.Put_Line("New Item: Entity=" & Temp.Entity.all &
+--" Kind=" & Subindex_Item_Kind_Type'Image(Temp.Kind) &
+--" From_Unit=" & Temp.From_Unit.all & " Keep_Set=" & Boolean'Image(Keep_Set));
+                   end if;
+               end if;
+               if Temp.Kind /= Subtype_In_Unit then
+                   Term_Text (Temp.Entity.all);
+               else
+                   declare
+                       Of_Loc : Natural :=
+                           Ada.Strings.Fixed.Index (Temp.Entity.all,
+                               " subtype of ");
+                   begin
+                       if Of_Loc = 0 then
+                           -- Weird, "subtype of" not found.
+                           Term_Text (Temp.Entity.all);
+                       else
+                           Term_Text (Temp.Entity (Temp.Entity'First .. 
Of_Loc));
+                           Italic_Text ("subtype of");
+                           Term_Text (Temp.Entity (Of_Loc+11 .. 
Temp.Entity'Last));
+                       end if;
+                   end;
+               end if;
+               if Temp.Kind = Top_Level then
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Hard_Space (Output_Object);
+                   ARM_Output.Ordinary_Character (Output_Object, ' ');
+                   Clause_Ref (Temp);
+               else
+                   if Is_Last_for_Entity (Temp) then
+                       -- Last (only) item of this term, always clear Keep:
+--Ada.Text_IO.Put_Line("Only New Item: Entity=" & Temp.Entity.all &
+--" Kind=" & Subindex_Item_Kind_Type'Image(Temp.Kind) &
+--" From_Unit=" & Temp.From_Unit.all & " Keep_Set=" & Boolean'Image(Keep_Set));
+                       if Minimize_Lines and then
+                          Temp.Kind = In_Unit and then
+                           Temp.Entity'Length + 4 + Temp.From_Unit'Length < 
CHARS_ON_SINGLE_LINE then
+                           -- Write this as a single line:
+                           ARM_Output.Ordinary_Character (Output_Object, ' ');
+                           Italic_Text ("in");
+                           ARM_Output.Ordinary_Character (Output_Object, ' ');
+                           Term_Text (Temp.From_Unit.all);
+                           ARM_Output.Hard_Space (Output_Object);
+                           ARM_Output.Hard_Space (Output_Object);
+                           ARM_Output.Ordinary_Character (Output_Object, ' ');
+                           Clause_Ref (Temp);
+                       else
+                           New_Kind (Temp, Reset_Keep => True, 
Last_Had_Same_Unit => False);
+                           Keep_Set := False;
+                       end if;
+                   else -- Leave keep set:
+--Ada.Text_IO.Put_Line("More New Item: Entity=" & Temp.Entity.all &
+--" Kind=" & Subindex_Item_Kind_Type'Image(Temp.Kind) &
+--" From_Unit=" & Temp.From_Unit.all & " Keep_Set=" & Boolean'Image(Keep_Set));
+                       New_Kind (Temp, Reset_Keep => False, Last_Had_Same_Unit 
=> False);
+                   end if;
+               end if;
+           elsif Last.Kind /= Temp.Kind then
+               If Last.Kind /= Top_Level and then
+                  Temp.Kind /= Top_Level and then
+                  Last.From_Unit.all = Temp.From_Unit.all then
+--Ada.Text_IO.Put_Line("New Kind, same unit: Entity=" & Temp.Entity.all &
+--" Kind=" & Subindex_Item_Kind_Type'Image(Temp.Kind) &
+--" From_Unit=" & Temp.From_Unit.all & " Keep_Set=" & Boolean'Image(Keep_Set));
+                   New_Kind (Temp, Reset_Keep => Keep_Set, Last_Had_Same_Unit 
=> True);
+               else
+--if Temp.Kind /= Top_Level then
+--Ada.Text_IO.Put_Line("New Kind: Entity=" & Temp.Entity.all &
+--" Kind=" & Subindex_Item_Kind_Type'Image(Temp.Kind) &
+--" From_Unit=" & Temp.From_Unit.all & " Keep_Set=" & Boolean'Image(Keep_Set));
+--else
+--Ada.Text_IO.Put_Line("New Kind: Entity=" & Temp.Entity.all &
+--" Kind=" & Subindex_Item_Kind_Type'Image(Temp.Kind) &
+--" Keep_Set=" & Boolean'Image(Keep_Set));
+--end if;
+                   New_Kind (Temp, Reset_Keep => Keep_Set, Last_Had_Same_Unit 
=> False);
+               end if;
+               Keep_Set := False;
+           elsif (Temp.Kind = In_Unit or else
+                  Temp.Kind = Child_of_Parent or else
+                  Temp.Kind = Subtype_In_Unit or else
+                  Temp.Kind = Description_In_Unit or else
+                  Temp.Kind = Raised_Belonging_to_Unit) and then
+               Last.From_Unit.all /= Temp.From_Unit.all then
+--Ada.Text_IO.Put_Line("Same Kind, new unit: Entity=" & Temp.Entity.all &
+--" Kind=" & Subindex_Item_Kind_Type'Image(Temp.Kind) &
+--" From_Unit=" & Temp.From_Unit.all & " Keep_Set=" & Boolean'Image(Keep_Set));
+               New_Kind (Temp, Reset_Keep => Keep_Set, Last_Had_Same_Unit => 
False);
+               Keep_Set := False;
+           elsif Last.Clause (1..Last.Clause_Len) = Temp.Clause 
(1..Temp.Clause_Len) and then
+                 Last.Paragraph (1..Last.Paragraph_Len) = Temp.Paragraph 
(1..Temp.Paragraph_Len) then
+               -- The reference and everything else is the same, so just
+               -- forget this item.
+               null;
+           else
+--if Temp.Kind /= Top_Level then
+--Ada.Text_IO.Put_Line("Same: Entity=" & Temp.Entity.all &
+--" Kind=" & Subindex_Item_Kind_Type'Image(Temp.Kind) &
+--" From_Unit=" & Temp.From_Unit.all & " Keep_Set=" & Boolean'Image(Keep_Set));
+--else
+--Ada.Text_IO.Put_Line("Same: Entity=" & Temp.Entity.all &
+--" Kind=" & Subindex_Item_Kind_Type'Image(Temp.Kind) &
+--" Keep_Set=" & Boolean'Image(Keep_Set));
+--end if;
+               -- Just add the next clause.
+               ARM_Output.Ordinary_Character (Output_Object, ',');
+               ARM_Output.Ordinary_Character (Output_Object, ' ');
+               Clause_Ref (Temp);
+           end if;
+           Last := Temp;
+           Temp := Temp.Next;
+       end loop;
+
+       ARM_Output.End_Paragraph (Output_Object);
+
+    end Write_Subindex;
+
+end ARM_Subindex;
+
+
diff --git a/packages/ada-ref-man/progs/arm_sub.ads 
b/packages/ada-ref-man/progs/arm_sub.ads
new file mode 100755
index 0000000..a006c63
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_sub.ads
@@ -0,0 +1,91 @@
+with ARM_Output;
+with ARM_Index;
+package ARM_Subindex is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the database to store subindex items for
+    -- non-normative appendixes.
+    --
+    -- ---------------------------------------
+    -- Copyright 2005, 2011
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    -- 10/28/05 - RLB - Created package.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+
+    type Subindex_Type is tagged limited private;
+
+    Not_Valid_Error : exception;
+
+    procedure Create (Subindex_Object : in out Subindex_Type);
+       -- Initialize a Subindex object.
+
+    procedure Destroy (Subindex_Object : in out Subindex_Type);
+       -- Destroy a Subindex object, freeing any resources used.
+
+    type Subindex_Item_Kind_Type is (Top_Level, In_Unit,
+       Child_of_Parent, Subtype_In_Unit,
+       Description_In_Unit, Raised_Belonging_to_Unit);
+
+    procedure Insert (Subindex_Object : in out Subindex_Type;
+                     Entity          : in String;
+                     From_Unit       : in String := "";
+                     Kind            : in Subindex_Item_Kind_Type := Top_Level;
+                     Clause          : in String := "";
+                     Paragraph       : in String := "";
+                      Key            : in ARM_Index.Index_Key);
+       -- Insert an item into the Subindex object.
+       -- The Key must be one returned by ARM_Index.Add or ARM_Index.Get_Key.
+       -- Raises Not_Valid_Error if In_Unit, Clause, or Paragraph is not
+       -- empty when the kind does not use it.
+
+    procedure Write_Subindex (
+               Subindex_Object : in out Subindex_Type;
+               Output_Object   : in out ARM_Output.Output_Type'Class;
+               Use_Paragraphs : in Boolean := True;
+               Minimize_Lines : in Boolean := False);
+       -- Generate the given subindex to Output_Object.
+       -- References include paragraph numbers if Use_Paragraphs is true.
+       -- Try to minimize lines if Minimize_Lines is True.
+
+private
+
+    type Item;
+    type Item_List is access all Item;
+    type Subindex_Type is tagged limited record
+       Is_Valid : Boolean := False;
+       List : Item_List;
+       Item_Count : Natural;
+    end record;
+
+end ARM_Subindex;
+
+
diff --git a/packages/ada-ref-man/progs/arm_syn.adb 
b/packages/ada-ref-man/progs/arm_syn.adb
new file mode 100755
index 0000000..9ee981e
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_syn.adb
@@ -0,0 +1,452 @@
+with Ada.Unchecked_Deallocation,
+     Ada.Strings.Fixed;
+package body ARM_Syntax is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the database to collect the syntax summary and
+    -- cross-reference.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2004, 2006, 2011
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/17/00 - RLB - Created package.
+    --  5/24/00 - RLB - Updated to use revised Tabset.
+    --  5/26/00 - RLB - Added a Tabset parameter.
+    --  8/ 4/00 - RLB - Changed style to make font smaller (per Duff).
+    --  8/16/00 - RLB - Added NoParaNum; removed junk space (which caused
+    --                 blank lines and paragraph numbers).
+    --  9/26/00 - RLB - Revised to use SyntaxDisplay format to get more
+    --                 control over the formating of this section.
+    --  9/27/00 - RLB - Revised XRef to decrease white space.
+    --  9/28/00 - RLB - Added code to make links in HTML version.
+    --  9/09/04 - RLB - Removed unused junk noted by Stephen Leake.
+    --  6/22/06 - RLB - Added additional information to improve the links.
+    --                 Changed the cross-reference table to use the Ada 83
+    --                 format (which adds missing section references).
+    -- 10/13/06 - RLB - Added Defined flag to cross-references to eliminate
+    --                 junk errors from not-quite-non-terminals.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+
+    type String_Ptr is access String;
+    type Rule_Type;
+    type Rule_Ptr is access Rule_Type;
+    type Rule_Type is record
+       Clause : String (1..10);
+       Clause_Len : Natural;
+       Rule : String_Ptr;
+       Tabset : String (1..40);
+       Next : Rule_Ptr;
+    end record;
+
+    Rule_List : Rule_Ptr := null;
+    Rule_List_Tail : Rule_Ptr := null;
+
+    type XRef_Type;
+    type XRef_Ptr is access XRef_Type;
+    type XRef_Type is record
+       Clause : String (1..10);
+       Clause_Len : Natural;
+       Name : String (1..40);
+       Name_Len : Natural;
+       Used_In : String (1..40);
+       Used_In_Len : Natural;
+       Defined : Boolean;
+       Next : XRef_Ptr;
+    end record;
+
+    XRef_List : XRef_Ptr := null;
+    XRef_Count : Natural := 0;
+
+    type NT_Type;
+    type NT_Ptr is access NT_Type;
+    type NT_Type is record
+       Name : String (1..40);
+       Name_Len : Natural;
+       Clause : String (1..10);
+       Clause_Len : Natural;
+       Link_Target : Target_Type;
+       Next : NT_Ptr;
+    end record;
+
+    NT_List : NT_Ptr := null;
+    NT_Count : Natural := 0;
+
+    procedure Free is new Ada.Unchecked_Deallocation (Rule_Type, Rule_Ptr);
+    --  procedure Free is new Ada.Unchecked_Deallocation (XRef_Type, 
XRef_Ptr); not referenced
+    --  procedure Free is new Ada.Unchecked_Deallocation (NT_Type, NT_Ptr);
+    procedure Free is new Ada.Unchecked_Deallocation (String, String_Ptr);
+
+    procedure Create is
+       -- Initialize the syntax database.
+    begin
+       Rule_List := null;
+       Rule_List_Tail := null;
+    end Create;
+
+
+    procedure Destroy is
+       -- Destroy the syntax database.
+       RTemp : Rule_Ptr;
+    begin
+       while Rule_List /= null loop
+           RTemp := Rule_List;
+           Rule_List := RTemp.Next;
+           Free (RTemp.Rule);
+           Free (RTemp);
+       end loop;
+
+    end Destroy;
+
+
+    procedure Insert_Rule (
+       For_Clause : in String;
+       Rule : in String;
+       Tabset : in String := "") is
+       -- Add a rule for the syntax summary. The rule appears in For_Clause.
+       -- Tabset provides any needed tab settings.
+       Temp_Rule : Rule_Type;
+    begin
+       Ada.Strings.Fixed.Move (Target => Temp_Rule.Clause,
+                               Source => For_Clause,
+                               Drop   => Ada.Strings.Error,
+                               Pad    => ' ');
+       Temp_Rule.Clause_Len := For_Clause'Length;
+       Temp_Rule.Rule := new String'(Rule);
+       Ada.Strings.Fixed.Move (Target => Temp_Rule.Tabset,
+                               Source => Tabset,
+                               Drop   => Ada.Strings.Error,
+                               Pad    => ' ');
+       Temp_Rule.Next := null;
+       if Rule_List_Tail = null then
+           Rule_List := new Rule_Type'(Temp_Rule);
+           Rule_List_Tail := Rule_List;
+       else
+           Rule_List_Tail.Next := new Rule_Type'(Temp_Rule);
+           Rule_List_Tail := Rule_List_Tail.Next;
+       end if;
+    end Insert_Rule;
+
+
+    procedure Add_Non_Terminal (
+       NT_Name : in String;
+       For_Clause : in String;
+       Link_Target : out ARM_Syntax.Target_Type) is
+       -- Add a non-terminal to the syntax list. Returns a new Link_Target
+       -- for the Non-Terminal.
+       Temp_NT : NT_Type;
+    begin
+       Ada.Strings.Fixed.Move (Target => Temp_NT.Clause,
+                               Source => For_Clause,
+                               Drop   => Ada.Strings.Error,
+                               Pad    => ' ');
+       Temp_NT.Clause_Len := For_Clause'Length;
+       Ada.Strings.Fixed.Move (Target => Temp_NT.Name,
+                               Source => NT_Name,
+                               Drop   => Ada.Strings.Error,
+                               Pad    => ' ');
+       Temp_NT.Name_Len := NT_Name'Length;
+
+       declare
+           Val : constant String := Natural'Image(NT_Count);
+       begin
+           Temp_NT.Link_Target := "S0000";
+           if Val'Length <= 5 then
+               Temp_NT.Link_Target (5-(Val'Length-2)..5) :=
+                   Val(2..Val'Last);
+           else
+               raise Program_Error; -- Too many.
+           end if;
+           Link_Target := Temp_NT.Link_Target;
+       end;
+
+       if NT_List = null then
+           Temp_NT.Next := null;
+           NT_List := new NT_Type'(Temp_NT);
+       else
+           Temp_NT.Next := NT_List;
+           NT_List := new NT_Type'(Temp_NT);
+       end if;
+       NT_Count := NT_Count + 1;
+
+    end Add_Non_Terminal;
+
+
+    function Non_Terminal_Clause (NT_Name : in String) return String is
+       -- Return the clause where NT_Name is declared.
+       -- Returns "" if NT_Name is not a declared Non_Terminal.
+       Loc : NT_Ptr;
+    begin
+       Loc := NT_List;
+       while Loc /= null loop
+           if NT_Name = Loc.Name(1..Loc.Name_Len) then
+               return Loc.Clause(1..Loc.Clause_Len);
+           end if;
+           Loc := Loc.Next;
+       end loop;
+       return ""; -- Not found.
+    end Non_Terminal_Clause;
+
+
+    function Non_Terminal_Link_Target (NT_Name : in String) return Target_Type 
is
+       -- Return the link target for NT_Name.
+       -- Returns "     " if NT_Name is not a declared Non_Terminal.
+       Loc : NT_Ptr;
+    begin
+       Loc := NT_List;
+       while Loc /= null loop
+           if NT_Name = Loc.Name(1..Loc.Name_Len) then
+               return Loc.Link_Target;
+           end if;
+           Loc := Loc.Next;
+       end loop;
+       return Target_Type'(others => ' '); -- Not found.
+    end Non_Terminal_Link_Target;
+
+
+    procedure Add_Xref (
+       Name : in String;
+       Used_In : in String;
+       Clause : in String;
+       Defined : in Boolean) is
+       -- Add a cross-reference entry.
+       -- The item referenced is Name, and it is referenced in the production
+       -- for Used_In, in Clause. It is a defined non-terminal if Defined
+       -- is True (thus it can be linked).
+       Temp_XRef : XRef_Type;
+    begin
+       Ada.Strings.Fixed.Move (Target => Temp_XRef.Clause,
+                               Source => Clause,
+                               Drop   => Ada.Strings.Error,
+                               Pad    => ' ');
+       Temp_XRef.Clause_Len := Clause'Length;
+       Ada.Strings.Fixed.Move (Target => Temp_XRef.Name,
+                               Source => Name,
+                               Drop   => Ada.Strings.Error,
+                               Pad    => ' ');
+       Temp_XRef.Name_Len := Name'Length;
+       Ada.Strings.Fixed.Move (Target => Temp_XRef.Used_In,
+                               Source => Used_In,
+                               Drop   => Ada.Strings.Error,
+                               Pad    => ' ');
+       Temp_XRef.Used_In_Len := Used_In'Length;
+       Temp_XRef.Defined := Defined;
+
+       -- Check for an identical record already loaded:
+       declare
+           Temp : XRef_Ptr := XRef_List;
+       begin
+           -- We assume that all of the items from the current clause
+           -- are together at the top of the list. If the list is inserted
+           -- in reverse order (the default), that will be true.
+           while Temp /= null and then
+                 (Temp.Clause_Len = Temp_XRef.Clause_Len) and then
+                 (Temp.Clause = Temp_XRef.Clause) loop
+               if (Temp.Name_Len = Temp_XRef.Name_Len) and then
+                  (Temp.Used_In_Len = Temp_XRef.Used_In_Len) and then
+                  (Temp.Name = Temp_XRef.Name) and then
+                  (Temp.Used_In = Temp_XRef.Used_In) then
+                   -- Identical to an existing item, forget it.
+                   -- (We do this to eliminate multiple items from one 
production.
+                   return;
+               end if;
+               Temp := Temp.Next;
+           end loop;
+       end;
+
+       if XRef_List = null then
+           Temp_XRef.Next := null;
+           XRef_List := new XRef_Type'(Temp_XRef);
+       else
+           Temp_XRef.Next := XRef_List;
+           XRef_List := new XRef_Type'(Temp_XRef);
+       end if;
+       XRef_Count := XRef_Count + 1;
+    end Add_Xref;
+
+
+    --generic
+    -- with procedure Format_Text (Text : in String;
+    --                             Text_Name : in String);
+    procedure Report is
+       -- Output the fully formatted syntax summary to the
+       -- "Format_Text" routine. "Format_Text" allows all commands
+       -- for the full formatter. (Text_Name is an identifying name
+       -- for error messages).
+       Temp : Rule_Ptr;
+    begin
+       Format_Text ("@begin(syntaxdisplay)" & Ascii.LF, "Prefix");
+       Temp := Rule_List;
+       while Temp /= null loop
+           if Ada.Strings.Fixed.Trim (Temp.Tabset, Ada.Strings.Right) = "" then
+               Format_Text ("@address@hidden" &
+                   Temp.Clause(1..Temp.Clause_Len) & "}:" & Ascii.LF &
+                   Temp.Rule.all & Ascii.LF & Ascii.LF,
+                   Temp.Clause(1..Temp.Clause_Len));
+           else
+               Format_Text ("@address@hidden@tabset{" &
+                   Ada.Strings.Fixed.Trim (Temp.Tabset, Ada.Strings.Right) &
+                   "address@hidden" & Temp.Clause(1..Temp.Clause_Len) & "}:" & 
Ascii.LF &
+                   Temp.Rule.all & Ascii.LF & Ascii.LF,
+                   Temp.Clause(1..Temp.Clause_Len));
+           end if;
+           Temp := Temp.Next;
+       end loop;
+       Format_Text ("@end(syntaxdisplay)" & Ascii.LF, "Suffix");
+    end Report;
+
+
+    --generic
+    -- with procedure Format_Text (Text : in String;
+    --                             Text_Name : in String);
+    procedure XRef is
+       -- Output the fully formatted syntax cross-reference to the
+       -- "Format_Text" routine. "Format_Text" allows all commands
+       -- for the full formatter. (Text_Name is an identifying name
+       -- for error messages).
+       Temp : XRef_Ptr;
+       Last : XRef_Ptr := null;
+       Items : array (1..XRef_Count) of XRef_Ptr;
+    begin
+       -- Sort the items:
+
+       -- Load the items:
+       Temp := XRef_List;
+       for I in Items'range loop
+           Items(I) := Temp;
+           Temp := Temp.Next;
+       end loop;
+
+       -- Sort the items array (use an insertion sort):
+       declare
+           Left : Natural;  -- Left sorting stop
+
+           function "<" (Left, Right : XRef_Ptr) return Boolean is
+           begin
+               -- We sort first on "Name", then on "Used_In".
+               if Left.Name (1..Left.Name_Len) < Right.Name 
(1..Right.Name_Len) then
+                   return True;
+               elsif Left.Name (1..Left.Name_Len) > Right.Name 
(1..Right.Name_Len) then
+                   return False;
+               else
+                   return Left.Used_In (1..Left.Used_In_Len) < Right.Used_In 
(1..Right.Used_In_Len);
+               end if;
+           end "<";
+
+       begin
+           for Right In Items'First+1 .. Items'Last loop -- Right sorting stop
+               Temp := Items(Right);
+               Left := Right - 1;
+               while Temp < Items(Left) loop -- Switch items
+                   Items(Left + 1) := Items(Left);
+                   Left := Left - 1;
+                   exit when Left = 0;
+               end loop;
+               Items(Left + 1) := Temp;
+           end loop;
+       end;
+
+        -- Relink the items in the sorted order:
+        for I in Items'First .. Items'Last - 1 loop
+           Items(I).Next := Items(I+1);
+        end loop;
+        if Items'Length > 0 then
+           Items(Items'Last).Next := null;
+           XRef_List := Items(1);
+        else
+           XRef_List := null;
+        end if;
+
+
+       Format_Text ("@begin(syntaxdisplay)" & Ascii.LF, "Prefix");
+       Format_Text ("@tabclear()@tabset(P4, P38)" & Ascii.LF, "Prefix");
+       Format_Text ("@begin(twocol)" & Ascii.LF, "Prefix");
+       Temp := XRef_List;
+       while Temp /= null loop
+           if Last = null or else
+               Last.Name (1..Last.Name_Len) /= Temp.Name (1..Temp.Name_Len) 
then
+               -- New header:
+               declare
+                   Clause : constant String :=
+                       Non_Terminal_Clause (Temp.Name (1..Temp.Name_Len));
+               begin
+                   if Temp.Defined then
+                       if Clause /= "" then
+                           Format_Text ("@address@hidden@nt{" & Temp.Name 
(1..Temp.Name_Len) &
+                                "address@hidden@RefSecbyNum{" & Clause & "}" & 
Ascii.LF,
+                                Temp.Name (1..Temp.Name_Len) & " header");
+                       else -- Undefined? Weird, but don't break, just use the
+                            -- Ada 83 ellipsis.
+                           Format_Text ("@address@hidden@nt{" & Temp.Name 
(1..Temp.Name_Len) &
+                                "address@hidden" & Ascii.LF,
+                                Temp.Name (1..Temp.Name_Len) & " header");
+                       end if;
+                   else
+                       if Clause /= "" then
+                           Format_Text ("@address@hidden@ntf{" & Temp.Name 
(1..Temp.Name_Len) &
+                                "address@hidden@RefSecbyNum{" & Clause & "}" & 
Ascii.LF,
+                                Temp.Name (1..Temp.Name_Len) & " header");
+                       else -- Undefined? Weird, but don't break, just use the
+                            -- Ada 83 ellipsis.
+                           Format_Text ("@address@hidden@ntf{" & Temp.Name 
(1..Temp.Name_Len) &
+                                "address@hidden" & Ascii.LF,
+                                Temp.Name (1..Temp.Name_Len) & " header");
+                       end if;
+                   end if;
+               end;
+               -- Original:
+               --Format_Text ("@address@hidden@nt{" & Temp.Name 
(1..Temp.Name_Len) &
+               --     "}" & Ascii.LF,
+               --     Temp.Name (1..Temp.Name_Len) & " header");
+               Last := Temp;
+           end if;
+           if Temp.Next = null or else
+               Temp.Name (1..Temp.Name_Len) /= Temp.Next.Name 
(1..Temp.Next.Name_Len) then
+               -- Last item of a set.
+               Format_Text ("@address@hidden" & 
Temp.Used_In(1..Temp.Used_In_Len) & "address@hidden" &
+                   "@RefSecbyNum{" & Temp.Clause(1..Temp.Clause_Len) & '}' & 
Ascii.LF & Ascii.LF,
+                   Temp.Name (1..Temp.Name_Len) & " ref " & 
Temp.Clause(1..Temp.Clause_Len));
+           else -- Not an end item.
+               Format_Text ("@address@hidden" & 
Temp.Used_In(1..Temp.Used_In_Len) & "address@hidden" &
+                   "@RefSecbyNum{" & Temp.Clause(1..Temp.Clause_Len) & '}' & 
Ascii.LF,
+                   Temp.Name (1..Temp.Name_Len) & " ref " & 
Temp.Clause(1..Temp.Clause_Len));
+           end if;
+           Temp := Temp.Next;
+       end loop;
+       Format_Text ("@end(twocol)" & Ascii.LF, "Suffix");
+       Format_Text ("@end(syntaxdisplay)" & Ascii.LF, "Suffix");
+       -- Should free the XRef list here, but we won't do anything
+       -- afterwards, so doing so doesn't matter.
+    end XRef;
+
+end ARM_Syntax;
+
+
diff --git a/packages/ada-ref-man/progs/arm_syn.ads 
b/packages/ada-ref-man/progs/arm_syn.ads
new file mode 100755
index 0000000..d7b3394
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_syn.ads
@@ -0,0 +1,109 @@
+package ARM_Syntax is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package contains the database to collect the syntax summary and
+    -- cross-reference.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2006, 2011
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  5/17/00 - RLB - Created package.
+    --  5/26/00 - RLB - Added a Tabset parameter.
+    --  6/22/06 - RLB - Added additional information to improve the links
+    --                 and to be able to use the Ada 83 format for the
+    --                 cross-reference table.
+    -- 10/13/06 - RLB - Added Defined flag to cross-references to eliminate
+    --                 junk errors from not-quite-non-terminals.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+
+    procedure Create;
+       -- Initialize the syntax database.
+
+    procedure Destroy;
+       -- Destroy the syntax database.
+
+    procedure Insert_Rule (
+       For_Clause : in String;
+       Rule : in String;
+       Tabset : in String := "");
+       -- Add a rule for the syntax summary. The rule appears in For_Clause.
+       -- Tabset provides any needed tab settings.
+
+    subtype Target_Type is String (1..5);
+
+    procedure Add_Non_Terminal (
+       NT_Name : in String;
+       For_Clause : in String;
+       Link_Target : out ARM_Syntax.Target_Type);
+       -- Add a non-terminal to the syntax list. Returns a new Link_Target
+       -- for the Non-Terminal.
+
+    procedure Add_Xref (
+       Name : in String;
+       Used_In : in String;
+       Clause : in String;
+       Defined : in Boolean);
+       -- Add a cross-reference entry.
+       -- The item referenced is Name, and it is referenced in the production
+       -- for Used_In, in Clause. It is a defined non-terminal if Defined
+       -- is True (thus it can be linked).
+
+    function Non_Terminal_Clause (NT_Name : in String) return String;
+       -- Return the clause where NT_Name is declared.
+       -- Returns "" if NT_Name is not a declared Non_Terminal.
+
+    function Non_Terminal_Link_Target (NT_Name : in String) return Target_Type;
+       -- Return the link target for NT_Name.
+       -- Returns "     " if NT_Name is not a declared Non_Terminal.
+
+    generic
+       with procedure Format_Text (Text : in String;
+                                   Text_Name : in String);
+    procedure Report;
+       -- Output the fully formatted syntax summary to the
+       -- "Format_Text" routine. "Format_Text" allows all commands
+       -- for the full formatter. (Text_Name is an identifying name
+       -- for error messages).
+
+    generic
+       with procedure Format_Text (Text : in String;
+                                   Text_Name : in String);
+    procedure XRef;
+       -- Output the fully formatted syntax cross-reference to the
+       -- "Format_Text" routine. "Format_Text" allows all commands
+       -- for the full formatter. (Text_Name is an identifying name
+       -- for error messages).
+
+end ARM_Syntax;
+
+
diff --git a/packages/ada-ref-man/progs/arm_texi.adb 
b/packages/ada-ref-man/progs/arm_texi.adb
new file mode 100755
index 0000000..220ef45
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_texi.adb
@@ -0,0 +1,1832 @@
+with Ada.Exceptions;
+with Ada.Strings.Fixed;
+package body ARM_Texinfo is
+
+   --  Copyright (C) 2003, 2007, 2010 - 2013, 2015, 2017 Stephen Leake.  All 
Rights Reserved.
+   --  E-Mail: address@hidden
+   --
+   --  This library is free software; you can redistribute it and/or
+   --  modify it under terms of the GNU General Public License as
+   --  published by the Free Software Foundation; either version 3, or (at
+   --  your option) any later version. This library 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
+   --  distributed with this program; see file gnu-3-0.txt. If not, write to
+   --  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   --  MA 02111-1307, USA.
+
+   -- ---------------------------------------
+   --
+   -- Edit History:
+   --
+   -- Ancient  - S L - Developed package as add-on to Arm_Form.
+   -- 10/19/11 - RLB - Integrated outside-developed package into Arm_Form.
+   --                  Commented out/replaced Ada 2005 features (this is
+   --                  Ada 95 code). Updated for a few other changes since
+   --                  the last update.
+   -- 10/25/11 - RLB - Added old insertion version to Revised_Clause_Header.
+   --  4/ 1/12 - S L - Implemented remaining Texinfo implementation.
+   --  4/22/12 - S L - Move @dircategory, @direntry before first @node.
+   --  4/28/12 - S L - Add @w{} after @anchor; otherwise following whitespace
+   --                  is dropped.
+   --  8/31/12 - RLB - Added Output_Path.
+   -- 10/18/12 - RLB - Added additional hanging styles.
+   -- 11/26/12 - RLB - Added subdivision names to Clause_Header and
+   --                  Revised_Clause_Header.
+   --  3/12/13 - S L - use correct version in direntry
+
+
+   use Ada.Text_IO;
+
+   Indentation : constant := 5;
+
+   --  VERSION: This is fragile; it changes with each version of the manual.
+   Index_Clause_Name : constant String    := "Index";
+   Operators_Clause  : constant String    := "operators";
+   Last_Index_Clause : constant Character := 'Y';
+
+   ----------
+   --  local subprograms
+
+   procedure Check_Not_In_Paragraph (Output_Object : in Texinfo_Output_Type)
+   is begin
+      if Output_Object.In_Paragraph then
+         Ada.Exceptions.Raise_Exception
+           (ARM_Output.Not_Valid_Error'Identity,
+            "In paragraph");
+      end if;
+   end Check_Not_In_Paragraph;
+
+   procedure Check_Valid (Output_Object : in Texinfo_Output_Type)
+   is begin
+      if not Output_Object.Is_Valid then
+         Ada.Exceptions.Raise_Exception
+           (ARM_Output.Not_Valid_Error'Identity,
+            "Not valid object");
+      end if;
+   end Check_Valid;
+
+   procedure Unexpected_State (Output_Object : in Texinfo_Output_Type)
+   is begin
+      Ada.Exceptions.Raise_Exception
+        (ARM_Output.Not_Valid_Error'Identity,
+         "Unexpected state: " & State_Type'Image (Output_Object.State));
+   end Unexpected_State;
+
+   procedure Escape_Put
+     (Output_Object  : in Texinfo_Output_Type;
+      Char           : in Character;
+      Preserve_Space : in Boolean             := False)
+   is begin
+      --  Escape special chars
+      if Char = '@' then
+         Put (Output_Object.File, "@@");
+      elsif Char = '{' then
+         Put (Output_Object.File, "@{");
+      elsif Char = '}' then
+         Put (Output_Object.File, "@}");
+      elsif Char = ''' then
+         --  Avoid makeinfo converting '' into "
+         Put (Output_Object.File, "'@w{}");
+      elsif Char = '`' then
+         --  Avoid makeinfo converting `` into "
+         Put (Output_Object.File, "address@hidden");
+      elsif Char = '-' then
+         Put (Output_Object.File, "@minus{}");
+      elsif Char = ' ' and Preserve_Space then
+         --  Don't allow collapsing spaces
+         Put (Output_Object.File, "@w{ }");
+      elsif Char = '\' then
+         --  This confuses texi2dvi if not escaped.
+         Put (Output_Object.File, "@code{\}");
+      else
+         Put (Output_Object.File, Char);
+      end if;
+   end Escape_Put;
+
+   procedure Escape_Put
+     (Output_Object  : in Texinfo_Output_Type;
+      Text           : in String;
+      Preserve_Space : in Boolean             := False)
+   is begin
+      for I in Text'Range loop
+         Escape_Put (Output_Object, Text (I), Preserve_Space);
+      end loop;
+   end Escape_Put;
+
+   procedure End_Title_Page (Output_Object : in out Texinfo_Output_Type)
+   is
+      use ARM_Contents;
+
+      procedure Put_Top_Menu_Item
+        (Title         : in     Title_Type;
+         Level         : in     Level_Type;
+         Clause_Number : in     Clause_Number_Type;
+         Version       : in     ARM_Contents.Change_Version_Type;
+         Quit          :    out Boolean)
+      is
+         pragma Unreferenced (Version); --  we are only concerned with version 
2
+         First_Part : String (1 .. 14); --  Get all Titles aligned.
+      begin
+         Quit := False;
+
+         case Level is
+         when Section | Normative_Annex | Informative_Annex | Plain_Annex =>
+            Ada.Strings.Fixed.Move
+              (Source =>
+                 "* " &
+                 Make_Clause_Number (Level, Clause_Number) &
+                 " ::",
+               Target => First_Part);
+
+            Put_Line (Output_Object.File, First_Part & Title);
+
+         when Unnumbered_Section | Clause | Subclause | Subsubclause =>
+            null;
+
+         when ARM_Contents.Dead_Clause  =>
+            raise Program_Error with "Dead_Clause header??";
+                -- No headers for dead clauses.
+
+         end case;
+      end Put_Top_Menu_Item;
+
+      procedure Put_Top_Menu is new For_Each (Put_Top_Menu_Item);
+   begin
+
+      New_Line (Output_Object.File); --  Terminate unneeded "@center"
+
+      Put_Line (Output_Object.File, "@menu");
+      Put_Line (Output_Object.File, "* Front Matter:: Copyright, Foreword, 
etc."); --  Not a section in ARM sources
+      Put_Top_Menu;
+      Put_Line (Output_Object.File, "* Index ::    Index"); --  Not in ARM 
sources
+      Put_Line (Output_Object.File, "@end menu");
+
+      -- @node current
+      Put_Line (Output_Object.File, "@node Front Matter");
+      Put_Line (Output_Object.File, "@chapter Front Matter");
+   end End_Title_Page;
+
+   procedure Get_Clause_Section
+     (Clause_String  : in     String;
+      Section_Number :    out ARM_Contents.Section_Number_Type;
+      Clause_Integer :    out Natural)
+   is
+      --  This is a partial inverse of ARM_Contents.Make_Clause_Number.
+      --
+      --  Clause_String has "section.clause.subclause", possibly no subclause.
+      --
+      --  "section" can be a number, a letter "N", or "Annex N", where
+      --
+      --  'N' = Character'Val (Character'Pos('A') + (Section_Number - 
ANNEX_START)
+
+      Section_Dot : constant Natural := Ada.Strings.Fixed.Index (Source => 
Clause_String, Pattern => ".");
+
+      Clause_Dot : constant Natural := Ada.Strings.Fixed.Index
+        (Source => Clause_String (Section_Dot + 1 .. Clause_String'Last),
+         Pattern => ".");
+
+      use type ARM_Contents.Section_Number_Type;
+   begin
+      if Section_Dot = 8 then
+         --  Section is "Annex N"
+         Section_Number := ARM_Contents.ANNEX_START +
+           Character'Pos (Clause_String (Clause_String'First + 6)) - 
Character'Pos ('A');
+      elsif Character'Pos (Clause_String (Clause_String'First)) >= 
Character'Pos ('A') then
+         --  Section is letter.
+         Section_Number := ARM_Contents.ANNEX_START +
+           Character'Pos (Clause_String (Clause_String'First)) - Character'Pos 
('A');
+      else
+         Section_Number := ARM_Contents.Section_Number_Type'Value
+           (Clause_String (Clause_String'First .. Section_Dot - 1));
+      end if;
+
+      if Clause_Dot = 0 then
+         Clause_Integer := Natural'Value
+           (Clause_String (Section_Dot + 1 .. Clause_String'Last));
+      else
+         Clause_Integer := Natural'Value
+           (Clause_String (Section_Dot + 1 .. Clause_Dot - 1));
+      end if;
+   end Get_Clause_Section;
+
+   procedure Handle_Indent
+     (Output_Object : in Texinfo_Output_Type;
+      Texinfo_Item  : in String;
+      Extra_Indent  : in ARM_Output.Paragraph_Indent_Type := 0)
+   is
+      use type ARM_Output.Paragraph_Indent_Type;
+   begin
+      for I in 1 .. Output_Object.Indent + Extra_Indent loop
+         Put_Line (Output_Object.File, Texinfo_Item);
+      end loop;
+   end Handle_Indent;
+
+   procedure Add_To_Column_Item (Output_Object : in out Texinfo_Output_Type; 
Text : in String)
+   is begin
+      if Output_Object.Column_Text (Output_Object.Current_Column) = null or 
else
+        Output_Object.Column_Text (Output_Object.Current_Column).Row /= 
Output_Object.Current_Row
+      then
+         --  Start a new row.
+         Output_Object.Column_Text (Output_Object.Current_Column) :=
+           new Column_Text_Item_Type'
+           (Text   => (others => ' '),
+            Length => 0,
+            Row    => Output_Object.Current_Row,
+            Next   => Output_Object.Column_Text 
(Output_Object.Current_Column));
+      end if;
+
+      if Output_Object.Column_Text (Output_Object.Current_Column).Length + 
Text'Length >
+        Output_Object.Column_Text (Output_Object.Current_Column).Text'Length
+      then
+         Ada.Exceptions.Raise_Exception
+           (ARM_Output.Not_Valid_Error'Identity,
+            "Column item full, but more text: " &
+              Output_Object.Column_Text (Output_Object.Current_Column).Text
+              (1 .. Output_Object.Column_Text 
(Output_Object.Current_Column).Length));
+      else
+         declare
+            Current_Text : Column_Text_Item_Type renames 
Output_Object.Column_Text (Output_Object.Current_Column).all;
+         begin
+            Current_Text.Text (Current_Text.Length + 1 .. Current_Text.Length 
+ Text'Length) := Text;
+
+            Current_Text.Length := Current_Text.Length + Text'Length;
+
+            if Output_Object.Column_Widths (Output_Object.Current_Column) < 
Current_Text.Length then
+               Output_Object.Column_Widths (Output_Object.Current_Column) := 
Current_Text.Length;
+            end if;
+         end;
+      end if;
+   end Add_To_Column_Item;
+
+   procedure Pad_Columns (Output_Object : in out Texinfo_Output_Type)
+   --  Ensure that all columns have the same number of (possibly
+   --  empty) rows, for table headers.
+   is
+      Item          : Column_Text_Ptr;
+      First_New_Row : Natural;
+   begin
+      for Col in 1 .. Output_Object.Column_Count loop
+         Item := Output_Object.Column_Text (Col);
+         if Item = null then
+            First_New_Row := 1;
+         else
+            First_New_Row := Item.Row + 1;
+         end if;
+
+         for I in First_New_Row .. Output_Object.Max_Row loop
+            Output_Object.Column_Text (Col) :=
+              new Column_Text_Item_Type'
+              (Text   => (others => ' '),
+               Length => 1,
+               Row    => I,
+               Next   => Output_Object.Column_Text (Col));
+         end loop;
+      end loop;
+   end Pad_Columns;
+
+   procedure Output_Column_Widths (Output_Object : in out Texinfo_Output_Type)
+   is begin
+      New_Line (Output_Object.File);
+      Put (Output_Object.File, "@multitable ");
+      for I in 1 .. Output_Object.Column_Count loop
+         Put
+           (Output_Object.File,
+            " {" &
+              String'(1 .. Output_Object.Column_Widths (I) => 'w') &
+              "}");
+      end loop;
+   end Output_Column_Widths;
+
+   procedure Output_Columns (Output_Object : in out Texinfo_Output_Type)
+   is
+      Row  : Natural         := 1;
+      Item : Column_Text_Ptr;
+      Temp : Column_Text_Ptr;
+   begin
+      Rows :
+      loop
+         New_Line (Output_Object.File);
+         Put (Output_Object.File, "@item ");
+
+         --  For all columns, output the items for this row. Note that
+         --  the last row is at the front of each column list; the
+         --  first row is at the end. We delete the rows as we output
+         --  them, so the one we want is always at the end of the
+         --  column list.
+         Columns :
+         for Col in 1 .. Output_Object.Column_Count loop
+            Item := Output_Object.Column_Text (Col);
+
+            if Item = null then
+               --  Previously finished column
+               null;
+
+            elsif Item.Next = null then
+               --  This is the last item in the column.
+               if Item.Row /= Row then
+                  --  This column is empty for this row.
+                  Item := null;
+               else
+                  --  Output Item, and mark that we're done outputing
+                  --  this column.
+                  Output_Object.Column_Text (Col) := null;
+               end if;
+            else
+               --  Find first item for this row in the column.
+               while Item.Next /= null and then Item.Next.Row /= Row loop
+                  Item := Item.Next;
+               end loop;
+
+               --  Output Item.Next, take it out of list.
+               Temp      := Item;
+               Item      := Item.Next;
+               Temp.Next := null;
+            end if;
+
+            if Item /= null then
+               --  Output the item
+               Escape_Put (Output_Object, Item.Text (1 .. Item.Length), 
Preserve_Space => True);
+               Free (Item);
+
+               if Col /= Output_Object.Column_Count then
+                  Put (Output_Object.File, " @tab ");
+               end if;
+
+            else
+               --  This column is empty for this row
+               if Col < Output_Object.Column_Count then
+                  Put (Output_Object.File, " @tab ");
+               end if;
+            end if;
+         end loop Columns;
+
+         if Output_Object.Column_Text = Column_Text_Ptrs_Type'(others => null) 
then
+            --  We've output everything.
+            exit Rows;
+         end if;
+
+         --  End the row:
+         Row := Row + 1;
+      end loop Rows;
+   end Output_Columns;
+
+   procedure Index_Menu (Output_Object : in out Texinfo_Output_Type)
+   is begin
+      Put_Line (Output_Object.File, "@menu");
+      Put_Line (Output_Object.File, "* operators::");
+      Put_Line (Output_Object.File, "* A::");
+      Put_Line (Output_Object.File, "* B::");
+      Put_Line (Output_Object.File, "* C::");
+      Put_Line (Output_Object.File, "* D::");
+      Put_Line (Output_Object.File, "* E::");
+      Put_Line (Output_Object.File, "* F::");
+      Put_Line (Output_Object.File, "* G::");
+      Put_Line (Output_Object.File, "* H::");
+      Put_Line (Output_Object.File, "* I::");
+      Put_Line (Output_Object.File, "* J::");
+      Put_Line (Output_Object.File, "* K::");
+      Put_Line (Output_Object.File, "* L::");
+      Put_Line (Output_Object.File, "* M::");
+      Put_Line (Output_Object.File, "* N::");
+      Put_Line (Output_Object.File, "* O::");
+      Put_Line (Output_Object.File, "* P::");
+      Put_Line (Output_Object.File, "* Q::");
+      Put_Line (Output_Object.File, "* R::");
+      Put_Line (Output_Object.File, "* S::");
+      Put_Line (Output_Object.File, "* T::");
+      Put_Line (Output_Object.File, "* U::");
+      Put_Line (Output_Object.File, "* V::");
+      Put_Line (Output_Object.File, "* W::");
+      Put_Line (Output_Object.File, "* X::");
+      Put_Line (Output_Object.File, "* Y::");
+      --  Put_Line (Output_Object.File, "* Z::"); --  VERSION: No entries in Z
+      Put_Line (Output_Object.File, "@end menu");
+
+      --  @node current
+      Put_Line (Output_Object.File, "@node " & Operators_Clause);
+
+      Put_Line (Output_Object.File, "@section operators");
+   end Index_Menu;
+
+   ----------
+   --  Public subprograms. Alphabetical order
+
+   procedure AI_Reference
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String;
+      AI_Number     : in     String)
+   is begin
+      Ordinary_Text (Output_Object, AI_Number & Text);
+   end AI_Reference;
+
+   procedure Category_Header
+     (Output_Object : in out Texinfo_Output_Type;
+      Header_Text   :        String)
+   is begin
+      Check_Not_In_Paragraph (Output_Object);
+
+      --  Can't be in a multi-column setting.
+      --
+      --  Don't use @heading; that causes a weird underline in info,
+      --  that isn't centered!
+      Put_Line (Output_Object.File, "@center @emph{" & Header_Text & "}");
+      New_Line (Output_Object.File, 2);
+   end Category_Header;
+
+   procedure Clause_Header
+     (Output_Object : in out Texinfo_Output_Type;
+      Header_Text   : in     String;
+      Level         : in     ARM_Contents.Level_Type;
+      Clause_Number : in     String;
+      Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+      No_Page_Break : in     Boolean                 := False)
+   is
+      pragma Unreferenced (No_Page_Break);
+      pragma Unreferenced (Top_Level_Subdivision_Name);
+      Title : constant String := Clause_Number & " " & Header_Text;
+
+      use ARM_Contents;
+
+      Section_Number : Section_Number_Type;
+      Clause_Integer : Natural;
+
+      procedure Put_Clause_Menu_Item
+        (Item_Title         : in     Title_Type;
+         Item_Level         : in     Level_Type;
+         Item_Clause_Number : in     Clause_Number_Type;
+         Version            : in     ARM_Contents.Change_Version_Type;
+         Quit               :    out Boolean)
+      is
+         pragma Unreferenced (Version); --  only version 2
+         First_Part : String (1 .. 14); --  Get all Titles aligned.
+      begin
+         Quit := False;
+
+         case Item_Level is
+         when Section | Unnumbered_Section |
+              Normative_Annex | Informative_Annex | Plain_Annex |
+              Subclause | Subsubclause =>
+            --  We are doing Clause here
+            null;
+
+         when Clause  =>
+            if Item_Clause_Number.Section < Section_Number then
+               null;
+
+            elsif Item_Clause_Number.Section = Section_Number then
+               Ada.Strings.Fixed.Move
+                 (Source =>
+                    "* " &
+                    Make_Clause_Number (Item_Level, Item_Clause_Number) &
+                    " ::",
+                  Target => First_Part);
+
+               Put_Line (Output_Object.File, First_Part & Item_Title);
+            else
+               Quit := True;
+            end if;
+         when Dead_Clause =>
+            raise Program_Error with "Dead Clause in menu??"; -- No dead 
clauses should be output.
+         end case;
+      end Put_Clause_Menu_Item;
+
+      procedure Put_Clause_Menu is new For_Each (Put_Clause_Menu_Item);
+
+      procedure Put_Subclause_Menu_Item
+        (Item_Title         : in     Title_Type;
+         Item_Level         : in     Level_Type;
+         Item_Clause_Number : in     Clause_Number_Type;
+         Version            : in     ARM_Contents.Change_Version_Type;
+         Quit               :    out Boolean)
+      is
+         pragma Unreferenced (Version); --  only version 2
+         First_Part : String (1 .. 14); --  Get all Titles aligned.
+      begin
+         Quit := False;
+
+         case Item_Level is
+            when Section | Unnumbered_Section |
+                 Normative_Annex | Informative_Annex | Plain_Annex |
+                 Clause | Subsubclause =>
+               --  We are doing Subclause here
+               null;
+
+         when Subclause  =>
+            if Item_Clause_Number.Section < Section_Number then
+               null;
+
+            elsif Item_Clause_Number.Section = Section_Number then
+               if Item_Clause_Number.Clause < Clause_Integer then
+                  null;
+
+               elsif Item_Clause_Number.Clause = Clause_Integer then
+                  Ada.Strings.Fixed.Move
+                    (Source =>
+                       "* " &
+                       Make_Clause_Number (Item_Level, Item_Clause_Number) &
+                       " ::",
+                     Target => First_Part);
+
+                  Put_Line (Output_Object.File, First_Part & Item_Title);
+               else
+                  Quit := True;
+               end if;
+            else
+               Quit := True;
+            end if;
+         when Dead_Clause =>
+            raise Program_Error with "Dead clause in submenu??"; -- No dead 
clauses should be output.
+         end case;
+      end Put_Subclause_Menu_Item;
+
+      procedure Put_Subclause_Menu is new For_Each (Put_Subclause_Menu_Item);
+
+   begin
+      Check_Not_In_Paragraph (Output_Object);
+
+      --  Handle special cases
+      if Clause_Number = "" and Header_Text = "Table of Contents" then
+         --  Actual contents output in TOC_Marker below.
+         return;
+
+      elsif Header_Text = "The Standard Libraries" then
+         --  This section has no content; don't confuse makeinfo.
+         return;
+
+      elsif Header_Text = Index_Clause_Name then
+
+         Put_Line (Output_Object.File, "@node " & Index_Clause_Name);
+
+         Put_Line (Output_Object.File, "@chapter Index");
+         Output_Object.State := Index_Start;
+
+         return;
+      end if;
+
+      case Level is
+      when Section | Normative_Annex | Informative_Annex | Plain_Annex =>
+         --  Menu of these done at @node Top
+         null;
+
+      when Unnumbered_Section =>
+         --  Unnumbered sections are not in ARM_Contents, but there's
+         --  currently only one of them, so they are not worth adding;
+         --  just hard-code the menu here.
+         Get_Clause_Section (Clause_Number, Section_Number, Clause_Integer);
+
+         if Section_Number = 0 and Clause_Integer = 1 then
+            Put_Line (Output_Object.File, "@menu");
+            Put_Line (Output_Object.File, "* 0.1 :: Foreword to this version 
of the Ada Reference Manual");
+            Put_Line (Output_Object.File, "* 0.2 :: Foreword");
+            Put_Line (Output_Object.File, "* 0.3 :: Introduction");
+            Put_Line (Output_Object.File, "* 0.99 :: International Standard");
+            Put_Line (Output_Object.File, "@end menu");
+         end if;
+
+      when Clause =>
+         --  Output menu of Clauses in this section, if we haven't already
+         Get_Clause_Section (Clause_Number, Section_Number, Clause_Integer);
+
+         if Output_Object.Menu_Section /= Section_Number then
+            Put_Line (Output_Object.File, "@menu");
+            Put_Clause_Menu;
+            Put_Line (Output_Object.File, "@end menu");
+            Output_Object.Menu_Section := Section_Number;
+            Output_Object.Menu_Clause  := 0;
+         end if;
+
+      when Subclause =>
+         --  Output menu of Subclauses in this Clause, if we haven't already
+         Get_Clause_Section (Clause_Number, Section_Number, Clause_Integer);
+
+         if Output_Object.Menu_Section = Section_Number and
+           Output_Object.Menu_Clause /= Clause_Integer
+         then
+            Put_Line (Output_Object.File, "@menu");
+            Put_Subclause_Menu;
+            Put_Line (Output_Object.File, "@end menu");
+            Output_Object.Menu_Clause := Clause_Integer;
+         end if;
+
+      when Subsubclause =>
+         Ada.Exceptions.Raise_Exception
+           (ARM_Output.Not_Valid_Error'Identity,
+            "Clause_Header: Subsubclause");
+
+      when Dead_Clause =>
+         Ada.Exceptions.Raise_Exception
+           (ARM_Output.Not_Valid_Error'Identity,
+            "Clause_Header: Dead_clause");
+
+      end case;
+
+      Put_Line (Output_Object.File, "@node " & Clause_Number);
+
+      case Level is
+      when Section =>
+         Put_Line (Output_Object.File, "@chapter " & Title);
+
+      when Normative_Annex | Informative_Annex | Plain_Annex =>
+         Put_Line (Output_Object.File, "@chapter " & Title);
+
+      when Clause | Unnumbered_Section =>
+         Put_Line (Output_Object.File, "@section " & Title);
+
+      when Subclause =>
+         Put_Line (Output_Object.File, "@subsection " & Title);
+
+      when Subsubclause =>
+         Put_Line (Output_Object.File, "@subsubsection " & Title);
+
+      when Dead_Clause =>
+         raise Program_Error with "Dead_Clause in header?"; -- No output of 
dead clauses.
+      end case;
+
+   end Clause_Header;
+
+   procedure Clause_Reference
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String;
+      Clause_Number : in     String)
+   is begin
+      case Output_Object.State is
+      when Contents =>
+         null;
+
+      when Multi_Column | Table_Header =>
+         --  If this happens, we need to store escaped text in columns.
+         Ada.Exceptions.Raise_Exception
+           (ARM_Output.Not_Valid_Error'Identity,
+            "clause reference in multi-column");
+
+      when Normal =>
+         if Text = Clause_Number then
+            Put
+              (Output_Object.File,
+               "@ref{" &
+                 Clause_Number &
+                 "}");
+         else
+            Put
+              (Output_Object.File,
+               "@ref{" &
+                 Clause_Number &
+                 "} " &
+                 Text);
+         end if;
+
+      when Title | Index_Start | Index =>
+         Unexpected_State (Output_Object);
+
+      end case;
+   end Clause_Reference;
+
+   procedure Close (Output_Object : in out Texinfo_Output_Type)
+   is begin
+      Check_Valid (Output_Object);
+
+      Put_Line (Output_Object.File, "@bye");
+
+      Close (Output_Object.File);
+
+      Output_Object.Is_Valid := False;
+   end Close;
+
+   procedure Create
+     (Output_Object  : in out Texinfo_Output_Type;
+      File_Prefix    : in     String;
+      Output_Path    : in     String;
+      Change_Version : in     ARM_Contents.Change_Version_Type;
+      Title          : in     String)
+   is
+      File_Name : constant String := Output_Path &
+         Ada.Strings.Fixed.Trim (File_Prefix, Ada.Strings.Right) &
+         ".texinfo";
+   begin
+      if Output_Object.Is_Valid then
+         Ada.Exceptions.Raise_Exception
+           (ARM_Output.Not_Valid_Error'Identity,
+            "Already valid object");
+      end if;
+
+      Output_Object.Is_Valid := True;
+
+      Create (Output_Object.File, Out_File, File_Name);
+
+      Put_Line (Output_Object.File, "\input texinfo");
+      Put_Line (Output_Object.File, "@documentencoding ISO-8859-1");
+      Put_Line (Output_Object.File, "@dircategory GNU Ada tools");
+
+      Put_Line (Output_Object.File, "@direntry");
+      case Change_Version is
+         when '2' =>
+            Put_Line (Output_Object.File, "* Ada Reference Manual: 
(arm2005).");
+            Put_Line (Output_Object.File, "* Annotated ARM: (arm2005).");
+         when '3' =>
+            Put_Line (Output_Object.File, "* Ada Reference Manual: 
(arm2012).");
+            Put_Line (Output_Object.File, "* Annotated ARM: (arm2012).");
+         when '4' =>
+            Put_Line (Output_Object.File, "* Ada Reference Manual TC1: 
(arm2012).");
+            Put_Line (Output_Object.File, "* Annotated ARM TC1: (arm2012).");
+         when others =>
+            Ada.Exceptions.Raise_Exception
+              (ARM_Output.Not_Valid_Error'Identity,
+               "unsupported Change_Version");
+      end case;
+      Put_Line (Output_Object.File, "@end direntry");
+
+      Put_Line (Output_Object.File, "@settitle " & Title);
+      Put_Line (Output_Object.File, "@paragraphindent none");
+      Put_Line (Output_Object.File, "@exampleindent" & Integer'Image 
(Indentation));
+
+      Put_Line (Output_Object.File, "@node Top");
+      Put_Line (Output_Object.File, "@top " & Title);
+
+      Output_Object.State           := ARM_Texinfo.Title;
+      Output_Object.First_Word_Last := 0;
+
+   end Create;
+
+   procedure DR_Reference
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String;
+      DR_Number     : in     String)
+   is begin
+      Ordinary_Text (Output_Object, DR_Number & Text);
+   end DR_Reference;
+
+   procedure End_Hang_Item (Output_Object : in out Texinfo_Output_Type)
+   is
+      use ARM_Output;
+   begin
+      Output_Object.End_Hang_Seen := True;
+
+      case Output_Object.Style is
+         when Normal |
+           Wide_Above |
+           Small |
+           Small_Wide_Above |
+           Header |
+           Small_Header |
+           Syntax_Summary =>
+
+            Handle_Indent (Output_Object, "@quotation");
+
+         when Index |
+           Title =>
+            null;
+
+         when Examples |
+           Small_Examples |
+           Swiss_Examples |
+           Small_Swiss_Examples =>
+
+            Handle_Indent (Output_Object, "@example");
+
+         when Bulleted |
+           Small_Bulleted =>
+
+            Handle_Indent (Output_Object, "@itemize");
+
+         when Nested_Bulleted |
+           Small_Nested_Bulleted =>
+
+            Handle_Indent (Output_Object, "@itemize", Extra_Indent => 1);
+
+         when Enumerated |
+           Small_Enumerated =>
+
+            --  Number has just been output; start text.
+            Put (Output_Object.File, "@w{  }");
+
+         when Giant_Hanging |
+           Small_Giant_Hanging |
+           Wide_Hanging |
+           Small_Wide_Hanging |
+           Medium_Hanging |
+           Small_Medium_Hanging |
+           Narrow_Hanging |
+           Small_Narrow_Hanging |
+           Hanging_in_Bulleted |
+           Small_Hanging_in_Bulleted =>
+
+            New_Line (Output_Object.File);
+            Handle_Indent (Output_Object, "@quotation");
+
+      end case;
+
+   end End_Hang_Item;
+
+   procedure Text_Format
+     (Output_Object : in out Texinfo_Output_Type;
+      Format        : in     ARM_Output.Format_Type)
+   is begin
+      null;
+   end Text_Format;
+
+   procedure End_Paragraph (Output_Object : in out Texinfo_Output_Type)
+   is
+      use ARM_Output;
+   begin
+      Output_Object.In_Paragraph := False;
+
+      case Output_Object.State is
+      when Contents =>
+         null;
+
+      when Multi_Column =>
+         --  Skip a row, to separate paragraphs in a column.
+         Output_Object.Current_Row := Output_Object.Current_Row + 2;
+
+      when Title =>
+         if Output_Object.Line_Empty then
+            null;
+         else
+            New_Line (Output_Object.File, 2);
+            Put (Output_Object.File, "@center ");
+            Output_Object.Line_Empty := True;
+         end if;
+
+      when Normal =>
+         case Output_Object.Style is
+         when Normal |
+           Wide_Above |
+           Small |
+           Small_Wide_Above |
+           Header |
+           Small_Header |
+           Syntax_Summary =>
+
+            New_Line (Output_Object.File);
+            Handle_Indent (Output_Object, "@end quotation");
+            New_Line (Output_Object.File);
+
+         when Index |
+           Title =>
+
+            New_Line (Output_Object.File, 2);
+
+         when Examples |
+           Small_Examples |
+           Swiss_Examples |
+           Small_Swiss_Examples =>
+
+            New_Line (Output_Object.File);
+            Handle_Indent (Output_Object, "@end example");
+            New_Line (Output_Object.File);
+
+         when Bulleted |
+           Small_Bulleted =>
+
+            New_Line (Output_Object.File);
+            Handle_Indent (Output_Object, "@end itemize");
+            New_Line (Output_Object.File);
+
+         when Nested_Bulleted |
+           Small_Nested_Bulleted =>
+
+            New_Line (Output_Object.File);
+            Handle_Indent (Output_Object, "@end itemize", Extra_Indent => 1);
+            New_Line (Output_Object.File);
+
+         when Enumerated |
+           Small_Enumerated =>
+
+            New_Line (Output_Object.File);
+            Handle_Indent (Output_Object, "@end itemize");
+            New_Line (Output_Object.File);
+
+         when Giant_Hanging |
+           Small_Giant_Hanging |
+           Wide_Hanging |
+           Small_Wide_Hanging |
+           Medium_Hanging |
+           Small_Medium_Hanging |
+           Narrow_Hanging |
+           Small_Narrow_Hanging |
+           Hanging_in_Bulleted |
+           Small_Hanging_in_Bulleted =>
+
+            New_Line (Output_Object.File);
+            if Output_Object.End_Hang_Seen then
+               Handle_Indent (Output_Object, "@end quotation");
+            end if;
+            New_Line (Output_Object.File);
+
+         end case;
+
+      when Index_Start =>
+         Output_Object.State := Index;
+
+         Index_Menu (Output_Object);
+
+      when Index =>
+         --  Keep index items tightly grouped.
+         Put_Line (Output_Object.File, "@*");
+
+      when Table_Header =>
+         Unexpected_State (Output_Object);
+
+      end case;
+   end End_Paragraph;
+
+   procedure Hard_Space (Output_Object : in out Texinfo_Output_Type)
+   is begin
+      case Output_Object.State is
+      when Contents =>
+         null;
+
+      when Multi_Column | Table_Header =>
+         --  Can't do line breaks in columns
+         Add_To_Column_Item (Output_Object, " ");
+
+      when Title =>
+         if Output_Object.Line_Empty then
+            null;
+         else
+            Put (Output_Object.File, "@w{ }");
+         end if;
+
+      when Normal | Index_Start | Index =>
+         Put (Output_Object.File, "@w{ }");
+      end case;
+   end Hard_Space;
+
+   procedure Index_Line_Break
+     (Output_Object        : in out Texinfo_Output_Type;
+      Clear_Keep_with_Next : in     Boolean)
+   is
+      pragma Unreferenced (Clear_Keep_with_Next);
+   begin
+      Put_Line (Output_Object.File, "@*");
+   end Index_Line_Break;
+
+   procedure Index_Reference
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String;
+      Index_Key     : in     Natural;
+      Clause_Number : in     String)
+   is
+      pragma Unreferenced (Clause_Number);
+      --  Text is clause_number & paragraph number (optional).
+   begin
+      Put (Output_Object.File, "@ref{" & Integer'Image (Index_Key) & ", " & 
Text & "}");
+   end Index_Reference;
+
+   procedure Index_Target
+     (Output_Object : in out Texinfo_Output_Type;
+      Index_Key     : in     Natural)
+   is begin
+      --  Add an empty non-break object, because @anchor ignores
+      --  whitespace after it, which often occurs in the current
+      --  Scribe-like source.
+      Put (Output_Object.File, "@anchor{" & Integer'Image (Index_Key) & 
"address@hidden");
+   end Index_Target;
+
+   procedure Line_Break (Output_Object : in out Texinfo_Output_Type)
+   is
+      use ARM_Output;
+   begin
+      case Output_Object.State is
+      when Title =>
+         if Output_Object.Line_Empty then
+            null;
+         else
+            Put_Line (Output_Object.File, "@*");
+            Output_Object.Line_Empty := True;
+         end if;
+
+      when Contents =>
+         null;
+
+      when Multi_Column | Table_Header =>
+         Output_Object.Current_Row := Output_Object.Current_Row + 1;
+         if Output_Object.Max_Row < Output_Object.Current_Row then
+            Output_Object.Max_Row := Output_Object.Current_Row;
+         end if;
+
+      when Index_Start =>
+         --  This doesn't happen
+         Ada.Exceptions.Raise_Exception
+           (ARM_Output.Not_Valid_Error'Identity,
+            "Line_Break Index_Start");
+
+      when Normal | Index =>
+         case Output_Object.Style is
+         when Normal |
+           Wide_Above |
+           Small |
+           Small_Wide_Above |
+           Header |
+           Small_Header |
+           Syntax_Summary |
+           Index |
+           Title =>
+
+            Put_Line (Output_Object.File, "@*");
+
+         when Examples |
+           Small_Examples |
+           Swiss_Examples |
+           Small_Swiss_Examples =>
+
+            New_Line (Output_Object.File);
+
+         when Bulleted |
+           Small_Bulleted |
+           Nested_Bulleted |
+           Small_Nested_Bulleted |
+           Enumerated |
+           Small_Enumerated |
+           Giant_Hanging |
+           Small_Giant_Hanging |
+           Wide_Hanging |
+           Small_Wide_Hanging |
+           Medium_Hanging |
+           Small_Medium_Hanging |
+           Narrow_Hanging |
+           Small_Narrow_Hanging |
+           Hanging_in_Bulleted |
+           Small_Hanging_in_Bulleted =>
+
+            Put_Line (Output_Object.File, "@*");
+
+         end case;
+
+      end case;
+   end Line_Break;
+
+   procedure Local_Link
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String;
+      Target        : in     String;
+      Clause_Number : in     String)
+   is
+      pragma Unreferenced (Target);
+      pragma Unreferenced (Clause_Number);
+   begin
+      --  These are typically references to words in the grammar
+      --  summary. Mildly useful, but the best we can do is:
+      --
+      --  "@ref{" & Target & "," & Text & "}"
+      --
+      --  makeinfo prepends 'see' and postpends '.', so it screws up
+      --  the text. For example, section 2.1 (1) ends up with "the
+      --  @ref{S0229, compilation}s." => "the see compilation: S0229."
+      --  Emacs info-mode suppresses the ': S0229', but not the 'see'
+      --  and the trailing '.'. So we just output the text.
+      Ordinary_Text (Output_Object, Text);
+   end Local_Link;
+
+   procedure Local_Link_End
+     (Output_Object : in out Texinfo_Output_Type;
+      Target        : in     String;
+      Clause_Number : in     String)
+   is begin
+      --  These work better than local links, because they are not in
+      --  the middle of plurals. First use is section 3.1 (1).
+      Put (Output_Object.File, " (@pxref{" & Target & "," & Clause_Number & 
"})");
+   end Local_Link_End;
+
+   procedure Local_Link_Start
+     (Output_Object : in out Texinfo_Output_Type;
+      Target        : in     String;
+      Clause_Number : in     String)
+   is
+      pragma Unreferenced (Output_Object);
+      pragma Unreferenced (Target);
+      pragma Unreferenced (Clause_Number);
+   begin
+      --  implemented in Local_Link_End
+      null;
+   end Local_Link_Start;
+
+   procedure Local_Target
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String;
+      Target        : in     String)
+   is begin
+      --  Add an empty non-break object, because @anchor ignores
+      --  whitespace after it, which often occurs in the current
+      --  Scheme source.
+      Put (Output_Object.File, "@anchor{" & Target & "address@hidden");
+      Ordinary_Text (Output_Object, Text);
+   end Local_Target;
+
+   procedure New_Column (Output_Object : in out Texinfo_Output_Type)
+   is begin
+      if Output_Object.Column_Count >= 4 then
+         Output_Object.Current_Column := Output_Object.Current_Column + 1;
+         Output_Object.Current_Row    := 1;
+      end if;
+   end New_Column;
+
+   procedure New_Page
+     (Output_Object : in out Texinfo_Output_Type;
+      Kind          :        ARM_Output.Page_Kind_Type := ARM_Output.Any_Page)
+   is
+      pragma Unreferenced (Kind);
+      pragma Unreferenced (Output_Object);
+   begin
+      --  No such thing in Info.
+      null;
+   end New_Page;
+
+   procedure Ordinary_Character
+     (Output_Object : in out Texinfo_Output_Type;
+      Char          : in     Character)
+   is
+      Copyright : constant String := "Copyright";
+   begin
+      case Output_Object.State is
+      when Contents =>
+         null;
+
+      when Multi_Column | Table_Header =>
+         Add_To_Column_Item (Output_Object, "" & Char);
+
+      when Title =>
+         --  Check for end of title page; indicated by line starting with 
"Copyright"
+         if Output_Object.Line_Empty then
+            if Output_Object.First_Word_Last > 0 then
+               if Copyright (Output_Object.First_Word_Last + 1) = Char then
+                  Output_Object.First_Word_Last := 
Output_Object.First_Word_Last + 1;
+                  Output_Object.First_Word (Output_Object.First_Word_Last) := 
Char;
+
+                  if Output_Object.First_Word_Last = Copyright'Last then
+                     End_Title_Page (Output_Object);
+                     Output_Object.State := Normal;
+                     Ordinary_Text (Output_Object, Output_Object.First_Word (1 
.. Output_Object.First_Word_Last));
+                  end if;
+               else
+                  --  First word is not Copyright; output it
+                  Ordinary_Text (Output_Object, Output_Object.First_Word (1 .. 
Output_Object.First_Word_Last));
+                  Output_Object.Line_Empty := False;
+               end if;
+            else
+               --  No non-space seen yet
+               if Char = ' ' then
+                  null;
+               elsif Char = Copyright (1) then
+                  Output_Object.First_Word_Last := 1;
+                  Output_Object.First_Word (1)  := Char;
+               else
+                  Escape_Put (Output_Object, Char);
+                  Output_Object.Line_Empty := False;
+               end if;
+            end if;
+         else
+            --  Line already has stuff on it
+            Escape_Put (Output_Object, Char);
+         end if;
+
+      when Normal =>
+         Output_Object.Line_Empty := Char /= ' ';
+
+         Escape_Put (Output_Object, Char);
+
+      when Index_Start =>
+         Escape_Put (Output_Object, Char);
+         if Char = '&' then
+            --  give debugger a place to break
+            Put_Line ("first index entry");
+         end if;
+
+      when Index =>
+         case Char is
+         when ' ' | ',' | '[' | ']' =>
+            Put (Output_Object.File, Char);
+
+         when 'A' .. Last_Index_Clause =>
+            --  Index section heading
+
+            --  @node current
+            Put_Line (Output_Object.File, "@node " & Char);
+
+            --  Add non-break space so Emacs info will use big bold
+            --  font for single letter titles.
+            Put_Line (Output_Object.File, "@section " & Char & "@w{ }");
+
+         when others =>
+            Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity, "Unexpected char in Index: " & Char);
+         end case;
+      end case;
+   end Ordinary_Character;
+
+   procedure Ordinary_Text
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String)
+   is begin
+      case Output_Object.State is
+      when Contents =>
+         null;
+
+      when Multi_Column | Table_Header =>
+         Add_To_Column_Item (Output_Object, Text);
+
+      when Normal | Title | Index_Start | Index =>
+         Output_Object.Line_Empty := False;
+
+         Escape_Put (Output_Object, Text);
+      end case;
+   end Ordinary_Text;
+
+   procedure Picture
+     (Output_Object : in out Texinfo_Output_Type;
+      Name          : in     String;
+      Descr         : in     String;
+      Alignment     : in     ARM_Output.Picture_Alignment;
+      Height, Width : in     Natural;
+      Border        : in     ARM_Output.Border_Kind)
+   is
+      pragma Unreferenced (Border);
+      pragma Unreferenced (Width);
+      pragma Unreferenced (Height);
+      pragma Unreferenced (Alignment);
+      pragma Unreferenced (Name);
+   begin
+      Ada.Exceptions.Raise_Exception
+        (ARM_Output.Not_Valid_Error'Identity,
+         "Picture: " & Descr);
+   end Picture;
+
+   procedure Revised_Clause_Header
+     (Output_Object   : in out Texinfo_Output_Type;
+      New_Header_Text : in     String;
+      Old_Header_Text : in     String;
+      Level           : in     ARM_Contents.Level_Type;
+      Clause_Number   : in     String;
+      Version         : in     ARM_Contents.Change_Version_Type;
+      Old_Version     : in     ARM_Contents.Change_Version_Type;
+      Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+      No_Page_Break   : in     Boolean                          := False)
+   is
+      pragma Unreferenced (Version);
+      pragma Unreferenced (Old_Version);
+      pragma Unreferenced (Old_Header_Text);
+   begin
+      Clause_Header (Output_Object, New_Header_Text, Level, Clause_Number,
+                     Top_Level_Subdivision_Name, No_Page_Break);
+   end Revised_Clause_Header;
+
+   procedure Section
+     (Output_Object : in out Texinfo_Output_Type;
+      Section_Title : in     String;
+      Section_Name  : in     String)
+   is
+      pragma Unreferenced (Section_Name);
+      pragma Unreferenced (Section_Title);
+      pragma Unreferenced (Output_Object);
+   begin
+      --  This is redundant with the various Clause functions
+      null;
+   end Section;
+
+   procedure Separator_Line
+     (Output_Object : in out Texinfo_Output_Type;
+      Is_Thin       :        Boolean             := True)
+   is begin
+      --  Can't be in a multi-column setting.
+      New_Line (Output_Object.File);
+      if Is_Thin then
+         Put_Line (Output_Object.File, "----------");
+      else
+         Put_Line (Output_Object.File, "==========");
+      end if;
+   end Separator_Line;
+
+   procedure Set_Columns
+     (Output_Object     : in out Texinfo_Output_Type;
+      Number_of_Columns : in     ARM_Output.Column_Count)
+   is begin
+      Check_Valid (Output_Object);
+      Check_Not_In_Paragraph (Output_Object);
+
+      --  2 and 3 column formats are displayed without any columns.
+      --  This is mainly used for the syntax cross-reference and
+      --  index, and these definitely look better without columns.
+      --
+      --  4 or more columns are output as a table. Note that we assume
+      --  such items are formated with explicit New_Column calls, and
+      --  do not contain any nested paragraph formats.
+
+      case Output_Object.State is
+      when Normal =>
+         if Number_of_Columns >= 4 then
+            Output_Object.State          := Multi_Column;
+            Output_Object.Current_Column := 1;
+            Output_Object.Current_Row    := 1;
+            Output_Object.Column_Widths  := (others => 0);
+
+            --  Accumulate all column rows in Output_Text, then output
+            --  when done, so we can set the correct column width in
+            --  the header. Each column is a linked list of allocated
+            --  Column_Text_Item_Type.
+         else
+            null;
+         end if;
+
+      when Multi_Column =>
+         if Number_of_Columns = 1 then
+            --  Finished accumulating columns, output the columns as a table.
+            Output_Column_Widths (Output_Object);
+            Output_Columns (Output_Object);
+            New_Line (Output_Object.File);
+            Put_Line (Output_Object.File, "@end multitable");
+            New_Line (Output_Object.File);
+
+            Output_Object.State := Normal;
+         else
+            Ada.Exceptions.Raise_Exception
+              (ARM_Output.Not_Valid_Error'Identity, "New multi-column section 
before end of old");
+         end if;
+
+      when Index_Start | Index =>
+         null;
+
+      when Table_Header | Contents | Title =>
+         Unexpected_State (Output_Object);
+      end case;
+
+      Output_Object.Column_Count := Number_of_Columns;
+   end Set_Columns;
+
+   procedure Soft_Hyphen_Break (Output_Object : in out Texinfo_Output_Type)
+   is begin
+      Put (Output_Object.File, "@-");
+   end Soft_Hyphen_Break;
+
+   procedure Soft_Line_Break (Output_Object : in out Texinfo_Output_Type)
+   is begin
+      case Output_Object.State is
+      when Contents | Title =>
+         null;
+
+      when Normal | Index_Start | Index =>
+         Put (Output_Object.File, "@-");
+
+      when Multi_Column | Table_Header =>
+         Unexpected_State (Output_Object);
+
+      end case;
+   end Soft_Line_Break;
+
+   procedure Special_Character
+     (Output_Object : in out Texinfo_Output_Type;
+      Char          : in     ARM_Output.Special_Character_Type)
+   is begin
+      --  We use Ordinary_Text, so this is output to columns when appropriate.
+      case Char is
+      when ARM_Output.EM_Dash =>
+         Ordinary_Text (Output_Object, "--");
+      when ARM_Output.EN_Dash =>
+         Ordinary_Text (Output_Object, "-"); -- used for '-' in 
binary_adding_operator
+      when ARM_Output.GEQ =>
+         Ordinary_Text (Output_Object, ">=");
+      when ARM_Output.LEQ =>
+         Ordinary_Text (Output_Object, "<=");
+      when ARM_Output.NEQ =>
+         Ordinary_Text (Output_Object, "/=");
+      when ARM_Output.PI =>
+         Ordinary_Text (Output_Object, "PI");
+
+      when ARM_Output.Left_Ceiling =>
+         case Output_Object.State is
+         when Multi_Column | Table_Header =>
+            Ada.Exceptions.Raise_Exception
+              (ARM_Output.Not_Valid_Error'Identity,
+               "Info does not support ceiling in multi-column");
+         when Contents =>
+            null;
+
+         when Normal | Index_Start | Index =>
+            Put (Output_Object.File, "@code{ceiling(");
+
+         when Title =>
+            Unexpected_State (Output_Object);
+
+         end case;
+
+      when ARM_Output.Right_Ceiling =>
+         case Output_Object.State is
+         when Multi_Column | Table_Header =>
+            Ada.Exceptions.Raise_Exception
+              (ARM_Output.Not_Valid_Error'Identity,
+               "Info does not support ceiling in multi-column");
+         when Contents =>
+            null;
+
+         when Normal | Index_Start | Index =>
+            Put (Output_Object.File, ")}");
+
+         when Title =>
+            Unexpected_State (Output_Object);
+
+         end case;
+
+      when ARM_Output.Left_Floor =>
+         case Output_Object.State is
+         when Multi_Column | Table_Header =>
+            Ada.Exceptions.Raise_Exception
+              (ARM_Output.Not_Valid_Error'Identity,
+               "Info does not support floor in multi-column");
+         when Contents =>
+            null;
+
+         when Normal | Index_Start | Index =>
+            Put (Output_Object.File, "@code{floor(");
+
+         when Title =>
+            Unexpected_State (Output_Object);
+
+         end case;
+
+      when ARM_Output.Right_Floor =>
+         case Output_Object.State is
+         when Multi_Column | Table_Header =>
+            Ada.Exceptions.Raise_Exception
+              (ARM_Output.Not_Valid_Error'Identity,
+               "Info does not support floor in multi-column");
+         when Contents =>
+            null;
+
+         when Normal | Index_Start | Index =>
+            Put (Output_Object.File, ")}");
+
+         when Title =>
+            Unexpected_State (Output_Object);
+
+         end case;
+
+      when ARM_Output.Thin_Space =>
+         Ordinary_Text (Output_Object, " ");
+
+      when ARM_Output.Left_Quote =>
+         Ordinary_Text (Output_Object, "`");
+
+      when ARM_Output.Right_Quote =>
+         Ordinary_Text (Output_Object, "'");
+
+      when ARM_Output.Left_Double_Quote =>
+         Ordinary_Text (Output_Object, """");
+
+      when ARM_Output.Right_Double_Quote =>
+         Ordinary_Text (Output_Object, """");
+
+      when ARM_Output.Small_Dotless_I =>
+         Ordinary_Text (Output_Object, "i");
+
+      when ARM_Output.Capital_Dotted_I =>
+         Ordinary_Text (Output_Object, "I");
+      end case;
+   end Special_Character;
+
+   procedure Start_Paragraph
+     (Output_Object  : in out Texinfo_Output_Type;
+      Style          : in     ARM_Output.Paragraph_Style_Type;
+      Indent         : in     ARM_Output.Paragraph_Indent_Type;
+      Number         : in     String;
+      No_Prefix      : in     Boolean                       := False;
+      Tab_Stops      : in     ARM_Output.Tab_Info           := 
ARM_Output.NO_TABS;
+      No_Breaks      : in     Boolean                       := False;
+      Keep_with_Next : in     Boolean                       := False;
+      Space_After    : in     ARM_Output.Space_After_Type   := 
ARM_Output.Normal;
+      Justification  : in     ARM_Output.Justification_Type := 
ARM_Output.Default)
+   is
+      pragma Unreferenced (Justification);
+      pragma Unreferenced (Space_After);
+      pragma Unreferenced (Keep_with_Next);
+      pragma Unreferenced (No_Breaks);
+      pragma Unreferenced (Tab_Stops);
+
+      use ARM_Output;
+
+   begin
+      Check_Valid (Output_Object);
+      Check_Not_In_Paragraph (Output_Object);
+
+      --  Note: makeinfo will do most of the formatting, so No_Breaks,
+      --  Keep_with_Next, Space_After, and Justification have no
+      --  effect here. In addition, info format has no support for
+      --  fonts, so the font aspects of Style are ignored as well. But
+      --  we try to respect the indentation and margin aspects.
+
+      --  TexInfo does not directly support tabs, but does use a fixed
+      --  font, so we could emulate them. But then we'd have to track
+      --  output characters; let's see if we really need it.
+
+      case Output_Object.State is
+      when Contents =>
+         null;
+
+      when Normal =>
+         if Number'Length > 0 then
+            Put_Line (Output_Object.File, Number & " @*");
+         end if;
+
+         Output_Object.In_Paragraph := True;
+         Output_Object.Style        := Style;
+         Output_Object.Indent       := Indent;
+
+         case Style is
+         when Normal |
+           Wide_Above |
+           Small |
+           Small_Wide_Above |
+           Header |
+           Small_Header |
+           Syntax_Summary  =>
+
+            Handle_Indent (Output_Object, "@quotation");
+
+         when Index |
+           Title =>
+
+            null;
+
+         when Examples |
+           Small_Examples |
+           Swiss_Examples |
+           Small_Swiss_Examples =>
+
+            Handle_Indent (Output_Object, "@example");
+
+         when Bulleted |
+           Small_Bulleted =>
+
+            Handle_Indent (Output_Object, "@itemize @bullet");
+            if not No_Prefix then
+               Put (Output_Object.File, "@item ");
+            end if;
+
+         when Nested_Bulleted |
+           Small_Nested_Bulleted =>
+
+            Handle_Indent (Output_Object, "@itemize @bullet", Extra_Indent => 
1);
+            if not No_Prefix then
+               Put (Output_Object.File, "@item ");
+            end if;
+
+         when Enumerated |
+           Small_Enumerated =>
+
+            Handle_Indent (Output_Object, "@itemize @w{}");
+            Put (Output_Object.File, "@item ");
+
+         when Giant_Hanging |
+           Small_Giant_Hanging |
+           Wide_Hanging |
+           Small_Wide_Hanging |
+           Medium_Hanging |
+           Small_Medium_Hanging |
+           Narrow_Hanging |
+           Small_Narrow_Hanging |
+           Hanging_in_Bulleted |
+           Small_Hanging_in_Bulleted =>
+
+            if No_Prefix then
+               --  Still in hanging part
+               Handle_Indent (Output_Object, "@quotation");
+               Output_Object.End_Hang_Seen := True;
+            else
+               Output_Object.End_Hang_Seen := False;
+            end if;
+
+         end case;
+
+      when Index_Start | Index | Title | Multi_Column | Table_Header =>
+         if Number'Length > 0 then
+            Unexpected_State (Output_Object);
+         end if;
+
+         Output_Object.In_Paragraph := True;
+         Output_Object.Style        := Style;
+         Output_Object.Indent       := Indent;
+
+      end case;
+
+   end Start_Paragraph;
+
+   procedure Start_Table
+     (Output_Object      : in out Texinfo_Output_Type;
+      Columns            : in     ARM_Output.Column_Count;
+      First_Column_Width : in     ARM_Output.Column_Count;
+      Last_Column_Width  : in     ARM_Output.Column_Count;
+      Alignment          : in     ARM_Output.Column_Text_Alignment;
+      No_Page_Break      : in     Boolean;
+      Has_Border         : in     Boolean;
+      Small_Text_Size    : in     Boolean;
+      Header_Kind        : in     ARM_Output.Header_Kind_Type)
+   is
+      pragma Unreferenced (Small_Text_Size);
+      pragma Unreferenced (Has_Border);
+      pragma Unreferenced (No_Page_Break);
+      pragma Unreferenced (Alignment);
+      pragma Unreferenced (Last_Column_Width);
+      pragma Unreferenced (First_Column_Width);
+      use ARM_Output;
+   begin
+      Output_Object.Column_Count := Columns;
+      case Header_Kind is
+      when Both_Caption_and_Header =>
+         New_Line (Output_Object.File);
+         --  Next text output will be the caption, which we don't
+         --  format in any special way (first example is F.3.2 (19)).
+         --  Then Table_Marker (End_Caption) is called, which will
+         --  start the actual table.
+
+      when Header_Only =>
+         --  Same as Table_Marker, End_Caption.
+         case Columns is
+         when 1 =>
+            Ada.Exceptions.Raise_Exception
+              (ARM_Output.Not_Valid_Error'Identity,
+               "Table with 1 column");
+
+         when 2 =>
+            New_Line (Output_Object.File);
+            Put_Line (Output_Object.File, "@table @asis");
+
+         when others =>
+            New_Line (Output_Object.File);
+            Put (Output_Object.File, "@multitable");
+            Output_Object.State          := Table_Header;
+            Output_Object.Current_Column := 1;
+            Output_Object.Current_Row    := 1;
+            Output_Object.Max_Row        := 0;
+            --  The next text output via Ordinary_Text or
+            --  Ordinary_Character is the table headers. We
+            --  capture them in Output_Object.Column_Text, and
+            --  use them to set the table column widths.
+         end case;
+
+      when No_Headers =>
+         null;
+
+      end case;
+   end Start_Table;
+
+   procedure Tab (Output_Object : in out Texinfo_Output_Type)
+   is begin
+      case Output_Object.State is
+      when Contents =>
+         null;
+
+      when Multi_Column | Table_Header =>
+         Ada.Exceptions.Raise_Exception
+           (ARM_Output.Not_Valid_Error'Identity,
+            "Tab in multi-column");
+
+      when Title =>
+         if Output_Object.Line_Empty then
+            null;
+         else
+            Put (Output_Object.File, "@w{ }");
+         end if;
+
+      when Normal | Index_Start | Index =>
+         --  Just three spaces for now, for indented trees
+         Put (Output_Object.File, "@w{   }");
+
+      end case;
+   end Tab;
+
+   procedure Table_Marker
+     (Output_Object : in out Texinfo_Output_Type;
+      Marker        : in     ARM_Output.Table_Marker_Type)
+   is begin
+      case Marker is
+      when ARM_Output.End_Caption =>
+         --  Start the actual table
+         case Output_Object.Column_Count is
+         when 1 =>
+            Ada.Exceptions.Raise_Exception
+              (ARM_Output.Not_Valid_Error'Identity,
+               "Table with 1 column");
+
+         when 2 =>
+            New_Line (Output_Object.File);
+            Put_Line (Output_Object.File, "@table @asis");
+
+         when others =>
+            New_Line (Output_Object.File);
+            Put (Output_Object.File, "@multitable");
+            Output_Object.State          := Table_Header;
+            Output_Object.Current_Column := 1;
+            Output_Object.Current_Row    := 1;
+            Output_Object.Max_Row        := 0;
+            --  The next text output via Ordinary_Text or
+            --  Ordinary_Character is the table headers. We
+            --  capture them in Output_Object.Column_Text, and
+            --  use them to set the table column widths.
+         end case;
+
+      when ARM_Output.End_Item =>
+         case Output_Object.State is
+         when Table_Header =>
+            Output_Object.Current_Column := Output_Object.Current_Column + 1;
+            Output_Object.Current_Row    := 1;
+
+         when Normal =>
+            case Output_Object.Column_Count is
+            when 2 =>
+               --  using @table
+               Put (Output_Object.File, ' ');
+
+            when others =>
+               Put (Output_Object.File, " @tab ");
+            end case;
+
+         when Multi_Column | Contents | Title | Index_Start | Index =>
+            Unexpected_State (Output_Object);
+         end case;
+
+      when ARM_Output.End_Header =>
+         case Output_Object.State is
+         when Table_Header =>
+            Output_Object.State := Normal;
+
+            for I in 1 .. Output_Object.Column_Count loop
+               Put
+                 (Output_Object.File,
+                  " {" &
+                    Output_Object.Column_Text (I).Text (1 .. 
Output_Object.Column_Text (I).Length) &
+                    "}");
+            end loop;
+
+            New_Line (Output_Object.File);
+
+            Put (Output_Object.File, "@item ");
+
+            Pad_Columns (Output_Object);
+            Output_Columns (Output_Object);
+            New_Line (Output_Object.File);
+            Put (Output_Object.File, "@item ");
+            Output_Object.Current_Column := 1;
+
+         when Normal =>
+            --  A two-column table; header has been output
+            null;
+
+         when Contents | Multi_Column | Title | Index_Start | Index =>
+            Unexpected_State (Output_Object);
+         end case;
+
+      when ARM_Output.End_Row | ARM_Output.End_Row_Next_Is_Last =>
+         New_Line (Output_Object.File);
+         Put (Output_Object.File, "@item ");
+         Output_Object.Current_Column := 1;
+
+      when ARM_Output.End_Table =>
+         case Output_Object.Column_Count is
+         when 2 =>
+            New_Line (Output_Object.File);
+            Put_Line (Output_Object.File, "@end table");
+
+         when others =>
+            Put_Line (Output_Object.File, "@end multitable");
+
+         end case;
+
+      end case;
+   end Table_Marker;
+
+   procedure TOC_Marker
+     (Output_Object : in out Texinfo_Output_Type;
+      For_Start     : in     Boolean)
+   is begin
+      --  We use menus, not @contents (since makeinfo ignores
+      --  @contents in info mode). The menus (including the top menu)
+      --  are generated from data stored in ARM_Contents during the
+      --  scan pass.
+
+      if For_Start then
+         Output_Object.State := Contents;
+         --  Ignore futher output until For_Start = False.
+      else
+         Output_Object.State := Normal;
+      end if;
+   end TOC_Marker;
+
+   procedure Unicode_Character
+     (Output_Object : in out Texinfo_Output_Type;
+      Char          : in     ARM_Output.Unicode_Type)
+   is begin
+      --  Used in section 2.3 Identifiers examples, 2.5 character
+      --  literals examples, 2.6 string literals examples, 3.3.1
+      --  Object Declarations examples, 4.4 Expressions examples
+      Put (Output_Object.File, "[Unicode" & ARM_Output.Unicode_Type'Image 
(Char) & "]");
+   end Unicode_Character;
+
+   procedure URL_Link
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String;
+      URL           : in     String)
+   is begin
+      Put (Output_Object.File, "@uref{" & URL & "," & Text & "}");
+   end URL_Link;
+
+end ARM_Texinfo;
diff --git a/packages/ada-ref-man/progs/arm_texi.ads 
b/packages/ada-ref-man/progs/arm_texi.ads
new file mode 100755
index 0000000..9ca6a33
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_texi.ads
@@ -0,0 +1,304 @@
+with Ada.Text_IO;
+with Ada.Unchecked_Deallocation;
+with ARM_Output;
+with ARM_Contents;
+package ARM_Texinfo is
+
+   --
+   --  Ada reference manual formatter.
+   --
+   --  This package defines the TEXINFO output object.
+   --  Output objects are responsible for implementing the details of
+   --  a particular format.
+   --
+   -- ---------------------------------------
+   --
+   --  Copyright (C) 2003, 2007, 2011, 2013 Stephen Leake.  All Rights 
Reserved.
+   --  E-Mail: address@hidden
+   --
+   --  This library is free software; you can redistribute it and/or
+   --  modify it under terms of the GNU General Public License as
+   --  published by the Free Software Foundation; either version 3, or (at
+   --  your option) any later version. This library 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
+   --  distributed with this program; see file gnu-3-0.txt. If not, write to
+   --  the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   --  MA 02111-1307, USA.
+
+   -- ---------------------------------------
+   --
+   -- Edit History:
+   --
+   -- Ancient  - S L - Developed package as add-on to Arm_Form.
+   -- 10/19/11 - RLB - Integrated outside-developed package into Arm_Form.
+   --                  Commented out/replaced Ada 2005 features (this is
+   --                 Ada 95 code). Updated for a few other changes since
+   --                 the last update.
+   -- 10/25/11 - RLB - Added old insertion version to Revised_Clause_Header.
+   --  4/ 1/12 - S L - Various revisions.
+   --  8/31/12 - RLB - Added Output_Path.
+   -- 11/26/12 - RLB - Added subdivision names to Clause_Header and
+   --                 Revised_Clause_Header.
+
+   type Texinfo_Output_Type is new ARM_Output.Output_Type with private;
+
+   --not overriding - Ada 2005-only
+   procedure Create
+     (Output_Object  : in out Texinfo_Output_Type;
+      File_Prefix    : in     String;
+      Output_Path    : in     String;
+      Change_Version : in     ARM_Contents.Change_Version_Type;
+      Title          : in     String);
+   --  Create an Output_Object for a document.
+
+   -- overriding - Ada 2005-only
+   procedure Close (Output_Object : in out Texinfo_Output_Type);
+
+   -- overriding
+   procedure Section
+     (Output_Object : in out Texinfo_Output_Type;
+      Section_Title : in     String;
+      Section_Name  : in     String);
+
+   -- overriding
+   procedure Set_Columns
+     (Output_Object     : in out Texinfo_Output_Type;
+      Number_of_Columns : in     ARM_Output.Column_Count);
+
+   -- overriding
+   procedure Start_Paragraph
+     (Output_Object  : in out Texinfo_Output_Type;
+      Style          : in     ARM_Output.Paragraph_Style_Type;
+      Indent         : in     ARM_Output.Paragraph_Indent_Type;
+      Number         : in     String;
+      No_Prefix      : in     Boolean                       := False;
+      Tab_Stops      : in     ARM_Output.Tab_Info           := 
ARM_Output.NO_TABS;
+      No_Breaks      : in     Boolean                       := False;
+      Keep_with_Next : in     Boolean                       := False;
+      Space_After    : in     ARM_Output.Space_After_Type   := 
ARM_Output.Normal;
+      Justification  : in     ARM_Output.Justification_Type := 
ARM_Output.Default);
+
+   -- overriding
+   procedure End_Paragraph (Output_Object : in out Texinfo_Output_Type);
+
+   -- overriding
+   procedure Category_Header
+     (Output_Object : in out Texinfo_Output_Type;
+      Header_Text   :        String);
+
+   -- overriding
+   procedure Clause_Header
+     (Output_Object : in out Texinfo_Output_Type;
+      Header_Text   : in     String;
+      Level         : in     ARM_Contents.Level_Type;
+      Clause_Number : in     String;
+      Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+      No_Page_Break : in     Boolean                 := False);
+
+   -- overriding
+   procedure Revised_Clause_Header
+     (Output_Object   : in out Texinfo_Output_Type;
+      New_Header_Text : in     String;
+      Old_Header_Text : in     String;
+      Level           : in     ARM_Contents.Level_Type;
+      Clause_Number   : in     String;
+      Version         : in     ARM_Contents.Change_Version_Type;
+      Old_Version     : in     ARM_Contents.Change_Version_Type;
+      Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+      No_Page_Break   : in     Boolean                          := False);
+
+   -- overriding
+   procedure TOC_Marker (Output_Object : in out Texinfo_Output_Type;
+                         For_Start : in Boolean);
+
+   -- overriding
+   procedure New_Page (Output_Object : in out Texinfo_Output_Type;
+                       Kind : ARM_Output.Page_Kind_Type := 
ARM_Output.Any_Page);
+
+   -- overriding
+   procedure New_Column (Output_Object : in out Texinfo_Output_Type);
+
+   -- overriding
+   procedure Separator_Line (Output_Object : in out Texinfo_Output_Type;
+                             Is_Thin : Boolean := True);
+
+   -- overriding
+   procedure Start_Table
+     (Output_Object      : in out Texinfo_Output_Type;
+      Columns            : in     ARM_Output.Column_Count;
+      First_Column_Width : in     ARM_Output.Column_Count;
+      Last_Column_Width  : in     ARM_Output.Column_Count;
+      Alignment          : in     ARM_Output.Column_Text_Alignment;
+      No_Page_Break      : in     Boolean;
+      Has_Border         : in     Boolean;
+      Small_Text_Size    : in     Boolean;
+      Header_Kind        : in     ARM_Output.Header_Kind_Type);
+
+   -- overriding
+   procedure Table_Marker (Output_Object : in out Texinfo_Output_Type;
+                           Marker : in ARM_Output.Table_Marker_Type);
+
+   -- overriding
+   procedure Ordinary_Text (Output_Object : in out Texinfo_Output_Type;
+                            Text : in String);
+
+   -- overriding
+   procedure Ordinary_Character (Output_Object : in out Texinfo_Output_Type;
+                                 Char : in Character);
+
+   -- overriding
+   procedure Hard_Space (Output_Object : in out Texinfo_Output_Type);
+
+   -- overriding
+   procedure Line_Break (Output_Object : in out Texinfo_Output_Type);
+
+   -- overriding
+   procedure Index_Line_Break (Output_Object : in out Texinfo_Output_Type;
+                               Clear_Keep_with_Next : in Boolean);
+
+   -- overriding
+   procedure Soft_Line_Break (Output_Object : in out Texinfo_Output_Type);
+
+   -- overriding
+   procedure Soft_Hyphen_Break (Output_Object : in out Texinfo_Output_Type);
+
+   -- overriding
+   procedure Tab (Output_Object : in out Texinfo_Output_Type);
+
+   -- overriding
+   procedure Special_Character
+     (Output_Object : in out Texinfo_Output_Type;
+      Char          : in     ARM_Output.Special_Character_Type);
+
+   -- overriding
+   procedure Unicode_Character
+     (Output_Object : in out Texinfo_Output_Type;
+      Char          : in     ARM_Output.Unicode_Type);
+
+   -- overriding
+   procedure End_Hang_Item (Output_Object : in out Texinfo_Output_Type);
+
+   -- overriding
+   procedure Text_Format
+     (Output_Object : in out Texinfo_Output_Type;
+      Format        : in     ARM_Output.Format_Type);
+
+   -- overriding
+   procedure Clause_Reference (Output_Object : in out Texinfo_Output_Type;
+                               Text : in String;
+                               Clause_Number : in String);
+
+   -- overriding
+   procedure Index_Target
+     (Output_Object : in out Texinfo_Output_Type;
+      Index_Key     : in     Natural);
+
+   -- overriding
+   procedure Index_Reference
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String;
+      Index_Key     : in     Natural;
+      Clause_Number : in     String);
+
+   -- overriding
+   procedure DR_Reference
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String;
+      DR_Number     : in     String);
+
+   -- overriding
+   procedure AI_Reference
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String;
+      AI_Number     : in     String);
+
+   -- overriding
+   procedure Local_Target
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String;
+      Target        : in     String);
+
+   -- overriding
+   procedure Local_Link
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String;
+      Target        : in     String;
+      Clause_Number : in     String);
+
+   -- overriding
+   procedure Local_Link_Start
+     (Output_Object : in out Texinfo_Output_Type;
+      Target        : in     String;
+      Clause_Number : in     String);
+
+   -- overriding
+   procedure Local_Link_End
+     (Output_Object : in out Texinfo_Output_Type;
+      Target        : in     String;
+      Clause_Number : in     String);
+
+   -- overriding
+   procedure URL_Link
+     (Output_Object : in out Texinfo_Output_Type;
+      Text          : in     String;
+      URL           : in     String);
+
+   -- overriding
+   procedure Picture
+     (Output_Object : in out Texinfo_Output_Type;
+      Name          : in     String;
+      Descr         : in     String;
+      Alignment     : in     ARM_Output.Picture_Alignment;
+      Height, Width : in     Natural;
+      Border        : in     ARM_Output.Border_Kind);
+
+private
+
+   subtype Column_Index_Type is Integer range 1 .. 5;
+   type Column_Text_Item_Type;
+   type Column_Text_Ptr is access Column_Text_Item_Type;
+   type Column_Text_Item_Type is record
+      Text     : String (1 .. 80);
+      Length   : Natural;
+      Row      : Natural; -- Which row in the column.
+      Next     : Column_Text_Ptr;
+   end record;
+   type Column_Text_Ptrs_Type is array (Column_Index_Type) of Column_Text_Ptr;
+   type Column_Widths_Type is array (Column_Index_Type) of Natural;
+
+   procedure Free is new Ada.Unchecked_Deallocation (Column_Text_Item_Type, 
Column_Text_Ptr);
+
+   type State_Type is (Title, Contents, Table_Header, Multi_Column, Normal, 
Index_Start, Index);
+
+   type Texinfo_Output_Type is new ARM_Output.Output_Type with record
+      File     : Ada.Text_IO.File_Type;
+      Is_Valid : Boolean := False;
+
+      State         : State_Type;
+      In_Paragraph  : Boolean := False; --  Sub-state within major states
+      Style         : ARM_Output.Paragraph_Style_Type;
+      Indent        : ARM_Output.Paragraph_Indent_Type;
+      End_Hang_Seen : Boolean;
+
+      --  Detecting end of title page
+      Line_Empty      : Boolean := False; --  True if current line contains 
only whitespace.
+      First_Word      : String (1 .. 80);
+      First_Word_Last : Natural;
+
+      --  Building menus
+      Menu_Section : ARM_Contents.Section_Number_Type := 0;
+      Menu_Clause  : Natural := 0;
+
+      --  Table and Multi-Column format
+      Column_Count    : ARM_Output.Column_Count;
+      Current_Column  : Natural;
+      Current_Row     : Natural;
+      Column_Text     : Column_Text_Ptrs_Type := (others => null);
+      Column_Widths   : Column_Widths_Type;
+      Max_Row         : Natural := 0;
+   end record;
+
+end ARM_Texinfo;
diff --git a/packages/ada-ref-man/progs/arm_text.adb 
b/packages/ada-ref-man/progs/arm_text.adb
new file mode 100755
index 0000000..803f2ea
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_text.adb
@@ -0,0 +1,1547 @@
+with --ARM_Output,
+     --ARM_Contents,
+     --Ada.Text_IO,
+     Ada.Exceptions,
+     Ada.Strings.Fixed;
+package body ARM_Text is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package defines the text output object.
+    -- Output objects are responsible for implementing the details of
+    -- a particular format.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2004, 2005, 2006, 2007, 2011, 2012
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  4/14/00 - RLB - Created base package.
+    --  4/18/00 - RLB - Added index and contents marker routines.
+    --               - Improved formatting.
+    --  4/21/00 - RLB - Added line break and hard space routines.
+    --  4/24/00 - RLB - Added DR references and Insert/Delete text formats.
+    --  4/25/00 - RLB - Added size to format.
+    --  4/29/00 - RLB - Added more formats.
+    --  5/10/00 - RLB - Added even more formats.
+    --          - RLB - Added End_Hang_Item.
+    --  5/12/00 - RLB - Added No_Prefix to Start_Paragraph.
+    --  5/13/00 - RLB - Added Special_Character.
+    --  5/17/00 - RLB - Added New_Page.
+    --  5/22/00 - RLB - Added Includes_Changes to Create.
+    --  5/23/00 - RLB - Added Set_Column and New_Column.
+    --               - Added Tab_Info and Tab_Stops.
+    --  5/24/00 - RLB - Added Location to Text_Format.
+    --         - RLB - Added No_Breaks and Keep_with_Next to Start_Paragraph.
+    --  5/25/00 - RLB - Added Big_Files to Create. Added Justification.
+    --         - RLB - Added Separator_Lines and TOC routines.
+    --  5/26/00 - RLB - Added table operations.
+    --  6/ 2/00 - RLB - Added Soft_Line_Break.
+    --  8/ 2/00 - RLB - Added Soft_Hyphen_Break and left and right quote
+    --                 characters.
+    --         - RLB - Added additional styles.
+    -- 8/ 4/00 - RLB - Added additional styles.
+    --  8/ 7/00 - RLB - Added Leading flag to Start_Paragraph, removed 
"Leading"
+    --                 styles.
+    --  8/11/00 - RLB - Added Hanging_in_Bulleted styles.
+    --  8/16/00 - RLB - Added Code_Indented_Nested_Bulleted.
+    --  8/17/00 - RLB - Replaced "Leading" by "Space_After".
+    --                 - RLB - Added Nested_Enumerated.
+    --  8/22/00 - RLB - Added Revised_Clause_Header.
+    --  8/23/00 - RLB - Fixed a problem with long lines in examples.
+    --  9/26/00 - RLB - Added Syntax_Summary style.
+    --  7/18/02 - RLB - Removed Document parameter from Create, replaced by
+    --                 three strings and For_ISO boolean.
+    --         - RLB - Added AI_Reference.
+    --         - RLB - Added Change_Version_Type and uses.
+    --  9/10/04 - RLB - Added "Both" to possible changes to handle
+    --                 replacement of changed text.
+    --  9/14/04 - RLB - Moved Change_Version_Type to ARM_Contents.
+    -- 11/03/04 - RLB - Added Nested_X2_Bulleted.
+    -- 11/15/04 - RLB - Added Indented_Nested_Bulleted.
+    --  1/24/05 - RLB - Added Inner_Indented.
+    --  2/ 1/05 - RLB - Added Turkish chars to allow an AARM note.
+    --  5/27/05 - RLB - Added arbitrary Unicode characters.
+    --  1/11/06 - RLB - Eliminated dispatching Create in favor of tailored
+    --                 versions.
+    --  1/13/06 - RLB - Added new Link operations.
+    --  1/18/06 - RLB - Added additional styles.
+    --  2/ 8/06 - RLB - Added additional parameters to the table command.
+    --  2/10/06 - RLB - Added even more additional parameters to the
+    --                 table command.
+    --         - RLB - Added picture command.
+    --  9/22/06 - RLB - Added Subsubclause.
+    --  9/25/06 - RLB - Handled optional renaming of TOC.
+    --         - RLB - Added Last_Column_Width to Start_Table.
+    -- 10/13/06 - RLB - Added Local_Link_Start and Local_Link_End to allow
+    --                 formatting in the linked text.
+    --  2/ 9/07 - RLB - Changed comments on AI_Reference.
+    --  2/13/07 - RLB - Revised to separate style and indent information
+    --                 for paragraphs.
+    -- 12/18/07 - RLB - Added Plain_Annex.
+    -- 12/19/07 - RLB - Added limited colors to Text_Format.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/25/11 - RLB - Fixed "hidden" indent (lost due to space for
+    --                 paragraph number).
+    --          - RLB - Added old insertion version to Revised_Clause_Header.
+    --  8/31/12 - RLB - Added Output_Path.
+    -- 10/18/12 - RLB - Added additional hanging styles.
+    -- 11/26/12 - RLB - Added subdivision names to Clause_Header and
+    --                 Revised_Clause_Header.
+
+    LINE_LENGTH : constant := 78;
+       -- Maximum intended line length.
+
+    procedure Put_Line_Centered (File : in out Ada.Text_IO.File_Type;
+                                Text : in String) is
+       -- Put a line of text centered.
+    begin
+       for I in 1 .. (LINE_LENGTH - Text'Length - 1) / 2 loop
+           -- Center the heading.
+           Ada.Text_IO.Put (File, ' ');
+       end loop;
+       Ada.Text_IO.Put_Line (File, Text);
+    end Put_Line_Centered;
+
+
+    procedure Create (Output_Object : in out Text_Output_Type;
+                     File_Prefix : in String;
+                     Output_Path : in String;
+                     Title : in String := "") is
+       -- Create an Output_Object for a document.
+       -- The prefix of the output file names is File_Prefix - this
+       -- should be no more then 5 characters allowed in file names.
+       -- The result files will be written to Output_Path.
+       -- The title of the document is Title.
+    begin
+       if Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Already valid object");
+       end if;
+       Output_Object.Is_Valid := True;
+       Ada.Strings.Fixed.Move (Target => Output_Object.File_Prefix,
+                               Source => File_Prefix);
+       Ada.Strings.Fixed.Move (Target => Output_Object.Output_Path,
+                               Source => Output_Path);
+        Output_Object.Output_Path_Len := Output_Path'Length;
+       -- We don't use the title.
+    end Create;
+
+
+    procedure Close (Output_Object : in out Text_Output_Type) is
+       -- Close an Output_Object. No further output to the object is
+       -- allowed after this call.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Ada.Text_IO.Is_Open (Output_Object.Output_File) then
+           Ada.Text_IO.Close (Output_Object.Output_File);
+       end if;
+       Output_Object.Is_Valid := False;
+    end Close;
+
+
+    procedure Section (Output_Object : in out Text_Output_Type;
+                      Section_Title : in String;
+                      Section_Name : in String) is
+       -- Start a new section. The title is Section_Title (this is
+       -- intended for humans). The name is Section_Name (this is
+       -- intended to be suitable to be a portion of a file name).
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Section in paragraph");
+       end if;
+       if Ada.Text_IO.Is_Open (Output_Object.Output_File) then
+           Ada.Text_IO.Close (Output_Object.Output_File);
+       end if;
+       -- Create a new file for this section:
+        -- Unix directory separators for Windows and Debian
+       Ada.Text_IO.Create (Output_Object.Output_File, Ada.Text_IO.Out_File,
+            Output_Object.Output_Path(1..Output_Object.Output_Path_Len) &
+               Ada.Strings.Fixed.Trim (Output_Object.File_Prefix, 
Ada.Strings.Right) &
+               "-" & Section_Name & ".TXT");
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+    end Section;
+
+
+    procedure Set_Columns (Output_Object : in out Text_Output_Type;
+                          Number_of_Columns : in ARM_Output.Column_Count) is
+       -- Set the number of columns.
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "In paragraph");
+       end if;
+       -- No columns in text format.
+    end Set_Columns;
+
+
+    procedure Make_Indent (Output_Object : in out Text_Output_Type) is
+       -- Internal:
+       -- Output the appropriate indent after a New_Line or Put_Line.
+    begin
+--Ada.Text_IO.Put_Line("Make_Indent: Amount=" & 
Natural'Image(Output_Object.Indent_Amount));
+        for I in 1 .. Output_Object.Indent_Amount loop
+           Ada.Text_IO.Put (Output_Object.Output_File, ' ');
+        end loop;
+        Output_Object.Char_Count := Output_Object.Indent_Amount;
+        Output_Object.Out_Char_Count := Output_Object.Indent_Amount;
+       Output_Object.Output_Buffer_Space_Before := False;
+    end Make_Indent;
+
+
+    procedure Spill (Output_Object : in out Text_Output_Type) is
+       -- Internal:
+       -- Empty the output buffer in preperation for a New_Line or Put_Line.
+    begin
+        if Output_Object.Output_Buffer_Space_Before then
+           Ada.Text_IO.Put (Output_Object.Output_File, ' ');
+           Output_Object.Char_Count := Output_Object.Char_Count + 1; -- Count 
the space.
+           Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + 1; 
-- Count the space.
+        end if;
+       if Output_Object.Output_Buffer_Len /= 0 then
+           Ada.Text_IO.Put (Output_Object.Output_File,
+               Output_Object.Output_Buffer (1 .. 
Output_Object.Output_Buffer_Len));
+--Ada.Text_IO.Put_Line("Spill: Len=" & 
Natural'Image(Output_Object.Output_Buffer_Len) &
+--     " Space added=" &  
Boolean'Image(Output_Object.Output_Buffer_Space_Before) & " Text=" &
+--     Output_Object.Output_Buffer (1 .. Output_Object.Output_Buffer_Len));
+           Output_Object.Output_Buffer_Len := 0;
+           Output_Object.Out_Char_Count := Output_Object.Out_Char_Count +
+               Output_Object.Output_Buffer_Len;
+       end if;
+        Output_Object.Output_Buffer_Space_Before := False;
+    end Spill;
+
+
+    procedure Buffer (Output_Object : in out Text_Output_Type;
+                     Char : in Character) is
+       -- Internal:
+       -- Add Char to the output buffer. Char will *not* be a word break
+       -- character.
+    begin
+       if Output_Object.Output_Buffer_Len = Output_Object.Output_Buffer'Last 
then
+           -- Oops, buffer is full. Spill it, and this character.
+--Ada.Text_IO.Put_Line("** Buffer overflow!!");
+           Spill (Output_Object);
+           Ada.Text_IO.Put (Output_Object.Output_File, Char);
+           Output_Object.Char_Count := Output_Object.Char_Count + 1;
+           return;
+       end if;
+       Output_Object.Output_Buffer_Len := Output_Object.Output_Buffer_Len + 1;
+       Output_Object.Output_Buffer(Output_Object.Output_Buffer_Len) := Char;
+        Output_Object.Char_Count := Output_Object.Char_Count + 1;
+    end Buffer;
+
+
+    procedure Start_Paragraph (Output_Object : in out Text_Output_Type;
+                              Style     : in ARM_Output.Paragraph_Style_Type;
+                              Indent    : in ARM_Output.Paragraph_Indent_Type;
+                              Number    : in String;
+                              No_Prefix : in Boolean := False;
+                              Tab_Stops : in ARM_Output.Tab_Info := 
ARM_Output.NO_TABS;
+                              No_Breaks : in Boolean := False;
+                              Keep_with_Next : in Boolean := False;
+                              Space_After : in ARM_Output.Space_After_Type
+                                  := ARM_Output.Normal;
+                              Justification : in ARM_Output.Justification_Type
+                                  := ARM_Output.Default) is
+       -- Start a new paragraph. The style and indent of the paragraph is as
+       -- specified. The (AA)RM paragraph number (which might include update
+       -- and version numbers as well: [12.1/1]) is Number. If the format is
+       -- a type with a prefix (bullets, hangining items), the prefix is
+       -- omitted if No_Prefix is true. Tab_Stops defines the tab stops for
+       -- the paragraph. If No_Breaks is True, we will try to avoid page breaks
+       -- in the paragraph. If Keep_with_Next is true, we will try to avoid
+       -- separating this paragraph and the next one. (These may have no
+       -- effect in formats that don't have page breaks). Space_After
+       -- specifies the amount of space following the paragraph. Justification
+       -- specifies the text justification for the paragraph. Not_Valid_Error
+       -- is raised if Tab_Stops /= NO_TABS for a hanging or bulleted format.
+       Start_Indent : Natural;
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Already in paragraph");
+       end if;
+       Output_Object.Is_In_Paragraph := True;
+       Output_Object.Is_Hanging := False;
+       Output_Object.Saw_Hang_End := False;
+       Output_Object.Char_Count := 0;
+       Output_Object.Out_Char_Count := 0;
+       Output_Object.Output_Buffer_Space_Before := False; -- Nothing in it or 
on the line.
+       Output_Object.Output_Buffer_Len := 0;
+
+       if ARM_Output."/=" (Indent, 0) then
+           Output_Object.Indent_Amount := Natural(Indent)*4 + 4;
+       else
+           Output_Object.Indent_Amount := 0;
+       end if;
+       Start_Indent := Output_Object.Indent_Amount;
+
+       case Style is
+           when ARM_Output.Normal => null;
+           when ARM_Output.Wide_Above => null;
+           when ARM_Output.Small => null;
+           when ARM_Output.Small_Wide_Above => null;
+           when ARM_Output.Header => null;
+           when ARM_Output.Small_Header => null;
+           when ARM_Output.Title => null;
+           when ARM_Output.Index => null;
+           when ARM_Output.Syntax_Summary => null;
+           when ARM_Output.Examples => null;
+           when ARM_Output.Small_Examples => null;
+           when ARM_Output.Swiss_Examples => null;
+           when ARM_Output.Small_Swiss_Examples => null;
+           when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted |
+                ARM_Output.Small_Bulleted | ARM_Output.Small_Nested_Bulleted =>
+               if No_Prefix then
+                   null;
+               else -- Has prefix (added later)
+                   Start_Indent := Start_Indent - 4;
+               end if;
+
+           when ARM_Output.Giant_Hanging | ARM_Output.Small_Giant_Hanging =>
+               Output_Object.Is_Hanging := True;
+               if No_Prefix then -- Four units for prefix.
+                   Output_Object.Saw_Hang_End := True;
+               else -- Has prefix
+                   Output_Object.Saw_Hang_End := False;
+                   Start_Indent := Start_Indent - 16; -- Leave space for 
prefix.
+               end if;
+
+           when ARM_Output.Wide_Hanging | ARM_Output.Small_Wide_Hanging =>
+               Output_Object.Is_Hanging := True;
+               if No_Prefix then -- Three units for prefix.
+                   Output_Object.Saw_Hang_End := True;
+               else -- Has prefix
+                   Output_Object.Saw_Hang_End := False;
+                   Start_Indent := Start_Indent - 12; -- Leave space for 
prefix.
+               end if;
+
+           when ARM_Output.Medium_Hanging | ARM_Output.Small_Medium_Hanging =>
+               Output_Object.Is_Hanging := True;
+               if No_Prefix then -- Two units for prefix.
+                   Output_Object.Saw_Hang_End := True;
+               else -- Has prefix
+                   Output_Object.Saw_Hang_End := False;
+                   Start_Indent := Start_Indent - 8; -- Leave space for prefix.
+               end if;
+
+           when ARM_Output.Narrow_Hanging | ARM_Output.Small_Narrow_Hanging => 
null;
+               Output_Object.Is_Hanging := True;
+               if No_Prefix then -- One unit for prefix.
+                   Output_Object.Saw_Hang_End := True;
+               else -- Has prefix.
+                   Output_Object.Saw_Hang_End := False;
+                   Start_Indent := Start_Indent - 4; -- Leave space for prefix.
+               end if;
+
+           when ARM_Output.Hanging_in_Bulleted |
+                ARM_Output.Small_Hanging_in_Bulleted =>
+               Output_Object.Is_Hanging := True;
+               if No_Prefix then -- Two units for prefix.
+                   Output_Object.Saw_Hang_End := True;
+               else -- Has prefix.
+                   Output_Object.Saw_Hang_End := False;
+                   Start_Indent := Start_Indent - 8; -- Leave space for prefix.
+               end if;
+
+           when ARM_Output.Enumerated | ARM_Output.Small_Enumerated =>
+               Output_Object.Is_Hanging := True;
+               if No_Prefix then -- One unit for prefix.
+                   Output_Object.Saw_Hang_End := True;
+               else -- Has prefix.
+                   Output_Object.Saw_Hang_End := False;
+                   Start_Indent := Start_Indent - 4; -- Leave space for prefix.
+               end if;
+       end case;
+       if Number /= "" then
+           -- Note: The following assumes that Start_Indent is a multiple of 4.
+           Ada.Text_IO.Put (Output_Object.Output_File, Number);
+           Output_Object.Char_Count := Output_Object.Char_Count + 
Number'Length;
+           for I in Integer'Min(Number'Length + 1, 4) .. 4 loop
+               -- The 'Min here ensures that every number is always followed
+               -- by at least one space.
+               Ada.Text_IO.Put (Output_Object.Output_File, ' ');
+               Output_Object.Char_Count := Output_Object.Char_Count + 1;
+           end loop;
+           -- Add the next four characters of indent (only if needed), taking
+           -- into account any use of this space by the paragraph number.
+           if Start_Indent > 4 then -- (Really 8 or more); add the next three 
characters of the indent, but take into account any paragraph number length.
+               if Number'Length <= 3 then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "    ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 4;
+               elsif Number'Length = 4 then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "   ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 3;
+               elsif Number'Length = 5 then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "  ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 2;
+               elsif Number'Length = 6 then
+                   Ada.Text_IO.Put (Output_Object.Output_File, ' ');
+                   Output_Object.Char_Count := Output_Object.Char_Count + 1;
+               end if;
+           end if;
+           -- Add the next four characters of indent (only if needed), taking
+           -- into account any use of this space by the paragraph number.
+           if Start_Indent > 8 then -- (Really 12 or more); add the next three 
characters of the indent, but take into account any paragraph number length.
+               if Number'Length <= 7 then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "    ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 4;
+               elsif Number'Length = 8 then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "   ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 3;
+               elsif Number'Length = 9 then
+                   Ada.Text_IO.Put (Output_Object.Output_File, "  ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 2;
+               elsif Number'Length = 10 then
+                   Ada.Text_IO.Put (Output_Object.Output_File, ' ');
+                   Output_Object.Char_Count := Output_Object.Char_Count + 1;
+               end if;
+           end if;
+           if Start_Indent > 12 then -- Add any remaining indent.
+               for I in 1 .. (Start_Indent-12)/4 loop
+                   Ada.Text_IO.Put (Output_Object.Output_File, "    ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 4;
+               end loop;
+           end if;
+       else -- No paragraph number:
+           if Start_Indent /= 0 then
+               for I in 1 .. Start_Indent/4 loop
+                   Ada.Text_IO.Put (Output_Object.Output_File, "    ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 4;
+               end loop;
+           end if;
+        end if;
+
+       -- Add bullets if needed:
+       case Style is
+           when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted |
+                ARM_Output.Small_Bulleted | ARM_Output.Small_Nested_Bulleted =>
+               if No_Prefix then
+                   null;
+               else -- Has prefix (added later)
+                   Ada.Text_IO.Put (Output_Object.Output_File, "  * ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 4;
+               end if;
+           when others =>
+               null;
+       end case;
+
+       case Style is
+           when ARM_Output.Normal | ARM_Output.Wide_Above |
+                ARM_Output.Small | ARM_Output.Small_Wide_Above |
+                ARM_Output.Header | ARM_Output.Small_Header |
+                ARM_Output.Index | ARM_Output.Syntax_Summary |
+                ARM_Output.Title |
+                ARM_Output.Examples | ARM_Output.Small_Examples |
+                ARM_Output.Swiss_Examples | ARM_Output.Small_Swiss_Examples =>
+               Output_Object.Tab_Stops := Tab_Stops;
+                   -- We'll expand proportional stops here (text characters
+                   -- are larger than the variable ones these are set up for).
+               for I in 1 .. Tab_Stops.Number loop
+                   if ARM_Output."=" (Tab_Stops.Stops(I).Kind,
+                                      ARM_Output.Left_Proportional) then
+                       Output_Object.Tab_Stops.Stops(I).Stop :=
+                               (Tab_Stops.Stops(I).Stop * 5 / 4) + 
Output_Object.Indent_Amount;
+                   else
+                       Output_Object.Tab_Stops.Stops(I).Stop :=
+                               Tab_Stops.Stops(I).Stop + 
Output_Object.Indent_Amount;
+                   end if;
+               end loop;
+           when ARM_Output.Bulleted | ARM_Output.Nested_Bulleted |
+                ARM_Output.Small_Bulleted | ARM_Output.Small_Nested_Bulleted |
+                ARM_Output.Giant_Hanging | ARM_Output.Wide_Hanging |
+                ARM_Output.Medium_Hanging | ARM_Output.Narrow_Hanging |
+                ARM_Output.Hanging_in_Bulleted |
+                ARM_Output.Small_Giant_Hanging | ARM_Output.Small_Wide_Hanging 
|
+                ARM_Output.Small_Medium_Hanging | 
ARM_Output.Small_Narrow_Hanging |
+                ARM_Output.Small_Hanging_in_Bulleted |
+                ARM_Output.Enumerated | ARM_Output.Small_Enumerated =>
+               if Tab_Stops.Number /= 0 then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Tabs in hanging/bulleted paragraph");
+               end if;
+       end case;
+       Output_Object.Out_Char_Count := Output_Object.Char_Count;
+
+       -- Note: No_Breaks, Keep_with_Next, and Justification have no effect
+       -- here.
+--Ada.Text_IO.Put_Line ("Start_Paragraph - Indent=" & 
Natural'Image(Output_Object.Indent_Amount) & " Cnt=" &
+--    Natural'Image(Output_Object.Char_Count));
+    end Start_Paragraph;
+
+
+    procedure End_Paragraph (Output_Object : in out Text_Output_Type) is
+       -- End a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.Output_Buffer_Len /= 0 then
+           Spill (Output_Object);
+       end if;
+       Output_Object.Is_In_Paragraph := False;
+       Ada.Text_IO.New_Line (Output_Object.Output_File, 2); -- Double space 
paragraphs.
+    end End_Paragraph;
+
+
+    procedure Category_Header (Output_Object : in out Text_Output_Type;
+                              Header_Text : String) is
+       -- Output a Category header (that is, "Legality Rules",
+       -- "Dynamic Semantics", etc.)
+       -- (Note: We did not use a enumeration here to insure that these
+       -- headers are spelled the same in all output versions).
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Header in paragraph");
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+       Put_Line_Centered (Output_Object.Output_File, Header_Text);
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+       Output_Object.Char_Count := 0;
+       Output_Object.Out_Char_Count := 0;
+    end Category_Header;
+
+
+    procedure Clause_Header (Output_Object     : in out Text_Output_Type;
+                            Header_Text       : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False) is
+       -- Output a Clause header. The level of the header is specified
+       -- in Level. The Clause Number is as specified; the top-level (and
+       -- other) subdivision names are as specified. These should appear in
+       -- the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Header in paragraph");
+       end if;
+        Ada.Text_IO.New_Line (Output_Object.Output_File);
+
+       -- Special for table of contents:
+       if Clause_Number = "" and then
+               (Header_Text = "Table of Contents" or else -- Ada 95 format
+                Header_Text = "Contents") then -- ISO 2004 format.
+           Put_Line_Centered (Output_Object.Output_File,
+                              Header_Text);
+           Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+           Output_Object.Char_Count := 0;
+           Output_Object.Out_Char_Count := 0;
+           return;
+       end if;
+
+       case Level is
+           when ARM_Contents.Plain_Annex =>
+               Put_Line_Centered (Output_Object.Output_File,
+                                  Clause_Number); -- Note: Clause_Number 
includes "Annex"
+               Put_Line_Centered (Output_Object.Output_File,
+                                  Header_Text);
+           when ARM_Contents.Normative_Annex =>
+               Put_Line_Centered (Output_Object.Output_File,
+                                  Clause_Number); -- Note: Clause_Number 
includes "Annex"
+               Put_Line_Centered (Output_Object.Output_File,
+                                  "(normative)");
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Put_Line_Centered (Output_Object.Output_File,
+                                  Header_Text);
+           when ARM_Contents.Informative_Annex =>
+               Put_Line_Centered (Output_Object.Output_File,
+                                  Clause_Number); -- Note: Clause_Number 
includes "Annex"
+               Put_Line_Centered (Output_Object.Output_File,
+                                  "(informative)");
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Put_Line_Centered (Output_Object.Output_File,
+                                  Header_Text);
+           when ARM_Contents.Section =>
+               case Top_Level_Subdivision_Name is
+                   when ARM_Output.Chapter =>
+                       Put_Line_Centered (Output_Object.Output_File,
+                                          "Chapter " & Clause_Number & ": " & 
Header_Text);
+                   when ARM_Output.Section =>
+                       Put_Line_Centered (Output_Object.Output_File,
+                                          "Section " & Clause_Number & ": " & 
Header_Text);
+                   when ARM_Output.Clause =>
+                       Put_Line_Centered (Output_Object.Output_File,
+                                          Clause_Number & "   " & Header_Text);
+               end case;
+           when ARM_Contents.Unnumbered_Section =>
+               if Header_Text /= "" then
+                   Put_Line_Centered (Output_Object.Output_File,
+                                      Header_Text);
+               end if;
+           when ARM_Contents.Clause | ARM_Contents.Subclause |
+                ARM_Contents.Subsubclause =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                     Clause_Number & ' ' & Header_Text);
+           when ARM_Contents.Dead_Clause =>
+               raise Program_Error; -- No headers for dead clauses.
+       end case;
+       Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+       Output_Object.Char_Count := 0;
+       Output_Object.Out_Char_Count := 0;
+       -- We don't have any page breaks here to suppress.
+    end Clause_Header;
+
+
+    procedure Revised_Clause_Header
+                           (Output_Object     : in out Text_Output_Type;
+                            New_Header_Text   : in String;
+                            Old_Header_Text   : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Version           : in 
ARM_Contents.Change_Version_Type;
+                            Old_Version       : in 
ARM_Contents.Change_Version_Type;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False) is
+       -- Output a revised clause header. Both the original and new text will
+       -- be output. The level of the header is specified in Level. The Clause
+       -- Number is as specified; the top-level (and other) subdivision names
+       -- are as specified. These should appear in the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- Version is the insertion version of the new text; Old_Version is
+       -- the insertion version of the old text.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+       function Header_Text return String is
+           -- Note: Version and Old_Version are not used.
+       begin
+           return '{' & New_Header_Text & "} [" & Old_Header_Text & ']';
+       end Header_Text;
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Header in paragraph");
+       end if;
+        Ada.Text_IO.New_Line (Output_Object.Output_File);
+
+       -- Special for table of contents:
+       if Clause_Number = "" and then
+               (Header_Text = "Table of Contents" or else -- Ada 95 format
+                Header_Text = "Contents") then -- ISO 2004 format.
+           Put_Line_Centered (Output_Object.Output_File,
+                              Header_Text);
+           Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+           Output_Object.Char_Count := 0;
+           Output_Object.Out_Char_Count := 0;
+           return;
+       end if;
+
+       case Level is
+           when ARM_Contents.Plain_Annex =>
+               Put_Line_Centered (Output_Object.Output_File,
+                                  Clause_Number); -- Note: Clause_Number 
includes "Annex"
+               Put_Line_Centered (Output_Object.Output_File,
+                                  Header_Text);
+           when ARM_Contents.Normative_Annex =>
+               Put_Line_Centered (Output_Object.Output_File,
+                                  Clause_Number); -- Note: Clause_Number 
includes "Annex"
+               Put_Line_Centered (Output_Object.Output_File,
+                                  "(normative)");
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Put_Line_Centered (Output_Object.Output_File,
+                                  Header_Text);
+           when ARM_Contents.Informative_Annex =>
+               Put_Line_Centered (Output_Object.Output_File,
+                                  Clause_Number); -- Note: Clause_Number 
includes "Annex"
+               Put_Line_Centered (Output_Object.Output_File,
+                                  "(informative)");
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Put_Line_Centered (Output_Object.Output_File,
+                                  Header_Text);
+           when ARM_Contents.Section =>
+               case Top_Level_Subdivision_Name is
+                   when ARM_Output.Chapter =>
+                       Put_Line_Centered (Output_Object.Output_File,
+                                          "Chapter " & Clause_Number & ": " & 
Header_Text);
+                   when ARM_Output.Section =>
+                       Put_Line_Centered (Output_Object.Output_File,
+                                          "Section " & Clause_Number & ": " & 
Header_Text);
+                   when ARM_Output.Clause =>
+                       Put_Line_Centered (Output_Object.Output_File,
+                                          Clause_Number & "   " & Header_Text);
+               end case;
+           when ARM_Contents.Unnumbered_Section =>
+               if Header_Text /= "" then
+                   Put_Line_Centered (Output_Object.Output_File,
+                                      Header_Text);
+               end if;
+           when ARM_Contents.Clause | ARM_Contents.Subclause |
+               ARM_Contents.Subsubclause =>
+               Ada.Text_IO.Put_Line (Output_Object.Output_File,
+                                     Clause_Number & ' ' & Header_Text);
+           when ARM_Contents.Dead_Clause =>
+               raise Program_Error; -- No headers for dead clauses.
+       end case;
+       Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+       Output_Object.Char_Count := 0;
+       Output_Object.Out_Char_Count := 0;
+       -- We don't have any page breaks here to suppress.
+    end Revised_Clause_Header;
+
+
+    procedure TOC_Marker (Output_Object : in out Text_Output_Type;
+                         For_Start : in Boolean) is
+       -- Mark the start (if For_Start is True) or end (if For_Start is
+       -- False) of the table of contents data. Output objects that
+       -- auto-generate the table of contents can use this to do needed
+       -- actions.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       null; -- We don't care about this.
+    end TOC_Marker;
+
+
+    procedure New_Page (Output_Object : in out Text_Output_Type;
+                       Kind : ARM_Output.Page_Kind_Type := 
ARM_Output.Any_Page) is
+       -- Output a page break.
+       -- Note that this has no effect on non-printing formats.
+       -- Any_Page breaks to the top of the next page (whatever it is);
+       -- Odd_Page_Only breaks to the top of the odd-numbered page;
+       -- Soft_Page allows a page break but does not force one (use in
+       -- "No_Breaks" paragraphs.)
+       -- Raises Not_Valid_Error if in a paragraph if Kind = Any_Page or
+       -- Odd_Page, and if not in a paragraph if Kind = Soft_Page.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       case Kind is
+           when ARM_Output.Any_Page | ARM_Output.Odd_Page_Only =>
+               if Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Page in paragraph");
+               end if;
+               Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+           when ARM_Output.Soft_Page =>
+               if not Output_Object.Is_In_Paragraph then
+                   Ada.Exceptions.Raise_Exception 
(ARM_Output.Not_Valid_Error'Identity,
+                       "Soft page not in paragraph");
+               end if;
+               null; -- No page breaks.
+               Spill (Output_Object);
+       end case;
+    end New_Page;
+
+
+    procedure New_Column (Output_Object : in out Text_Output_Type) is
+       -- Output a column break.
+       -- Raises Not_Valid_Error if in a paragraph, or if the number of
+       -- columns is 1.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "New column in paragraph");
+       end if;
+       -- No columns in text format.
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+    end New_Column;
+
+
+    procedure Start_Table (Output_Object : in out Text_Output_Type;
+                          Columns : in ARM_Output.Column_Count;
+                          First_Column_Width : in ARM_Output.Column_Count;
+                          Last_Column_Width : in ARM_Output.Column_Count;
+                          Alignment : in ARM_Output.Column_Text_Alignment;
+                          No_Page_Break : in Boolean;
+                          Has_Border : in Boolean;
+                          Small_Text_Size : in Boolean;
+                          Header_Kind : in ARM_Output.Header_Kind_Type) is
+       -- Starts a table. The number of columns is Columns; the first
+       -- column has First_Column_Width times the normal column width, and
+       -- the last column has Last_Column_Width times the normal column width.
+       -- Alignment is the horizontal text alignment within the columns.
+       -- No_Page_Break should be True to keep the table intact on a single
+       -- page; False to allow it to be split across pages.
+       -- Has_Border should be true if a border is desired, false otherwise.
+       -- Small_Text_Size means that the contents will have the AARM size;
+       -- otherwise it will have the normal size.
+       -- Header_Kind determines whether the table has headers.
+       -- This command starts a paragraph; the entire table is a single
+       -- paragraph. Text will be considered part of the caption until the
+       -- next table marker call.
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       -- Alignment, No_Page_Break, Border, Small_Text_Size, and Header_Kind
+       -- not used here.
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Table in paragraph");
+       end if;
+
+       Output_Object.Tab_Stops.Number := Columns;
+       declare
+            Column_Units : constant ARM_Output.Column_Count :=
+               Columns+First_Column_Width+Last_Column_Width-2;
+            Width : Natural :=
+               (72/(Column_Units));
+       begin
+           if Column_Units <= 3 then -- Keep it from getting too wide.
+               Width := 22;
+           end if;
+           for I in 1 .. Columns loop
+               Output_Object.Tab_Stops.Stops(I) := (Kind => 
ARM_Output.Left_Fixed,
+                                                    Stop => 
Width*(I+First_Column_Width-1)+10);
+           end loop;
+       end;
+
+       Output_Object.Indent_Amount := 10;
+        Ada.Text_IO.Put (Output_Object.Output_File, "          ");
+       Output_Object.Char_Count := 10;
+       Output_Object.Out_Char_Count := 10;
+
+       Output_Object.Is_In_Paragraph := True;
+       Output_Object.Is_In_Table := True;
+    end Start_Table;
+
+
+    procedure Table_Marker (Output_Object : in out Text_Output_Type;
+                           Marker : in ARM_Output.Table_Marker_Type) is
+       -- Marks the end of an entity in a table.
+       -- If Marker is End_Caption, the table caption ends and the
+       --      future text is part of the table header.
+       -- If Marker is End_Header, the table header ends and the
+       --      future text is part of the table body.
+       -- If Marker is End_Row, a row in the table is completed, and another
+       --      row started.
+       -- If Marker is End_Row_Next_Is_Last, a row in the table is completed,
+       --      and another row started. That row is the last row in the table.
+       -- If Marker is End_Item, an item in the table header or body is ended,
+       --      and another started.
+       -- If Marker is End_Table, the entire table is finished.
+       -- Raises Not_Valid_Error if not in a table.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if (not Output_Object.Is_In_Paragraph) or (not 
Output_Object.Is_In_Table) then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Table marker not in table");
+       end if;
+       case Marker is
+           when ARM_Output.End_Item =>
+               -- Just tab over one row:
+               Spill (Output_Object);
+               Ada.Text_IO.Put (Output_Object.Output_File, " ");
+               Output_Object.Char_Count := Output_Object.Char_Count + 1;
+               Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + 
1;
+               for I in 1 .. Output_Object.Tab_Stops.Number loop
+                   if Output_Object.Tab_Stops.Stops(I).Stop > 
Output_Object.Char_Count then
+                       for J in Output_Object.Char_Count+1 .. 
Output_Object.Tab_Stops.Stops(I).Stop-1 loop
+                           Ada.Text_IO.Put (Output_Object.Output_File, " ");
+                           Output_Object.Char_Count := 
Output_Object.Char_Count + 1;
+                           Output_Object.Out_Char_Count := 
Output_Object.Out_Char_Count + 1;
+                       end loop;
+                   end if;
+               end loop;
+
+           when ARM_Output.End_Caption =>
+               Spill (Output_Object);
+               Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+               Ada.Text_IO.Put (Output_Object.Output_File, "          ");
+               Output_Object.Char_Count := 10;
+               Output_Object.Out_Char_Count := 10;
+           when ARM_Output.End_Header =>
+               Spill (Output_Object);
+               Ada.Text_IO.New_Line (Output_Object.Output_File, 2);
+               Ada.Text_IO.Put (Output_Object.Output_File, "          ");
+               Output_Object.Char_Count := 10;
+               Output_Object.Out_Char_Count := 10;
+           when ARM_Output.End_Row | ARM_Output.End_Row_Next_Is_Last =>
+               Spill (Output_Object);
+               Ada.Text_IO.New_Line (Output_Object.Output_File, 1);
+               Ada.Text_IO.Put (Output_Object.Output_File, "          ");
+               Output_Object.Char_Count := 10;
+               Output_Object.Out_Char_Count := 10;
+           when ARM_Output.End_Table =>
+               Spill (Output_Object);
+               Output_Object.Is_In_Paragraph := False;
+               Output_Object.Is_In_Table := False;
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Output_Object.Tab_Stops := ARM_Output.NO_TABS;
+       end case;
+    end Table_Marker;
+
+
+    procedure Separator_Line (Output_Object : in out Text_Output_Type;
+                             Is_Thin : Boolean := True) is
+       -- Output a separator line. It is thin if "Is_Thin" is true.
+       -- Raises Not_Valid_Error if in a paragraph.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Separator in paragraph");
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+       if Is_Thin then
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"---------------------------------------------------------------------");
+       else
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, 
"=====================================================================");
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+    end Separator_Line;
+
+
+    -- Text output: These are only allowed after a Start_Paragraph and
+    -- before any End_Paragraph. Raises Not_Valid_Error if not allowed.
+
+    procedure Ordinary_Text (Output_Object : in out Text_Output_Type;
+                            Text : in String) is
+       -- Output ordinary text.
+       -- The text must end at a word break, never in the middle of a word.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+--Ada.Text_IO.Put_Line ("Ordinary_Text: Cnt=" & 
Natural'Image(Output_Object.Char_Count) &
+--" Buffer=" & Natural'Image(Output_Object.Output_Buffer_Len));
+       if Output_Object.Char_Count + Text'Length >= LINE_LENGTH - 2 and then
+          Output_Object.Out_Char_Count > Output_Object.Indent_Amount then
+           -- We want a line break here if the line is too long and something 
was output:
+           Ada.Text_IO.New_Line (Output_Object.Output_File);
+           Make_Indent (Output_Object);
+           --Output_Object.Output_Buffer_Space_Before := False;
+               -- Start of line, this is done by Make_Indent.
+           Spill (Output_Object);
+       else
+           Spill (Output_Object);
+       end if;
+        Ada.Text_IO.Put (Output_Object.Output_File, Text);
+        Output_Object.Char_Count := Output_Object.Char_Count + Text'Length;
+        Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + 
Text'Length;
+        Output_Object.Output_Buffer_Space_Before := False; -- No space between
+                                                          -- this and any 
following text.
+    end Ordinary_Text;
+
+
+    procedure Ordinary_Character (Output_Object : in out Text_Output_Type;
+                                 Char : in Character) is
+       -- Output an ordinary character.
+       -- Spaces will be used to break lines as needed.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+
+       if Output_Object.Char_Count >= LINE_LENGTH and then
+          Output_Object.Out_Char_Count > Output_Object.Indent_Amount then
+           -- Insert a break here if anything has been output (but don't
+           -- Spill the buffer):
+--Ada.Text_IO.Put_Line ("Ordinary_Char [Break, no spill]: Cnt=" & 
Natural'Image(Output_Object.Char_Count));
+           Ada.Text_IO.New_Line (Output_Object.Output_File);
+           Make_Indent (Output_Object);
+           --Output_Object.Output_Buffer_Space_Before := False;
+               -- Start of line, this is done by Make_Indent.
+               -- Note that this may make the space disappear.
+           -- Add the contents of the buffer to the character count for this 
line:
+           Output_Object.Char_Count := Output_Object.Char_Count +
+               Output_Object.Output_Buffer_Len;
+           if Char /= ' ' then
+               Buffer (Output_Object, Char);
+           else -- Break character, spill on the new line:
+               if Output_Object.Output_Buffer_Len /= 0 then
+                   Spill (Output_Object); -- Output the buffer up to the space.
+                   Output_Object.Output_Buffer_Space_Before := True; -- 
Mid-line now.
+               -- else nothing in buffer, so nothing to output; just skip it.
+               end if;
+           end if;
+       elsif Char = ' ' then
+           -- Break character, and it fits on this line:
+           if Output_Object.Output_Buffer_Len /= 0 then
+--Ada.Text_IO.Put_Line ("Ordinary_Char [Space spill]: Cnt=" & 
Natural'Image(Output_Object.Char_Count));
+               Spill (Output_Object); -- Output the buffer up to the space.
+               Output_Object.Output_Buffer_Space_Before := True; -- Mid-line 
now.
+           else -- nothing in buffer.
+               -- nothing to output. But make sure we display a space before
+               -- the next item.
+               Output_Object.Output_Buffer_Space_Before := True; -- Mid-line 
now.
+           end if;
+       else
+           Buffer (Output_Object, Char);
+       end if;
+    end Ordinary_Character;
+
+
+    procedure Hard_Space (Output_Object : in out Text_Output_Type) is
+       -- Output a hard space. No line break should happen at a hard space.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+        Buffer (Output_Object, ' ');
+    end Hard_Space;
+
+
+    procedure Line_Break (Output_Object : in out Text_Output_Type) is
+       -- Output a line break. This does not start a new paragraph.
+       -- This corresponds to a "<BR>" in HTML.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+--Ada.Text_Io.Put_Line ("Line_Break");
+       if Output_Object.Output_Buffer_Len /= 0 then
+           Spill (Output_Object);
+       end if;
+       Ada.Text_IO.New_Line (Output_Object.Output_File);
+        Make_Indent (Output_Object);
+    end Line_Break;
+
+
+    procedure Index_Line_Break (Output_Object : in out Text_Output_Type;
+                               Clear_Keep_with_Next : in Boolean) is
+       -- Output a line break for the index. This does not start a new
+       -- paragraph in terms of spacing. This corresponds to a "<BR>"
+       -- in HTML. If Clear_Keep_with_Next is true, insure that the next
+       -- line does not require the following line to stay with it.
+       -- Raises Not_Valid_Error if the paragraph is not in the index format.
+    begin
+       Line_Break (Output_Object);
+    end Index_Line_Break;
+
+
+    procedure Soft_Line_Break (Output_Object : in out Text_Output_Type) is
+       -- Output a soft line break. This is a place (in the middle of a
+       -- "word") that we allow a line break. It is usually used after
+       -- underscores in long non-terminals.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.Char_Count >= LINE_LENGTH - 10 then
+           if Output_Object.Output_Buffer_Len /= 0 then
+               Spill (Output_Object);
+           end if;
+           Ada.Text_IO.New_Line (Output_Object.Output_File);
+            Make_Indent (Output_Object);
+       -- else we don't need a line break.
+       end if;
+    end Soft_Line_Break;
+
+
+    procedure Soft_Hyphen_Break (Output_Object : in out Text_Output_Type) is
+       -- Output a soft line break, with a hyphen. This is a place (in the 
middle of
+       -- a "word") that we allow a line break. If the line break is used,
+       -- a hyphen will be added to the text.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Output_Object.Char_Count >= LINE_LENGTH - 8 then
+           Spill (Output_Object);
+           Ada.Text_IO.Put_Line (Output_Object.Output_File, "-"); -- Add the 
hyphen and break.
+            Make_Indent (Output_Object);
+       -- else we don't need a line break.
+       end if;
+    end Soft_Hyphen_Break;
+
+
+    procedure Tab (Output_Object : in out Text_Output_Type) is
+       -- Output a tab, inserting space up to the next tab stop.
+       -- Raises Not_Valid_Error if the paragraph was created with
+       -- Tab_Stops = ARM_Output.NO_TABS.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if ARM_Output."="(Output_Object.Tab_Stops, ARM_Output.NO_TABS) then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Tab, but none set");
+       end if;
+       -- We use the tab stops as characters here, and fixed and proportional
+       -- stops are treated identically.
+       -- Find the first stop greater than the current character count. (After
+       -- writing a space).
+--Ada.Text_IO.Put_Line ("Tab");
+       Spill (Output_Object);
+        Ada.Text_IO.Put (Output_Object.Output_File, " ");
+        Output_Object.Char_Count := Output_Object.Char_Count + 1;
+        Output_Object.Out_Char_Count := Output_Object.Out_Char_Count + 1;
+       for I in 1 .. Output_Object.Tab_Stops.Number loop
+           if Output_Object.Tab_Stops.Stops(I).Stop > Output_Object.Char_Count 
then
+               for J in Output_Object.Char_Count+1 .. 
Output_Object.Tab_Stops.Stops(I).Stop-1 loop
+                   Ada.Text_IO.Put (Output_Object.Output_File, " ");
+                   Output_Object.Char_Count := Output_Object.Char_Count + 1;
+                   Output_Object.Out_Char_Count := 
Output_Object.Out_Char_Count + 1;
+--Ada.Text_IO.Put ("#");
+               end loop;
+               exit;
+           end if;
+       end loop; -- If we drop out without finding a tab, we just use the 
single
+                 -- space already written.
+--Ada.Text_IO.New_Line;
+       Output_Object.Output_Buffer_Space_Before := False; -- Spaces needed 
were output.
+    end Tab;
+
+
+    procedure Special_Character (Output_Object : in out Text_Output_Type;
+                                Char : in ARM_Output.Special_Character_Type) is
+       -- Output an special character.
+    begin
+       case Char is
+           when ARM_Output.EM_Dash =>
+               Ordinary_Character (Output_Object, '-'); -- Not available in 
plain text.
+           when ARM_Output.EN_Dash =>
+               Ordinary_Character (Output_Object, '-'); -- Not available in 
plain text.
+           when ARM_Output.GEQ =>
+               Ordinary_Text (Output_Object, ">="); -- Not available in plain 
text, use the Ada one.
+           when ARM_Output.LEQ =>
+               Ordinary_Text (Output_Object, "<="); -- Not available in plain 
text, use the Ada one.
+           when ARM_Output.NEQ =>
+               Ordinary_Text (Output_Object, "/="); -- Not available in plain 
text, use the Ada one.
+           when ARM_Output.PI =>
+               Ordinary_Text (Output_Object, "PI"); -- Not available in plain 
text.
+           when ARM_Output.Left_Ceiling =>
+               Ordinary_Text (Output_Object, "Ceiling("); -- Not available in 
plain text.
+           when ARM_Output.Right_Ceiling =>
+               Ordinary_Text (Output_Object, ")"); -- Not available in plain 
text.
+           when ARM_Output.Left_Floor =>
+               Ordinary_Text (Output_Object, "Floor("); -- Not available in 
plain text.
+           when ARM_Output.Right_Floor =>
+               Ordinary_Text (Output_Object, ")"); -- Not available in plain 
text.
+           when ARM_Output.Thin_Space =>
+               Ordinary_Text (Output_Object, " "); -- Not available in plain 
text.
+           when ARM_Output.Left_Quote =>
+               Ordinary_Text (Output_Object, "`"); -- Not available in plain 
text, use back-quote.
+           when ARM_Output.Right_Quote =>
+               Ordinary_Text (Output_Object, "'"); -- Not available in plain 
text, use quote.
+           when ARM_Output.Left_Double_Quote =>
+               Ordinary_Text (Output_Object, """"); -- Not available in plain 
text, use double quote.
+           when ARM_Output.Right_Double_Quote =>
+               Ordinary_Text (Output_Object, """"); -- Not available in plain 
text, use double quote.
+           when ARM_Output.Small_Dotless_I =>
+               Ordinary_Text (Output_Object, "i"); -- Not available in plain 
text, use the nearest text.
+           when ARM_Output.Capital_Dotted_I =>
+               Ordinary_Text (Output_Object, "I"); -- Not available in plain 
text, use the nearest text.
+       end case;
+    end Special_Character;
+
+
+    procedure Unicode_Character (Output_Object : in out Text_Output_Type;
+                                Char : in ARM_Output.Unicode_Type) is
+       -- Output a Unicode character, with code position Char.
+       Char_Code : constant String := ARM_Output.Unicode_Type'Image(Char);
+    begin
+       -- We don't check, but we assume this is not a normal character.
+       Ordinary_Text (Output_Object, "<Unicode-" & 
Char_Code(2..Char_Code'Last) & ">");
+    end Unicode_Character;
+
+
+    procedure End_Hang_Item (Output_Object : in out Text_Output_Type) is
+       -- Marks the end of a hanging item. Call only once per paragraph.
+       -- Raises Not_Valid_Error if the paragraph style is not in
+       -- Text_Prefixed_Style_Subtype, or if this has already been
+       -- called for the current paragraph, or if the paragraph was started
+       -- with No_Prefix = True.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if not Output_Object.Is_Hanging then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not a hanging paragraph");
+       end if;
+       if Output_Object.Saw_Hang_End then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Already saw the end of the hanging part");
+       end if;
+       Output_Object.Saw_Hang_End := True;
+
+       if Output_Object.Char_Count >= Output_Object.Indent_Amount then
+           if Output_Object.Output_Buffer_Len /= 0 then
+               Spill (Output_Object);
+           end if;
+           Ada.Text_IO.New_Line (Output_Object.Output_File);
+            Make_Indent (Output_Object);
+       else
+           Spill (Output_Object);
+           for I in Output_Object.Char_Count + 1 ..
+                    Output_Object.Indent_Amount loop
+               Ada.Text_IO.Put (Output_Object.Output_File, ' ');
+           end loop;
+           Output_Object.Char_Count := Output_Object.Indent_Amount;
+           Output_Object.Out_Char_Count := Output_Object.Indent_Amount;
+           Output_Object.Output_Buffer_Space_Before := False; -- Spaces needed 
were output.
+       end if;
+    end End_Hang_Item;
+
+
+    procedure Text_Format (Output_Object : in out Text_Output_Type;
+                          Format : in ARM_Output.Format_Type) is
+       -- Change the text format so that all of the properties are as 
specified.
+       -- Note: Changes to these properties ought be stack-like; that is,
+       -- Bold on, Italic on, Italic off, Bold off is OK; Bold on, Italic on,
+       -- Bold off, Italic off should be avoided (as separate commands).
+       use type ARM_Output.Change_Type;
+       use type ARM_Output.Location_Type;
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       if Format.Location /= Output_Object.Location then
+           if Output_Object.Location /= ARM_Output.Normal then
+               Buffer(Output_Object, ')');
+           end if;
+       end if;
+       if Format.Change /= Output_Object.Change then
+           if Format.Change = ARM_Output.Both then
+               -- Open only the one(s) needed:
+               case Output_Object.Change is
+                   -- Note: Version is not used.
+                   when ARM_Output.Insertion =>
+                       -- Open the deletion:
+                       Buffer(Output_Object, '[');
+                   when ARM_Output.Deletion =>
+                       -- Open the insertion:
+                       Buffer(Output_Object, '{');
+                   when ARM_Output.None =>
+                       Buffer(Output_Object, '{');
+                       Buffer(Output_Object, '[');
+                   when ARM_Output.Both =>
+                       null;
+               end case;
+           elsif Output_Object.Change = ARM_Output.Both then
+               -- Close only the one(s) needed:
+               case Format.Change is
+                   -- Note: Version is not used.
+                   when ARM_Output.Insertion =>
+                       -- Close the deletion:
+                       Buffer(Output_Object, ']');
+                   when ARM_Output.Deletion =>
+                       -- Close the insertion:
+                       Buffer(Output_Object, '}');
+                   when ARM_Output.None =>
+                       Buffer(Output_Object, ']');
+                       Buffer(Output_Object, '}');
+                   when ARM_Output.Both =>
+                       null;
+               end case;
+           else -- Both can't get here.
+               case Output_Object.Change is
+                   when ARM_Output.Insertion =>
+                       Buffer(Output_Object, '}');
+                   when ARM_Output.Deletion =>
+                       Buffer(Output_Object, ']');
+                   when ARM_Output.None =>
+                       null;
+                   when ARM_Output.Both =>
+                       Buffer(Output_Object, ']');
+                       Buffer(Output_Object, '}');
+               end case;
+               case Format.Change is
+                   -- Note: Version is not used.
+                   when ARM_Output.Insertion =>
+                       Buffer(Output_Object, '{');
+                   when ARM_Output.Deletion =>
+                       Buffer(Output_Object, '[');
+                   when ARM_Output.None =>
+                       null;
+                   when ARM_Output.Both =>
+                       Buffer(Output_Object, '{');
+                       Buffer(Output_Object, '[');
+               end case;
+           end if;
+           Output_Object.Change := Format.Change;
+       end if;
+       if Format.Location /= Output_Object.Location then
+           if Format.Location /= ARM_Output.Normal then
+               Buffer(Output_Object, '(');
+           end if;
+           Output_Object.Location := Format.Location;
+       end if;
+       null; -- Nothing else to do for plain text.
+    end Text_Format;
+
+
+    procedure Clause_Reference (Output_Object : in out Text_Output_Type;
+                               Text : in String;
+                               Clause_Number : in String) is
+       -- Generate a reference to a clause in the standard. The text of
+       -- the reference is "Text", and the number of the clause is
+       -- Clause_Number. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end Clause_Reference;
+
+
+    procedure Index_Target (Output_Object : in out Text_Output_Type;
+                           Index_Key : in Natural) is
+       -- Generate a index target. This marks the location where an index
+       -- reference occurs. Index_Key names the index item involved.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, nothing is generated.
+    begin
+       if not Output_Object.Is_Valid then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not valid object");
+       end if;
+       if not Output_Object.Is_In_Paragraph then
+           Ada.Exceptions.Raise_Exception (ARM_Output.Not_Valid_Error'Identity,
+               "Not in paragraph");
+       end if;
+       null; -- Nothing to do for plain text.
+    end Index_Target;
+
+
+    procedure Index_Reference (Output_Object : in out Text_Output_Type;
+                              Text : in String;
+                              Index_Key : in Natural;
+                              Clause_Number : in String) is
+       -- Generate a reference to an index target in the standard. The text
+       -- of the reference is "Text", and Index_Key and Clause_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end Index_Reference;
+
+
+    procedure DR_Reference (Output_Object : in out Text_Output_Type;
+                           Text : in String;
+                           DR_Number : in String) is
+       -- Generate a reference to an DR from the standard. The text
+       -- of the reference is "Text", and DR_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end DR_Reference;
+
+
+    procedure AI_Reference (Output_Object : in out Text_Output_Type;
+                           Text : in String;
+                           AI_Number : in String) is
+       -- Generate a reference to an AI from the standard. The text
+       -- of the reference is "Text", and AI_Number denotes
+       -- the target (in unfolded format). For hyperlinked formats, this should
+       -- generate a link; for other formats, the text alone is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end AI_Reference;
+
+
+    procedure Local_Target (Output_Object : in out Text_Output_Type;
+                           Text : in String;
+                           Target : in String) is
+       -- Generate a local target. This marks the potential target of local
+       -- links identified by "Target". Text is the text of the target.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, only the text is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end Local_Target;
+
+
+    procedure Local_Link (Output_Object : in out Text_Output_Type;
+                         Text : in String;
+                         Target : in String;
+                         Clause_Number : in String) is
+       -- Generate a local link to the target and clause given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end Local_Link;
+
+
+    procedure Local_Link_Start (Output_Object : in out Text_Output_Type;
+                               Target : in String;
+                               Clause_Number : in String) is
+       -- Generate a local link to the target and clause given.
+       -- The link will surround text until Local_Link_End is called.
+       -- Local_Link_End must be called before this routine can be used again.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       null; -- No link, nothing to do.
+    end Local_Link_Start;
+
+
+    procedure Local_Link_End (Output_Object : in out Text_Output_Type;
+                             Target : in String;
+                             Clause_Number : in String) is
+       -- End a local link for the target and clause given.
+       -- This must be in the same paragraph as the Local_Link_Start.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       null; -- No link, nothing to do.
+    end Local_Link_End;
+
+
+    procedure URL_Link (Output_Object : in out Text_Output_Type;
+                       Text : in String;
+                       URL : in String) is
+       -- Generate a link to the URL given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+    begin
+       Ordinary_Text (Output_Object, Text); -- Nothing special in this format.
+    end URL_Link;
+
+
+    procedure Picture  (Output_Object : in out Text_Output_Type;
+                       Name  : in String;
+                       Descr : in String;
+                       Alignment : in ARM_Output.Picture_Alignment;
+                       Height, Width : in Natural;
+                       Border : in ARM_Output.Border_Kind) is
+       -- Generate a picture.
+       -- Name is the (simple) file name of the picture; Descr is a
+       -- descriptive name for the picture (it will appear in some web
+       -- browsers).
+       -- We assume that it is a .GIF or .JPG and that it will be present
+       -- in the same directory as the input files and the same directory as
+       -- the .HTML output files.
+       -- Alignment specifies the picture alignment.
+       -- Height and Width specify the picture size in pixels.
+       -- Border specifies the kind of border.
+    begin
+       case Alignment is
+           when ARM_Output.Inline |
+                ARM_Output.Float_Left | ARM_Output.Float_Right =>
+               -- Inside a paragraph:
+               Ordinary_Text (Output_Object, "[Picture: " & Name &
+                 " - " & Descr & "]");
+           when ARM_Output.Alone_Left | ARM_Output.Alone_Right |
+                ARM_Output.Alone_Center =>
+               -- Not in a paragraph:
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+               Ada.Text_IO.Put_Line (Output_Object.Output_File, "[Picture: " & 
Name &
+                 " - " & Descr & "]");
+               Ada.Text_IO.New_Line (Output_Object.Output_File);
+       end case;
+    end Picture;
+
+end ARM_Text;
diff --git a/packages/ada-ref-man/progs/arm_text.ads 
b/packages/ada-ref-man/progs/arm_text.ads
new file mode 100755
index 0000000..a4596ff
--- /dev/null
+++ b/packages/ada-ref-man/progs/arm_text.ads
@@ -0,0 +1,453 @@
+with ARM_Output,
+     ARM_Contents,
+     Ada.Text_IO;
+package ARM_Text is
+
+    --
+    -- Ada reference manual formatter (ARM_Form).
+    --
+    -- This package defines the text output object.
+    -- Output objects are responsible for implementing the details of
+    -- a particular format.
+    --
+    -- ---------------------------------------
+    -- Copyright 2000, 2002, 2004, 2005, 2006, 2007, 2011, 2012
+    --   AXE Consultants. All rights reserved.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  4/14/00 - RLB - Created base package.
+    --  4/18/00 - RLB - Added index and contents marker routines.
+    --  4/21/00 - RLB - Added line break and hard space routines.
+    --  4/24/00 - RLB - Added DR references and Insert/Delete text formats.
+    --  4/25/00 - RLB - Added size to format.
+    -- 5/10/00 - RLB - Added End_Hang_Item.
+    --  5/12/00 - RLB - Added No_Prefix to Start_Paragraph.
+    --  5/13/00 - RLB - Added Special_Character.
+    --  5/17/00 - RLB - Added New_Page.
+    --  5/22/00 - RLB - Added Includes_Changes to Create.
+    --  5/23/00 - RLB - Added Set_Column and New_Column.
+    --               - Added Tab_Info and Tab_Stops.
+    --  5/24/00 - RLB - Added Location to Text_Format.
+    --         - RLB - Added No_Breaks and Keep_with_Next to Start_Paragraph.
+    --  5/25/00 - RLB - Added Big_Files to Create. Added Justification.
+    --         - RLB - Added Separator_Lines and TOC routines.
+    --  5/26/00 - RLB - Added table operations.
+    --  6/ 2/00 - RLB - Added Soft_Line_Break.
+    --  8/ 2/00 - RLB - Added Soft_Hyphen_Break.
+    --  8/ 7/00 - RLB - Added Leading flag to Start_Paragraph.
+    --  8/17/00 - RLB - Replaced "Leading" by "Space_After".
+    --  8/22/00 - RLB - Added Revised_Clause_Header.
+    --  8/23/00 - RLB - Added Real_Char_Count.
+    --  7/18/02 - RLB - Removed Document parameter from Create, replaced by
+    --                 three strings and For_ISO boolean.
+    --         - RLB - Added AI_Reference.
+    --         - RLB - Added Change_Version_Type and uses.
+    --  9/10/04 - RLB - Added "Both" to possible changes to handle
+    --                 replacement of changed text.
+    --  9/14/04 - RLB - Moved Change_Version_Type to ARM_Contents.
+    --  5/27/05 - RLB - Added arbitrary Unicode characters.
+    --  1/11/06 - RLB - Eliminated dispatching Create in favor of tailored
+    --                 versions.
+    --  1/13/06 - RLB - Added new Link operations.
+    --  2/ 8/06 - RLB - Added additional parameters to the table command.
+    --  2/10/06 - RLB - Added even more additional parameters to the
+    --                 table command.
+    --         - RLB - Added picture command.
+    --  9/25/06 - RLB - Added Last_Column_Width to Start_Table.
+    -- 10/13/06 - RLB - Added Local_Link_Start and Local_Link_End to allow
+    --                 formatting in the linked text.
+    --  2/ 9/07 - RLB - Changed comments on AI_Reference.
+    --  2/13/07 - RLB - Revised to separate style and indent information
+    --                 for paragraphs.
+    -- 12/19/07 - RLB - Added limited colors to Text_Format.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+    -- 10/25/11 - RLB - Added old insertion version to Revised_Clause_Header.
+    --  8/31/12 - RLB - Added Output_Path.
+    -- 11/26/12 - RLB - Added subdivision names to Clause_Header and
+    --                 Revised_Clause_Header.
+
+    type Text_Output_Type is new ARM_Output.Output_Type with private;
+
+    procedure Create (Output_Object : in out Text_Output_Type;
+                     File_Prefix : in String;
+                     Output_Path : in String;
+                     Title : in String := "");
+       -- Create an Output_Object for a document.
+       -- The prefix of the output file names is File_Prefix - this
+       -- should be no more then 5 characters allowed in file names.
+       -- The result files will be written to Output_Path.
+       -- The title of the document is Title.
+
+    procedure Close (Output_Object : in out Text_Output_Type);
+       -- Close an Output_Object. No further output to the object is
+       -- allowed after this call.
+
+
+    procedure Section (Output_Object : in out Text_Output_Type;
+                      Section_Title : in String;
+                      Section_Name : in String);
+       -- Start a new section. The title is Section_Title (this is
+       -- intended for humans). The name is Section_Name (this is
+       -- intended to be suitable to be a portion of a file name).
+
+    procedure Set_Columns (Output_Object : in out Text_Output_Type;
+                          Number_of_Columns : in ARM_Output.Column_Count);
+       -- Set the number of columns.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Start_Paragraph (Output_Object : in out Text_Output_Type;
+                              Style     : in ARM_Output.Paragraph_Style_Type;
+                              Indent    : in ARM_Output.Paragraph_Indent_Type;
+                              Number    : in String;
+                              No_Prefix : in Boolean := False;
+                              Tab_Stops : in ARM_Output.Tab_Info := 
ARM_Output.NO_TABS;
+                              No_Breaks : in Boolean := False;
+                              Keep_with_Next : in Boolean := False;
+                              Space_After : in ARM_Output.Space_After_Type
+                                  := ARM_Output.Normal;
+                              Justification : in ARM_Output.Justification_Type
+                                  := ARM_Output.Default);
+       -- Start a new paragraph. The style and indent of the paragraph is as
+       -- specified. The (AA)RM paragraph number (which might include update
+       -- and version numbers as well: [12.1/1]) is Number. If the format is
+       -- a type with a prefix (bullets, hangining items), the prefix is
+       -- omitted if No_Prefix is true. Tab_Stops defines the tab stops for
+       -- the paragraph. If No_Breaks is True, we will try to avoid page breaks
+       -- in the paragraph. If Keep_with_Next is true, we will try to avoid
+       -- separating this paragraph and the next one. (These may have no
+       -- effect in formats that don't have page breaks). Space_After
+       -- specifies the amount of space following the paragraph. Justification
+       -- specifies the text justification for the paragraph. Not_Valid_Error
+       -- is raised if Tab_Stops /= NO_TABS for a hanging or bulleted format.
+
+    procedure End_Paragraph (Output_Object : in out Text_Output_Type);
+       -- End a paragraph.
+
+    procedure Category_Header (Output_Object : in out Text_Output_Type;
+                              Header_Text : String);
+       -- Output a Category header (that is, "Legality Rules",
+       -- "Dynamic Semantics", etc.)
+       -- (Note: We did not use a enumeration here to insure that these
+       -- headers are spelled the same in all output versions).
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Clause_Header (Output_Object     : in out Text_Output_Type;
+                            Header_Text       : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False);
+       -- Output a Clause header. The level of the header is specified
+       -- in Level. The Clause Number is as specified; the top-level (and
+       -- other) subdivision names are as specified. These should appear in
+       -- the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Revised_Clause_Header
+                           (Output_Object     : in out Text_Output_Type;
+                            New_Header_Text   : in String;
+                            Old_Header_Text   : in String;
+                            Level             : in ARM_Contents.Level_Type;
+                            Clause_Number     : in String;
+                            Version           : in 
ARM_Contents.Change_Version_Type;
+                            Old_Version       : in 
ARM_Contents.Change_Version_Type;
+                            Top_Level_Subdivision_Name : in 
ARM_Output.Top_Level_Subdivision_Name_Kind;
+                            No_Page_Break     : in Boolean := False);
+       -- Output a revised clause header. Both the original and new text will
+       -- be output. The level of the header is specified in Level. The Clause
+       -- Number is as specified; the top-level (and other) subdivision names
+       -- are as specified. These should appear in the table of contents.
+       -- For hyperlinked formats, this should generate a link target.
+       -- Version is the insertion version of the new text; Old_Version is
+       -- the insertion version of the old text.
+       -- If No_Page_Break is True, suppress any page breaks.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure TOC_Marker (Output_Object : in out Text_Output_Type;
+                         For_Start : in Boolean);
+       -- Mark the start (if For_Start is True) or end (if For_Start is
+       -- False) of the table of contents data. Output objects that
+       -- auto-generate the table of contents can use this to do needed
+       -- actions.
+
+    procedure New_Page (Output_Object : in out Text_Output_Type;
+                       Kind : ARM_Output.Page_Kind_Type := 
ARM_Output.Any_Page);
+       -- Output a page break.
+       -- Note that this has no effect on non-printing formats.
+       -- Any_Page breaks to the top of the next page (whatever it is);
+       -- Odd_Page_Only breaks to the top of the odd-numbered page;
+       -- Soft_Page allows a page break but does not force one (use in
+       -- "No_Breaks" paragraphs.)
+       -- Raises Not_Valid_Error if in a paragraph if Kind = Any_Page or
+       -- Odd_Page, and if not in a paragraph if Kind = Soft_Page.
+
+    procedure New_Column (Output_Object : in out Text_Output_Type);
+       -- Output a column break.
+       -- Raises Not_Valid_Error if in a paragraph, or if the number of
+       -- columns is 1.
+
+    procedure Separator_Line (Output_Object : in out Text_Output_Type;
+                             Is_Thin : Boolean := True);
+       -- Output a separator line. It is thin if "Is_Thin" is true.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Start_Table (Output_Object : in out Text_Output_Type;
+                          Columns : in ARM_Output.Column_Count;
+                          First_Column_Width : in ARM_Output.Column_Count;
+                          Last_Column_Width : in ARM_Output.Column_Count;
+                          Alignment : in ARM_Output.Column_Text_Alignment;
+                          No_Page_Break : in Boolean;
+                          Has_Border : in Boolean;
+                          Small_Text_Size : in Boolean;
+                          Header_Kind : in ARM_Output.Header_Kind_Type);
+       -- Starts a table. The number of columns is Columns; the first
+       -- column has First_Column_Width times the normal column width, and
+       -- the last column has Last_Column_Width times the normal column width.
+       -- Alignment is the horizontal text alignment within the columns.
+       -- No_Page_Break should be True to keep the table intact on a single
+       -- page; False to allow it to be split across pages.
+       -- Has_Border should be true if a border is desired, false otherwise.
+       -- Small_Text_Size means that the contents will have the AARM size;
+       -- otherwise it will have the normal size.
+       -- Header_Kind determines whether the table has headers.
+       -- This command starts a paragraph; the entire table is a single
+       -- paragraph. Text will be considered part of the caption until the
+       -- next table marker call.
+       -- Raises Not_Valid_Error if in a paragraph.
+
+    procedure Table_Marker (Output_Object : in out Text_Output_Type;
+                           Marker : in ARM_Output.Table_Marker_Type);
+       -- Marks the end of an entity in a table.
+       -- If Marker is End_Caption, the table caption ends and the
+       --      future text is part of the table header.
+       -- If Marker is End_Header, the table header ends and the
+       --      future text is part of the table body.
+       -- If Marker is End_Row, a row in the table is completed, and another
+       --      row started.
+       -- If Marker is End_Item, an item in the table header or body is ended,
+       --      and another started.
+       -- If Marker is End_Table, the entire table is finished.
+       -- Raises Not_Valid_Error if not in a table.
+
+    -- Text output: These are only allowed after a Start_Paragraph and
+    -- before any End_Paragraph. Raises Not_Valid_Error if not allowed.
+
+    procedure Ordinary_Text (Output_Object : in out Text_Output_Type;
+                            Text : in String);
+       -- Output ordinary text.
+       -- The text must end at a word break, never in the middle of a word.
+
+    procedure Ordinary_Character (Output_Object : in out Text_Output_Type;
+                                 Char : in Character);
+       -- Output an ordinary character.
+       -- Spaces will be used to break lines as needed.
+
+    procedure Hard_Space (Output_Object : in out Text_Output_Type);
+       -- Output a hard space. No line break should happen at a hard space.
+
+    procedure Line_Break (Output_Object : in out Text_Output_Type);
+       -- Output a line break. This does not start a new paragraph.
+       -- This corresponds to a "<BR>" in HTML.
+
+    procedure Index_Line_Break (Output_Object : in out Text_Output_Type;
+                               Clear_Keep_with_Next : in Boolean);
+       -- Output a line break for the index. This does not start a new
+       -- paragraph in terms of spacing. This corresponds to a "<BR>"
+       -- in HTML. If Clear_Keep_with_Next is true, insure that the next
+       -- line does not require the following line to stay with it.
+
+    procedure Soft_Line_Break (Output_Object : in out Text_Output_Type);
+       -- Output a soft line break. This is a place (in the middle of a
+       -- "word") that we allow a line break. It is usually used after
+       -- underscores in long non-terminals.
+
+    procedure Soft_Hyphen_Break (Output_Object : in out Text_Output_Type);
+       -- Output a soft line break, with a hyphen. This is a place (in the 
middle of
+       -- a "word") that we allow a line break. If the line break is used,
+       -- a hyphen will be added to the text.
+
+    procedure Tab (Output_Object : in out Text_Output_Type);
+       -- Output a tab, inserting space up to the next tab stop.
+       -- Raises Not_Valid_Error if the paragraph was created with
+       -- Tab_Stops = ARM_Output.NO_TABS.
+
+    procedure Special_Character (Output_Object : in out Text_Output_Type;
+                                Char : in ARM_Output.Special_Character_Type);
+       -- Output an special character.
+
+    procedure Unicode_Character (Output_Object : in out Text_Output_Type;
+                                Char : in ARM_Output.Unicode_Type);
+       -- Output a Unicode character, with code position Char.
+
+    procedure End_Hang_Item (Output_Object : in out Text_Output_Type);
+       -- Marks the end of a hanging item. Call only once per paragraph.
+       -- Raises Not_Valid_Error if the paragraph style is not in
+       -- Text_Prefixed_Style_Subtype, or if this has already been
+       -- called for the current paragraph, or if the paragraph was started
+       -- with No_Prefix = True.
+
+    procedure Text_Format (Output_Object : in out Text_Output_Type;
+                          Format : in ARM_Output.Format_Type);
+       -- Change the text format so that all of the properties are as 
specified.
+       -- Note: Changes to these properties ought be stack-like; that is,
+       -- Bold on, Italic on, Italic off, Bold off is OK; Bold on, Italic on,
+       -- Bold off, Italic off should be avoided (as separate commands).
+
+    procedure Clause_Reference (Output_Object : in out Text_Output_Type;
+                               Text : in String;
+                               Clause_Number : in String);
+       -- Generate a reference to a clause in the standard. The text of
+       -- the reference is "Text", and the number of the clause is
+       -- Clause_Number. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure Index_Target (Output_Object : in out Text_Output_Type;
+                           Index_Key : in Natural);
+       -- Generate a index target. This marks the location where an index
+       -- reference occurs. Index_Key names the index item involved.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, nothing is generated.
+
+    procedure Index_Reference (Output_Object : in out Text_Output_Type;
+                              Text : in String;
+                              Index_Key : in Natural;
+                              Clause_Number : in String);
+       -- Generate a reference to an index target in the standard. The text
+       -- of the reference is "Text", and Index_Key and Clause_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure DR_Reference (Output_Object : in out Text_Output_Type;
+                           Text : in String;
+                           DR_Number : in String);
+       -- Generate a reference to an DR from the standard. The text
+       -- of the reference is "Text", and DR_Number denotes
+       -- the target. For hyperlinked formats, this should generate
+       -- a link; for other formats, the text alone is generated.
+
+    procedure AI_Reference (Output_Object : in out Text_Output_Type;
+                           Text : in String;
+                           AI_Number : in String);
+       -- Generate a reference to an AI from the standard. The text
+       -- of the reference is "Text", and AI_Number denotes
+       -- the target (in unfolded format). For hyperlinked formats, this should
+       -- generate a link; for other formats, the text alone is generated.
+
+    procedure Local_Target (Output_Object : in out Text_Output_Type;
+                           Text : in String;
+                           Target : in String);
+       -- Generate a local target. This marks the potential target of local
+       -- links identified by "Target". Text is the text of the target.
+       -- For hyperlinked formats, this should generate a link target;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link (Output_Object : in out Text_Output_Type;
+                         Text : in String;
+                         Target : in String;
+                         Clause_Number : in String);
+       -- Generate a local link to the target and clause given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link_Start (Output_Object : in out Text_Output_Type;
+                               Target : in String;
+                               Clause_Number : in String);
+       -- Generate a local link to the target and clause given.
+       -- The link will surround text until Local_Link_End is called.
+       -- Local_Link_End must be called before this routine can be used again.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Local_Link_End (Output_Object : in out Text_Output_Type;
+                             Target : in String;
+                             Clause_Number : in String);
+       -- End a local link for the target and clause given.
+       -- This must be in the same paragraph as the Local_Link_Start.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure URL_Link (Output_Object : in out Text_Output_Type;
+                       Text : in String;
+                       URL : in String);
+       -- Generate a link to the URL given.
+       -- Text is the text of the link.
+       -- For hyperlinked formats, this should generate a link;
+       -- for other formats, only the text is generated.
+
+    procedure Picture  (Output_Object : in out Text_Output_Type;
+                       Name  : in String;
+                       Descr : in String;
+                       Alignment : in ARM_Output.Picture_Alignment;
+                       Height, Width : in Natural;
+                       Border : in ARM_Output.Border_Kind);
+       -- Generate a picture.
+       -- Name is the (simple) file name of the picture; Descr is a
+       -- descriptive name for the picture (it will appear in some web
+       -- browsers).
+       -- We assume that it is a .GIF or .JPG and that it will be present
+       -- in the same directory as the input files and the same directory as
+       -- the .HTML output files.
+       -- Alignment specifies the picture alignment.
+       -- Height and Width specify the picture size in pixels.
+       -- Border specifies the kind of border.
+
+private
+
+    subtype Buffer_String is String (1 .. 120);
+    subtype Prefix_String is String(1..5);
+    type Text_Output_Type is new ARM_Output.Output_Type with record
+       Is_Valid : Boolean := False;
+       Is_In_Paragraph : Boolean := False;
+       Is_In_Table : Boolean := False; -- Are we processing a table?
+       Is_Hanging : Boolean := False; -- If we are in a paragraph,
+                                      -- is it a hanging paragraph?
+       Saw_Hang_End : Boolean := False; -- If we are in a hanging paragraph,
+                                      -- have we seen the end of the hanging 
part yet?
+       Output_Buffer : Buffer_String;  -- Output buffer to make smarter breaks.
+       Output_Buffer_Len : Natural := 0; -- This should be empty between 
paragraphs.
+                       -- The idea is that the buffer is always logically
+                       -- preceeded by a space. Thus it is always OK to
+                       -- move the text in the buffer to the next line.
+       Output_Buffer_Space_Before : Boolean := False;
+                       -- Do we need to output a space before the buffer?
+       Output_File : Ada.Text_IO.File_Type;
+       Output_Path : Buffer_String;
+       Output_Path_Len : Natural := 0;
+       File_Prefix : Prefix_String; -- Blank padded.
+       Char_Count : Natural := 0; -- Characters on current line.
+       Out_Char_Count : Natural := 0; -- Characters output on current line.
+       Indent_Amount : Natural := 0; -- Amount to indent paragraphs.
+       Change : ARM_Output.Change_Type := ARM_Output.None;
+       Location : ARM_Output.Location_Type := ARM_Output.Normal;
+       Tab_Stops : ARM_Output.Tab_Info := ARM_Output.NO_TABS;
+    end record;
+
+end ARM_Text;
diff --git a/packages/ada-ref-man/progs/command.txt 
b/packages/ada-ref-man/progs/command.txt
new file mode 100755
index 0000000..f927f06
--- /dev/null
+++ b/packages/ada-ref-man/progs/command.txt
@@ -0,0 +1,1360 @@
+Ada formatting tool.
+
+Copyright 2000, 2002, 2004, 2005, 2006, 2007, 2009, 2011, 2012, 2016
+   AXE Consultants.
+P.O. Box 1512, Madison WI  53701
+E-Mail: address@hidden
+
+ARM_Form is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 3
+as published by the Free Software Foundation.
+
+AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+A copy of the GNU General Public License is available in the file
+gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+Otherwise, see <http://www.gnu.org/licenses/>.
+
+If the GPLv3 license is not satisfactory for your needs, a commercial
+use license is available for this tool. Contact Randy at AXE Consultants
+for more information.
+
+
+The formatting tool is written in Ada 2005, but mainly uses Ada 95 constructs.
+Thus, it should be possible to compile it with an Ada 95 compiler with only
+small modifications.
+
+
+Running the formating tool:
+
+The formating tool reads the source text input files (.MSS files) in a
+Scribe-like format. The files to read, and general formatting parameters,
+are controlled by a master input file (.MSM file). The tool allows determining
+the output document, format, and other properties.
+
+The output of the tool is written into a subdirectory
+"Output" of the directory where Arm_Form is run. The tool is self-contained; it
+does not require any pre or post processing except to have Word create the real
+table of contents for the .RTF outout.
+
+Usage: Arm_Form <Master_File> [<Format>[ <Changes>[ <BaseVers> [<ChgVers>[ 
<Output_Path>]]]]]
+
+The <Master_File> specifies the layout of the document to generate (see below).
+If <Master_File> has no extension, ".MSM" is assumed.
+
+The formats are:
+   Text: Pure text files. These are missing a lot of formatting; we recommend
+        using the HTML versions instead.
+   HTML: (Default) HTML files. The HTML is designed for HTML version 4.0. Old
+         browsers may display the documents with little formatting.
+   RTF:  RTF files. The RTF files are designed for Word 97 and later. PDF
+        versions should be created from these file using Word and Adobe tools.
+   Corr: Text files with !corrigendum like markup.
+   Info: File in the open source Info format (not supported by AXE).
+
+<Changes> are:
+   No-Changes: The original text (same as specifying version 0).
+   New-Only: Text with changes applied through the specified change
+             version (<ChgVers>). There are no marking for changes.
+   Show-Changes: The text with changes shown and marked for versions
+                 <BaseVers> though <ChgVers>. Changes for older versions
+                 are applied without marking. For HTML, deleted text is shown
+                 as struck-through and inserted text as underlined. Changes for
+                different versions are in different colors.
+                For RTF, this uses Word's "changes" mechanisms, which can
+                 shows changes in different colors.
+   New-Changes: The text with changes applied for versions <BaseVers> though
+                <ChgVers>, with insertions marked. Deletions are marked by just
+                a single blank space. (See Show-Changes for how these are
+                marked). This form is intended to be used with revision bars
+                in Word 97/2000 (Older versions of Word do not reformat the
+                document when deletions are hidden, leaving unsightly blank
+                spaces. This is not a problem with current versions of Word).
+
+<BaseVers> and <ChgVers> = a value in 0 .. 9 representing the base and
+                primary change version desired.
+
+<Output_Path> = the path to which to write the result files. This must end
+   with a path separator.
+
+Summary of commands used in the ARM text input files (.MSM and .MSS files):
+
+Syntax summary:
+
+Commands are represented by @<command_name>[<args>]. The command name can be an
+identifier, or certain special characters. The command name is not
+case-sensitive: @newpage; @NewPage; @NEWPAGE; all represent the same command.
+The argument list (if any) is surrounded by one of the bracket pairs
+(), {}, [], <>, `', "", or %%. These pairs are equivalent, however the matching
+end character must be used to close an argument list. The arguments can be 
anything.
+It can be another sequence of text, keywords, or other items (described below).
+In this list below, arguments are always signified by {}, but any of the other
+characters can be used. (Note that there is no escape character for the
+brackets, so if one of the bracket characters appears in the text, a different
+pair of bracket characters should be used. Also note that there is no sane way
+to tell the end of a quoted parameter from the end of a nested quoted command,
+so parameters nested in a "" pair should never used "" as their brackets. A
+similar restriction applies to the %% pair.)
+
+-----------------
+
+Master file (.MSM) command summary:
+
+The master file determines the source files that make up a document and their
+collating order, along with general properties of the output as a whole.
+
+Note that regular source commands are not allowed in the master file, unless
+otherwise noted.
+
+Source commands (the order of these determines the collating order):
address@hidden<File 
Name>,SectionName=<Name>,SectionNumber=<AlphaNum>,NewSection=[T|F]} -
+     Specifies a source file for the document. The <File Name> indicates where
+     the source file is found, and may include a path if desired. If <File 
Name>
+     does not include an extension, ".MSS" is assumed. <Name> gives
+     a short name for the section; it will be used to name the output files,
+     if appropriate for the specified kind of output. <AlphaNum> specifies the
+     section number; it is either a number in the range 0 to 20, or a letter
+     from A .. Z. If NewSection is true (T), this is the first file for the
+     indicated section; otherwise, this is a continuation file for the
+     section. (If this setting is wrong, there will be extra or missing headers
+     for the section.)
address@hidden
+     Specifies where the table of contents will appear in the collating order;
+     if this is omitted, there will be no table of contents.
+
+Global properties:
+
address@hidden
+     If given in the master file, index and glossary entries are visibly
+     displayed in the document. If this command is not given, these items are
+     not displayed (although they may create links if the
+     output format supports links).
address@hidden
+     If given in the master file, or ShowIndexEntries is not given, Index and
+     glossary entries are not displayed in the document (although they may
+     create links if the output format supports links).
address@hidden
+     If given in the master file, annotations will be included in the output.
+     "Annotations" are often described as belonging to the "AARM" below.
+     "RMOnly" text is not included in the output. If this command is not given,
+     the annotations are not included in any form, and "RMOnly" text is
+     included.
address@hidden
+     If given in the master file, or ShowAnnotations is not given,
+     annotations are not included in the output in any form, and "RMOnly"
+     text is included in the output.
address@hidden
+     If given in the master file, text marked "ISOOnly" will be included in the
+     output. "NotISO" text is not included in the output. If this command is
+     not given, "ISOOnly" text is not included in any form, and "NotISO" text
+     is included.
address@hidden
+     If given in the master file, or ShowISO is not given,
+     "ISOOnly" text is not included in the output in any form, and "NotISO"
+     text is included in the output.
address@hidden
+     If given in the master file, non-terminals are linked to their original
+     definition (as given in @Syn and similar commands). Otherwise,
+     non-terminals are not linked.
address@hidden
+     If given in the master file, paragraphs are numbered per subclause
+     (as in the Ada Reference Manual). Otherwise, paragraphs are not numbered.
address@hidden<version>],Text=[<title_text>]}
+     The document title for version, this is used in headers and footers.
+     If no title is given for the current version, the title of the previous
+     version is used; to use the same title for all versions, give the title
+     for Version=[0].
address@hidden<Prefix>}
+     This specifies the prefix of the output file(s). All of the output files
+     will start with this prefix. Keep this short!
address@hidden|Fixed|Roman}
+     This specifies which font is used to display examples.
+     This changes the @Exam{<text>} and @begin{Example} formats.
+     By default, the Fixed font is used.
address@hidden|Roman}
+     This specifies which font is used to display the body of the document.
+     This changes all styles that are not defined to use a specific font.
+     By default, the Roman font is used.
address@hidden|ISO2004}
+     This specifies the format of notes sections.
+     If Ada95, the word "NOTES" is on a separate line, and each note is
+     numbered, with the numbers starting at 1 for each section.
+     If ISO2004, each note starts with the word "NOTE", and a number,
+     with the numbers starting from 1 for each subclause.
+     If there is only one note in a subclause, the number should be omitted.
address@hidden|ISO2004}
+     This specifies the format of contents sections.
+     If Ada95, the title is "Table of Contents".
+     If ISO2004, the title is "Contents".
address@hidden|ISO2004}
+     This specifies the format of numbered lists ("enumerate").
+     If Ada95, they're numbered "1.";
+     If ISO2004, they're lettered "a)"; inner lists are numbered "1)".
address@hidden|Section|Clause}
+     This specifies the names of subdivisions and the format of section 
headers.
+     Note: In this document, top-level subdivisions are called sections,
+     and lower-level subdivisions are called clauses, subclauses,
+     and subsubclauses. The names in the final output may be different.
+     If Chapter, top-level subdivisions are called "chapters" and this appears
+     in the titles. Lower-level subdivisions are called "sections". If Section,
+     top-level subdivisions are called "sections" and this appears in the
+     titles. Lower-level subdivisions are called "clauses". If Clause,
+     top-level subdivisions are called "clauses" and this does not appear in
+     the title of top-level subdivisions (Annex still appears). Lower-level
+     subdivisions are called "subclauses". If this is not given, "Section"
+     is used.
+
+HTML Output properties:
+
address@hidden
+     If given in the master file, generate a single large file for
+     the output, rather than one file per clause. If this is not given,
+     smaller files are generated.
address@hidden
+     If given in the master file, use 8.3 MS-DOS style filenames.
+     In this case, the @FilePrefix must be less than 4 characters in size,
+     and no clause or subclause number should exceed 35
+     if @SingleHTMLOutputFile isn't given.
address@hidden|4Comp|4],Unicode=[T|F]}
+     Specifies the kind of HTML that will be output.
+     If Version=3, HTML compatible with (virtually) all browsers will be
+     generated, but it will have limited formatting. The Unicode setting is
+     ignored; special characters will be output using ASCII equivalents,
+     and explicit output with the @Unicode command is prohibited and will
+     cause an error.
+     If Version=4Comp, the HTML will have more extensive formatting, but older
+     browsers will have more limited formatting. If Unicode is true (T),
+     Unicode characters will be used where appropriate (presuming the
+     characters are available on the US version of Windows 2000); otherwise
+     ASCII equivalents will be used. In either case, explicit Unicode
+     characters (@Unicode) are generated.
+     If Version=4, the HTML will have the best formatting on modern
+     browsers (IE 5.0, Firefox 1.0, Netscape 6.2, and later versions of these)
+     but older browsers will have almost no formatting. If Unicode is true (T),
+     Unicode characters will be used where appropriate (presuming the
+     characters are available on the US version of Windows 2000); otherwise
+     ASCII equivalents will be used. In either case, explicit Unicode
+     characters (@Unicode) are generated.
+     The default is a version of 4Comp with Unicode = T.
address@hidden|QuadSpace|EmulateFixedOnly|EmulateFixedOnlyQuad|EmulateAll]}
+     Specifies how tabs are emulated for text.
+     (HTML does not have tabs, they have to be faked.)
+     For SingleSpace, the tabs are replaced by a single space (always).
+     For QuadSpace, the tabs are replaced by a four hard spaces (always).
+     For EmulateFixedOnly, the tabs are replaced by an appropriate number of
+     hard spaces for styles using fixed fonts (or if the tab is the first
+     character on a line); for other styles, a single space is used.
+     For EmulateFixedOnlyQuad, the tabs are replaced by an appropriate number
+     of hard spaces for styles using fixed fonts; for other styles, four hard
+     spaces are used.
+     For EmulateAll, the tabs are replaced by an appropriate number of
+     hard spaces for all styles. Note that the number of spaces is a guess
+     for non-fixed fonts, and it is unlikely that the tabbed text will line up
+     perfectly.
+     EmulateFixedOnly is the default (as the result will look correct in a
+     fixed font).
address@hidden<URL>],SrchName=[<URL>],IndexName=[<URL>],
+   UseButtons=[T|F],OnTop=[T|F],OnBottom=[T|F]}
+     Specifies the properties of the Navigation Bar in the files.
+     RefName gives the URL of the references page. This can be part of the
+     current document (in which case the URL can be relative), or an external
+     page. It will be the URL assigned to the "References" button/label; if set
+     to null, the "References" button/label will link to the section named
+     "References" if one exists, or the button/label will be omitted otherwise.
+     SrchName gives the URL of the search page. This can be a relative or
+     absolute URL. It will be the URL assigned to the "Search" button/label; if
+     set to null, the "Search" button/label will link to the section named
+     "Search" if one exists, or the button/label will be omitted otherwise.
+     IndexName gives the URL of the search page. This can be a relative or
+     absolute URL. It will be the URL assigned to the "Index" button/label;
+     if set to null, the "Index" button/label will link to the section named
+     "Index" if one exists, or the button/label will be omitted otherwise.
+     If UseButtons is true (T), the navigation bar will use graphic buttons;
+     otherwise, text labels will be generated.
+     If OnTop is true (T), the navigation bar will be on the top of the
+     document page(s) in the header; otherwise it will not appear on top.
+     If OnBottom is true (T), the navigation bar will be on the bottom of the
+     document page(s) in the footer; otherwise it will not appear on the 
bottom.
+     One of OnTop or OnBottom should be true, or navigation will be difficult!
+     By default, the "References" and "Search" buttons are omitted, buttons
+     are used, and navigation bars are shown on the top and bottom of every
+     page.
address@hidden<Script>}
+     Specifies Script code (including the <SCRIPT> </SCRIPT> tags) that should
+     go directly before the </HEAD> on each page. By default, this is empty.
+     This command was designed to allow placing Google Analytics code on
+     each page for web sites that use that for tracking.
address@hidden<HTML_for_Header>}
+     Specifies HTML markup for the header of the the document. This will be
+     repeated on every page, and needs to be a self-contained HTML fragment.
+     By default, this is empty.
address@hidden<HTML_for_Footer>}
+     Specifies HTML markup for the footer of the the document. This will be
+     repeated on every page, and needs to be a self-contained HTML fragment.
+     By default, this is empty.
address@hidden<Color]>,Background=[<Color>],Link=[<Color>],VLink=[<Color>],
+   ALink=[<Color>]}
+     Specifies the default text, background and link colors for the document.
+     <Color> is a color in standard HTML format ("#rrggbb", with each letter
+     replaced by a hex digit).
+     VLink is the color for visited links; ALink is the color for links
+     being clicked. The default is:
+     @HTMLColor{Text=[#000000],Background=[#FFFFF0],Link=[#0000FF],
+       VLink=[#800080],ALink=[#FF0000]}
+     That is, black text, cream background, blue links, purple visited links,
+     and red active links.
+
+
+RTF Output properties:
+
address@hidden
+     If given in the master file, generate a single large file for
+     the output, rather than one file per section. If this is not given,
+     smaller files are generated.
address@hidden<version>],Text=[<title_text>]}
+     The text given in the header before the title; this is *RTF* text; no
+     embedded commands can be given here. If no header prefix is given for the
+     current version, the prefix of the previous version is used; to use the
+     same prefix for all versions, give the prefix for Version=[0]. If this is
+     empty, only the title will be used.
address@hidden<version>],Text=[<title_text>]}
+     The fixed text given in the footer; this is *RTF* text; no embedded
+     commands can be given here. If no footer text is given for the current
+     version, the text of the previous version is used; to use the same text 
for
+     all versions, give the prefix for Version=[0]. This text will not be used
+     if UseClauseName is True.
address@hidden|F],UseClauseName=[T|F],UseISOFormat=[T|F]}
+     Specifies the format of the footer. The date will be included if
+     UseDate is true (T), otherwise it will be omitted; by default it is
+     included. The footer text will be the name of the clause that starts the
+     page (other clauses may start on the page) if UseClauseName is true (T),
+     otherwise it will be the FooterText. The defailt is to use clause names.
+     The text font and size will match the ISO requirements if UseISOFormat
+     is true (T) - this means the footer will be in a Swiss font with multiple
+     sizes; otherwise (and this is the default) the footer will be in the body
+     font with a single size.
address@hidden|A4|HalfLetter|Ada95}
+     Specifies the size of the RTF output; Letter is used if this is not
+     specified. Letter is 8.5"x11"; A4 is European standard size; HalfLetter
+     is 5.5"x8.5"; Ada95 is 7"x9".
address@hidden|Souvenir],SansSerif=[Arial|Helvetica]}
+     Specifies the specific fonts used for the Serif and Sans Serif fonts.
+     If not specified, Times ("Times New Roman") and Arial are used.
address@hidden<version>],Text=[<title_text>]}
+     The specified text names the version as the "author" of any revisions.
+     For instance, for the Ada Standard, 
@RTFVersionName{Version=[2],Text=[Amendment 1]}
+     gives the author name "Amendment 1" to all version 2 revisions.
+
+Other commands:
+
address@hidden<text>} - The text is a comment to the master file, and is ignored
+            on output.
+
+
+
+---------------------
+
+Source file (.MSS) command summary:
+
+Meta-commands:
+
+@; - Signifies nothing. Used to break a parameterless command from following
+     text: "@LegalityName@;s" (otherwise the command "LegalityNames" would be
+     looked for).
+@: - After a period, signifies an sentence ending period, rather than a
+     initial period. Not used currently, but remains in text in case someone
+     cares eventually. (Only matters if the amount of space after sentences
+     is different than the amount between words within a sentence.)
+@| - Marks a potential line break point, without inserting a hyphen. (Scribe
+     says that it is a "zero-length word".) Not used currently, as the RTF
+     command (\zwbo) prints a square box in both Word 97 and Word 2000 -- and
+     no break. Similarly, zero-width space in HTML 4.0 doesn't work on Internet
+     Exploder 4.1 - it also prints a square box and no break.
address@hidden - Marks a potential line break point, inserting a hyphen if the 
break is
+     used. (A so-called "soft-hyphen"). Unlike the above, this actually
+     works in Word 97 and HTML. &shy.
+
+
+Text commands:
+
+@@ - the literal character '@'.
address@hidden - A tab, or end of centered text. Also used to mark the 
separation between
+     hanging text and the rest of the paragraph.
address@hidden - Sets a tab stop at the current text location. (*Can't 
implement in RTF and
+     HTML does not have tabs at all; has been removed from the text *)
+@  - [@<space>] - A hard space; cannot be used to insert a line break.
address@hidden - Line break inside a paragraph.
+
address@hidden<text>} - Superscript text (text size will be smaller).
address@hidden<text>} - Subscript text (text size will be smaller).
address@hidden<text>} - Bold text.
address@hidden<text>} - Italic text.
address@hidden<text>} - Roman font text.
address@hidden<text>} -Roman italic text (use for comments in examples).
address@hidden<text>} - Swiss font text.
address@hidden<text>} - Fixed-width font text.
address@hidden<text>} - Text is one size smaller. (Typically 1 point smaller).
address@hidden<text>} - Text is one size larger. (Typically 1 point larger).
address@hidden<text>} - Text is in a black color.
address@hidden<text>} - Text is in a red color.
address@hidden<text>} - Text is in a green color.
address@hidden<text>} - Text is in a blue color.
address@hidden<text>} - The text is a comment to the input files, and is ignored
+            on output.
address@hidden   - Insert a page break. Ends a paragraph.
address@hidden - Insert a page break in the RM (that is, when HideAnnotations is
+            used), ignored otherwise. Ends a paragraph. Use to insert page
+            breaks to make the printed RM look better.
address@hidden - Insert a column break. Only allowed in a multi-column formats.
+            Ends a paragraph.
address@hidden<version>} - Insert a page break if we are generating
+             <version> (and ends a paragraph). Otherwise, does nothing.
address@hidden<version>} - Insert a page break in the RM (that is,
+             when HideAnnotations is used) and we are generating <version>,
+            ignored otherwise. Ends a paragraph. Use to insert page
+            breaks to make the printed RM look better.
address@hidden<version>} - Insert a page break in the RM (that
+            is, when HideAnnotations is used), @ShowISO was given in
+             the master file, and we are generating <version>,
+            ignored otherwise. Ends a paragraph. Use to insert page
+            breaks to make the printed RM look better.
address@hidden<version>} - Insert a page break in the RM (that
+            is, when HideAnnotations is used), @ShowISO was not given in
+             the master file, and we are generating <version>,
+            ignored otherwise. Ends a paragraph. Use to insert page
+            breaks to make the printed RM look better.
address@hidden<version>} -  - Insert a column break if we are generating
+             <version>, otherwise does nothing. Only allowed in a multi-column
+            formats. Ends a paragraph.
address@hidden  - Insert a soft page break in a format that does not generally
+            allow one. A page is allowed (but not required) at this point.
+             [Note: This doesn't seem to work in Word 97, but we've kept it
+            anyway.]
address@hidden  - The following paragraph does not have a prefix (that is, 
hanging
+            text, numbers, or bullets). For example, if the paragraph is in
+            a bulleted list, it will not have a bullet. This command must be
+            given before any text for the paragraph (including index entries
+            and even spaces in example formats).
address@hidden  - Keep this paragraph with the next one (usually used on 
leadins,
+            like "The following example shows...:"). This command must be
+            given before any text for the paragraph.
address@hidden   - This paragraph leads in an example or list. Cut the space
+            following the paragraph (usually by 30%). This command must be
+            given before any text for the paragraph.
address@hidden  - This paragraph ends an item of some sort. Increase the space
+            following the paragraph (usually by 50%). This command must be
+            given before any text for the paragraph.
address@hidden - This paragraph has no number. This command must be
+            given before any text for the paragraph.
+
address@hidden  - Draw a thin separator line across the page. Ends any 
paragraph.
address@hidden - Draw a thick separator line across the page. Ends any 
paragraph.
+
+-- Section/Clause commands:
address@hidden<text>} - Start a labeled section (chapter). The title will be
+       "text". The formatter assigns section numbers.
address@hidden<text>} - Start a labeled section (chapter). The
+       title will be "text". The formatter assigns section numbers. No page
+       break before it.
address@hidden<text>} - Start a labeled (unqualified) annex. The title
+       will be "text". The formatter assigns annex letters.
address@hidden<text>} - Start a labeled informative annex. The title
+       will be "text". The formatter assigns annex letters.
address@hidden<text>} - Start a labeled normative annex. The title
+       will be "text". The formatter assigns annex letters.
address@hidden<text>} - Start a labeled clause. The title will be "text".
+       The formatter assigns clause numbers.
address@hidden<text>} - Start a labeled subclause. The title will be "text".
+       The formatter assigns subclause numbers.
address@hidden<text>} - Start a labeled subsubclause. The title will be "text".
+       The formatter assigns subsubclause numbers.
address@hidden<version>],
+    [InitialVersion=[<version>],]New=[<new_text>],Old=[<old_text>]} -
+       Start a labeled (unqualified) annex. The title will be "new_text". If
+        we are generating an old version of the document, the title is 
"old_text"
+        instead. (Note that annex references in commands always use the
+        new_text name.) The formatter assigns annex letters. Version is the
+        version number of the change (see @ChgRef for details); InitialVersion
+        is the original insertion version of the Old text (this defaults to 0
+        if not given).
address@hidden<version>],
+    [InitialVersion=[<version>],]New=[<new_text>],Old=[<old_text>]} -
+       Start a labeled normative annex. The title will be "new_text". If we
+        are generating an old version of the document, the title is "old_text"
+        instead. (Note that annex references in commands always use the
+        new_text name.) The formatter assigns annex letters. Version is the
+        version number of the change (see @ChgRef for details); InitialVersion
+        is the original insertion version of the Old text (this defaults to 0
+        if not given).
address@hidden<version>],
+    [InitialVersion=[<version>],]New=[<new_text>],Old=[<old_text>]} -
+       Start a labeled informative annex. The title will be "new_text". If we
+        are generating an old version of the document, the title is "old_text"
+        instead. (Note that annex references in commands always use the
+        new_text name.) The formatter assigns annex letters. Version is the
+        version number of the change (see @ChgRef for details); InitialVersion
+        is the original insertion version of the Old text (this defaults to 0
+        if not given).
address@hidden<version>],
+    [InitialVersion=[<version>],]New=[<new_text>],Old=[<old_text>]} -
+        Start a labeled section (chapter). The title will be "new_text". If we 
are
+        generating an old version of the document, the title is "old_text" 
instead.
+        (Note that clause references in commands always use the new_text name.)
+        The formatter assigns clause numbers. Version is the
+        version number of the change (see @ChgRef for details); InitialVersion
+        is the original insertion version of the Old text (this defaults to 0
+        if not given).
address@hidden<version>],
+    [InitialVersion=[<version>],]New=[<new_text>],Old=[<old_text>]} -
+        Start a labeled clause. The title will be "new_text". If we are
+        generating an old version of the document, the title is "old_text" 
instead.
+        (Note that clause references in commands always use the new_text name.)
+        The formatter assigns clause numbers. Version is the
+        version number of the change (see @ChgRef for details); InitialVersion
+        is the original insertion version of the Old text (this defaults to 0
+        if not given).
address@hidden<version>],
+    [InitialVersion=[<version>],]New=[<new_text>],Old=[<old_text>]} -
+        Start a labeled subclause. The title will be "new_text". If we are
+       generating an old version of the document, the title is "old_text" 
instead.
+       (Note that clause references in commands always use the new_text name.)
+        The formatter assigns subclause numbers. Version is the
+        version number of the change (see @ChgRef for details); InitialVersion
+        is the original insertion version of the Old text (this defaults to 0
+        if not given).
address@hidden<version>],
+    [InitialVersion=[<version>],]New=[<new_text>],Old=[<old_text>]} -
+        Start a labeled subsubclause. The title will be "new_text". If we are
+       generating an old version of the document, the title is "old_text" 
instead.
+       (Note that clause references in commands always use the new_text name.)
+        The formatter assigns subsubclause numbers. Version is the
+        version number of the change (see @ChgRef for details); InitialVersion
+        is the original insertion version of the Old text (this defaults to 0
+        if not given).
address@hidden<version>],Name=[<new_text>]} - Start a labeled
+        section (chapter). The title will be "new_text". If we are generating 
an old
+       version of the document, this clause does not exist. (Any clause 
references
+       ought to be in new text.) The formatter assigns clause numbers. Version
+       is the version number of the change (see @ChgRef for details).
address@hidden<version>],Name=[<new_text>]} - Start a labeled
+        clause. The title will be "new_text". If we are generating an old
+       version of the document, this clause does not exist. (Any clause 
references
+       ought to be in new text.) The formatter assigns clause numbers. Version
+       is the version number of the change (see @ChgRef for details).
address@hidden<version>],Name=[<new_text>]} - Start a labeled
+        subclause. The title will be "new_text". If we are generating an old
+       version of the document, this subclause does not exist. (Any subclause
+       references ought to be in new text.) The formatter assigns subclause
+        numbers. Version is the version number of the change (see @ChgRef for
+        details).
address@hidden<version>],Name=[<new_text>]} - Start a labeled
+        subsubclause. The title will be "new_text". If we are generating an old
+       version of the document, this subsubclause does not exist. (Any 
subsubclause
+       references ought to be in new text.) The formatter assigns subsubclause
+        numbers. Version is the version number of the change (see @ChgRef for
+        details).
address@hidden<version>],Name=[<new_text>]]} -
+       Start a labeled (unqualified) annex. The title will be "new_text". If we
+        are generating an old version of the document, this annex does not 
appear.
+        (Any annex references in commands ought to be "new text".) The
+        formatter assigns annex letters. Version is the
+        version number of the change (see @ChgRef for details).
address@hidden<version>],Name=[<new_text>]]} -
+       Start a labeled normative annex. The title will be "new_text". If we
+        are generating an old version of the document, this annex does not 
appear.
+        (Any annex references in commands ought to be "new text".) The
+        formatter assigns annex letters. Version is the
+        version number of the change (see @ChgRef for details).
address@hidden<version>],Name=[<new_text>]} -
+       Start a labeled informative annex. The title will be "new_text". If we
+        are generating an old version of the document, this annex does not 
appear.
+        (Any annex references in commands ought to be "new text".) The
+        formatter assigns annex letters. Version is the
+        version number of the change (see @ChgRef for details).
address@hidden<version>],Name=[<old_text>]} - Start a labeled
+        clause. The title will be "old_text". If we are generating a new
+       version of the document, this clause does not exist. (Any clause 
references
+       ought to be in old deleted text.) The formatter assigns clause numbers. 
Version
+       is the version number of the change (see @ChgRef for details).
+       [Note: We do not support deleting sections or annexes.]
address@hidden<version>],Name=[<old_text>]} - Start a labeled
+        subclause. The title will be "old_text". If we are generating a new
+       version of the document, this subclause does not exist. (Any subclause
+       references ought to be in old deleted text.) The formatter assigns 
subclause
+        numbers. Version is the version number of the change (see @ChgRef for
+        details).
address@hidden<version>],Name=[<old_text>]} - Start a labeled
+        subsubclause. The title will be "old_text". If we are generating a new
+       version of the document, this subsubclause does not exist. (Any 
subsubclause
+       references ought to be in old deleted text.) The formatter assigns 
subsubclause
+        numbers. Version is the version number of the change (see @ChgRef for
+        details).
+
address@hidden<text>} - Start an unnumbered section. (These are the
+       Forward and Introduction). This *can* be referenced by a reference,
+       and will appear in the table of contents.
address@hidden<text>} - Start an unnumbered subclause (a subclause of an
+       unnumbered section). These are formatting only, they cannot be
+       referenced, nor do they appear in the table of contents.
address@hidden<text>} - Start an unnumbered clause (a clause of an unnumbered
+       section). These are formatting only, they cannot be referenced, nor do
+       they appear in the table of contents.
address@hidden<text>} - Center the otherwise normal text. Note that this is a
+       paragraph style and is treated like a header.
address@hidden<text>} - Right justify the otherwise normal text. Note that this 
is a
+       paragraph style and is treated like a header.
+
address@hidden - Start a new clause without numbering or title - just a
+       page break to an odd page.
+
address@hidden<title>} - Generates a reference to the clause "title". (This must
+       match exactly except for case). The reference is of the form
+       "<clause number>, ``<title>''". (The ARG has directed that this be
+       changed to '<clause number>, "<title>"').
address@hidden<title>} - Generates a reference to the clause "title". (This must
+       match exactly except for case). The reference is of the form
+       "<clause number>".
address@hidden<num>} - Generates a reference to the clause with <num> as a
+       clause number. This is intended to be used internally to the tool,
+       not in document source (the tool assigns the clause numbers).
+
address@hidden<target-text>],Text=[<text>]} - Generates a target for
+       future @LocalLink commands at the current location. <target-text>
+        should be short, using alphanumeric characters. <text> will be
+       generated normally, using the current formatting (no formatting
+       is allowed in <text>).
address@hidden<target-text>],Sec=[<title>],Text=[<text>]} - Generates a
+       link to the target specifed in the section given by "title" (this
+       should have been defined by a @LocalTarget command). <text> will be
+       generated as the body of the link, using the current formatting (no
+       formatting in <text>).
address@hidden<URL>],Text=[<text>]} - Generates a link to the URL specified;
+       <text> will be the body of the link, using the current formatting (no
+       formatting in <text>). The URL should be a complete URL, including
+       "http://";.
address@hidden<AI>],Text=[<text>]} - Generates a link to the AI specified;
+       <text> will be the body of the link, using the current formatting (no
+       formatting in <text>). The AI should be an AI number in the full
+       format (AI95-0yyyy-zz, AI05-yyyy-z, or SI99-yyyy-z).
+
+-- Ada specific commands:
address@hidden<text>} - A non-terminal in normal text. This will be set in a 
Swiss
+             (sans-serif) font. Also, for HTML, this will linked to the
+              definition text; use @ntf instead if this is not a real
+              non-terminal.
address@hidden<text>} - Format as a non-terminal in normal text. This will be 
set
+              in a Swiss (sans-serif) font.
address@hidden<text>} - A keyword in normal text. This will be set in boldface.
address@hidden<text>} - Example text occurring in normal text. This will be set
+        in the example font (which is selected in the master file).
address@hidden<text>} - The body of an example comment; this is shown in the
+        roman font in italics. (This is the same as the @RI command, but
+        by using a separate name, we can change the format in the future.)
address@hidden<text>} - Marks text thought to be unnecessary in the RM. That is,
+       the rules are explained elsewhere. The text is formatted normally.
+       When annotations are shown, this text is surrounded in brackets.
+        When annotations are not shown, no special formatting is used.
+
address@hidden<Tabset>, ]LHS=<Non-terminal>, RHS=<Production>}
+       - Marks a syntax production.
+       <Production> contains @syn2 (and @synf) commands for RHS non-terminals.
+       <Tabset> defines any tabs needed by the <Production>.
+       The <Non-terminal> is indexed. The <Non-Terminal> and <Production>
+       (and the clause number) are sent to the syntax manager. Also, saves
+       <Non-terminal> for any following @Syn2 to use. The command also writes
+           @nt<Non-Terminal> ::= <Production>
+       to the output.
+       Note: <Non-Terminal> and <Production> allow @Chg commands.
address@hidden<prefix>} - Generates <prefix> in the italics of a non-terminal 
prefix.
address@hidden<name>} - Marks a non-terminal name in the production of a syntax 
rule.
+       If the current non-terminal is not null, generates a cross reference
+       entry: <Name> in <Non-Terminal> at <ClauseNum>. Also, generate an index
+       entry for the item: @Defn2(Term=<Name>,address@hidden). (For the 
purposes
+       of the index, all of Annex P is a single paragraph). Otherwise, is the
+       same as @nt.
address@hidden<name>} - Marks a non-terminal name in the production of a syntax 
rule,
+       for which there is no formal definition in the document. (Character
+       set names in Ada fall into this category).
+       If the current non-terminal is not null, generates a cross reference
+       entry: <Name> in <Non-Terminal> at <ClauseNum>. Also, generate an index
+       entry for the item: @Defn2(Term=<Name>,address@hidden). (For the 
purposes
+       of the index, all of Annex P is a single paragraph). Otherwise, is the
+       same as @ntf.
address@hidden -- Generate the syntax summary at this point. *No paragraph
+       numbers*!
address@hidden -- Generate the syntax cross-reference at this point. *No 
paragraph
+       numbers*!
address@hidden<Version>],[Tabs=<Tabset>, ]LHS=<Non-terminal>, RHS=<Production>}
+       Add a syntax production for Version. Otherwise, the meaning is the
+       same as for @Syn, above. Note: <Non-terminal> and <Production> need
+       @Chg commands; this command only adds processing for "::=" and overall
+       inclusion or skipping when necessary.
address@hidden<Version>],[Tabs=<Tabset>, ]LHS=<Non-terminal>, RHS=<Production>}
+       Delete a syntax production for version. Otherwise, the meaning is the
+       same as for @Syn, above. Note: <Non-terminal> and <Production> need
+       @Chg commands; this command only adds processing for "::=" and overall
+       inclusion or skipping when necessary.
+
address@hidden<Prefix>,AttrName=<Name>,Text=<Text>}
+       Defines an attribute. Creates a hanging text item <Prefix>'<Name>,
+       with the specified text. The text can contain arbitrary commands;
+       it will be run through the full evaluation code.
+       The attribute and text is also sent to a database used to later create
+       Annex K. (This uses the current value of PrefixType.) Finally, the
+       attribute <Name> is indexed as by calling @Defn2{Term=[Attribute],
+       Sec=<Name>}, and as by calling @Defn{<Name> attribute}. See also
+       ChgAttribute.
address@hidden<Prefix>,AttrName=<Name>,Text=<Text>}
+        Same as attribute, except that the first paragraph is a "Leading"
+       paragraph. (Use when the second paragraph is a DescExample, such
+       as when a function specification is given.)
address@hidden
+       Dumps the summary list of all attributes from the attribute database
+       to the output file.
address@hidden
+       Save the indicated text to use as part of any following attribute
+       definitions. The text is also written to the output. The text should
+       fit in the phrase: "For {text}:". For instance, the text could be
+       "every scalar subtype S". See also ChgPrefixType.
address@hidden
+       (The parameter list must exist and be empty) Set the saved attribute
+       text to "@b{NONE!}". This exists to ensure that the prefixes are set
+       properly, and aren't just set by accident.
+
address@hidden<Text>}
+       Defines a pragma. The text is displayed in the current format.
+       The text should contain an @prag command (which specifies and indexes
+       the name - see below.) The text can contain arbitrary commands;
+       it will be run through the full evaluation code.
+       The text is also sent to a database used to later create Annex L.
address@hidden<Version>],<Text>}
+       Defines a pragma added by <Version>. Otherwise, the text is as
+        described for PragmaSyntax. Text includes an appropriate @Chg;
+        the purpose of the Version number here is
+       to determine whether (and how) this is entered into Annex L,
+       along with the cross-reference text.
address@hidden<Version>],InitialVersion=[<InitialVersion>],<Text>}
+       Defines a pragma deleted by <Version>, originally added by
+        <InitialVersion>. Otherwise, the text is as
+        described for PragmaSyntax. Text includes an appropriate @Chg;
+       the purpose of the Version number here is to determine whether
+        (and how) this is entered into Annex L, along with the cross-reference
+        text.
address@hidden
+       Dumps the summary list of all pragmas from the pragma database
+       to the output file.
+
+-- Indexing:
+
+If Show-Index-Entries is not used on the command line, indexing entries
+are transparent (this is usually the case for the RM).
+
+If Show-Index-Entries is used on the command line, indexing entries show as
+italized in curly brackets. RootDefn adds "[distributed]", PDefn adds
+"[partial]", IndexSee adds ": see <OtherTerm>", and IndexSeeAlso adds
+": see also <OtherTerm>" to the reference.
+
address@hidden - Generates the index at this point.
+
address@hidden<text>} - Defines a term, where the entire definition is given in 
the
+       referenced paragraph.
address@hidden<text>} - Defines a term, where the definition is given in several
+       paragraphs. This is the primary definition.
address@hidden<text>} - Defines a term, where the definition is given in several
+       paragraphs. This is one of the secondary definitions.
address@hidden<term>],Sec=(<subterm>)} - Same as Defn, except a subterm is
+       allowed. The subterm will be indexed under the primary term.
address@hidden<term>],Sec=(<subterm>)} - Same as RootDefn, except a
+       subterm is allowed.
address@hidden<term>],Sec=(<subterm>)} - Same as PDefn, except a subterm is
+       allowed.
address@hidden<term>],Other=(<other_term>)} - Generates a See
+       reference to <other_term> in the index. No page/clause reference is
+       generated.
address@hidden<term>],Other=(<other_term>)} - Generates a See also
+       reference to <other_term> in the index. No page/clause reference is
+       generated.
address@hidden<term>],See=(<other_term>)} - Generates a See
+       reference to <other_term> in the index. A page/clause reference is
+       generated.
address@hidden<term>],See=(<other_term>)} - Generates a See also
+       reference to <other_term> in the index. A page/clause reference is
+       generated.
address@hidden<parent>],Child=[<child>]}
+       Generates three index entries: An index entry for <child>, with a 
secondary
+       of "@i{child of} <parent>", an index entry for "Language-Defined
+       Library Units" with a secondary entry of <parent>.<child>, and an index
+       entry for <parent>.<child>. The Unit is set to <parent>.<child>.
+        (For version 2 or later, the Language-Defined entry is not generated.)
+        The first entry is added to the package list as well.
address@hidden<parent>],Child=[<child>]}
+        Same as @ChildUnit, except that the first entry is added to the
+       subprogram list, rather than the package list.
address@hidden<unit>} - Generates two index entries: An index entry for
+       "Language-Defined Library Units" with a secondary entry of <unit>,
+       and an index entry for <unit>. The Unit is set to <parent>.<child>.
+        (For version 2 or later, the Language-Defined entry is not generated.)
+        The first entry is added to the package list as well.
address@hidden<defn>} - Generates an index entry for <defn> with a secondary 
entry
+       of "@i{in} <Unit>" (where Unit is the unit saved by a previous
+       RootLibUnit or ChildUnit.) Also outputs the <defn> to the output file.
address@hidden<defn>} - Generates two index entries: one for <defn> with a
+       secondary entry of "@i{in} <Unit>" (where Unit is the unit saved by
+       a previous RootLibUnit or ChildUnit.), and second for "Language-Defined
+       Subprogram" with a secondary entry of "<defn> @i{in} <Unit>".
+        (For version 2 or later, the Language-Defined entry is not generated.)
+        The first entry is added to the subprogram list as well.
+       Also outputs the <defn> to the output file.
address@hidden<defn>} - Generates two index entries: one for <defn> with a
+       secondary entry of "@i{in} <Unit>" (where Unit is the unit saved by
+       a previous RootLibUnit or ChildUnit.), and second for "Language-Defined
+       Type" with a secondary entry of "<defn> @i{in} <Unit>".
+        (For version 2 or later, the Language-Defined entry is not generated.)
+        The first entry is added to the type list as well.
+       Also outputs the <defn> to the output file.
address@hidden<defn>,Of=<type>} - Generates an index entry of
+        "<defn> @i{subtype of} <type>" with a secondary entry of
+        "@i{in} <Unit>" (where Unit is the unit saved by a previous
+        RootLibUnit or ChildUnit.) The entry is added to the type list as well.
+       Also outputs the <defn> to the output file.
address@hidden<defn>} - Generates an index entry for <defn> with a
+       secondary entry of "@i{in} <Unit>" (where Unit is the unit saved by
+       a previous RootLibUnit or ChildUnit.)
+        The entry is added to the exception list as well.
+       Also outputs the <defn> to the output file.
address@hidden<defn>} - Generates an index entry for <defn> with a
+       secondary entry of "@i{in} <Unit>" (where Unit is the unit saved by
+       a previous RootLibUnit or ChildUnit.)
+        The entry is added to the object list as well.
+       Also outputs the <defn> to the output file.
address@hidden<defn>} - Generates an index entry for <defn> with a
+       secondary entry of "@i{in} <Unit>" (where Unit is the unit saved by
+       a previous RootLibUnit or ChildUnit.)
+        The entry is added to the package list as well.
+       Also outputs the <defn> to the output file.
+       Use this for *nested* packages.
address@hidden<check>} - Generates an index entry for "check, language defined"
+       with a secondary entry of <check>. (Essentially a Defn2). Also,
+       indexes <check> as a partial definition. (PDefn).
address@hidden<name>} -- Generates an index entry for "attributes"
+       with a secondary entry of <name>. (Essentially a Defn2). Also
+       with a secondary entry of <name> (a Defn2), and also an index entry
+        of "<name> attribute" (a Defn). Also puts <name> to the output.
address@hidden<name>} -- Generates an index entry for "pragmas"
+       with a secondary entry of <name> (a Defn2), and also an index entry
+        of "<name> pragma" (a Defn). Also puts <name> to the output.
address@hidden<name>} -- Generates an index entry for "aspects"
+       with a secondary entry of <name> (a Defn2), and also an index entry
+        of "<name> aspect" (a Defn).
+
+
address@hidden -- Generates the list of language-defined packages.
address@hidden -- Generates the list of language-defined types and subtypes.
address@hidden -- Generates the list of language-defined subprograms.
address@hidden -- Generates the list of language-defined exceptions.
address@hidden -- Generates the list of language-defined objects.
+
+-- Glossary:
address@hidden(Term=[<term>], Text=[<text>])
+       Creates a glossary entry for <term> with the value <text>.
+       The item is shown as a annotation in the AARM. The term is also
+       indexed (and displayed as such if appropriate) with @Defn immediately
+       after the annotation header.
address@hidden(Term=[<term>], Text=[<text>])
+       Creates a glossary entry for <term> with the value <text>.
+       The text is part of the current paragraph. If Show-Index-Entries is
+       used on the command line, a "[Glossary Entry]" marker is shown;
+       otherwise nothing is. The term is also indexed (and displayed as
+       such if appropriate) with @Defn immediately after the marker.
address@hidden
+       Generates the glossary.
+
+-- Implementation-defined annex:
address@hidden<text>}
+       Creates an implementation-defined entry for <text>. The clause and
+       paragraph references are saved to create part of Annex M. For the AARM,
+       <text> is an annotation; otherwise, it is discarded. See also
+       ChgImplDef.
address@hidden
+       Generates the implementation-defined list.
+
+-- Changes:
address@hidden<version>],Kind=(<kind>){,Ref=(<DR_Number>)}{,ARef=(<AI_Number>)}}
+       - Marks a paragraph changed in a corrigendu or amendment. This command
+        precedes any text of the paragraph. The version number of the change is
+       <version>. [This is "1" for technical corrigenum 1; "2" for amendment 
1].
+       Kind is either "Revised" (an ordinary change), "Added" (for a paragraph
+       added by the change), "AddedNormal" (for a paragraph added by the
+       change which gets a normal paragraph number - used for insertions at
+       the end of clauses and added to new clauses), "Deleted" (for a
+       paragraph deleted by the change), "DeletedAdded" (for an
+        added paragraph which is later deleted), "DeletedNoDelMsg" (for a
+       paragraph deleted by the change; the "This paragraph was deleted"
+        message is suppressed), "DeletedAddedNoDelMsg" (combines the last
+       two kinds), or "RevisedAdded" (for an
+        added paragraph which is later revised). [These control the paragraph
+       numbering of the following paragraph.] The <DR_Number>(s) and/or
+       <AI_Number>(s) that triggered the change are given. As many references
+       as necessary can be given. (Zero is allowed). The format of the AI
+       numbers is as described for @AILink.
+       Note: If there are changes to the same paragraph in multiple versions,
+       each version should have their own chgref.
+       The ChgRefs should be in the order of the versions (first version 1,
+       then version 2, etc.) The Kind should be consistent for all chgrefs -
+       the numbering is the same no matter when the paragraph was added or
+       deleted. That means "RevisedAdded" after "Added", etc.
address@hidden<text>} Notes on particular change. This is treated as a comment; 
it
+       has a separate command solely so that stripped easily in the future.
address@hidden<Version>],]New=[<new text>],Old=[<old text>]}
+       Marks a particular change. The new text and the old text are given.
+       (We have both sets of text so we can generate useful differences).
+       @chg commands can be nested; it recommended that they be nested with
+        the newest changes inside of older changes. The text may not contain
+        any command that ends the paragraph. The Version is assumed to be '1'
+        if that parameter is not given. Version is interpreted as for ChgRef.
address@hidden<Version>],[NoPrefix=[T|F],][NoParamnum=[T|F],]
+        [Type=[Leading|Trailing|Normal],][Keepnext=[T|F],]Text=[text]}
+       Marks an insertion of a complete paragraph consisting of 'text'. This
+       cannot be nested in other commands. The AARM prefix (if any) also is
+       marked as an insertion. The optional parameters (conditionally) set the
+       paragraph properties; NoPrefix, Noparanum, and KeepNext work the same
+       as the @NoPrefix, @NoParanum, and @KeepNext commands if set to T,
+       except that they're conditional on the paragraph text being inserted.
+       Similarly, Type works the same as @Leading and @Trailing if set to
+       those values, except that they are conditional. If omitted, NoPrefix
+       is set to F, NoParanum is set to F, KeepNext is set to F, and
+       Type is set to Normal.
address@hidden<Version>],[NoPrefix=[T|F],][NoParamnum=[T|F],]
+        [Type=[Leading|Trailing|Normal],][Keepnext=[T|F],]Text=[text]}
+       Marks a deletion of a complete paragraph consisting of 'text'. This
+       cannot be nested in other commands. The AARM prefix (if any) also is
+       marked as a deletion. The optional parameters (conditionally) set the
+       paragraph properties; they work as described in ChgAdded. Note that
+       they're conditional on the paragraph text being included in the
+       document (even if it is marked as deleted).
+
address@hidden<version>],Kind=(<kind>),
+        [InitialVersion=[<version>],]Text=<text>}
+       Marks a changed implementation-defined entry. (Essentially a
+       combination of ChgRef and Impldef.) <text> is the
+       implementation-defined entry. See ChgRef and Impldef for details
+       on the handling of the arguments. The optional InitialVersion parameter
+       specifies the version number for the originally inserted text; if
+       not specified, the Version number is used. (This is appropriate for
+       added items, others should explicitly give an initial version.)
+
address@hidden<version>],Kind=(<kind>),
+        [InitialVersion=[<version>],]Text=<text>}
+       Marks a new or changed implementation advice entry. All IA entries
+       are new with version 2. The clause and paragraph references (along
+       with <text>) are saved to create part of Annex M. For the AARM,
+       <text> is an annotation; otherwise, it is discarded.
+       See ChgRef for details on the handling of Version and Kind arguments.
+        The optional InitialVersion parameter specifies the version number for
+       the originally inserted text; if not specified, the Version number is
+       used.
address@hidden
+       Generates the implementation advice list; it is inserted with the
+       given version number.
+
address@hidden<version>],Kind=(<kind>),
+        [InitialVersion=[<version>],]Text=<text>}
+       Marks a new or changed documentation requirements entry. All DocReq
+       entries are new with version 2. The clause and paragraph references
+       (along with <text>) are saved to create part of Annex M. For the AARM,
+       <text> is an annotation; otherwise, it is discarded.
+       See ChgRef for details on the handling of Version and Kind arguments.
+        The optional InitialVersion parameter specifies the version number for
+       the originally inserted text; if not specified, the Version number is
+       used.
address@hidden
+       Generates the documentation requirements list; it is inserted with the
+       given version number.
+
address@hidden<version>],Kind=(<kind>),Aspect=[<name>],
+        [InitialVersion=[<version>],]Text=<text>}
+       Marks a new or changed aspect description entry. All aspect
+        descriptions are new with version 3. The clause and paragraph
+        references (along with <name> and <text>) are saved to create part of
+       Annex K. For the AARM, <text> is an annotation; otherwise, it is
+       discarded. See ChgRef for details on the handling of Version and Kind
+       arguments. The optional InitialVersion parameter specifies the version
+       number for the originally inserted text; if not specified, the Version
+       number is used.
address@hidden
+       Generates the aspect description list; it is inserted with the
+       given version number.
+
+
address@hidden<version>],Kind=(<kind>),ChginAnnex=[T|F],
+       Leading=[T|F],Prefix=<Prefix>,AttrName=<Name>,
+       {[Ref={<DR_Number>}|ARef={<AI_Number>}]},
+        [InitialVersion=[<version>],]Text=<Text>}
+       Marks a changed attribute entry. (Essentially a combination of
+       ChgRef and Attribute.) ChginAnnex controls whether the change
+       is reflected in the Annex. (Set this to F when the change is in
+       text "glued" onto the annex paragraph.) Leading controls whether the
+       first paragraph is leading or not. The optional InitialVersion parameter
+        specifies the version number for the originally inserted text; if not
+        specified, the Version number is used. See ChgRef and Attribute
+       for the meaning of the other parameters.
address@hidden<version>],Kind=(<kind>),Text=[<text>]}
+       Marks a changed prefix type text. Also, saves the indicated text to
+       use as part of any following attribute definitions. The text is also
+       written to the output. See ChgRef and PrefixType for more information.
address@hidden<version>],<text>}
+       Same as Subheading, except that this heading is present only in
+       new versions of the document.
address@hidden<version>],Kind=(<kind>),Term=[<term>],Text=[<text>]}
+       Marks a changed glossary entry. (Essentially a
+       combination of ChgRef and ToGlossary.) <term> and <text> are the
+       glossary entry; they can contain @Chg commands. See ChgRef and
+        ToGlossary for details on the handling of the arguments.
address@hidden<version>],Kind=(<kind>),Term=[<term>],Text=[<text>]}
+       Marks a changed glossary entry. (Essentially a
+       combination of ChgRef and ToGlossaryAlso.) <term> and <text> are the
+       glossary entry; they can contain @Chg commands. See ChgRef and
+        ToGlossaryAlso for details on the handling of the arguments.
+
+-- Tabs:
address@hidden() - Clears all tab settings. Tabs are also cleared by leaving the
+       @begin region that contains the tabstop command. Also ends any
+       paragraphs.
address@hidden(<list>) - Sets tab stops at the indicated values, in picas. The 
list
+       is increasing (each value is larger than the one to its right), and
+       separated by commas. Each value can be preceeded by a modifier:
+           L - fixed left tab;
+           P - proporational left tab.
+       (Other modifiers are possible, but are hard to implement in text mode.)
+       Proportional tab values are based on the font size; the values
+       given are for 12 point fonts (in picas); the value is then adjusted
+       for the actual (default) font size of the paragraph.
+       Tab stops can only be set in formats that preserve
+       breaks (i.e. Display). Also ends any paragraphs.
address@hidden      - Move to the next tab stop.
+
+-- Paragraphs:
address@hidden<kind>}
+       Marks the beginning of a group of paragraphs of a particular kind.
+       See the definition of the kinds below. Most groupings have a
+       subheading.
address@hidden<kind>}
+       Marks the ending of a group of paragraphs of a particular kind.
+
+
+-- Paragraph kinds (nesting is allowed; characteristics are not preserved
+--                 unless specifically marked below):
+
+
+    Pure formatting:
+       Comment - The text is never output into the document.
+       WideAbove- The paragraph has wider than usual space above, but is
+                 otherwise normal.
+       DescribeCode -
+                 The text is indented 2 units.
+       Example - The text is formatted in the example font (which is selected
+                 in the master file) with an indent of 1 unit; spaces and
+                 breaks are preserved. This format preserves size
+                 characteristics of its parent (if any), except that if the
+                 parent is "DescribeCode", the normal characteristics are
+                 used. No page breaks are allowed within a paragraph.
+                 Do not confuse this with "Examples", which is a text
+                 grouping.
+       ChildExample - The text is formatted in the example font (which is
+                 selected in the master file); spaces and breaks are
+                 preserved. This format preserves size and
+                 indenting characteristics of its parent (if any);
+                 with the exception that the text here is indented one
+                 additional unit.
+       Itemize - The text is indented and bulleted (with solid circle bullets).
+                 The text preserves the size and indenting of its parent (if
+                 any).
+       InnerItemize - The text is indented to fit inside an Itemize or
+                 Enumerate paragraph, and bulleted (with [smaller] solid
+                 circle bullets).
+       InnerInnerItemize - The text is indented to fit inside an InnerItemize
+                 paragraph, and bulleted (with [smaller] solid circle bullets).
+       Enumerate - The text is indented and numbered (that is, each paragraph
+                 has a prefix number). The text preserves the size and
+                 indenting of its parent (if any). The format of the number
+                 depends on the ListFormat master setting: for RM,
+                 a number followed by a period is used ["1."], for
+                 ISO2004 a letter followed by a paren is used for the main
+                 list ["a)"]; nested lists use a number ["1)"].
+       InnerEnumerate - The text is indented to fit inside an Itemize or
+                 Enumerate paragraph, and numbered as for Enumerate.
+                 (These should only be used inside of regular Enumerate
+                 blocks if ISO 2004 formatting is desired.)
+       Display - A normal paragraph indented one level from its parent, except
+                 that spaces and breaks are preserved. The text preserves the
+                 size of its parent (if any). No page breaks are allowed
+                 within a paragraph.
+       Indent  - A normal paragraph indented one level from its parent.
+                 The text preserves the size of its parent (if any).
+       SyntaxDisplay - The text is in a smaller font, is indented one level,
+                 and spaces and breaks are preserved. No page breaks are
+                 allowed within a paragraph.
+       Description - A paragraph with text indented 3 units; but the item
+                 is a hanging undent to the normal paragraph level. Usually
+                 used for attributes, but sometimes used for other items.
+                 Same as Hang3List.
+       DescExample - The text is formatted in a fixed-width example font with
+                 an indent of 4 units; spaces and breaks are preserved. No 
page breaks
+                 are allowed within a paragraph.
+       SyntaxText -
+                 The text is indented 1 unit. This is intended to match the
+                 indentation of syntax and is usually used in the syntax
+                 grouping; however syntax is usually in the swiss font.
+       Hang1List -
+                 A paragraph with text indented 1 unit; but the item
+                 is a hanging undent to the normal paragraph level.
+       Hang2List -
+                 A paragraph with text indented 2 units; but the item
+                 is a hanging undent to the normal paragraph level.
+       Hang3List -
+                 A paragraph with text indented 3 units; but the item
+                 is a hanging undent to the normal paragraph level.
+       Hang4List -
+                 A paragraph with text indented 4 units; but the item
+                 is a hanging undent to the normal paragraph level.
+       Small -   The text has the size of an AARM note, but doesn't
+                 have any headers or extra indentation.
+       Title -   The text is 5 size units (usually 5 points) larger than
+                 normal.
+       Bundle -  The text in the 'bundle' should never be page-breaked.
+                 The format is unchanged.
+       TwoCol -  Sets the text to a two-column format. The text format
+                 is unchanged.
+       FourCol - Sets the text to a four-column format. The text format
+                 is unchanged.
+
+    RM groupings:
+       Intro     - Introductory text. No heading.
+       Syntax    - Syntax.
+       Resolution- Name resolution rules.
+       Legality  - Legality rules.
+       StaticSem - Static Semantics.
+       LinkTime  - Post-Compilation Rules.
+       RunTime   - Dynamic Semantics.
+       Bounded   - Bounded (Run-Time) errors.
+       Erron     - Erroneous Execution.
+       ImplReq   - Implementation Requirements.
+       DocReq    - Documentation Requirements.
+       Metrics   - Metrics.
+       ImplPerm  - Implementation Permissions.
+       ImplAdvice- Implementation Advice.
+       Notes     - Notes. (Each of these is numbered and indented 1 unit.
+                   The format is controlled by the @NoteFormat command
+                   in the master file.)
+       SingleNote - A single note (it is indented 1 unit, but not numbered.
+                   The format is controlled by the @NoteFormat command
+                   in the master file.)
+       Examples  - Examples. (Do not confuse this with the text format
+                   "Example". This is a grouping with a subhead. It is in
+                   the normal font by default; often an "Example" is found
+                   inside of "Examples".)
+       NotIso    - Text that is not included in ISO documents. No format is 
implied.
+       IsoOnly   - Text that is included only in ISO documents. No format is 
implied.
+       RMOnly    - Text that is not included in the AARM (that is, it is only
+                   included in the output if HideAnnotations is used). No
+                   format is implied.
+
+    AARM-only groupings: (not shown if HideAnnotations is used)
+       MetaRules - Language Design Principles.
+       Inconsistent83 - Inconsistencies with Ada 83.
+       Incompatible83 - Incompatibilities with Ada 83.
+       Extend83  - Extensions to Ada 83.
+       DiffWord83- Wording Changes from Ada 83.
+       Inconsistent95 - Inconsistencies with Ada 95.
+       Incompatible95 - Incompatibilities with Ada 95.
+       Extend95  - Extensions to Ada 95.
+       DiffWord95- Wording Changes from Ada 95.
+       Inconsistent2005 - Inconsistencies with Ada 2005.
+       Incompatible2005 - Incompatibilities with Ada 2005.
+       Extend2005  - Extensions to Ada 2005.
+       DiffWord2005- Wording Changes from Ada 2005.
+       Inconsistent2012 - Inconsistencies with Ada 2012.
+       Incompatible2012 - Incompatibilities with Ada 2012.
+       Extend2012  - Extensions to Ada 2012.
+       DiffWord2012- Wording Changes from Ada 2012.
+       AARMOnly  - Text that is not included in the RM. No format is implied.
+
+    AARM annotations: (not shown if HideAnnotations is used)
+       Reason    - Why a rule is necessary.
+       Ramification- Consequences of rules. (Important ones should be Notes).
+       Discussion - General annotations.
+       TheProof  - Informal proof as to why Notes or Redundant text follows
+                   from the language.
+       ImplNote  - A note on implementation.
+       Honest    - To be Honest: Only pedants need apply.
+       GlossaryMarker - Looks like a glossary entry in the AARM (but isn't
+                   really one). (Also internally used by the formatter for
+                   real glossary entries.)
+       ElementRef - (For ASIS) Marks an Element Reference.
+       ChildRef  - (For ASIS) Marks child references for the preceding
+                   Element Reference.
+       UsageNote - (For ASIS) Marks a Usage Note.
+
+-- Text Macros:
+
+<Grouping>Name  - The name of a kind of rule (as in "This is a
+                 @ResolutionName.").
+<Grouping>Title - The title of a kind of rule (as in "This belongs under
+                 "@ResolutionTitle".").
+       where <Grouping> is any of the paragraph grouping kinds listed above.
+
+-- Character Macros:
+
+These represent characters not available in the lower 128 of Latin-1, including
+various mathematical symbols.
+
address@hidden  - EM dash (a very long dash)
address@hidden  - EN dash (a long dash)
address@hidden   - A thin space (quarter em if possible)
address@hidden  - Greater than or equal symbol
address@hidden  - Greater than symbol
address@hidden  - Less than or equal symbol
address@hidden  - Less than symbol
address@hidden  - Not equal symbol
address@hidden  - Pi
address@hidden -- Small Dotless I (for examples). Use @Unicode(305) if we ever 
implement that.
address@hidden -- Capital Dotted I (for examples). Use @Unicode(304) if we ever 
implement that.
address@hidden - Single quote ('''). Used to avoid confusion in syntax rules.
address@hidden<number>} - Generate the Latin-1 character with the decimal code
+       "number".
address@hidden<number>} - Generate the Unicode character with the decimal code
+       "number". Careful: this is unchecked; usually, the characters used
+       should be limited to the 615 generally supported by Windows.
address@hidden  - The middle dot multiply symbol.
address@hidden   - The plus or minus symbol.
address@hidden<text>} - The ceiling operator, surrounding <text>.
address@hidden<text>} - The floor operator, surrounding <text>.
address@hidden<text>} - The mathematical absolute value operation, surrounding 
<text>.
address@hidden<text>} - The log operation, surrounding <text>. (In practice, 
this is
+        always translated "log(<text>)").
address@hidden - Left (directed) single quote.
address@hidden - Right (directed) single quote.
address@hidden - Left (directed) double quote.
address@hidden - Right (directed) double quote.
address@hidden - Pair of left (directed) single quotes. (Note: The ARG has 
directed
+          that these be changed to a left double quote, so this is now the
+          same as ldquote.)
address@hidden - Pair of right (directed) single quotes. (Note: The ARG has 
directed
+          that these be changed to a right double quote, so this is now the
+          same as rdquote.)
+
+-- Tables:
address@hidden(Columns=<number>,
+       Alignment=<AllLeft|AllCenter|CenterExceptFirst>,
+       FirstColWidth=<number>,
+       LastColWidth=<number>,
+       NoBreak=<T|F>,
+       Border=<T|F>,
+       SmallSize=<T|F>,
+       Caption=<text>,
+       Headers=<text>,
+       Body=<row_text>)
+
+       Defines a table.
+       - Columns must be a single digit (2-9).
+       - Alignment defines the column text alignment (centered or left edge).
+       - FirstColWidth defines the width of the first column compared to
+         the rest - it's in multiples of the standard column width.
+          Note that some target formats with self-sizing columns (i.e. HTML)
+          ignore this value. It must be a single digit from 1 to 9.
+       - LastColWidth defines the width of the last column compared to
+         the rest - it's in multiples of the standard column width.
+          Note that some target formats with self-sizing columns (i.e. HTML)
+          ignore this value. It must be a single digit from 1 to 9.
+       - If NoBreak is T, the table will be formatted on a single page.
+         Otherwise, it will be allowed to be split across pages. This
+         must be F if the table is larger than a single page!
+       - If Border is T, then a border will be drawn around the table;
+          otherwise, not border will be used.
+       - If SmallSize is T, then the text size will be small (AARM-sized);
+         else the text size will be normal.
+       - Caption defines the table caption. This spans the entire table.
+       - Headers defines the table headers. Each header is separated by
+         a tab stop (@\). This should be a single line.
+       - Body defines the table body. Each row should be a single line,
+         with each item separated by a tab stop.
+         The text may contain character and text formatting commands, but
+         no paragraph commands. But no text command may extend across the
+         tab marking the end of an item.
address@hidden  - Marks the end of the second last row of the table. (If left 
out,
+         the bottom line of the table may be missing).
+
+-- Pictures: (Graphics, Images)
+
address@hidden(Alignment=<Inline|FloatLeft|FloatRight>,
+         Border=<None|Thin|Thick>,
+         Height=<nnn>,
+         Width=<nnn>,
+         Name=<name>,
+         Descr=<descr>)
address@hidden(Alignment=<Left|Right|Center>,
+         Border=<None|Thin|Thick>,
+         Height=<nnn>,
+         Width=<nnn>,
+         Name=<name>,
+         Descr=<descr>)
+       Includes a picture in the output. PictureAlone is a stand-alone
+       picture with the appropriate alignment; it must appear outside
+       of a paragraph. PictureInline occurs in the flow of text (Inline),
+       or floats to the appropriate margin; it must appear inside of a
+       paragraph. Otherwise, these are the same.
+       The picture file's simple name is
+       "name"; the file is assumed to be a .PNG or .JPG, found in the output
+       directory. (It needs to be included with the HTML output.)
+       "descr" is a description of the picture; it's used for the popups
+       in HTML. Height and Width are the picture size in pixels.
+       Border specifies the border of the picture.
+       [Note: Inline alignment is not recommended; the picture location
+       cannot be controlled, especially on RTF, it can appear in margins
+       and other bad locations.]
+
+-------------------
+
+Use to create Ada standard documents.
+
+
+The master file AARM.MSM specifies the Annotated Ada Reference Manual. This
+is mainly intended for implementors and language lawyers. It includes
+annotations. (In the past, it also included visible index entries, but that
+has been turned off by popular demand).
+
+The master file RM.MSM specifies the Ada Reference Manual. This is the
+version used by most users.
+
+The master file ISO-RM.MSM specifies Ada Reference Manual in ISO format.
+This version lacks some sections, paragraph numbers, and is formatted for A4
+paper.
+
+Versions:
+   0-Original Ada 95 (equivalent to No-Changes)
+   1-Technical Corrigendum 1
+   2-Amendment 1 [Ada 2005 (standard published 2007, so could be considered 
Ada 2007)]
+   3-3rd Edition (Ada 2012)
+   4-4th Edition (Ada 202x) - Not official yet.
+
+Please note that there some changes to earlier versions (mostly typographical,
+but there are some that are significant) that are not preserved in the Ada 2012
+source code (.MSM and .MSS files), so to get an exact match to one of the
+previous versions, you must use the source code appropriate for that version.
+
+One specific change; the MSM files for Ada 2012 have @SubdivisionNames{Clause}
+(as this is required by ITTF) while the MSM files for Ada 95 and Ada 2005 have
address@hidden (as this was required when those standards were
+current).
+
+In addition, several clauses were moved to different numbers within the
+Standard (for both Ada 2012 and Ada 2005); usually, these were done by
+by just renaming the clause (and changing the @Label command) and the
+original location is not preserved.
+
diff --git a/packages/ada-ref-man/progs/gpl-3-0.txt 
b/packages/ada-ref-man/progs/gpl-3-0.txt
new file mode 100755
index 0000000..818433e
--- /dev/null
+++ b/packages/ada-ref-man/progs/gpl-3-0.txt
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program 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 <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/packages/ada-ref-man/progs/makeana.bat 
b/packages/ada-ref-man/progs/makeana.bat
new file mode 100755
index 0000000..a023af3
--- /dev/null
+++ b/packages/ada-ref-man/progs/makeana.bat
@@ -0,0 +1 @@
+corder arm_analyzer 
/i/z/w/b'ana.bat'/c'/w3/c/zt/t/sc:\windows\temp'/jb'/t/l'/q'/w'/r.\object/jx'alkc
 arm_anal'
diff --git a/packages/ada-ref-man/progs/makearm.bat 
b/packages/ada-ref-man/progs/makearm.bat
new file mode 100755
index 0000000..b3cff2f
--- /dev/null
+++ b/packages/ada-ref-man/progs/makearm.bat
@@ -0,0 +1 @@
+corder arm_formatter 
/t/z/w/k255/b'arm.bat'/l'ads'/n'adb'/n'ada'/n'a'/c'/zt/t'/jb'/t/l'/q'/w'/r.\object/jx'alkc
 arm_form'
diff --git a/packages/ada-ref-man/progs/mklnk.bat 
b/packages/ada-ref-man/progs/mklnk.bat
new file mode 100755
index 0000000..153cb81
--- /dev/null
+++ b/packages/ada-ref-man/progs/mklnk.bat
@@ -0,0 +1,3 @@
+Del .\Object\_Janus.Prj
+Jmanager Add_Project (.\Object\,Default)
+Jmanager Add_Link (.\Object\,Default,C:\Jnt312\Rts\Console, JNT_RTS_CONSOLE)
diff --git a/packages/ada-ref-man/progs/rtf2form.ada 
b/packages/ada-ref-man/progs/rtf2form.ada
new file mode 100755
index 0000000..00c406d
--- /dev/null
+++ b/packages/ada-ref-man/progs/rtf2form.ada
@@ -0,0 +1,686 @@
+with Ada.Text_IO,
+     Ada.Strings.Fixed,
+     Ada.Strings.Unbounded,
+     Ada.Characters.Handling,
+     Ada.Command_Line;
+procedure Rtf2Form is
+
+    --
+    -- Convert an RTF file (as in the Rationale) to a roughly formatted .MSS
+    -- file. This tool is part of ARM_Form, the Ada Reference Manual formatter.
+    --
+    -- ---------------------------------------
+    -- Copyright  2006, 2011  AXE Consultants.
+    -- P.O. Box 1512, Madison WI  53701
+    -- E-Mail: address@hidden
+    --
+    -- ARM_Form is free software: you can redistribute it and/or modify
+    -- it under the terms of the GNU General Public License version 3
+    -- as published by the Free Software Foundation.
+    --
+    -- AXE CONSULTANTS MAKES THIS TOOL AND SOURCE CODE AVAILABLE ON AN "AS IS"
+    -- BASIS AND MAKES NO WARRANTY, EXPRESS OR IMPLIED, AS TO THE ACCURACY,
+    -- CAPABILITY, EFFICIENCY, MERCHANTABILITY, OR FUNCTIONING OF THIS TOOL.
+    -- IN NO EVENT WILL AXE CONSULTANTS BE LIABLE FOR ANY GENERAL,
+    -- CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+    -- EVEN IF AXE CONSULTANTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    -- DAMAGES.
+    --
+    -- A copy of the GNU General Public License is available in the file
+    -- gpl-3-0.txt in the standard distribution of the ARM_Form tool.
+    -- Otherwise, see <http://www.gnu.org/licenses/>.
+    --
+    -- If the GPLv3 license is not satisfactory for your needs, a commercial
+    -- use license is available for this tool. Contact Randy at AXE Consultants
+    -- for more information.
+    --
+    -- ---------------------------------------
+    --
+    -- Edit History:
+    --
+    --  1/19/06 - RLB - Created program.
+    --  1/20/06 - RLB - Changed to generate tab markers for tabs, as John
+    --                 wants to preserve tabs where possible.
+    -- 10/18/11 - RLB - Changed to GPLv3 license.
+
+    use Ada.Strings.Unbounded;
+
+    -- Declarations stolen from Trash-Finder:
+
+    type Line_Count is range 0 .. 1_000_000; -- 1 million lines ought to be 
enough.
+    type Line_Type;
+    type Line_Access is access Line_Type;
+    type Line_Type is record
+        Number : Line_Count;
+        Text : Ada.Strings.Unbounded.Unbounded_String;
+        Next : Line_Access;
+    end record;
+
+    procedure Free is new Ada.Unchecked_Deallocation (Line_Type, Line_Access);
+        -- Free an individual line.
+
+    procedure Free_All (List : in out Line_Access) is
+        -- Free the entire list.
+        Temp : Line_Access;
+    begin
+        while List /= null loop
+            Temp := List;
+            List := List.Next;
+            Free (Temp);
+        end loop;
+    end Free_All;
+
+    procedure Load_File (File_Name : in String;
+                        Data : in out Line_Access) is
+       -- Read the file, breaking at each paragraph end (to keep the lines from
+       -- getting too long). The original line breaks are irrelevant.
+       File : Ada.Text_IO.File_Type;
+        Last, Working : Line_Access := null;
+       Count : Line_Count := 0;
+       Buffer : String (1..1000); -- Since line endings aren't significant, the
+                                  -- length doesn't matter much, other than we
+                                  -- might miss a "\par" that way.
+       BLength : Natural;
+       Break_Loc, Start_Loc : Natural;
+    begin
+       Ada.Text_IO.Open (File, Ada.Text_IO.In_File, File_Name);
+       loop
+           Ada.Text_IO.Get_Line (File, Buffer, BLength);
+           Count := Count + 1;
+--Ada.Text_IO.Put_Line("Line" & Line_Count'Image(Count) & ": read=" & 
Buffer(1..BLength));
+           Start_Loc := 1;
+           Break_Loc := Start_Loc;
+           while Break_Loc <= BLength-4 loop
+               -- Look for "\par " or "\par\", only (in particular, not 
"\pard").
+               exit when Buffer(Break_Loc..Break_Loc+3) = "\par" and then
+                  (Buffer(Break_Loc+4) = ' ' or else
+                   Buffer(Break_Loc+4) = '\');
+                   -- Found it.
+               Break_Loc := Break_Loc + 1;
+           end loop;
+           if Break_Loc > BLength-4 then
+               Break_Loc := BLength+1;
+           end if;
+           if Last = null then
+               Working := new Line_Type;
+               Working.Number := Count;
+               Working.Next := null;
+               Working.Text := To_Unbounded_String (Buffer(1..Break_Loc-1));
+               Data := Working;
+               Last := Working;
+--Ada.Text_IO.Put_Line("Line" & Line_Count'Image(Count) & ": initial=" & 
Buffer(1..Break_Loc-1));
+           elsif Length(Last.Text) > 30000 and then Break_Loc > BLength then
+               -- Break at the original place, as this is too long.
+               -- This is fine so long as the length of Buffer < 2768/2 (1386)
+               Last.Text := Last.Text & To_Unbounded_String 
(Buffer(1..Break_Loc-1));
+--Ada.Text_IO.Put_Line("Line" & Line_Count'Image(Count) & ": append, then 
break=" & Buffer(1..Break_Loc-1));
+               Break_Loc := BLength - 3; -- Force a new line here. (This will 
make
+                                         -- Start_Loc small enough to enter the
+                                         -- loop below and create an empty 
line.)
+           else
+               Last.Text := Last.Text & To_Unbounded_String 
(Buffer(1..Break_Loc-1));
+--Ada.Text_IO.Put_Line("Line" & Line_Count'Image(Count) & ": append=" & 
Buffer(1..Break_Loc-1));
+           end if;
+           Start_Loc := Break_Loc + 4; -- Skip \par.
+           if Start_Loc <= BLength and then Buffer(Start_Loc) = ' ' then
+               Start_Loc := Start_Loc + 1; -- Skip trailling space, too.
+           end if;
+--Ada.Text_IO.Put_Line("Start_Loc = " & Natural'Image(Start_Loc) & " Blength=" 
& Natural'Image(BLength));
+           while Start_Loc <= BLength+1 loop -- +1 so we handle end of line 
"\par" properly.
+               -- Create a new line:
+               Working := new Line_Type;
+               Working.Number := Count;
+               Working.Next := null;
+               Last.Next := Working;
+               Last := Working;
+               Break_Loc := Start_Loc;
+               while Break_Loc <= BLength-4 loop
+                   -- Look for "\par " or "\par\", only (in particular, not 
"\pard").
+                   exit when Buffer(Break_Loc..Break_Loc+3) = "\par" and then
+                      (Buffer(Break_Loc+4) = ' ' or else
+                       Buffer(Break_Loc+4) = '\');
+                       -- Found it.
+                   Break_Loc := Break_Loc + 1;
+               end loop;
+               if Break_Loc > BLength-4 then
+                   Break_Loc := BLength+1;
+               end if;
+               Working.Text := To_Unbounded_String 
(Buffer(Start_Loc..Break_Loc-1));
+--Ada.Text_IO.Put_Line("Line" & Line_Count'Image(Count) & ": startp=" & 
Buffer(Start_Loc..Break_Loc-1));
+               Start_Loc := Break_Loc + 4; -- Skip \par.
+               if Start_Loc <= BLength and then Buffer(Start_Loc) = ' ' then
+                   Start_Loc := Start_Loc + 1; -- Skip trailling space, too.
+               end if;
+           end loop;
+           -- Done with line when we get here.
+       end loop;
+    exception
+       when Ada.Text_IO.End_Error => -- Done reading.
+           Ada.Text_IO.Close (File);
+    end Load_File;
+
+
+    -- Stack of RTF command information:
+    type RTF_Group_Kind is (Unknown, Empty,
+                           Bold, Italic, Tab, Line_Break,
+                           Exam, ExamCom, Key); -- Type of RTF command.
+    type Brace_Info is record
+       Kind : RTF_Group_Kind;
+    end record;
+    Brace_Info_Stack : array (1..1000) of Brace_Info;
+    Current_Brace : Natural := 0;
+
+    type Paragraph_Styles is (Unknown, None, Normal, Example, Description);
+    Current_Paragraph_Style : Paragraph_Styles := Unknown;
+
+    procedure Process_and_Write_File (File_Name : in String;
+                                     Data : in out Line_Access) is
+       File : Ada.Text_IO.File_Type;
+        Cursor : Line_Access := Data;
+       Chars_on_Line : Natural; -- Number of characters output on the current 
line.
+       -- Data:
+       Deepest_Brace_Nesting : Natural := 0;
+       Paragraphs : Natural := 0;
+       Escaped_Chars : Natural := 0;
+       EM_Dashes : Natural := 0;
+       EN_Dashes : Natural := 0;
+       Intraparagraph_Line_Breaks : Natural := 0;
+       Intraparagraph_Tabs : Natural := 0;
+       Brace_Kinds_Found : array (RTF_Group_Kind) of Natural := (others => 0);
+       Styles_Found : array (Paragraph_Styles) of Natural := (others => 0);
+       procedure Close_Old_Style is
+           -- Close the current paragraph style in preparation for a new one.
+       begin
+           case Current_Paragraph_Style is
+               when Unknown => null;
+               when None => null;
+               when Normal =>
+                   null; --Ada.Text_IO.Put_Line (File, "@end[Intro]"); -- ** 
Temp (no style needed for these).
+               when Example =>
+                   Ada.Text_IO.Put_Line (File, "@end[Example]");
+               when Description =>
+                   Ada.Text_IO.Put_Line (File, "@end[Description]");
+           end case;
+       end Close_Old_Style;
+    begin
+       Ada.Text_IO.Create (File, Ada.Text_IO.Out_File, File_Name);
+       -- Header stuff (ignored, really).
+       Ada.Text_IO.Put_Line (File, "@Part(xxx, Root=""rat.msm"")");
+       Ada.Text_IO.Put_Line (File, "");
+       Ada.Text_IO.Put_Line (File, "@comment($Source: 
e:\\cvsroot/ARM/Progs/rtf2form.ada,v $)");
+       Ada.Text_IO.Put_Line (File, "@comment($Revision: 1.4 $ $Date: 
2012/05/19 01:00:26 $)");
+       Ada.Text_IO.Put_Line (File, "");
+
+       while Cursor /= null loop
+           declare
+               Our_Line : constant String := To_String(Cursor.Text);
+               Working : Natural := Our_Line'First;
+               Last_Output : Natural := Working - 1;
+               procedure Clean_Buffer_and_Close_Old_Style is
+                   -- Close the current paragraph style in preparation for a 
new one.
+               begin
+                   Ada.Text_IO.Put_Line (File, 
Our_Line(Last_Output+1..Working-1));
+--Ada.Text_IO.Put_Line("Close style on Line" & Line_Count'Image(Cursor.Number) 
& ": output=" & Our_Line(Last_Output+1..Working-1));
+                   Chars_on_Line := 0; -- Start over.
+                   Last_Output := Working-1;
+                   Close_Old_Style;
+               end Clean_Buffer_and_Close_Old_Style;
+
+               function Possible_Style (Head, Tail : Natural) return Boolean is
+                   -- Check that the stuff between Head and Tail
+                   -- can *only* be a style, with nothing extra.
+               begin
+--Ada.Text_IO.Put_Line ("Possible style=" & Our_Line(Head..Tail));
+                   for I in Head .. Tail loop
+                       if Our_Line(I) = '{' then
+--Ada.Text_IO.Put_Line ("  NO - open group");
+                           return False; -- Starts some group, not part of a 
style.
+                       elsif Our_Line(I) = '{' then
+--Ada.Text_IO.Put_Line ("  NO - close group");
+                           return False; -- Ends some group, not part of a 
style.
+                       elsif Our_Line(I) = ' ' then
+                           if I = Tail then
+--Ada.Text_IO.Put_Line ("  OK");
+                               return True;
+                            elsif Our_Line(I+1) = '\' then
+                               null; -- OK.
+                           else -- We have to have another command, not text, 
immediately following.
+--Ada.Text_IO.Put_Line ("  NO - plain text found");
+                               return False;
+                           end if;
+                       elsif Our_Line(I) in 'a'..'z' or else
+                            Our_Line(I) in '0'..'9' or else
+                            Our_Line(I) = '-' or else
+                            Our_Line(I) = '\' then
+                           null; -- OK.
+                       else
+--Ada.Text_IO.Put_Line ("  NO - odd character at" & Natural'Image(I));
+                           return False; -- Don't know what this is.
+                       end if;
+                   end loop;
+--Ada.Text_IO.Put_Line ("  OK");
+                   return True; -- OK if we get here.
+               end Possible_Style;
+
+               procedure Start_Style (Style_Code_Loc, End_of_Style : Natural) 
is
+                   -- Generate an appropriate style operation.
+                   -- We've already checked the basic legality of the style.
+                   -- Set Working and Last_Output as needed.
+               begin
+                   -- We can assume that the style code has enough room.
+                   if Our_Line(Style_Code_Loc..Style_Code_Loc+4) = "\s15\" then
+                       -- Normal style (called "TP Text para")
+--Ada.Text_IO.Put_Line ("  Normal style");
+                       if Current_Paragraph_Style /= Normal then
+                           Clean_Buffer_and_Close_Old_Style;
+                           --Ada.Text_IO.Put_Line (File, "@begin[Intro]"); -- 
** Temp.
+                           Current_Paragraph_Style := Normal;
+                       -- else no change needed.
+                       end if;
+                       Styles_Found(Normal) := Styles_Found(Normal) + 1;
+                       -- We just discard the entire style mess.
+                       Last_Output := End_of_Style;
+                       Working := Last_Output + 1;
+
+                   elsif Our_Line(Style_Code_Loc..Style_Code_Loc+4) = "\s25\" 
then
+                       -- Example style (called "PP Program para")
+--Ada.Text_IO.Put_Line ("  Example style");
+                       if Current_Paragraph_Style /= Example then
+                           Clean_Buffer_and_Close_Old_Style;
+                           Ada.Text_IO.Put_Line (File, "@begin[Example]");
+                           Current_Paragraph_Style := Example;
+                       -- else no change needed.
+                       end if;
+                       Styles_Found(Example) := Styles_Found(Example) + 1;
+                       -- We just discard the entire style mess.
+                       Last_Output := End_of_Style;
+                       Working := Last_Output + 1;
+
+                   elsif Our_Line(Style_Code_Loc..Style_Code_Loc+4) = "\s32\" 
then
+                       -- Description style (called "BP Bullet", but often
+                       -- not used for bullets)
+--Ada.Text_IO.Put_Line ("  Description style");
+                       if Current_Paragraph_Style /= Description then
+                           Clean_Buffer_and_Close_Old_Style;
+                           Ada.Text_IO.Put_Line (File, "@begin[Description]");
+                           Current_Paragraph_Style := Description;
+                       -- else no change needed.
+                       end if;
+                       Styles_Found(Description) := Styles_Found(Description) 
+ 1;
+                       -- We just discard the entire style mess.
+                       Last_Output := End_of_Style;
+                       Working := Last_Output + 1;
+
+                   else -- Unknown style.
+--Ada.Text_IO.Put_Line ("  Unknown style: code = " & 
Our_Line(Style_Code_Loc..Style_Code_Loc+4));
+                       if Current_Paragraph_Style /= Unknown then
+                           Clean_Buffer_and_Close_Old_Style;
+                           Current_Paragraph_Style := Unknown;
+                       -- else no change needed.
+                       end if;
+                       Styles_Found(Unknown) := Styles_Found(Unknown) + 1;
+                       -- We leave the style mess for analysis.
+                       Working := Working + 1;
+                   end if;
+               end Start_Style;
+
+           begin
+               Paragraphs := Paragraphs + 1;
+               Chars_on_Line := 0;
+               while Working <= Our_Line'Last loop
+                   if Our_Line(Working) = '{' then
+                       -- Start an RTF section.
+                       -- Output everything to here:
+                       Ada.Text_IO.Put (File, 
Our_Line(Last_Output+1..Working-1));
+--Ada.Text_IO.Put_Line("Open Brace on Line" & Line_Count'Image(Cursor.Number) 
& ": output=" & Our_Line(Last_Output+1..Working-1));
+                       Chars_on_Line := Chars_on_Line + ((Working-1) - 
(Last_Output+1) + 1);
+
+                       -- Stack this opening:
+                       Current_Brace := Current_Brace + 1;
+                       if Current_Brace > Deepest_Brace_Nesting then
+                           Deepest_Brace_Nesting := Current_Brace;
+                       end if;
+
+                       if Working+1 > Our_Line'Last or else
+                          Our_Line(Working+1) /= '\' then
+                           -- No command here, so it is not interesting (ever)
+                           -- and we might as well remove it.
+                           Brace_Info_Stack(Current_Brace).Kind := Empty;
+                           Last_Output := Working; -- Skip the brace.
+--Ada.Text_IO.Put_Line("Empty Open Brace on Line" & 
Line_Count'Image(Cursor.Number));
+
+                       elsif Working+3 <= Our_Line'Last and then
+                          Our_Line(Working..Working+3) = "{\b " then
+                           Brace_Info_Stack(Current_Brace).Kind := Bold;
+                           Ada.Text_IO.Put (File, "@b[");
+                           Chars_on_Line := Chars_on_Line + 3;
+                           Last_Output := Working+3;
+--Ada.Text_IO.Put_Line("Bold Open Brace on Line" & 
Line_Count'Image(Cursor.Number));
+
+                       elsif Working+3 <= Our_Line'Last and then
+                          Our_Line(Working..Working+3) = "{\i " then
+                           Brace_Info_Stack(Current_Brace).Kind := Italic;
+                           Ada.Text_IO.Put (File, "@i[");
+                           Chars_on_Line := Chars_on_Line + 3;
+                           Last_Output := Working+3;
+--Ada.Text_IO.Put_Line("Italic Open Brace on Line" & 
Line_Count'Image(Cursor.Number));
+
+                       elsif Working+6 <= Our_Line'Last and then
+                          Our_Line(Working..Working+6) = "{\line " then
+                           Brace_Info_Stack(Current_Brace).Kind := Line_Break;
+                           Ada.Text_IO.New_Line (File);
+                           Chars_on_Line := 0; -- Start over.
+                           Last_Output := Working+6;
+--Ada.Text_IO.Put_Line("Line_Break Open Brace on Line" & 
Line_Count'Image(Cursor.Number));
+
+                       elsif Working+5 <= Our_Line'Last and then
+                          Our_Line(Working..Working+5) = "{\tab " then
+                           Brace_Info_Stack(Current_Brace).Kind := Tab;
+                           Ada.Text_IO.Put (File, "@\");
+                           Chars_on_Line := Chars_on_Line + 2;
+                           Last_Output := Working+5;
+--Ada.Text_IO.Put_Line("Tab Open Brace on Line" & 
Line_Count'Image(Cursor.Number));
+
+                       elsif Working+14 <= Our_Line'Last and then
+                          Our_Line(Working..Working+14) = "{\cs16\f1\fs20 " 
then
+                           -- \cs16 = "PC Program char" style. Could look for
+                           -- that early on to find the number. Same with
+                           -- "\f1" (Arial). But they might be constant, and
+                           -- that would be wasted work.
+                           Brace_Info_Stack(Current_Brace).Kind := Exam;
+                           Ada.Text_IO.Put (File, "@exam[");
+                           Chars_on_Line := Chars_on_Line + 6;
+                           Last_Output := Working+14;
+--Ada.Text_IO.Put_Line("Exam Open Brace on Line" & 
Line_Count'Image(Cursor.Number));
+
+                       elsif Working+8 <= Our_Line'Last and then
+                          Our_Line(Working..Working+8) = "{\cs20\b " then
+                           -- \cs20 = "RW Reserved word" style. Could look for
+                           -- that early on to find the number.
+                           Brace_Info_Stack(Current_Brace).Kind := Key;
+                           Ada.Text_IO.Put (File, "@key[");
+                           Chars_on_Line := Chars_on_Line + 5;
+                           Last_Output := Working+8;
+--Ada.Text_IO.Put_Line("Key (in example) Open Brace on Line" & 
Line_Count'Image(Cursor.Number));
+
+                       elsif Working+16 <= Our_Line'Last and then
+                          Our_Line(Working..Working+16) = "{\cs20\b\f1\fs20 " 
then
+                           -- \cs20 = "RW Reserved word" style. \f1 = Arial
+                           -- font.
+                           Brace_Info_Stack(Current_Brace).Kind := Key;
+                           Ada.Text_IO.Put (File, "@key[");
+                           Chars_on_Line := Chars_on_Line + 5;
+                           Last_Output := Working+16;
+--Ada.Text_IO.Put_Line("Key (in text) Open Brace on Line" & 
Line_Count'Image(Cursor.Number));
+
+                       elsif Working+8 <= Our_Line'Last and then
+                          Our_Line(Working..Working+8) = "{\cs24\i " then
+                           -- \cs24 = "CT Comment" style.
+                           Brace_Info_Stack(Current_Brace).Kind := ExamCom;
+                           Ada.Text_IO.Put (File, "@examcom[");
+                           Chars_on_Line := Chars_on_Line + 9;
+                           Last_Output := Working+8;
+--Ada.Text_IO.Put_Line("ExamCom Open Brace on Line" & 
Line_Count'Image(Cursor.Number));
+
+                       else
+                           Brace_Info_Stack(Current_Brace).Kind := Unknown;
+                           Ada.Text_IO.Put (File, '{');
+                           Chars_on_Line := Chars_on_Line + 1;
+                           Last_Output := Working;
+--Ada.Text_IO.Put_Line("Unknown Open Brace on Line" & 
Line_Count'Image(Cursor.Number));
+                       end if;
+                       Brace_Kinds_Found(Brace_Info_Stack(Current_Brace).Kind) 
:=
+                           
Brace_Kinds_Found(Brace_Info_Stack(Current_Brace).Kind) + 1;
+                       Working := Last_Output + 1;
+
+                   elsif Our_Line(Working) = '}' then
+                       -- End an RTF section.
+                       -- Output everything to here:
+                       Ada.Text_IO.Put (File, 
Our_Line(Last_Output+1..Working-1));
+--Ada.Text_IO.Put_Line("Close Brace on Line" & Line_Count'Image(Cursor.Number) 
& ": output=" & Our_Line(Last_Output+1..Working-1));
+                       Chars_on_Line := Chars_on_Line + ((Working-1) - 
(Last_Output+1) + 1);
+                       Last_Output := Working; -- We're including this 
character.
+                       case Brace_Info_Stack(Current_Brace).Kind is
+                           when Unknown =>
+                               Ada.Text_IO.Put (File, '}');
+--Ada.Text_IO.Put_Line("Unknown Close Brace on Line" & 
Line_Count'Image(Cursor.Number));
+                               Chars_on_Line := Chars_on_Line + 1;
+                           when Empty =>
+                               -- Just remove this one.
+--Ada.Text_IO.Put_Line("Empty Close Brace on Line" & 
Line_Count'Image(Cursor.Number));
+                               null;
+                           when Bold =>
+                               Ada.Text_IO.Put (File, ']');
+--Ada.Text_IO.Put_Line("Bold Close Brace on Line" & 
Line_Count'Image(Cursor.Number));
+                               Chars_on_Line := Chars_on_Line + 1;
+                           when Italic =>
+                               Ada.Text_IO.Put (File, ']');
+--Ada.Text_IO.Put_Line("Italic Close Brace on Line" & 
Line_Count'Image(Cursor.Number));
+                               Chars_on_Line := Chars_on_Line + 1;
+                           when Line_Break =>
+                               null;
+--Ada.Text_IO.Put_Line("Link_Break Close Brace on Line" & 
Line_Count'Image(Cursor.Number));
+                           when Tab =>
+                               null;
+--Ada.Text_IO.Put_Line("Tab Close Brace on Line" & 
Line_Count'Image(Cursor.Number));
+                           when Exam =>
+                               Ada.Text_IO.Put (File, ']');
+--Ada.Text_IO.Put_Line("Exam Close Brace on Line" & 
Line_Count'Image(Cursor.Number));
+                               Chars_on_Line := Chars_on_Line + 1;
+                           when ExamCom =>
+                               Ada.Text_IO.Put (File, ']');
+--Ada.Text_IO.Put_Line("ExamCom Close Brace on Line" & 
Line_Count'Image(Cursor.Number));
+                               Chars_on_Line := Chars_on_Line + 1;
+                           when Key =>
+                               Ada.Text_IO.Put (File, ']');
+--Ada.Text_IO.Put_Line("Key Close Brace on Line" & 
Line_Count'Image(Cursor.Number));
+                               Chars_on_Line := Chars_on_Line + 1;
+                       end case;
+                       Current_Brace := Current_Brace - 1;
+                       Working := Working + 1;
+
+                   elsif Our_Line(Working) = ' ' then
+                       -- Possible break here.
+                       if Chars_on_Line + (Working - (Last_Output+1) + 1) > 65 
then
+                           -- We need a break here; write it.
+                           Ada.Text_IO.Put_Line (File, 
Our_Line(Last_Output+1..Working));
+--Ada.Text_IO.Put_Line("Soft line break on Line" & 
Line_Count'Image(Cursor.Number) & ": output=" & 
Our_Line(Last_Output+1..Working));
+                           Chars_on_Line := 0; -- Start over.
+                           Last_Output := Working;
+                           Working := Working + 1;
+                       else -- Don't need a break.
+                           Working := Working + 1;
+                       end if;
+
+                   elsif Our_Line(Working) = '\' then
+                       -- RTF control word or symbol; see whether it is
+                       -- interesting.
+                       if Working+5 <= Our_Line'Last and then
+                          Our_Line(Working..Working+5) = "\line " then
+                           -- Line break in a paragraph (without an open
+                           -- brace). Output a New_line.
+                           Ada.Text_IO.Put_Line (File, 
Our_Line(Last_Output+1..Working-1));
+--Ada.Text_IO.Put_Line("Line break on Line" & Line_Count'Image(Cursor.Number) 
& ": output=" & Our_Line(Last_Output+1..Working));
+                           Intraparagraph_Line_Breaks := 
Intraparagraph_Line_Breaks + 1;
+                           Chars_on_Line := 0; -- Start over.
+                           Last_Output := Working+5;
+                           Working := Last_Output + 1;
+
+                       elsif Working+4 <= Our_Line'Last and then
+                          Our_Line(Working..Working+4) = "\tab " then
+                           -- Tab inside of a paragraph. Output the previous 
text and a tab command.
+                           -- (Note: We don't define any tabstops here; that
+                           -- will need to be done by hand as needed).
+                           Ada.Text_IO.Put (File, 
Our_Line(Last_Output+1..Working-1));
+--Ada.Text_IO.Put_Line("Tab on Line" & Line_Count'Image(Cursor.Number) & ": 
output=" & Our_Line(Last_Output+1..Working));
+                           Chars_on_Line := Chars_on_Line + ((Working-1) - 
(Last_Output+1) + 1);
+                           Ada.Text_IO.Put (File, "@\");
+                           Chars_on_Line := Chars_on_Line + 2;
+                           Intraparagraph_Tabs := Intraparagraph_Tabs + 1;
+                           Last_Output := Working+4;
+                           Working := Last_Output + 1;
+
+                       elsif Working+1 <= Our_Line'Last and then
+                          (Our_Line(Working+1) = '\' or else
+                           Our_Line(Working+1) = '{' or else
+                           Our_Line(Working+1) = '}') then
+                           -- Escaped character. Output the previous text and
+                           -- the literal character. (We have to do this to
+                           -- prevent the escaped character from being
+                           -- acted on as if it is a control or group marker).
+                           Ada.Text_IO.Put (File, 
Our_Line(Last_Output+1..Working-1));
+--Ada.Text_IO.Put_Line("Escaped char on Line" & 
Line_Count'Image(Cursor.Number) & ": output=" & 
Our_Line(Last_Output+1..Working));
+                           Chars_on_Line := Chars_on_Line + ((Working-1) - 
(Last_Output+1) + 1);
+                           Escaped_Chars := Escaped_Chars + 1;
+                           Last_Output := Working;
+                           Working := Working + 2;
+                           -- We leave the literal character in the output 
buffer for later writing.
+
+                       elsif Working+7 <= Our_Line'Last and then
+                          Our_Line(Working..Working+7) = "\endash " then
+                           -- Line break in a paragraph. Output a New_line.
+                           Ada.Text_IO.Put (File, 
Our_Line(Last_Output+1..Working-1));
+--Ada.Text_IO.Put_Line("Endash on Line" & Line_Count'Image(Cursor.Number) & ": 
output=" & Our_Line(Last_Output+1..Working));
+                           Chars_on_Line := Chars_on_Line + ((Working-1) - 
(Last_Output+1) + 1);
+                           Ada.Text_IO.Put (File, "@en");
+                           Chars_on_Line := Chars_on_Line + 3;
+                           EN_Dashes := EN_Dashes + 1;
+                           Last_Output := Working+7;
+                           Working := Last_Output + 1;
+
+                       elsif Working+7 <= Our_Line'Last and then
+                          Our_Line(Working..Working+7) = "\emdash " then
+                           -- Line break in a paragraph. Output a New_line.
+                           Ada.Text_IO.Put (File, 
Our_Line(Last_Output+1..Working-1));
+--Ada.Text_IO.Put_Line("Emdash on Line" & Line_Count'Image(Cursor.Number) & ": 
output=" & Our_Line(Last_Output+1..Working));
+                           Chars_on_Line := Chars_on_Line + ((Working-1) - 
(Last_Output+1) + 1);
+                           Ada.Text_IO.Put (File, "@em");
+                           Chars_on_Line := Chars_on_Line + 3;
+                           EM_Dashes := EM_Dashes + 1;
+                           Last_Output := Working+7;
+                           Working := Last_Output + 1;
+
+                       elsif Working+5 <= Our_Line'Last and then
+                          Our_Line(Working..Working+5) = "\pard\" then
+                           -- Starts a (full) paragraph style.
+--Ada.Text_IO.Put_Line("Paragraph style on Line" & 
Line_Count'Image(Cursor.Number));
+                           declare
+                               End_of_Style : Natural :=
+                                   Ada.Strings.Fixed.Index 
(Our_Line(Working..Our_Line'Last),
+                                       "\langfenp1033 ") + 13;
+                               -- For some reason, all of the styles end with 
this.
+                               Style_Code : Natural :=
+                                   Ada.Strings.Fixed.Index 
(Our_Line(Working..Our_Line'Last),
+                                       "\s");
+                               -- The style code is generally first.
+                           begin
+--Ada.Text_IO.Put_Line("Style_Code=" & Natural'Image(Style_Code) &
+--                     "; End_of_Style=" & Natural'Image(End_of_Style));
+                               if Style_Code = 0 or else End_of_Style = 13 or 
else
+                                   Style_Code > End_of_Style or else
+                                   (not Possible_Style (Working, 
End_of_Style)) then
+                                   -- No style code, no end of style, the style
+                                   -- code comes after the end of the style, or
+                                   -- the style has problems. (In which case, 
we are
+                                   -- probably taking too much as the style).
+                                   -- This is unknown. Do nothing and just 
output the character.
+                                   Working := Working + 1;
+                               else
+                                   Start_Style (Style_Code, End_of_Style);
+                                       -- This sets Working and Last_Output 
appropriately.
+                               end if;
+                           end;
+
+                       elsif Working+5 <= Our_Line'Last and then
+                           Our_Line(Working..Working+5) = "\pard " then
+                           -- Starts a (short) paragraph style.
+--Ada.Text_IO.Put_Line("Short paragraph style on Line" & 
Line_Count'Image(Cursor.Number));
+                           declare
+                               End_of_Style : Natural :=
+                                   Ada.Strings.Fixed.Index 
(Our_Line(Working..Our_Line'Last),
+                                       "\lin0\itap0 ");
+                               -- For some reason, all of the styles end with 
this.
+                               Style_Code : Natural :=
+                                   Ada.Strings.Fixed.Index 
(Our_Line(Working..Our_Line'Last),
+                                       "\s");
+                               -- The style code is generally first.
+                           begin
+                               if End_of_Style = 0 then
+                                   End_of_Style :=
+                                       Ada.Strings.Fixed.Index 
(Our_Line(Working..Our_Line'Last),
+                                           "\lin480\itap0 ");
+                                   if End_of_Style = 0 then
+                                       End_of_Style :=
+                                           Ada.Strings.Fixed.Index 
(Our_Line(Working..Our_Line'Last),
+                                               "\lin360\itap0 ");
+                                       if End_of_Style /= 0 then
+                                           End_of_Style := End_of_Style + 13;
+                                       end if;
+                                   else
+                                       End_of_Style := End_of_Style + 13;
+                                   end if;
+                               else
+                                   End_of_Style := End_of_Style + 11;
+                               end if;
+
+                               if Style_Code = 0 or else End_of_Style = 0 or 
else
+                                   Style_Code > End_of_Style or else
+                                   (not Possible_Style (Working, 
End_of_Style)) then
+                                   -- No style code, no end of style, the style
+                                   -- code comes after the end of the style, or
+                                   -- the style has problems. (In which case, 
we are
+                                   -- probably taking too much as the style).
+                                   -- This is unknown. Do nothing and just 
output the character.
+                                   Working := Working + 1;
+                               else
+                                   Start_Style (Style_Code, End_of_Style);
+                                       -- This sets Working and Last_Output 
appropriately.
+                               end if;
+                           end;
+
+                       else -- Don't recognize it, just output it (later).
+                           Working := Working + 1;
+                       end if;
+                   else -- Just output it (later).
+                       Working := Working + 1;
+                   end if;
+               end loop;
+               -- Output any remaining text (it can't need to be broken):
+               Ada.Text_IO.Put (File, Our_Line(Last_Output+1..Our_Line'Last));
+--Ada.Text_IO.Put_Line("Remaining text on Line" & 
Line_Count'Image(Cursor.Number) & ": output=" & 
Our_Line(Last_Output+1..Our_Line'Last));
+           end;
+           Ada.Text_IO.New_Line (File, 2); -- Double space.
+           Cursor := Cursor.Next;
+       end loop;
+       Close_Old_Style; -- Close the last style.
+       Ada.Text_IO.Close (File);
+       Free_All (Data);
+       -- Display statistics:
+       Ada.Text_IO.Put_Line ("Conversion statistics:");
+       Ada.Text_IO.Put_Line ("  Total paragraphs:" & 
Natural'Image(Paragraphs));
+       Ada.Text_IO.Put_Line ("  Deepest nesting:" & 
Natural'Image(Deepest_Brace_Nesting));
+       for I in RTF_Group_Kind loop
+           Ada.Text_IO.Put_Line ("  Kind " & RTF_Group_Kind'Image(I) &
+               ":" & Natural'Image(Brace_Kinds_Found(I)));
+       end loop;
+       Ada.Text_IO.Put_Line ("  Escaped characters found:" & 
Natural'Image(Escaped_Chars));
+       Ada.Text_IO.Put_Line ("  EM Dashes found:" & Natural'Image(EM_Dashes));
+       Ada.Text_IO.Put_Line ("  EN Dashes found:" & Natural'Image(EN_Dashes));
+       Ada.Text_IO.Put_Line ("  Line breaks inside of paragraphs:" & 
Natural'Image(Intraparagraph_Line_Breaks));
+       Ada.Text_IO.Put_Line ("  Tabs inside of paragraphs:" & 
Natural'Image(Intraparagraph_Tabs));
+       for I in Paragraph_Styles loop
+           Ada.Text_IO.Put_Line ("  Style " & Paragraph_Styles'Image(I) &
+               ":" & Natural'Image(Styles_Found(I)));
+       end loop;
+    end Process_and_Write_File;
+
+    File_Contents : Line_Access;
+
+begin
+    Ada.Text_IO.Put_Line ("Convert " &
+       Ada.Command_Line.Argument(1) & ".rtf to " &
+       Ada.Command_Line.Argument(1) & ".mss");
+    Load_File (Ada.Command_Line.Argument(1) & ".rtf", File_Contents);
+    Process_and_Write_File (Ada.Command_Line.Argument(1) & ".mss", 
File_Contents);
+    Ada.Text_IO.Put_Line ("Conversion completed");
+end Rtf2Form;
diff --git a/packages/ada-ref-man/source_2012/01.mss 
b/packages/ada-ref-man/source_2012/01.mss
new file mode 100755
index 0000000..d1bc4bc
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/01.mss
@@ -0,0 +1,2387 @@
address@hidden(01, Root="ada.mss")
+
address@hidden @Comment{Go to odd page.}
+
address@hidden
+The following stuff is to get the "INTERNATIONAL STANDARD" title between
+two horizontal rules at the top of page 1. (RLB-The following is a hack:
+I probably ought to add a style just for this purpose)
address@hidden
+
address@hidden
+
address@hidden
address@hidden@address@hidden()@tabset(P45)
address@hidden<@address@hidden address@hidden/IEC 
8652:@Chg{Version=[2],address@hidden,New=[202x],address@hidden,New=[2012(E)@Chg{Version=[4],New=[
 with Cor 1:2016],Old=[]}],Old=[2007(E), Ed. 3]}]}],address@hidden, 
New=[1995(E) with COR.1:2001], Old=[1995(E)]}]}}]>
address@hidden
+
address@hidden
+
address@hidden
address@hidden@ @address@hidden vertical whitespace}
+
address@hidden@address@hidden technology @Em address@hidden
address@hidden@address@hidden @Em Ada}}
+
address@hidden@ @address@hidden vertical whitespace}
address@hidden
+
address@hidden
address@hidden: 2016/02/12 05:25:37 $}
+
address@hidden: e:\\cvsroot/ARM/Source/01.mss,v $}
address@hidden: 1.89 $}
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0299-1]}
address@hidden,Text=[Ada is a programming language designed to support
+the construction of long-lived, highly reliable software systems. The language
+includes facilities to define packages
+of related types, objects, and operations.
+The packages may be parameterized
+and the types may be extended to support the construction of libraries
+of reusable, adaptable software components. The operations
+may be implemented as subprograms using conventional sequential
+control structures, or as entries that include synchronization
+of concurrent threads of control as part of their invocation.
+The language treats modularity in the physical
+sense as well, with a facility to support separate compilation.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0269-1],ARef=[AI05-0299-1]}
address@hidden,Text=[The language includes a complete facility for
+the support of real-time, concurrent programming.
+Errors can be signaled as exceptions and handled explicitly.
+The language also
+covers systems programming; this requires precise control over the
+representation of data and access to system-dependent properties. Finally,
+a predefined environment of standard packages is provided, including
+facilities for, among others, input-output, string manipulation,
+numeric elementary functions, and random
+number generation.]}
address@hidden
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
+This Annotated Ada Reference Manual (AARM) contains the entire text of
+the @Chg{Version=[3],New=[third edition of the ],Old=[]}Ada Reference
+Manual @Chg{Version=[5],New=[as updated
+for Ada 202x (referred to here as the Ada 202x RM)],
address@hidden,New=[as updated by Technical Corrigendum 1],
address@hidden,New=[ (the
+Ada 2012 RM],address@hidden,New=[with
+Amendment 1 (the Ada 2005 RM],Old=[(RM95]}]})]},
+plus certain annotations.
+The annotations give a more in-depth analysis of the language.
+They describe the reason for each nonobvious rule,
+and point out interesting ramifications of the rules
+and interactions among the rules
+(interesting to language lawyers, that is).
+Differences between Ada address@hidden,New=[, Ada 95,
address@hidden,New=[],Old=[and ]}Ada address@hidden,address@hidden,New=[, Ada 
2012, and Ada 202x],Old=[, and Ada
+2012]}],Old=[]}],Old=[ and Ada 95]} are listed.
+(The text you are reading now is an annotation.)
+
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
+The AARM stresses detailed correctness and uniformity over
+readability and understandability.
+We're not trying to make the language @lquotes@;address@hidden@; simple here;
+on the contrary, we're trying to expose hidden complexities,
+so we can more easily detect language bugs.
+The @Chg{Version=[2],New=[Ada 
@Chg{Version=[3],address@hidden,New=[202x],Old=[2012]}],Old=[2005]} 
RM],Old=[RM95]}, on the other hand, is intended to be a more
+readable document for programmers.
+
address@hidden@keepnext@;The annotations in the AARM are as follows:
address@hidden
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
+Text that is logically redundant is shown
address@hidden square brackets, like this].
+Technically, such text could be written as a @NotesName
+in the @Chg{Version=[2],New=[Ada 
@Chg{Version=[3],address@hidden,New=[202x],Old=[2012]}],Old=[2005]} RM
+(and the Ada 95 @Chg{Version=[3],New=[and 2005 RMs],Old=[RM]} before 
it)],Old=[RM95]},
+since it is really a theorem that can
+be proven from the nonredundant rules of the language.
+We use the square brackets instead when it seems to make the
address@hidden,New=[Ada 
@Chg{Version=[3],address@hidden,New=[202x],Old=[2012]}],Old=[2005]} 
RM],Old=[RM95]} more readable.
+
+The rules of the language (and some AARM-only text) are categorized,
+and placed under certain @i{sub-headings} that indicate
+the category.
+For example, the distinction between @ResolutionName@;s
+and @LegalityName@;s is particularly important,
+as explained in @RefSecNum{The Context of Overload Resolution}.
+
+Text under the following sub-headings appears in both documents:
address@hidden(Inneritemize)
+The unlabeled text at the beginning of each clause or subclause,
+
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden
address@hidden(Inneritemize)
+
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
+Text under the following sub-headings
+does not appear in the @Chg{Version=[2],New=[Ada 
@Chg{Version=[3],address@hidden,New=[202x],Old=[2012]}],Old=[2005]} 
RM],Old=[RM95]}:
address@hidden(Inneritemize)
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden,
+
address@hidden,Kind=[Revised]}
address@hidden@Chg{Version=[2],New=[,],Old=[.]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden,]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden,]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden,]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,address@hidden@Chg{Version=[3],New=[,],Old=[.]}]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden,]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden,]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden,]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden,]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden,]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden,]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden
address@hidden(Inneritemize)
+
+The AARM also includes the following kinds of annotations.
+These do not necessarily annotate the immediately preceding
+rule, although they often do.
address@hidden
address@hidden
address@hidden
+An explanation of why a certain rule is necessary,
+or why it is worded in a certain way.
address@hidden
address@hidden
+An obscure ramification of the rules that is of interest
+only to language lawyers.
+(If a ramification of the rules is of interest to programmers,
+then it appears under @NotesTitle.)
address@hidden
address@hidden
+An informal proof explaining how a given
address@hidden or
address@hidden piece of text
+follows from the other rules of the language.
address@hidden
address@hidden
+A hint about how to implement a feature, or a particular potential
+pitfall that an implementer needs to be aware of.
+
address@hidden:} Change annotations are not used in this version. Changes from
+previous versions have been removed. Changes in this version are marked with
+versioned paragraph numbers, as explained in the
address@hidden@;Corrigendum address@hidden@; clause of the
address@hidden@;address@hidden@;.
address@hidden
+
address@hidden
+Other annotations not covered by the above.
address@hidden
address@hidden
+A rule that is considered logically necessary to the definition of the
+language, but which is so obscure or pedantic that only a language
+lawyer would care.
+These are the only annotations that could be considered part of the
+language definition.
address@hidden
address@hidden
+The text of a Glossary entry @em this text will also appear
+in @RefSec{Glossary}.
address@hidden
address@hidden
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
+In general, @Chg{Version=[2],New=[the Ada 
@Chg{Version=[3],address@hidden,New=[202x],Old=[2012]}],Old=[2005]} 
RM],Old=[RM95]} text appears in the normal font,
+whereas AARM-only text appears in a smaller font.
address@hidden@;s also appear in the smaller font,
+as recommended by ISO/IEC style guidelines.
+Ada examples are also usually printed in a smaller font.
+
+If you have trouble finding things, be sure to use the index.
address@hidden, like this}
+Each defined term appears there,
+and also in @i{italics, like this}.
+Syntactic categories defined in BNF are also indexed.
+
+A definition marked @lquotes@;address@hidden@; is the main definition for a
+term whose complete definition is given in pieces distributed
+throughout the document.
+The pieces are marked @lquotes@;address@hidden@;
+or with a phrase explaining what cases the partial definition applies
+to.
address@hidden
address@hidden
+
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0299-1]}
+This International Standard specifies the form and meaning of programs
+written in Ada.
+Its purpose is to promote the portability of Ada programs to a variety
+of @Chg{Version=[3],New=[computing],Old=[data processing]} systems.
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0299-1]}
address@hidden,Text=[Ada is a programming language designed to support
+the construction of long-lived, highly reliable software systems. The language
+includes facilities to define packages of related types, objects, and
+operations. The packages may be parameterized and the types may be extended to
+support the construction of libraries of reusable, adaptable software
+components. The operations may be implemented as subprograms using conventional
+sequential control structures, or as entries that include synchronization of
+concurrent threads of control as part of their invocation. Ada supports
+object-oriented programming by providing classes and interfaces, inheritance,
+polymorphism of variables and methods, and generic units. The language treats
+modularity in the physical sense as well, with a facility to support separate
+compilation.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0269-1],ARef=[AI05-0299-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0056-1]}
address@hidden,Text=[The language provides rich support for real-time, 
concurrent programming, and
+includes facilities for multicore and multiprocessor programming. Errors can be
+signaled as exceptions and handled explicitly. The language also covers systems
+programming; this requires precise control over the representation of data and
+access to system-dependent properties. Finally, a predefined environment of
+standard packages is provided, including facilities for, among others,
+input-output, string manipulation, numeric elementary functions,
address@hidden,New=[],Old=[and ]}random number generation, and definition and
+use of containers.]}
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden@keepnext@;This International Standard specifies:
address@hidden(Itemize)
+     The form of a program written in Ada;
+
+     The effect of translating and executing such a program;
+
+     The manner in which program units may be combined to form Ada
+     programs;
+
+     The language-defined library units that a conforming implementation
+     is required to supply;
+
+     The permissible variations within the standard, and the manner in
+     which they are to be documented;
+
+     Those violations of the standard that a conforming implementation
+     is required to detect, and the effect of attempting to translate or
+     execute a program containing such violations;
+
+     Those violations of the standard that a conforming implementation
+     is not required to detect.
address@hidden(Itemize)
+
address@hidden
address@hidden@keepnext@;This International Standard does not specify:
address@hidden
address@hidden(Itemize)
+     The means whereby a program written in Ada is transformed into
+     object code executable by a processor;
+
+     The means whereby translation or execution of programs is invoked
+     and the executing units are controlled;
+
+     The size or speed of the object code, or the relative execution
+     speed of different language constructs;
+
+     The form or contents of any listings produced by implementations;
+     in particular, the form or contents of error or warning messages;
+
+     The effect of unspecified execution.
+
+     The size of a program or program unit that will exceed the capacity
+     of a particular conforming implementation.
address@hidden(Itemize)
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This International Standard contains thirteen 
@Chg{Version=[3],New=[clauses],Old=[sections]},
address@hidden,New=[fifteen],Old=[fourteen]} annexes,
+and an index.
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0299-1]}
address@hidden,Text=[What Ada 83 called a @ldquote@;address@hidden and
+Ada 95 (and Ada 2005) called a @ldquote@;address@hidden is called a 
@ldquote@;address@hidden
+in this Standard. Similarly, what Ada 83 called a @ldquote@;address@hidden and
+Ada 95 (and Ada 2005) called a @ldquote@;address@hidden is called a 
@ldquote@;address@hidden
+in this Standard. Confused yet? This terminology is out of our hands; it is
+(and was) forced by ever-changing ISO rules for drafting Standards.]}
address@hidden
+
address@hidden@Defn{core language}
+The @i{core} of the Ada language consists of:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,New=[Clauses],Old=[Sections]} 1 through 13
+
address@hidden Language Environment}
+
address@hidden to Other Languages}
+
address@hidden Features}
address@hidden
+
address@hidden
address@hidden@Defn{Specialized Needs Annexes}
address@hidden,Sec=(Specialized Needs)}
address@hidden areas}
+The following @i{Specialized Needs Annexes}
+define features that are needed by certain
+application areas:
address@hidden
address@hidden
address@hidden Programming}
+
address@hidden Systems}
+
address@hidden Systems}
+
address@hidden Systems}
+
address@hidden
+
address@hidden Integrity Systems}
address@hidden
+
address@hidden
address@hidden@Defn{normative}
address@hidden,Sec=(normative)}
+The core language and the Specialized Needs Annexes are normative,
+except that the material in each of the items listed below
+is informative:
address@hidden
address@hidden(Itemize)
+    Text under a NOTES or Examples heading.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+    Each @Chg{Version=[3],New=[],Old=[clause or ]}subclause whose title starts
+    with the word @lquotes@;address@hidden@; or @lquotes@;address@hidden@;.
address@hidden(Itemize)
+
+All implementations shall conform to the core language.
+In addition, an implementation may conform separately to one or more
+Specialized Needs Annexes.
+
address@hidden
address@hidden@address@hidden
address@hidden,See=(informative)}
address@hidden,Sec=(informative)}
+The following Annexes are informative:
address@hidden
address@hidden
address@hidden Aspects and Attributes}
+
address@hidden Pragmas}
+
address@hidden,Kind=[Revised],ARef=[AI05-0004-1]}
address@hidden,address@hidden of Documentation Requirements}],address@hidden 
Characteristics}]}
+
address@hidden
+
address@hidden Summary}
+
address@hidden,Kind=[Added],ARef=[AI05-0262-1]}
address@hidden,address@hidden Entities}]}
+
address@hidden
address@hidden(Discussion)
+The idea of the Specialized Needs Annexes is that implementations
+can choose to target certain application areas.
+For example, an implementation specifically targeted to embedded
+machines might support the application-specific features for
+Real-time Systems, but not the application-specific features
+for Information Systems.
+
+The Specialized Needs Annexes extend the core language only in ways that
+users, implementations, and standards bodies are allowed to extend the
+language;
+for example, via additional library units,
+attributes, representation items (see @RefSecNum{Operational and 
Representation Aspects}),
address@hidden,
+and constraints on semantic details that are left unspecified by the
+core language.
+Many implementations already provide much of the functionality defined
+by Specialized Needs Annexes;
+our goal is to increase uniformity among implementations by defining
+standard ways of providing the functionality.
+
address@hidden,Kind=[Revised],address@hidden consistent with 18009}
+We recommend that the @Chg{Version=[2],New=[certification],Old=[validation]}
+procedures allow implementations to
address@hidden,New=[certify],Old=[validate]} the core language, plus any
+set of the Specialized Needs Annexes. We recommend that
+implementations @i{not} be allowed to 
@Chg{Version=[2],New=[certify],Old=[validate]}
+a portion of one of the Specialized Needs Annexes,
+although implementations can, of course, provide @Chg{Version=[2],
+New=[uncertified],Old=[unvalidated]} support for such
+portions. We have designed the Specialized Needs Annexes assuming that
+this recommendation is followed. Thus, our decisions about what to
+include and what not to include in those annexes are
+based on the assumption that each
+annex is @Chg{Version=[2],New=[certified],Old=[validated]} in an
address@hidden@;address@hidden@; manner.
+
+An implementation may, of course,
+support extensions that are different from
+(but possibly related to)
+those defined by one of the Specialized Needs Annexes.
+We recommend that, where appropriate, implementations do this by adding
+library units that are children of existing language-defined library
+packages.
+
+An implementation should not provide extensions that conflict with
+those defined in the Specialized Needs Annexes, in the following sense:
+Suppose an
+implementation supports a certain error-free program that uses only
+functionality defined in the core and in the Specialized Needs Annexes.
+The implementation should ensure that that program will still be error
+free in some possible full implementation of all of the Specialized Needs
+Annexes, and that the semantics of the program will not change.
+For example, an implementation should not provide a package
+with the same name as one defined in one of the Specialized Needs Annexes,
+but that behaves
+differently, @i{even if that implementation does not claim
+conformance to that Annex}.
+
+Note that the Specialized Needs Annexes do not conflict with each
+other; it is the intent that a single implementation can conform
+to all of them.
address@hidden(Discussion)
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0056-1]}
+Each @Chg{Version=[4],New=[clause],Old=[section]} is divided into
address@hidden,New=[],Old=[clauses and]} subclauses that have a
+common structure.
+Each @Chg{Version=[3],New=[],Old=[section, address@hidden,New=[],Old=[,]}
+and subclause first introduces its subject.
+After the introductory text, text is labeled with the following headings:
address@hidden
address@hidden
+
address@hidden
+These are not rules of the language, but guiding principles or goals used in
+defining the rules of the language.
+In some cases, the goal is only partially met;
+such cases are explained.
+
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+This is not part of the definition of the language,
+and does not appear in the @Chg{Version=[2],New=[Ada
address@hidden,address@hidden,New=[202x],Old=[2012]}],Old=[2005]} 
RM],Old=[RM95]}.
address@hidden
+
address@hidden
address@hidden
address@hidden, Sec=(under Syntax heading)}
address@hidden, Sec=(under Syntax heading)}
address@hidden free grammar], Sec=(under Syntax heading)}
address@hidden (Backus-Naur Form)], Sec=(under Syntax heading)}
address@hidden Form (BNF)], Sec=(under Syntax heading)}
+Syntax rules (indented).
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden resolution rules}
address@hidden rules}
address@hidden rules}
+Compile-time rules that are used in name resolution,
+including overload resolution.
address@hidden
+These rules are observed at compile time.
+(We say @lquotes@;address@hidden@; rather than @lquotes@;checked,@rquotes@;
+because these rules are not individually checked.
+They are really just part of the @LegalityName@;s in 
@Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden Rules} that require exactly one interpretation of each
+constituent of a complete context.) The only rules used in overload resolution
+are the @SyntaxName@;s and the @ResolutionName@;s.
+
+When dealing with nonoverloadable declarations it sometimes makes no
+semantic difference whether a given rule is a @ResolutionName
+or a @LegalityName,
+and it is sometimes difficult to decide which it should be.
+We generally make a given rule a @ResolutionName only if it has to be.
+For example,
address@hidden@;The @nt{name}, if any, in a @nt{raise_statement} shall be the 
@nt{name}
+of an address@hidden@;
+is under @lquotes@;@address@hidden@;
address@hidden
address@hidden
+
address@hidden
address@hidden rules}
address@hidden error}
address@hidden, Sec=(compile-time)}
+Rules that are enforced at compile time.
address@hidden, Sec=(construct)}
address@hidden, Sec=(construct)}
+A construct is @i{legal} if it obeys all of the @LegalityName@;s.
address@hidden
+These rules are not used in overload resolution.
+
+Note that run-time errors are always attached to exceptions;
+for example, it is not @lquotes@;address@hidden@; to divide by zero,
+it just raises an exception.
address@hidden
address@hidden
+
address@hidden
address@hidden semantics}
address@hidden semantics}
+A definition of the compile-time effect of each construct.
address@hidden
+The most important compile-time effects represent the effects
+on the symbol table associated with declarations (implicit or
+explicit). In addition, we use this heading as a bit of a grab
+bag for equivalences, package specifications, etc.
+For example, this is where we put statements like so-and-so is
+equivalent to such-and-such. (We ought to try to really mean it when we say
+such things!)
+Similarly, statements about magically-generated implicit declarations
+go here.
+These rules are generally written as statements of fact about the
+semantics, rather than as a you-shall-do-such-and-such sort of thing.
address@hidden
address@hidden
+
address@hidden
address@hidden error}
address@hidden rules}
address@hidden error],See=(post-compilation error)}
address@hidden, Sec=(link-time)}
+Rules that are enforced before running a partition.
address@hidden, Sec=(partition)}
address@hidden, Sec=(partition)}
+A partition is legal if its compilation units are legal
+and it obeys all of the @LinkTimeName@;s.
address@hidden
+It is not specified exactly when these rules are checked, so
+long as they are checked for any given partition before that partition starts
+running. An implementation may choose to check some such rules at compile
+time, and reject @nt{compilation_unit}s accordingly.
+Alternatively, an implementation may check such rules when the partition is
+created (usually known as @lquotes@;link address@hidden@;),
+or when the partition is mapped to a particular piece of hardware (but before
+the partition starts running).
address@hidden
address@hidden
+
address@hidden
address@hidden semantics}
address@hidden semantics}
address@hidden error}
address@hidden, Sec=(run-time)}
+A definition of the run-time effect of each construct.
address@hidden
+This heading describes what happens at run time.
+Run-time checks,
+which raise exceptions upon failure,
+are described here.
+Each item that involves a run-time check is marked with the name
+of the check @em these are the same check names that are used in a
address@hidden Suppress.
+Principle: Every check should have a name,
+usable in a @nt{pragma} Suppress.
address@hidden
address@hidden
+
address@hidden
address@hidden error}
address@hidden, Other=(bounded error)}
+Situations that result in bounded (run-time) errors
+(see @RefSecNum{Classification of Errors}).
address@hidden
+The @lquotes@;address@hidden@; of each such error are described here @em
+that is, we characterize the set of all possible behaviors that can
+result from a bounded error occurring at run time.
address@hidden
address@hidden
+
address@hidden
address@hidden execution}
address@hidden, Other=(erroneous execution)}
+Situations that result in erroneous execution
+(see @RefSecNum{Classification of Errors}).
address@hidden
+
address@hidden
address@hidden requirements}
+Additional requirements for conforming implementations.
address@hidden
+...as opposed to rules imposed on the programmer.
+An example might be,
address@hidden@;The smallest representable duration, Duration'Small,
+shall not be greater than twenty address@hidden@;
+
+It's really just an issue of how the rule is worded.
+We could write the same rule as @lquotes@;The smallest representable duration 
is
+an implementation-defined value less than or equal to 20 address@hidden@;
+and then it would be under @lquotes@;@address@hidden@;
address@hidden
address@hidden
+
address@hidden
address@hidden requirements}
+Documentation requirements for conforming implementations.
address@hidden
+These requirements are beyond those that are implicitly specified by
+the phrase @lquotes@;implementation address@hidden@;. The
+latter require documentation as well, but we don't repeat these cases
+under this heading. Usually this heading is used for when the
+description of the documentation requirement is longer and does not
+correspond directly to one, narrow normative sentence.
address@hidden
address@hidden
+
address@hidden
address@hidden
+Metrics that are specified for the time/space properties of the execution
+of certain language constructs.
address@hidden
+
address@hidden
address@hidden permissions}
+Additional permissions given to the implementer.
address@hidden
+For example, @lquotes@;The implementation is allowed to impose further
+restrictions on the record aggregates allowed in code address@hidden@;
+When there are restrictions on the permission,
+those restrictions are given here also.
+For example, @lquotes@;An implementation is allowed to restrict the kinds of
+subprograms that are allowed to be main subprograms.
+However, it shall support at least parameterless address@hidden@;
address@hidden we don't split this up between here and 
@lquotes@;@address@hidden@;
address@hidden
address@hidden
+
address@hidden
address@hidden advice}
address@hidden
+Optional advice given to the implementer.
+The word @lquotes@;address@hidden@; is used to indicate that the advice is
+a recommendation, not a requirement.
+It is implementation defined
+whether or not a given recommendation is obeyed.
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[Whether or not each recommendation
+given in @ImplAdviceTitle is address@hidden,
+New=[ @em see @RefSec{Implementation Advice} for a listing],Old=[]}.]}
address@hidden
address@hidden,Kind=[Revised]}
+The advice generally shows the intended implementation, but
+the implementer is free to ignore it.
+The implementer is the sole arbiter of whether or not the advice has
+been obeyed, if not, whether the reason is a good one,
+and whether the required documentation is sufficient.
address@hidden,New=[],address@hidden,Sec=(Ada Compiler Validation Capability)}
address@hidden Compiler Validation Capability],Sec=(ACVC)}]}
+It would be wrong for the @Chg{Version=[1],New=[ACATS],Old=[ACVC]} to enforce 
any of
+this advice.
+
+For example,
address@hidden@;Whenever possible, the implementation should choose a value no
+greater than fifty microseconds for the smallest representable duration,
+Duration'address@hidden@;
+
+We use this heading, for example, when the rule is so low level or
+implementation-oriented as to be untestable.
+We also use this heading when we wish to encourage implementations
+to behave in a certain way in most cases, but we do not wish to
+burden implementations by requiring the behavior.
address@hidden
address@hidden
+
address@hidden
address@hidden
+Notes emphasize consequences of the rules
+described in the (sub)clause or elsewhere.
+This material is informative.
address@hidden
+
address@hidden
+Examples illustrate the possible forms of the constructs described.
+This material is informative.
address@hidden
+@ @* @Comment{Two blank lines: why? Because it was in the original.}
address@hidden
+The next three headings list all language changes between Ada 83
+and Ada 95. Language changes are any change that changes the set of
+text strings that are legal Ada programs, or changes the meaning of
+any legal program.
+Wording changes, such as changes in terminology, are not language
+changes.
+Each language change falls into one of the following three
+categories:
address@hidden
address@hidden
+
address@hidden
address@hidden with Ada 83}
+This heading lists all of the upward inconsistencies between Ada 83 and Ada
+95. Upward inconsistencies are situations in which a legal Ada 83 program
+is a legal Ada 95 program with different semantics.
+This type of upward incompatibility is the worst type for users,
+so we only tolerate it in rare situations.
+
+(Note that the semantics of a program is not the same thing as the
+behavior of the program.
+Because of Ada's indeterminacy,
+the @lquotes@;address@hidden@; of a given feature describes a @i{set} of 
behaviors
+that can be exhibited by that feature.
+The set can contain more than one allowed behavior.
+Thus, when we ask whether the semantics changes,
+we are asking whether the set of behaviors changes.)
+
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
+This is not part of the definition of the language,
+and does not appear in the @Chg{Version=[2],New=[Ada 
address@hidden,New=[,],Old=[ or]}
+Ada address@hidden,address@hidden,New=[, Ada 2012,
+or Ada 202x],Old=[, or Ada 2012]}],Old=[]} RM],Old=[RM95]}.
address@hidden
+
address@hidden
address@hidden with Ada 83}
+This heading lists all of the upward incompatibilities between Ada 83
+and Ada 95, except for the ones listed under @lquotes@;@address@hidden@;
+above. These are the situations in which a legal Ada 83 program is
+illegal in Ada 95.
+We do not generally consider a change that turns erroneous execution
+into an exception, or into an illegality, to be upwardly incompatible.
+
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
+This is not part of the definition of the language,
+and does not appear in the @Chg{Version=[2],New=[Ada 
address@hidden,New=[,],Old=[ or]}
+Ada address@hidden,address@hidden,New=[, Ada 2012, or
+Ada 202x],Old=[, or Ada 2012]}],Old=[]} RM],Old=[RM95]}.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+This heading is used to list all upward compatible language changes;
+that is, language extensions.
+These are the situations in which a legal Ada 95 program is not a
+legal Ada 83 program.
+The vast majority of language changes fall into this category.
+
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
+This is not part of the definition of the language,
+and does not appear in the @Chg{Version=[2],New=[Ada 
address@hidden,New=[,],Old=[ or]}
+Ada address@hidden,address@hidden,New=[, Ada 2012, or
+Ada 202x],Old=[, or Ada 2012]}],Old=[]} RM],Old=[RM95]}.
+
address@hidden@ @* @Comment{Two blank lines: why? Because it was in the 
original.}
address@hidden
+As explained above,
+the next heading does not represent any language change:
address@hidden
+
address@hidden
address@hidden,Kind=[Revised]}
address@hidden changes from Ada 83}
+This heading lists some of the nonsemantic changes between @Chg{Version=[2],
+New=[the Ada 83 RM],Old=[RM83]} and
+the @Chg{Version=[2],New=[Ada 95 RM],Old=[RM95]}.
+It is incomplete; we have not attempted to list all wording
+changes, but only the @lquotes@;address@hidden@; ones.
+
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
+This is not part of the definition of the language,
+and does not appear in the @Chg{Version=[2],New=[Ada 
address@hidden,New=[,],Old=[ or]}
+Ada address@hidden,address@hidden,New=[, Ada 2012, or
+Ada 202x],Old=[, or Ada 2012]}],Old=[]} RM],Old=[RM95]}.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[@ @* @Comment{Two blank lines: why? Because 
it was in the Ada 95 original.}
address@hidden
+The next three headings list all language changes between Ada 95
+and Ada 2005 (the language defined by the Ada 95 standard plus
+Technical Corrigendum 1 plus Amendment 1).
+Each language change falls into one of the following three
+categories:]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden with Ada 95}
+This heading lists all of the upward inconsistencies between Ada 95 and Ada
+2005. Upward inconsistencies are situations in which a legal Ada 95 program
+is a legal Ada 2005 program with different semantics.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
address@hidden,Text=[Inconsistencies marked with
address@hidden:address@hidden are corrections to the original Ada 95
+definition introduced by Corrigendum 1. Inconsistencies marked with
address@hidden Correction:address@hidden Correction} are corrections to the
+original Ada 95 definition added by Amendment 1. Formally, these are
+inconsistencies caused by Ada Issues classified as Binding Interpretations;
+implementations of Ada 95 are supposed to follow these corrections, not the
+original flawed language definition. Thus, these strictly speaking are not
+inconsistencies between Ada 95 and Ada 2005. Practically, however, they very
+well may be, as early Ada 95 implementations 
@Chg{Version=[3],New=[might],Old=[may]}
+not follow the recommendation.
+Inconsistencies so marked are not portable between Ada 95 implementations,
+while usually Ada 2005 will have more clearly defined behavior. Therefore, we
+document these for completeness.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
address@hidden,Text=[This is not part of the definition of the language,
+and does not appear in the Ada 2005 @Chg{Version=[3],address@hidden,New=[,
+Ada 2012, or Ada 202x],Old=[or Ada 2012]}],Old=[]} RM.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden with Ada 95}
+This heading lists all of the upward incompatibilities between Ada 95
+and Ada 2005, except for the ones listed under @lquotes@;@address@hidden@;
+above. These are the situations in which a legal Ada 95 program is
+illegal in Ada 2005.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
address@hidden,Text=[As with inconsistencies, incompatibilities
+marked with @b[Corrigendum:]
+are corrections to the original Ada 95 definition introduced by Corrigendum
+1. Incompatibilities marked with @b[Amendment Correction:] are corrections
+to the original Ada 95 definition added by Amendment 1. Formally, these are
+incompatibilities caused by Ada Issues classified as Binding Interpretations;
+implementations of Ada 95 are supposed to follow these corrections, not the
+original flawed language definition. Thus,
+these strictly speaking are not incompatibilities between Ada 95 and Ada 2005.
+Practically, however, they very well may be, as early Ada 95 implementations
address@hidden,New=[might],Old=[may]} not follow the recommendation.
+Therefore, some Ada 95 implementations
+may be able to compile the examples, while others
address@hidden,New=[might],Old=[may]} not. In
address@hidden,New=[contrast],Old=[constrast]},
+Ada 2005 compilers will have consistent behavior. Therefore, we document these
+for completeness.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
address@hidden,Text=[This is not part of the definition of the language,
+and does not appear in the Ada 2005 @Chg{Version=[3],address@hidden,New=[,
+Ada 2012, or Ada 202x],Old=[or Ada 2012]}],Old=[]} RM.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden to Ada 95}
+This heading is used to list all upward compatible language changes;
+that is, language extensions.
+These are the situations in which a legal Ada 2005 program is not a
+legal Ada 95 program.
+The vast majority of language changes fall into this category.],Old=[]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
address@hidden,Text=[As with incompatibilities, extensions
+marked with @b[Corrigendum:]
+are corrections to the original Ada 95 definition introduced by Corrigendum
+1. Extensions marked with @b[Amendment Correction:] are corrections
+to the original Ada 95 definition added by Amendment 1. Formally, these are
+extensions allowed by Ada Issues classified as Binding Interpretations.
+As corrections, implementations of Ada 95 are allowed to implement these
+extensions. Thus, these strictly speaking are not extensions of Ada 95;
+they're part of Ada 95. Practically, however, they very well may be extensions,
+as early Ada 95 implementations @Chg{Version=[3],New=[might],Old=[may]} not
+implement the extension. Therefore, some Ada 95 implementations may be able
+to compile the examples, while others @Chg{Version=[3],New=[might],Old=[may]}
+not. In @Chg{Version=[3],New=[contrast],Old=[constrast]},
+Ada 2005 compilers will always support the extensions.
+Therefore, we document these for completeness.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
address@hidden,Text=[This is not part of the definition of the language,
+and does not appear in the Ada 2005 @Chg{Version=[3],address@hidden,New=[,
+Ada 2012, or Ada 202x],Old=[or Ada 2012]}],Old=[]} RM.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[@ @* @Comment{Two blank lines: why? Because 
it was in the Ada 95 original.}
address@hidden
+As explained above,
+the next heading does not represent any language change:]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden changes from Ada 95}
+This heading lists some of the nonsemantic changes between the Ada 95 RM and
+the Ada 2005 RM. This heading lists only @lquotes@;address@hidden@; changes
+(for instance, editorial corrections are not listed). Changes which
+come from Technical Corrigendum 1 are marked @b{Corrigendum}; unmarked changes
+come from Amendment 1.],Old=[]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
address@hidden,Text=[This is not part of the definition of the language,
+and does not appear in the Ada 2005 @Chg{Version=[3],address@hidden,New=[,
+Ada 2012, or Ada 202x],Old=[or Ada 2012]}],Old=[]} RM.]}
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[@ @* @Comment{Two blank lines: why? Because 
it was in the Ada 95 original.}
address@hidden
+The next three headings list all language changes between Ada 2005
+(the language defined by the Ada 95 standard plus
+Technical Corrigendum 1 plus Amendment 1)
+and Ada 2012 (the language defined by the third edition of the address@hidden:
+Ada 95 standard plus Technical Corrigendum 1 plus Amendment 1 plus Amendment 
2}).
+Each language change falls into one of the following three categories:]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden with Ada 2005}
+This heading lists all of the upward inconsistencies between Ada 2005 and Ada
+2012. Upward inconsistencies are situations in which a legal Ada 2005 program
+is a legal Ada 2012 program with different semantics.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Inconsistencies marked with
address@hidden:address@hidden are corrections to the original Ada 2005
+definition added by the third edition of the Standard.
+Formally, these are
+inconsistencies caused by Ada Issues classified as Binding Interpretations;
+implementations of Ada 2005 are supposed to follow these corrections, not the
+original flawed language definition. Thus, these strictly speaking are not
+inconsistencies between Ada 2005 and Ada 2012. Practically, however, they very
+well may be, as early Ada 2005 implementations might not follow the 
recommendation.
+Inconsistencies so marked are not portable between Ada 2005 implementations,
+while usually Ada 2012 will have more clearly defined behavior. Therefore, we
+document these for completeness.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,Text=[This is not part of the definition of the language,
+and does not appear in the Ada address@hidden,New=[ or Ada 202x],Old=[]}
+RM.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden with Ada 2005}
+This heading lists all of the upward incompatibilities between Ada 2005
+and Ada 2012, except for the ones listed under @lquotes@;@address@hidden@;
+above. These are the situations in which a legal Ada 2005 program is
+illegal in Ada 2012.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[As with inconsistencies, incompatibilities
+marked with @b[Correction:] are corrections to the original Ada 2005 definition
+added by the third edition. Formally, these are
+incompatibilities caused by Ada Issues classified as Binding Interpretations;
+implementations of Ada 2005 are supposed to follow these corrections, not the
+original flawed language definition. Thus,
+these strictly speaking are not incompatibilities between Ada 2005 and Ada 
2012.
+Practically, however, they very well may be, as early Ada 2005 implementations
+might not follow the recommendation. Therefore, some Ada 2005 implementations
+may be able to compile the examples, while others might not. In
address@hidden,New=[contrast],Old=[constrast]},
+Ada 2012 compilers will have consistent behavior. Therefore, we document these
+for completeness.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,Text=[This is not part of the definition of the language,
+and does not appear in the Ada address@hidden,New=[ or Ada 202x],Old=[]}
+RM.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden to Ada 2005}
+This heading is used to list all upward compatible language changes;
+that is, language extensions.
+These are the situations in which a legal Ada 2012 program is not a
+legal Ada 2005 program.
+The vast majority of language changes fall into this category.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[As with incompatibilities, extensions
+marked with @b[Correction:]
+are corrections to the original Ada 2005 definition added by the third edition.
+Formally, these are extensions allowed by Ada Issues classified as Binding
+Interpretations. As corrections, implementations of Ada 2005 (and sometimes 
Ada 95)
+are allowed to implement these extensions. Thus, these strictly speaking are 
not
+extensions of Ada 2005; they're part of Ada 2005. Practically, however, they
+very well may be extensions, as early Ada 2005 implementations might not 
implement
+the extension. Therefore, some Ada 2005 implementations may be able to compile
+the examples, while others might not. In contrast, Ada 2012 compilers will 
always
+support the extensions. Therefore, we document these for completeness.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,Text=[This is not part of the definition of the language,
+and does not appear in the Ada address@hidden,New=[ or Ada 202x],Old=[]}
+RM.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[@ @* @Comment{Two blank lines: why? Because 
it was in the Ada 95 original.}
address@hidden
+As explained above, the next heading does not represent any language change:]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden changes from Ada 2005}
+This heading lists some of the nonsemantic changes between the Ada 2005 RM and
+the Ada 2012 RM. This heading lists only @lquotes@;address@hidden@; changes
+(for instance, editorial corrections are not listed). Items marked
address@hidden:] come from Ada Issues classified
+as Binding Interpretations and strictly speaking belong to Ada 2005; other 
items
+only belong to Ada 2012.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,Text=[This is not part of the definition of the language,
+and does not appear in the Ada address@hidden,New=[ or Ada 202x],Old=[]}
+RM.]}
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,Type=[Leading],Text=[@ @* @Comment{Two blank lines: why? Because 
it was in the Ada 95 original.}
address@hidden
+The next three headings list all language changes between
address@hidden,New=[Ada 2012
+(the language defined by ISO/IEC 8652:2012(E))
+and Ada 202x (the language defined by this edition of the 
Standard)],Old=[original
+Ada 2012 (the language defined by unmodified ISO/IEC 8652:2012(E)) and current
+Ada 2012 (the language defined by ISO/IEC 8652:2012(E) as
+corrected by the Corrigendum ISO/IEC 8652:2012/Cor 1:2016)]}.
+Each language change falls into one of the following three categories:]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,address@hidden with Ada 2012}
+This heading lists all of the upward inconsistencies between
address@hidden,New=[Ada 2012 and Ada 202x],Old=[original and current Ada 2012]}.
+Upward inconsistencies are situations in which a legal
address@hidden,New=[Ada 2012 program is a legal Ada 202x],Old=[
+original Ada 2012 program is a legal current Ada 2012]}
+program with different semantics.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,Text=[Inconsistencies marked with
address@hidden:address@hidden are corrections to the original Ada 2012
+definition added by Technical Corrigendum 1 to Ada address@hidden,
+New=[ Inconsistencies marked
+with @b[Correction:address@hidden are corrections to the original Ada 2012
+definition added by this edition of the Standard.],Old=[]}
+Formally, these are
+inconsistencies caused by Ada Issues classified as Binding Interpretations;
+implementations of Ada 2012 are supposed to follow these corrections, not the
+original flawed language definition. Thus, these strictly speaking are not
+inconsistencies between @Chg{Version=[5],New=[Ada 2012 and Ada 
202x],Old=[current
+and original Ada 2012]}. Practically, however, they very
+well may be, as early Ada 2012 implementations might not follow the 
recommendation.
+Inconsistencies so marked are not portable between Ada 2012
address@hidden,New=[, while usually Ada 202x will have
+more clearly defined behavior],Old=[]}. Therefore, we
+document these for completeness.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This is not part of the definition of the language,
+and does not appear in any version of the Ada RM.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,address@hidden with Ada 2012}
+This heading lists all of the upward incompatibilities between
address@hidden,New=[Ada 2012 and Ada 202x],Old=[original and current Ada 2012]},
+except for the ones listed under @lquotes@;@address@hidden@;
+above. These are the situations in which a legal
address@hidden,New=[Ada 2012 program is illegal in Ada 202x],Old=[
+original Ada 2012 program is illegal in current Ada 2012]}.]}
+
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,Text=[As with inconsistencies, incompatibilities
+marked with
address@hidden:address@hidden are corrections to the original Ada 2012
+definition added by Corrigendum 1 to Ada address@hidden,
+New=[, and incompatibilities marked
+with @b[Correction:address@hidden are corrections to the original Ada 2012
+definition added by this edition.],Old=[]}
+Formally, these are
+incompatibilities caused by Ada Issues classified as Binding Interpretations;
+implementations of Ada 2012 are supposed to follow these corrections, not the
+original flawed language definition. Thus,
+these strictly speaking are not incompatibilities between
address@hidden,New=[Ada 2012 and Ada 202x],Old=[current and original Ada 2012]}.
+Practically, however, they very well may be, as early Ada 2012 implementations
+might not follow the recommendation. Therefore, some Ada 2012 implementations
+may be able to compile the examples, while others might
address@hidden,New=[ In contrast, Ada 202x compilers will have
+consistent behavior.],Old=[]} Therefore, we document these
+for completeness.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This is not part of the definition of the language,
+and does not appear in any version of the Ada RM.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,address@hidden to Ada 2012}
+This heading is used to list all upward compatible language changes;
+that is, language extensions.
+These are the situations in which a legal
address@hidden,New=[Ada 202x program is not a legal Ada 202x],Old=[
+current Ada 2012 program is not a legal original Ada 2012]} program.
+The vast majority of language changes fall into this category.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,Text=[As with incompatibilities, extensions
+marked with
address@hidden:address@hidden are corrections to the original Ada 2012
+definition added by Corrigendum 1 to Ada address@hidden,
+New=[, and extensions
+marked with @b[Correction:] are corrections to the original Ada 2012 definition
+added by this edition],Old=[]}.
+Formally, these are extensions allowed by Ada Issues classified as Binding
+Interpretations. As corrections, implementations of Ada 2012 (and sometimes 
Ada 95)
+are allowed to implement these extensions. Thus, these strictly speaking are 
not
+extensions of Ada 2012; they're part of Ada 2012. Practically, however, they
+very well may be extensions, as early Ada 2012 implementations might not 
implement
+the extension. Therefore, some Ada 2012 implementations may be able to compile
+the examples, while others might address@hidden,New=[ In contrast,
+Ada 202x compilers will always support the extensions.],Old=[]}
+Therefore, we document these for completeness.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This is not part of the definition of the language,
+and does not appear in any version of the Ada RM.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[@ @* @Comment{Two blank lines: why? Because 
it was in the Ada 95 original.}
address@hidden
+As explained above, the next heading does not represent any language change:]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,address@hidden changes from Ada 2012}
+This heading lists some of the nonsemantic changes between the
address@hidden,New=[Ada 2012 RM and
+the Ada 202x RM],Old=[original and corrected Ada 2012 RM]}. This heading lists
+only @lquotes@;address@hidden@; changes
+(for instance, editorial corrections are not listed). Items marked
address@hidden:address@hidden are included in Corrigendum 1 to Ada
address@hidden,New=[, and items marked with @b[Correction:] are added by this 
edition.
+In both cases, the],Old=[. These]}
+items come from Ada Issues classified
+as Binding Interpretations and strictly speaking belong to Ada
address@hidden,New=[; other items only belong to Ada 202x],Old=[]}.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This is not part of the definition of the language,
+and does not appear in any version of the Ada RM.]}
address@hidden
+
+
address@hidden of an Implementation with the Standard}
+
address@hidden
+
address@hidden@address@hidden,Sec=(of an implementation with the Standard)}
+A conforming implementation shall:
address@hidden
address@hidden
+The @i{implementation} is the software and hardware that implements
+the language.
+This includes compiler, linker, operating system, hardware, etc.
+
+We first define what it means to @lquotes@;address@hidden@; in general @em
+basically, the implementation has to properly implement the normative
+rules given throughout the standard.
+Then we define what it means to conform to a Specialized Needs
+Annex @em the implementation must support the core features plus the
+features of that Annex.
+Finally, we define what it means to @lquotes@;conform to the address@hidden@; 
@em
+this requires support for the core language,
+and allows partial (but not conflicting) support for
+the Specialized Needs Annexes.
address@hidden
address@hidden(Itemize)
+     Translate and correctly execute
+     legal programs written in Ada,
+     provided that they are not so large as to exceed the capacity of
+     the implementation;
+
+     Identify all programs or program units
+     that are so large as to exceed the capacity of
+     the implementation (or raise an appropriate
+     exception at run time);
+     @ImplDef{Capacity limitations of the implementation.}
+
+     Identify all programs or program units that contain
+     errors whose detection is required by this
+     International Standard;
+     @begin{Discussion}
+       Note that we no longer use the term @lquotes@;address@hidden@; of
+       programs or program units.
+       We require that programs or program units with errors or that
+       exceed some capacity limit be @lquotes@;address@hidden@;.
+       The way in which errors or capacity problems are reported is not
+       specified.
+
+       An implementation is allowed to use standard error-recovery
+       techniques.
+       We do not disallow such techniques from being used across
+       @nt{compilation_unit} or @nt{compilation} boundaries.
+
+       See also the @ImplReqTitle of @RefSecNum{Program Execution},
+       which disallow the execution of illegal partitions.
+
+     @end{Discussion}
+
+     Supply all language-defined library units required by this
+     International Standard;
+     @begin{ImplNote}
+       An implementation cannot add to or modify the visible part of
+       a language-defined library unit,
+       except where such permission is explicitly granted,
+       unless such modifications are semantically neutral with respect
+       to the client compilation units of the library unit.
+       An implementation defines the contents of the private part and
+       body of language-defined library units.
+
+       An implementation can add @nt{with_clause}s and @nt{use_clause}s,
+       since these modifications are semantically neutral to clients.
+       (The implementation might need @nt{with_clause}s in order to
+       implement the private part, for example.)
+       Similarly, an implementation can add a private part even in cases
+       where a private part is not shown in the standard.
+       Explicit declarations can be provided implicitly or by renaming,
+       provided the changes are semantically neutral.
+
+       @Defn2{Term=[italics],Sec=(implementation-defined)}
+       Wherever in the standard the text of a language-defined library
+       unit contains an italicized phrase starting with
+       @lquotes@;@address@hidden@;, the implementation's version
+       will replace that phrase with some implementation-defined text
+       that is syntactically legal at that place, and follows any other
+       applicable rules.
+
+       Note that modifications are permitted, even if there are other tools
+       in the environment that can detect the changes (such as a program
+       library browser), so long as the modifications make no difference
+       with respect to the static or dynamic semantics of the resulting
+       programs, as defined by the standard.
+     @end{ImplNote}
+
+     Contain no variations except
+     those explicitly permitted by this
+     International Standard, or those that are impossible or impractical
+     to avoid given the implementation's execution environment;
+     @ImplDef{Variations from the standard that are impractical to avoid
+     given the implementation's execution environment.}
+     @begin{Reason}
+     The @lquotes@;impossible or address@hidden@; wording comes from AI-325.
+     It takes some judgement and common sense to interpret this.
+     Restricting compilation units to less than 4 lines is probably
+     unreasonable, whereas restricting them to less than 4 billion lines
+     is probably reasonable (at least given today's technology).
+     We do not know exactly where to draw the line,
+     so we have to make the rule vague.
+     @end{Reason}
+
+     Specify all such variations in the manner prescribed
+     by this International Standard.
address@hidden(Itemize)
+
address@hidden
address@hidden@address@hidden effect], Sec=(of the execution of an Ada program)}
address@hidden, Sec=(external)}
+The @i(external effect) of the execution of an Ada program is
+defined in terms of its interactions
+with its external environment.
address@hidden interaction}
+The following are defined as @i(external interactions):
address@hidden
address@hidden(Itemize)
+  Any interaction with an external file
+  (see @RefSecNum(External Files and File Objects));
+
+  The execution of
+  certain @nt<code_statement>s
+  (see @RefSecNum{Machine Code Insertions});
+  which @nt{code_statement}s cause external interactions
+  is implementation defined.
+  @ImplDef{Which @nt{code_statement}s cause external interactions.}
+
+  Any call on an imported subprogram
+  (see @RefSecNum(Interface to Other Languages)),
+  including any parameters passed to it;
+
+  Any result returned or exception
+  propagated from a main subprogram
+  (see @RefSecNum(Program Execution))
+  or an exported subprogram
+  (see @RefSecNum(Interface to Other Languages)) to an external caller;
+  @begin{Discussion}
+    By @lquotes@;result address@hidden@; we mean to include function results
+    and values returned in address@hidden(in)] @key(out) parameters.
+
+    @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0094],ARef=[AI95-00119-01]}
+    @Chg{Version=[1],New=[The lack of a result from a program that does not 
terminate
+    is also included here.],Old=[]}
+  @end{Discussion}
+
+  @Redundant[Any read or update of an atomic or volatile object
+  (see @RefSecNum(Shared Variable Control));]
+
+  The values of imported and exported objects
+  (see @RefSecNum(Interface to Other Languages)) at the time
+  of any other interaction with the external environment.
+    @begin{Honest}
+    @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+    Also other uses of imported and exported entities,
+    as defined by the implementation,
+    if the implementation supports such @Chg{Version=[3],New=[importing or
+    exporting],address@hidden
+    @end{Honest}
address@hidden(Itemize)
+
address@hidden
+A conforming implementation
+of this International Standard shall produce for the
+execution of a given Ada program
+a set of interactions with the external environment whose
+order and timing are consistent with the definitions and requirements of this
+International Standard for the semantics of the given program.
address@hidden
address@hidden
+  There is no need to produce any of the @lquotes@;internal address@hidden@;
+  defined for the semantics of the program @em all of these
+  can be optimized away @em so long as an appropriate sequence
+  of external interactions is produced.
address@hidden
address@hidden
+  See also @RefSecNum(Exceptions and Optimization) which specifies
+  various liberties associated with optimizations in
+  the presence of language-defined checks,
+  that could change the external effects that
+  might be produced. These alternative external effects
+  are still consistent with the standard, since
+  @RefSecNum(Exceptions and Optimization) is part of the standard.
+
+  Note also that we only require @lquotes@;@i(an appropriate) sequence
+  of external address@hidden@; rather than @lquotes@;@i(the same) 
address@hidden@;
+  An optimizer may cause a different sequence of external interactions
+  to be produced than would be produced without the optimizer, so
+  long as the new sequence still satisfies the requirements
+  of the standard. For example, optimization might affect
+  the relative rate of progress of two concurrent tasks, thereby
+  altering the order in which two external interactions occur.
+
address@hidden,Kind=[Revised]}
+  Note that @Chg{Version=[2],New=[the Ada 83 RM],Old=[RM83]} explicitly
+  mentions the case of an @lquotes@;exact address@hidden@;
+  of a program, but since so few programs have their effects defined
+  that exactly,
+  we don't even mention this @lquotes@;address@hidden@; case. In particular,
+  almost any program that uses floating point or tasking has to have
+  some level
+  of inexactness in the specification of its effects. And if one
+  includes aspects of the timing of the external interactions
+  in the external effect of the program (as is appropriate for a real-time
+  language), no @lquotes@;exact address@hidden@; can be specified.
+  For example, if two external interactions initiated by a single task
+  are separated by a @lquotes@;@key(delay) 1.0;@rquotes@; then the language 
rules
+  imply that the two external interactions have to be separated in time
+  by at least one second, as defined by the clock associated with
+  the @nt<delay_relative_statement>. This in turn implies that
+  the time at which an external interaction occurs is part of
+  the characterization of the external interaction, at least in
+  some cases, again making the specification of the required
+  @lquotes@;exact address@hidden@; impractical.
address@hidden
+
+An implementation that conforms to this Standard shall support each
+capability required by the core language as specified.
+In addition,
+an implementation that conforms to this Standard may conform to one
+or more Specialized Needs Annexes (or to none).
+Conformance to a Specialized Needs Annex means that each capability
+required by the Annex is provided as specified.
address@hidden
+  The last sentence defines what it means to say that an
+  implementation conforms to a Specialized Needs Annex, namely, only
+  by supporting all capabilities required by the Annex.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+An implementation conforming to this International Standard
+may provide additional
address@hidden,New=[aspects, ],Old=[]}attributes, library units, and pragmas.
+However, it shall not provide any
address@hidden,New=[aspect, ],Old=[]}attribute,
+library unit, or pragma having the same name
+as an @Chg{Version=[3],New=[aspect, ],Old=[]}attribute, library unit,
+or pragma (respectively)
+specified in a Specialized Needs Annex unless the provided construct
+is either as specified in the Specialized Needs Annex or is more
+limited in capability than that required by the Annex.
+A program that attempts to use an unsupported capability of an Annex
+shall either be identified by the implementation before run time or
+shall raise an exception at run time.
address@hidden
+  The last sentence of the preceding paragraph defines what an
+  implementation is allowed to do when it does not "conform" to a
+  Specialized Needs Annex.
+  In particular, the sentence forbids implementations from providing
+  a construct with the same name as a corresponding construct in a
+  Specialized Needs Annex but with a different syntax
+  (e.g., an extended syntax) or quite different semantics.
+  The phrase concerning "more limited in capability" is intended to
+  give permission to provide a partial implementation, such as not
+  implementing a subprogram in a package or having a restriction not
+  permitted by an implementation that conforms to the Annex.
+  For example, a partial implementation of the package Ada.Decimal
+  might have Decimal.Max_Decimal_Digits as 15 (rather than the
+  required 18).
+  This allows a partial implementation to grow to a fully conforming
+  implementation.
+
+  A restricted implementation might be restricted by not providing
+  some subprograms specified in one of the packages defined by an
+  Annex.
+  In this case, a program that tries to use the missing subprogram
+  will usually fail to compile.
+  Alternatively, the implementation might declare the subprogram as
+  abstract, so it cannot be called.
+  Alternatively, a subprogram body might be implemented just to raise
+  Program_Error.
+  The advantage of this approach is that a program to be run under a
+  fully conforming Annex implementation can be checked syntactically
+  and semantically under an implementation that only partially
+  supports the Annex.
+  Finally, an implementation might provide a package declaration
+  without the corresponding body, so that programs can be compiled,
+  but partitions cannot be built and executed.
+
+  To ensure against wrong answers being delivered by a partial
+  implementation, implementers are required to raise an exception
+  when a program attempts to use an unsupported capability and this
+  can be detected only at run time.
+  For example, a partial implementation of Ada.Decimal might require
+  the length of the Currency string to be 1, and hence, an
+  exception would be raised if a subprogram were called in the
+  package Edited_Output with a length greater than 1.
address@hidden
address@hidden
+
address@hidden
address@hidden defined}
address@hidden
address@hidden (not!)}
address@hidden,See=(unspecified)}
address@hidden (required of an implementation)}
+Certain aspects of the semantics are defined to be either
address@hidden defined} or @i{unspecified}.
+In such cases, the set of possible effects is specified, and
+the implementation may choose any effect in the set.
+Implementations shall document their behavior in
+implementation-defined situations, but documentation is not required
+for unspecified situations.
+The implementation-defined characteristics are summarized in
address@hidden Characteristics}.
address@hidden
+  We used to use the term @lquotes@;implementation address@hidden@;
+  instead of @lquotes@;address@hidden@;.
+  However, that sounded too much like @lquotes@;implementation 
address@hidden@;.
+  Furthermore, the term @lquotes@;address@hidden@; is used in the ANSI C and
+  POSIX standards for this purpose, so that is another advantage.
+  We also use @lquotes@;not address@hidden@; and @lquotes@;not specified by 
the address@hidden@;
+  as synonyms for @lquotes@;address@hidden@;
+  The documentation requirement is the only difference between
+  implementation defined and unspecified.
+
+  Note that the @lquotes@;set of possible address@hidden@; can be 
@lquotes@;all imaginable
+  address@hidden@;, as is the case with erroneous execution.
address@hidden
+
+The implementation may choose to document implementation-defined behavior
+either by documenting what happens in general,
+or by providing some mechanism for the user to determine what
+happens in a particular case.
address@hidden(Discussion)
+For example, if the standard says that library unit elaboration order
+is implementation defined,
+the implementation might describe (in its user's manual)
+the algorithm it uses to determine the elaboration order.
+On the other hand, the implementation might provide a
+command that produces
+a description of the elaboration order for a partition upon request
+from the user.
+It is also acceptable to provide cross references to existing
+documentation (for example, a hardware manual), where appropriate.
+
+Note that dependence of a program on implementation-defined or
+unspecified functionality is not defined to be an error;
+it might cause the program to be less portable, however.
address@hidden(Discussion)
address@hidden,Kind=[AddedNormal],address@hidden,Text=[
+The behavior of implementations in implementation-defined situations
+shall be documented @em see @RefSec{Implementation-Defined Characteristics}
+for a listing.]}]}
address@hidden
+
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+If an implementation detects the use of an unsupported
+Specialized Needs Annex feature at run time,
+it should raise Program_Error if feasible.
address@hidden,Kind=[Added],address@hidden,
+Text=[Program_Error should be raised when an unsupported
+Specialized Needs Annex feature is used at run time.]}]}
address@hidden
+The reason we don't @i{require} Program_Error is that there are
+situations where other exceptions might make sense.
+For example, if the Real Time Systems Annex requires
+that the range of System.Priority include at least 30 values,
+an implementation could conform to the Standard
+(but not to the Annex)
+if it supported only 12 values.
+Since the rules of the language require Constraint_Error to be raised
+for out-of-range values,
+we cannot require Program_Error to be raised instead.
address@hidden
+
+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.
address@hidden,Kind=[Added],address@hidden,
+Text=[Implementation-defined extensions to the functionality of a
+language-defined library unit should be provided by adding children
+to the library unit.]}]}
address@hidden(ImplNote)
+If an implementation has support code
+(@lquotes@;run-time system address@hidden@;)
+that is needed for the execution of user-defined code,
+it can put that support code in child packages of System.
+Otherwise, it has to use some trick to avoid polluting the user's
+namespace.
+It is important that such tricks not be available
+to user-defined code
+(not in the standard mode, at least)
address@hidden that would defeat the purpose.
address@hidden(ImplNote)
address@hidden
+
address@hidden
+The above requirements imply that an implementation conforming
+to this Standard may support some of the capabilities required by a
+Specialized Needs Annex without supporting all required
+capabilities.
address@hidden
+  A conforming implementation can partially support a
+  Specialized Needs Annex.
+  Such an implementation does not conform to the Annex,
+  but it does conform to the Standard.
address@hidden
address@hidden
+
address@hidden of Description and Syntax Notation}
+
address@hidden
+The form of an Ada program is described by means of a context-free
+syntax together with context-dependent requirements expressed by
+narrative rules.
+
+The meaning of Ada programs is described by means of narrative
+rules defining both the effects of each construct and the composition
+rules for constructs.
+
address@hidden@keepnext@;@Defn2{Term=[syntax], Sec=(notation)}
address@hidden, Sec=(notation)}
address@hidden free grammar], Sec=(notation)}
address@hidden (Backus-Naur Form)], Sec=(notation)}
address@hidden Form (BNF)], Sec=(notation)}
+The context-free syntax of the language is described using a simple variant
+of Backus-Naur Form. In particular:
address@hidden(Itemize)
address@hidden@keepnext@;Lower case words in a sans-serif font,
+some containing embedded underlines, are used to
+denote syntactic categories, for example:
address@hidden(Display)
address@hidden<case_statement>
address@hidden(Display)
+
address@hidden@keepnext@;Boldface words are used to denote reserved words, for 
example:
address@hidden(Display)
address@hidden(array)
address@hidden(Display)
+
address@hidden@keepnext@;Square brackets enclose optional items. Thus the two 
following
+rules are equivalent.
address@hidden(Display)
address@hidden,Kind=[Revised],address@hidden,address@hidden<simple_return_statement>],address@hidden<return_statement>]}
 ::= @key(return) address@hidden<expression>];
address@hidden,address@hidden<simple_return_statement>],address@hidden<return_statement>]}
 ::= @key(return); | @key(return) @nt<expression>;
address@hidden(Display)
+
address@hidden@keepnext@;Curly brackets enclose a repeated item. The item may 
appear zero
+or more times; the repetitions occur from left to right as with an
+equivalent left-recursive rule. Thus the two following rules are
+equivalent.
address@hidden(Display)
address@hidden<term> ::= @nt<factor> address@hidden<multiplying_operator> 
@nt<factor>}
address@hidden<term> ::= @nt<factor> | @nt<term> @nt<multiplying_operator> 
@nt<factor>
address@hidden(Display)
+
address@hidden@keepnext@;A vertical line separates alternative items unless it 
occurs
+immediately after an opening curly bracket,
+in which case it stands for itself:
address@hidden(Display)
address@hidden<constraint> ::= @nt<scalar_constraint> | 
@nt<composite_constraint>
address@hidden<discrete_choice_list> ::= @nt<discrete_choice> {| 
@nt<discrete_choice>}
address@hidden(Display)
+
address@hidden,Sec=(syntax rules)}
+If the name of any syntactic category starts with an italicized
+part, it is equivalent to the category name without the italicized
+part. The italicized part is intended to convey some semantic
+information. For example @i(subtype_)@nt<name> and
address@hidden(task_)@nt<name> are both equivalent to @nt<name> alone.
address@hidden(Itemize)
address@hidden(Discussion)
address@hidden(1)}
address@hidden grammar}
address@hidden,Sec=(resolution of ambiguity)}
address@hidden,Sec=(ambiguous)}
+The grammar given in @Chg{Version=[2],New=[this International Standard],
+old=[the RM95]} is not LR(1).
+In fact, it is ambiguous; the ambiguities are resolved
+by the overload resolution rules
+(see @RefSecNum{The Context of Overload Resolution}).
+
+We often use @lquotes@;address@hidden@; to mean @lquotes@;if and only 
address@hidden@; in definitions.
+For example, if we define @lquotes@;address@hidden@; by saying,
address@hidden@;A type is photogenic if it has the following 
properties...,@rquotes@;
+we mean that a type is photogenic if @i{and only if}
+it has those properties.
+It is usually clear from the context,
+and adding the @lquotes@;and only address@hidden@; seems too cumbersome.
+
+When we say, for example, @lquotes@;a @nt{declarative_item} of a
address@hidden@rquotes@;, we are talking about a @nt{declarative_item}
+immediately within that @nt{declarative_part}. When we say @lquotes@;a
address@hidden in, or within, a @address@hidden@;, we are
+talking about a @nt{declarative_item} anywhere in the
address@hidden, possibly deeply nested within other
address@hidden (This notation doesn't work very well for
address@hidden, since the name @lquotes@;address@hidden@; something also has 
another meaning.)
+
+When we refer to the name of a language-defined
+entity (for example, Duration),
+we mean the language-defined entity even in programs where the declaration
+of the language-defined entity is hidden by another declaration.
+For example, when we say that the expected type for the @nt<expression>
+of a @nt<delay_relative_statement> is Duration, we mean the language-defined
+type Duration that is declared in Standard, not some type
+Duration the user might have declared.
address@hidden(Discussion)
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0004-1],ARef=[AI05-0262-1]}
address@hidden,Text=[The delimiters, compound delimiters, reserved words, and
address@hidden are exclusively made of the
+characters whose code @Chg{Version=[3],New=[point],Old=[position]} is
+between 16#20# and 16#7E#, inclusively.
+The special characters for which names are defined in this
+International Standard (see @RefSecNum{Character Set}) belong to the same 
range.
address@hidden example, the character E in the definition of @Chg{Version=[3],
address@hidden,Old=[exponent]} is the
+character whose name is @lquotes@;LATIN CAPITAL LETTER address@hidden@;, not
address@hidden@;GREEK CAPITAL LETTER address@hidden@;.]]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This just means that programs can be written in plain
+ASCII characters; no characters outside of the 7-bit range are required.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00395-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0227-1],ARef=[AI05-0299-1]}
address@hidden,Text=[When this International Standard mentions the
+conversion of some character or sequence of characters to upper case, it means
+the character or sequence of characters obtained by using
address@hidden,New=[simple upper case mapping],Old=[locale-independent
+full case folding]}, as defined by documents referenced in the note in
address@hidden,New=[Clause],Old=[section]} 1
+of ISO/IEC 10646:@Chg{Version=[3],New=[2011],Old=[2003]}.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[DeletedAdded]}
+  @ChgAdded{Version=[2],address@hidden,New=[],Old=[Unless otherwise
+  specified for sequences of characters, case folding is applied to the
+  sequence, not to individual characters. It sometimes can make a
+  difference.]}]}
address@hidden
address@hidden
+
address@hidden
address@hidden category}
+A @i{syntactic category} is
+a nonterminal in the grammar defined in BNF under @lquotes@;@address@hidden@;
+Names of syntactic categories are set in a different font,
address@hidden
address@hidden
+
address@hidden<Construct>,
+  Text=<A @i(construct) is a piece of text
+  (explicit or implicit) that is an instance of a syntactic category
+  defined under @lquotes@;@address@hidden@;.>}
address@hidden
+For example, an @nt{expression} is a construct.
+A declaration is a construct,
+whereas the thing declared by a declaration is an @lquotes@;address@hidden@;
address@hidden
address@hidden
address@hidden@;address@hidden@; and @lquotes@;address@hidden@; don't mean 
exactly what you might think
+they mean: The text of an instance of a generic is
+considered explicit, even though it does not appear explicitly (in
+the nontechnical sense) in the program text,
+and even though its meaning is not defined entirely in terms of that
+text.
address@hidden
+
address@hidden<constituent>, Sec=<of a construct>}
+A @i{constituent} of a construct is the construct itself,
+or any construct appearing within it.
+
address@hidden order}
+Whenever the run-time semantics
+defines certain actions to happen in an @i{arbitrary order},
+this means that the implementation shall arrange for these actions
+to occur in a way that is equivalent to some sequential order,
+following the rules that result from that sequential order.
+When evaluations are defined to happen in an arbitrary order,
+with conversion of the results to some subtypes,
+or with some run-time checks,
+the evaluations, conversions, and checks may be arbitrarily
+interspersed, so long as each expression is evaluated before converting
+or checking its value.
address@hidden conversion],Sec=(arbitrary order)}
address@hidden,Sec=(arbitrary order)}
address@hidden that the effect of a program can depend on the
+order chosen by the implementation.
+This can happen, for example,
+if two actual parameters of a given call have side effects.]
address@hidden
+Programs will be more portable if their external effect does not
+depend on the particular order chosen by an implementation.
address@hidden
address@hidden
+Additional reordering permissions are given in
address@hidden(Exceptions and Optimization).
+
+There is no requirement that the implementation always choose
+the same order in a given kind of situation. In fact, the
+implementation is allowed to choose a different order for two
+different executions of the same construct.
+However, we expect most implementations will behave in a relatively
+predictable manner in most situations.
address@hidden
address@hidden
+The @lquotes@;sequential address@hidden@; wording is intended to allow the 
programmer
+to rely on @lquotes@;address@hidden@; side effects.
+For example, if F is a function that returns a unique integer by
+incrementing some global and returning the result,
+a call such as P(F, F) is OK if the programmer cares only
+that the two results of F are unique;
+the two calls of F cannot be executed in parallel,
+unless the compiler can prove that parallel execution is
+equivalent to some sequential order.
address@hidden
address@hidden
+
address@hidden@Comment{For printed version of Ada 2012 RM}
+
address@hidden
+The syntax rules describing structured constructs are presented in a
+form that corresponds to the recommended paragraphing. For example, an
address@hidden is defined as:
address@hidden(Example)
address@hidden<if_statement> ::=
+    @key(if) @nt<condition> @key(then)
+      @nt<sequence_of_statements>
+   address@hidden(elsif) @nt<condition> @key(then)
+      @nt<sequence_of_statements>}
+   address@hidden(else)
+      @nt<sequence_of_statements>]
+    @key(end if);
address@hidden(Example)
+
+The line breaks and indentation in the syntax rules indicate the
+recommended line breaks and indentation in the corresponding constructs.
+The preferred places for other line breaks are after semicolons.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[We now explicitly say that the lexical elements
+  of the language (with a few exceptions) are made up of characters in the
+  lower half of the Latin-1 character set. This is needed to avoid confusion
+  given the new capability to use most ISO 10646 characters in identifiers and
+  strings.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00395-01]}
+  @ChgAdded{Version=[2],Text=[We now explicitly define what the Standard means
+  by upper case, as there are many possibilities for ISO 10646 characters.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00433-01]}
+  @ChgAdded{Version=[2],Text=[The example for square brackets has been changed
+  as there is no longer a @ntf{return_statement} syntax rule.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0227-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Upper case is defined by
+  "simple upper case mapping", because "full case folding" is a mapping
+  (mostly) to lower case.]}
address@hidden
+
+
+
address@hidden of Errors}
+
address@hidden
address@hidden@Keepnext@;The language definition classifies errors into several
+different categories:
address@hidden(Itemize)
+     @Keepnext@;Errors that are required to be detected prior to run time by 
every
+     Ada implementation;
+
+     @NoPrefix@;These errors correspond to any violation of a rule given in 
this
+     International Standard, other than those listed below.
+     In particular, violation of any rule that uses the
+     terms shall, allowed, permitted, legal, or illegal belongs to this
+     category. Any program that contains such an error is not a legal
+     Ada program; on the other hand, the fact that a program is legal
+     does not mean, @i(per se), that the program is free from other
+     forms of error.
+
+     @address@hidden error}
+     @Defn2{Term=[error], Sec=(compile-time)}
+     @IndexSee{Term=[link-time error],See=(post-compilation error)}
+     @Defn2{Term=[error], Sec=(link-time)}
+     The rules are further classified as either compile time rules, or
+     post compilation rules, depending on whether a violation has to be
+     detected at the time a compilation unit is submitted to
+     the compiler,
+     or may be postponed until the time a compilation unit is
+     incorporated into a partition of a program.
+     @begin{Ramification}
+       See, for example, @RefSec(Subunits of Compilation Units),
+       for some errors that are detected only after compilation.
+       Implementations are allowed, but not required, to detect post
+       compilation rules at compile time when possible.
+     @end{Ramification}
+
+     @Keepnext@;Errors that are required to be detected at run time by the
+     execution of an Ada program;
+
+     @address@hidden error}
+     @Defn2{Term=[error], Sec=(run-time)}
+     The corresponding error situations are associated with the names of
+     the predefined exceptions. Every Ada compiler is required to
+     generate code that raises the corresponding exception if such an
+     error situation arises during program execution.
+     @Redundant[If such an error situation is certain to arise in every
+     execution of a construct, then an implementation is allowed
+     (although not required) to report this fact at compilation time.]
+
+
+     @Keepnext@;Bounded errors;
+
+     @NoPrefix@;The language rules define certain kinds of errors that need 
not be
+     detected either prior to or during run time, but if not detected,
+     the range of possible effects shall be bounded.
+     @Defn{bounded error}
+     The errors of this category are called @i{bounded errors}.
+     @Defn2{Term=[Program_Error],Sec=(raised by failure of run-time check)}
+     The possible effects of a given bounded error are specified for
+     each such error, but in any case one possible effect of a bounded
+     error is the raising of the exception Program_Error.
+
+     @Keepnext@;Erroneous execution.
+
+     @address@hidden execution}
+     In addition to bounded errors, the language rules define certain
+     kinds of errors as leading to @i{erroneous execution}. Like bounded
+     errors, the implementation need not detect such errors either prior
+     to or during run time. Unlike bounded errors, there is no
+     language-specified bound on the possible effect of erroneous
+     execution; the effect is in general not predictable.
+     @begin{Ramification}
+       Executions are erroneous, not programs or parts of programs.
+       Once something erroneous happens, the execution of the entire program
+       is erroneous from that point on, and potentially before given
+       possible reorderings permitted by
+       @RefSecNum(Exceptions and Optimization) and elsewhere.
+       We cannot limit it to just one partition,
+       since partitions are not required to live in separate address spaces.
+       (But implementations are encouraged to limit it as much as possible.)
+
+       Suppose a program contains a pair of things that will be executed 
@lquotes@;in
+       an arbitrary address@hidden@;
+       It is possible that one order will result in something sensible, whereas
+       the other order will result in erroneous execution.
+       If the implementation happens to choose the first order,
+       then the execution is not erroneous.
+       This may seem odd, but it is not harmful.
+
+       Saying that something is erroneous is semantically
+       equivalent to saying that the behavior is unspecified.
+       However, @lquotes@;address@hidden@; has a slightly more disapproving
+       flavor.
+     @end{Ramification}
+
address@hidden(Itemize)
address@hidden
+
address@hidden
address@hidden@Defn2{Term={mode of operation}, Sec=(nonstandard)}
address@hidden mode}An implementation may provide
address@hidden(nonstandard modes) of operation.
+Typically these modes would be selected by a @nt<pragma> or by a command line
+switch when the compiler is invoked. When operating in
+a nonstandard mode, the implementation may reject @nt<compilation_unit>s
+that do not conform to additional requirements associated
+with the mode, such as an excessive number of warnings or violation
+of coding style guidelines. Similarly, in a nonstandard mode,
+the implementation may apply special optimizations or alternative
+algorithms that are only meaningful for programs that
+satisfy certain criteria specified by the implementation.
address@hidden of operation}, Sec=(standard)}
address@hidden mode}
+In any case, an implementation shall support a @i(standard) mode that
+conforms to the requirements of this International Standard; in particular, in 
the standard
+mode, all legal @nt<compilation_unit>s shall be accepted.]
address@hidden
+  These permissions are designed to authorize explicitly the
+  support for alternative modes. Of course, nothing we say can
+  prevent them anyway, but this (redundant) paragraph is designed
+  to indicate that such alternative modes are in some sense 
@lquotes@;address@hidden@;
+  and even encouraged where they serve the specialized needs of
+  a given user community, so long as the standard mode, designed
+  to foster maximum portability, is always available.
address@hidden
address@hidden
+
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+If an implementation detects a bounded error or erroneous execution,
+it should raise Program_Error.
address@hidden,Kind=[Added],address@hidden,
+Text=[If a bounded error or erroneous execution is detected, Program_Error
+should be raised.]}]}
address@hidden
+
address@hidden
+Some situations that are erroneous in Ada 83 are no longer errors
+at all.
+For example, depending on the parameter passing mechanism when
+unspecified is possibly nonportable, but not erroneous.
+
+Other situations that are erroneous in Ada 83 are changed
+to be bounded errors.
+In particular, evaluating an uninitialized scalar variable is
+a bounded error.
address@hidden,Sec=(raised by failure of run-time check)}
+The possible results are to raise Program_Error (as always), or to
+produce a machine-representable value (which might not be in the
+subtype of the variable).
address@hidden,Sec=(raised by failure of run-time check)}
+Violating a Range_Check or Overflow_Check raises
+Constraint_Error, even if the value came from an uninitialized
+variable.
+This means that optimizers can no longer
address@hidden@;address@hidden@; that all variables are initialized within 
their subtype's
+range.
+Violating a check that is suppressed remains erroneous.
+
+The @lquotes@;incorrect order address@hidden@; category of errors is removed.
+All such situations are simply considered potential nonportabilities.
+This category was removed due to the difficulty of defining
+what it means for two executions to have a @lquotes@;different address@hidden@;
+For example, if a function with a side effect is called twice in a single
+expression, it is not in principle possible for the compiler to
+decide whether the correctness of the resulting program depends on the order
+of execution of the two function calls. A compile time warning
+might be appropriate, but raising of Program_Error at
+run time would not be.
address@hidden
+
address@hidden References}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden
address@hidden
+The following @Chg{Version=[3],New=[documents, in whole or in part, are
+normatively referenced in this document and are indispensable for its
+application. For dated references, only the edition cited applies. For undated
+references, the latest edition of the referenced document (including any
+amendments) applies.],Old=[standards contain provisions which,
+through reference in this text, constitute provisions of this International
+Standard. At the time of publication, the editions indicated were valid. All
+standards are subject to revision, and parties to agreements based on this
+International Standard are encouraged to investigate the possibility of 
applying
+the most recent editions of the standards indicated below. Members of IEC and
+ISO maintain registers of currently valid International Standards.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0127-2],ARef=[AI05-0299-1]}
address@hidden,address@hidden 639-3:2007}
address@hidden:2007, ISO standard}
address@hidden code standard}
+ISO 639-3:2007, @i{Codes for the representation of names of languages @em Part
+3: Alpha-3 code for comprehensive coverage of languages}.]}
+
address@hidden/IEC 646:1991}
address@hidden:1991, ISO/IEC standard}
address@hidden set standard],Sec=(7-bit)}
+ISO/IEC 646:1991,
address@hidden technology @em ISO 7-bit coded character
+    set for information interchange}.
+
address@hidden,Kind=[Revised],ARef=[AI95-00415-01]}
address@hidden,address@hidden/IEC 1539-1:2004}
address@hidden:2004, ISO/IEC standard}
address@hidden standard}],
address@hidden/IEC 1539:1991}
address@hidden:1991, ISO/IEC standard}
address@hidden standard}]}
+ISO/IEC @Chg{Version=[2],New=[1539-1:2004],Old=[1539:1991]},
address@hidden technology @em Programming languages @em @Chg{Version=[2],
+New=[Fortran @em Part 1: Base language],Old=[FORTRAN]}}.
+
address@hidden,Kind=[Revised],ARef=[AI95-00415-01]}
address@hidden,address@hidden 1989:2002}
address@hidden:2002, ISO standard}],address@hidden 1989:1985}
address@hidden:1985, ISO standard}]}
address@hidden standard}
address@hidden,New=[/IEC],Old=[]} 1989:@Chg{Version=[2],New=[2002],Old=[1985]},
address@hidden@Chg{Version=[2],New=[Information technology @em 
],Old=[]}Programming languages @em COBOL}.
+
address@hidden,Kind=[Added],ARef=[AI05-0127-2],ARef=[AI05-0299-1]}
address@hidden,address@hidden/IEC 3166-1:2006}
address@hidden:2006, ISO/IEC standard}
address@hidden code standard}
+ISO/IEC 3166-1:2006, @i{Codes for the representation of names of countries and
+their subdivisions @em Part 1: Country Codes}.]}
+
address@hidden/IEC 6429:1992}
address@hidden:1992, ISO/IEC standard}
address@hidden set standard],Sec=(control functions)}
+ISO/IEC 6429:1992,
address@hidden technology @em Control functions for coded
+    graphic character sets}.
+
address@hidden,Kind=[Added],ARef=[AI95-00351-01]}
address@hidden,address@hidden 8601:2004}
address@hidden and time formatting standard}
+ISO 8601:2004, @i{Data elements and interchange formats @em Information
+interchange @em Representation of dates and times}.]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,address@hidden/IEC 8859-1:1998}
address@hidden:1998, ISO/IEC standard}],address@hidden/IEC 8859-1:1987}
address@hidden:1987, ISO/IEC standard}]}
address@hidden set standard],Sec=(8-bit)}
+ISO/IEC 8859-1:@Chg{Version=[3],New=[1998],Old=[1987]},
address@hidden @Chg{Version=[3],New=[technology],Old=[processing]} @em
+8-bit single-byte coded @Chg{Version=[3],New=[graphic ],Old=[]}character
+sets @em Part 1: Latin alphabet No. 1}.
+
address@hidden,Kind=[Revised],ARef=[AI95-00415-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0266-1]}
address@hidden,address@hidden,address@hidden/IEC 9899:2011}
address@hidden:2011, ISO/IEC standard}],address@hidden/IEC 9899:1999}
address@hidden:1999, ISO/IEC standard}]}],
address@hidden/IEC 9899:1990}
address@hidden:1990, ISO/IEC standard}]}
address@hidden standard}
+ISO/IEC 9899:@Chg{Version=[2],address@hidden,New=[2011],Old=[1999]}],
+Old=[1990]},
address@hidden@Chg{Version=[3],New=[Information technology @em 
],Old=[]}Programming
+languages @em address@hidden,address@hidden,New=[],Old=[, supplemented by 
Technical
+Corrigendum 1:2001 and Technical Corrigendum 2:2004]}],Old=[]}.
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg]}
+  @ChgAdded{Version=[2],address@hidden,New=[],Old=[Unlike Fortran and
+  COBOL, which added the @i{Information technology} prefix to the titles of
+  their standard, C did not. This was confirmed in the list of standards titles
+  on the ISO web site. No idea why ISO allowed address@hidden, or whether C is
+  planning to secede from SC22}.]}]}
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0001],ARef=[AI95-00124-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0266-1]}
address@hidden,address@hidden,address@hidden/IEC 10646:2011}
address@hidden:2011, ISO/IEC standard}],address@hidden/IEC 10646:2003}
address@hidden:2003, ISO/IEC standard}]}
address@hidden set standard],Sec=(16 and 32-bit)}
+ISO/IEC 10646:@Chg{Version=[3],New=[2011],Old=[2003]}, @i{Information 
technology @em Universal Multiple-Octet
+Coded Character Set (UCS)}.],
address@hidden/IEC 10646-1:1993}
address@hidden:1993, ISO/IEC standard}
address@hidden set standard],Sec=(16-bit)}
+ISO/IEC 10646-1:1993,
address@hidden technology @em Universal Multiple-Octet
+    Coded Character Set (UCS) @em Part 1: Architecture and Basic
+    Multilingual address@hidden,New=[, supplemented by Technical Corrigendum
+    1:1996], Old=[]}.]}
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0001],ARef=[AI95-00124-01]}
address@hidden,Kind=[DeletedAdded],ARef=[AI95-00285-01]}
address@hidden is of only historical interest, so it was deleted; we use the
+Unicode characterization now.}
address@hidden,Text=[
address@hidden,New=[The Technical Corrigendum 1:1996 is needed so that character
+codes C6 and E6 (the ligatures @latin1(198) and @latin1(230)) are considered
+letters. These were named Latin Ligature AE in the original 1993 version,
+which would exclude them from being letters as defined in
address@hidden Set}.], Old=[]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00376-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0266-1]}
address@hidden,address@hidden,address@hidden/IEC 14882:2011}
address@hidden:2011, ISO/IEC standard}],address@hidden/IEC 14882:2003}
address@hidden:2003, ISO/IEC standard}]}
address@hidden standard}
+ISO/IEC 14882:@Chg{Version=[3],New=[2011],Old=[2003]},
address@hidden@Chg{Version=[3],New=[Information technology @em 
],Old=[]}Programming languages @em C++}.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg]}
+  @ChgAdded{Version=[2],address@hidden,New=[],Old=[This title is also missing 
the
+  @i{Information technology} part. That was confirmed in the list of standards
+  titles on the ISO web site.]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,address@hidden/IEC TR 19769:2004}
address@hidden:2004, ISO/IEC technical report}
+ISO/IEC TR 19769:2004, @i{Information technology @em Programming languages,
+their environments and system software interfaces @em Extensions for the
+programming language C to support new character data types}.]}
+
address@hidden
address@hidden
+POSIX,
address@hidden Operating System Interface (POSIX)
+  @em Part 1: System Application Program Interface (API) [C Language]},
+  The Institute of Electrical and Electronics Engineers,
+  1990.
address@hidden
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01],ARef=[AI95-00376-01],ARef=[AI95-00415-01]}
+  @ChgAdded{Version=[2],Text=[Updated references to the most recent versions
+  of these standards. Added C++ and time standards. Added C character set 
technical
+  report.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0127-2]}
+  @ChgAdded{Version=[3],Text=[Added language and country code standards for
+  locale support.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0266-1]}
+  @ChgAdded{Version=[3],Text=[Updated references to the most recent versions
+  of these standards.]}
address@hidden
+
+
+
address@hidden,New=[Terms and Definitions],Old=[Definitions]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00415-01]}
address@hidden,Sec=(terms introduced or defined)}
+Terms are defined throughout this International Standard,
+indicated by @i(italic) type.
+Terms explicitly defined in this International Standard are not to be presumed 
to
+refer implicitly to similar terms defined elsewhere.
address@hidden,New=[Mathematical terms not defined in this International
+Standard are to be interpreted according to the @i<CRC Concise Encyclopedia of
+Mathematics, Second Edition>. Other terms],Old=[Terms]} not defined in this
+International Standard are to be interpreted according to
+the @i(Webster's Third New International Dictionary of the
+English Language).
+Informal descriptions of some terms are also given in
address@hidden
address@hidden are here to avoid a blank paragraph at the end, and because
+they have to be somewhere.}
address@hidden unit], Other=(language-defined library units)}
address@hidden library unit], Other=(language-defined library units)}
address@hidden, Other=(language-defined types)}
address@hidden type], Other=(language-defined types)}
address@hidden
+The index contains an entry for every defined term.
+
address@hidden,Kind=[Added],ARef=[AI95-00415-01]}
address@hidden,Text=[The contents of the @i<CRC Concise Encyclopedia of
+Mathematics, Second Edition> can be accessed on
address@hidden://www.mathworld.com],Text=[http://www.mathworld.com]}.
+The ISBN number of the book is ISBN 1584883472.]}
address@hidden
address@hidden
+Each term defined in @RefSecNum{Glossary}
+is marked like this.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
+Here are some AARM-only definitions:
address@hidden Rapporteur Group (ARG)}
address@hidden(ARG)
+The Ada Rapporteur Group (ARG) interprets the @Chg{Version=[1],New=<Ada 
Reference Manual>,Old=<RM83>}.
address@hidden Issue (AI)}
address@hidden(AI)
+An Ada Issue (AI) is a numbered ruling from the address@hidden,New=< Ada Issues
+created for Ada 83 are denoted as "AI83", while Ada Issues created for Ada 95
+are denoted as "AI95" in this address@hidden,New=< Similarly,
+Ada Issues created for Ada 2005 are denoted as "AI05">,Old=<>}>,Old=<>}
address@hidden Commentary Integration Document (ACID)}
address@hidden(ACID)
+The Ada Commentary Integration Document (ACID)
+is an edition of @Chg{Version=[2],New=[the Ada 83 RM],Old=[RM83]}
+in which clearly marked insertions
+and deletions indicate the effect of integrating the approved AIs.
address@hidden Rapporteur Group (URG)}
address@hidden(URG)
+The Uniformity Rapporteur Group (URG) 
@Chg{Version=[1],New=<issued>,Old=<issues>}
+recommendations intended to increase uniformity across Ada implementations.
address@hidden,New=<The functions of the URG have been assumed by the 
ARG.>,Old=<>}
address@hidden Issue (UI)}
address@hidden(UI)
+A Uniformity Issue (UI) @Chg{Version=[1],New=<was>,Old=<is>} a numbered 
recommendation from the URG.
address@hidden,New=<A Defect Report and Response is an official query to WG9 
about an
+error in the standard. Defect Reports are processed by the ARG, and are
+referenced here by their ISO numbers: 8652/nnnn. Most changes to the Ada 95
+standard include reference(s) to the Defect Report(s) that prompted the 
change.>,Old=<>}
address@hidden,address@hidden,Sec=(Ada Compiler Validation Capability)}
address@hidden Compiler Validation Capability],Sec=(ACVC)}
address@hidden,Sec=(Ada Conformity Assessment Test Suite)}
address@hidden Conformity Assessment Test Suite],Sec=(ACATS)}
+The @i<Ada Conformity Assessment Test Suite (ACATS)> is a set of tests intended
+to check the conformity of Ada implementations to this standard. This set of
+tests was previously known as the Ada Compiler Validation Capability 
(ACVC).],Old=[]}
address@hidden
diff --git a/packages/ada-ref-man/source_2012/02.mss 
b/packages/ada-ref-man/source_2012/02.mss
new file mode 100755
index 0000000..b6e62a3
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/02.mss
@@ -0,0 +1,2186 @@
address@hidden(02, Root="ada.mss")
+
address@hidden: 2012/11/28 23:53:02 $}
address@hidden Elements}
+
address@hidden: e:\\cvsroot/ARM/Source/02.mss,v $}
address@hidden: 1.85 $}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden text of a program consists of the texts of one or more
address@hidden<compilation>s. The text of a @nt<compilation> is a sequence of
+lexical elements, each composed of characters; the rules of
+composition are given in this @Chg{Version=[3],New=[clause],Old=[section]}.
address@hidden, which provide certain information for the compiler, are also
+described in this @Chg{Version=[3],New=[clause],Old=[section]}.]
address@hidden
+
address@hidden Set}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0266-1]}
address@hidden set}
+The @Chg{Version=[2],New=[character repertoire for the text of an Ada
+program consists of the
+entire coding space described by the ISO/IEC 
10646:@Chg{Version=[3],New=[2011],Old=[2003]}
+Universal
+Multiple-Octet Coded Character Set. This coding space is organized in
address@hidden<planes>, each plane comprising 65536 
address@hidden,Sec=[character]}
address@hidden plane}],Old=[only characters
+allowed outside of @nt{comment}s are the @nt{graphic_character}s and
address@hidden
+
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00285-01]}
address@hidden,Text=[Any character, including an
address@hidden<other_control_function>, is allowed in a comment.]}
+
address@hidden,Kind=[Deleted],address@hidden below}
address@hidden,Text=[Note that this rule doesn't really have much
+force, since the implementation can represent characters in the source in any
+way it sees fit.
+For example, an implementation could simply define that what seems to be
+a nongraphic, non-format-effector character is actually a
+representation of the space character.]}
address@hidden
address@hidden(Discussion)
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0266-1]}
+It is our intent to follow the terminology of
address@hidden,New=[ISO/IEC 
10646:@Chg{Version=[3],New=[2011],Old=[2003]}],Old=[ISO 10646 BMP]} where
+appropriate, and to remain compatible with the character
+classifications defined in @RefSec{Character address@hidden,
+New=[],Old=[Note that our definition for
address@hidden<graphic_character> is more inclusive than that of ISO 10646-1.]}
address@hidden(Discussion)
address@hidden
+
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraphs 2 and 3
+were deleted.>address@hidden message should be
+deleted if the paragraphs are ever renumbered.}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01]}
address@hidden,lhs=<@Chg{Version=[2],New=<>,Old=<character>}>,
+rhs="@Chg{Version=[2],New=<>,Old=<@Syn2{graphic_character} | 
@Synf{format_effector} | @Synf{other_control_function}>}"}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01]}
address@hidden,lhs=<@Chg{Version=[2],New=<>,Old=<graphic_character>}>,
+rhs="@Chg{Version=[2],New=<>,Old=<@Synf{identifier_letter} | @Synf{digit} | 
@Synf{space_character} | @Synf{special_character}>}"}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0266-1]}
address@hidden,Text=[A @ntf{character} is defined by this International
+Standard for each cell in the coding space described by ISO/IEC 
10646:@Chg{Version=[3],New=[2011],Old=[2003]},
+regardless of whether or not ISO/IEC 
10646:@Chg{Version=[3],New=[2011],Old=[2003]} allocates a character to that
+cell.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0079-1],ARef=[AI05-0262-1],ARef=[AI05-0266-1]}
address@hidden,New=[],Old=[ character repertoire for the text of
+an Ada program consists of the
+collection of characters
address@hidden,New=[described by the ISO/IEC 
10646:@Chg{Version=[3],New=[2011],Old=[2003]}],
+Old=[called the Basic Multilingual Plane (BMP) of the
+ISO 10646]} Universal Multiple-Octet Coded Character Set, plus a set
+of @ntf<format_effector>s and, in comments only,
+a set of @ntf<other_control_function>s; the]} coded representation for
address@hidden,New=[],Old=[these ]}characters is implementation defined
address@hidden(it need not be a
+representation defined within @Chg{Version=[2],New=[ISO/IEC 
10646:@Chg{Version=[3],New=[2011],Old=[2003]}],
+Old=[ISO-10646-1]})address@hidden,New=[ A character whose relative
+code @Chg{Version=[3],New=[point],Old=[position]} in its plane
+is 16#FFFE# or 16#FFFF# is not allowed anywhere
+in the text of a program.],address@hidden,New=[ The only
+characters allowed outside of comments are those in categories
address@hidden, @ntf{format_effector}, and @ntf{graphic_character}.],Old=[]}
address@hidden coded representation for the text of an Ada program.}
+
address@hidden@ChgNote{Moved from above}
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[Note that this rule doesn't really have
+  much force, since the implementation can represent characters in the
+  source in any way it sees fit.
+  For example, an implementation could simply define that what seems to be
+  an @ntf{other_private_use} character is actually a
+  representation of the space character.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0266-1],ARef=[AI05-0299-1]}
address@hidden,Text=[The semantics of an Ada program whose text is not
+in Normalization Form KC (as defined by @Chg{Version=[3],New=[Clause 
21],Old=[section 24]}
+of ISO/IEC 10646:@Chg{Version=[3],New=[2011],Old=[2003]})
+is implementation defined.]}
address@hidden,Kind=[AddedNormal],address@hidden,Text=[The
+semantics of an Ada program whose text is not in Normalization Form KC.]}]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0266-1],ARef=[AI05-0299-1]}
+The description of the
+language definition in this International Standard uses the @Chg{Version=[2],
+New=[character properties General Category, Simple Uppercase Mapping,
+Uppercase Mapping, and Special Case Condition of the documents referenced by
+the note in @Chg{Version=[3],New=[Clause],Old=[section]} 1 of ISO/IEC 
10646:@Chg{Version=[3],New=[2011],Old=[2003]}],Old=[graphic symbols
+defined for Row 00: Basic Latin and Row 00: Latin-1 Supplement
+of the ISO 10646 BMP; these correspond to the graphic symbols of
+ISO 8859-1 (Latin-1); no graphic symbols are used in this International 
Standard for
+characters outside of Row 00 of the BMP]}.
+The actual set of graphic symbols used by an implementation
+for the visual representation of
+the text of an Ada program is not specified.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0266-1]}
address@hidden@keepnext@;@Chg{Version=[2],New=[Characters],Old=[The categories 
of
+characters]} are @Chg{Version=[2],New=[categorized],Old=[defined]} as follows:
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0005-1],ARef=[AI05-0262-1],ARef=[AI05-0266-1]}
address@hidden,Text=[Our character classification considers that the
+cells not allocated in ISO/IEC 10646:@Chg{Version=[3],New=[2011],Old=[2003]} 
are graphic characters, except for
+those whose relative code @Chg{Version=[3],New=[point],Old=[position]}
+in their plane is 16#FFFE# or 16#FFFF#. This
+seems to provide the best compatibility with future versions of ISO/IEC 10646,
+as future characters can @Chg{Version=[3],New=[],Old=[be ]}already be
+used in Ada character and string literals.]}
address@hidden
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00285-01]}
address@hidden,address@hidden@ntf<identifier_letter>@address@hidden | 
@ntf{lower_case_identifier_letter}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[We use @ntf<identifier_letter>
+  instead of simply @ntf<letter> because
+  ISO 10646 BMP includes many other characters that would generally
+  be considered "letters."]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,address@hidden@ntf{letter_uppercase}],
address@hidden@ntf<upper_case_identifier_letter>address@hidden
+character @Chg{Version=[2],New=[whose General Category is defined
+to be @lquotes@;Letter, address@hidden@;],
+Old=[of Row 00 of ISO 10646 BMP whose name begins
address@hidden@;Latin Capital address@hidden@;]}.
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,address@hidden@ntf{letter_lowercase}],
address@hidden@ntf<lower_case_identifier_letter>address@hidden
+character @Chg{Version=[2],New=[whose General Category is defined
+to be @lquotes@;Letter, address@hidden@;],
+Old=[of Row 00 of ISO 10646 BMP whose name begins
address@hidden@;Latin Small address@hidden@;]}.
address@hidden
address@hidden,Kind=[Deleted],Ref=[8652/0001],ARef=[AI95-00124-01]}
address@hidden change in subclause 1.3 for 8652/0001 handles this problem.}
address@hidden,Text=[The above rules do not include the ligatures
address@hidden(198) and @latin1(230).
+However, the intent is to include these characters as identifier letters.
+This problem was pointed out by a comment from the Netherlands.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,address@hidden@address@hidden
+character whose General Category is defined to be @lquotes@;Letter, 
address@hidden@;.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,address@hidden@address@hidden
+character whose General Category is defined to be @lquotes@;Letter, 
address@hidden@;.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,address@hidden@address@hidden
+character whose General Category is defined to be @lquotes@;Letter, 
address@hidden@;.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,address@hidden@address@hidden
+character whose General Category is defined to be @lquotes@;Mark, 
address@hidden@;.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,address@hidden@address@hidden
+character whose General Category is defined to be @lquotes@;Mark, Spacing 
address@hidden@;.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,address@hidden@ntf{number_decimal}],
address@hidden@address@hidden@Chg{Version=[2],New=[Any
+character whose General Category is defined
+to be @lquotes@;Number, address@hidden@;],
+Old=[One of the characters 0, 1, 2, 3, 4, 5, 6, 7, 8, or 9]}.
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,address@hidden@address@hidden
+character whose General Category is defined to be @lquotes@;Number, 
address@hidden@;.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,address@hidden@address@hidden
+character whose General Category is defined to be @lquotes@;Punctuation, 
address@hidden@;.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,address@hidden@address@hidden
+character whose General Category is defined to be @lquotes@;Other, 
address@hidden@;.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,address@hidden@ntf<separator_space>],
address@hidden@address@hidden@Chg{Version=[2],New=[Any
+character whose General Category is defined to be @lquotes@;Separator,
address@hidden@;.],Old=[The character of ISO 10646 BMP named
address@hidden@;address@hidden@;.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,address@hidden@ntf{separator_line}],
address@hidden@address@hidden character
address@hidden,New=[whose General Category is defined to be
address@hidden@;Separator, address@hidden@;.],
+Old=[of the ISO 10646 BMP that is not reserved for a control function, and
+is not the @ntf<space_character>, an @ntf<identifier_letter>, or a 
@ntf<digit>.]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[Note that the no break space and soft hyphen
+are @ntf<special_character>s,
+and therefore @nt<graphic_character>s.
+They are not the same characters as space and hyphen-minus.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,address@hidden@address@hidden
+character whose General Category is defined to be @lquotes@;Separator, 
address@hidden@;.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden@ntf<format_effector>@\The
address@hidden,New=[characters whose code 
@Chg{Version=[3],New=[points],Old=[positions]} are
+16#09# (CHARACTER TABULATION), 16#0A# (LINE FEED), 16#0B# (LINE TABULATION),
+16#0C# (FORM FEED), 16#0D# (CARRIAGE RETURN), 16#85# (NEXT LINE),
+and the characters in categories @ntf{separator_line} and
address@hidden,
+Old=[control functions of ISO 6429 called
+  character tabulation (HT), line tabulation (VT), carriage return (CR),
+  line feed (LF), and form feed (FF)]}.
address@hidden character],See=(format_effector)}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[ISO/IEC 10646:2003 does not define the names
+  of control characters, but rather refers to the names defined by
+  ISO/IEC 6429:1992. These are the names that we use
+  address@hidden:2011 gives a list of the long names from 6429:1992,
+  so I'm not sure the above is true anymore. Best leave the old reference.}]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,address@hidden@address@hidden
+character whose General Category is defined
+to be @lquotes@;Other, address@hidden@;, and which is not defined to be a
address@hidden<format_effector>.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,address@hidden@address@hidden
+character whose General Category is defined to be @lquotes@;Other, Private 
address@hidden@;.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,address@hidden@address@hidden
+character whose General Category is defined to be @lquotes@;Other, 
address@hidden@;.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden,address@hidden@ntf{graphic_character}],
address@hidden@ntf<other_control_function>address@hidden@Chg{Version=[2],
+New=[Any character that is not in the categories @ntf{other_control},
address@hidden, @ntf{other_surrogate},
address@hidden, and whose relative code
address@hidden,New=[point],Old=[position]} in its plane is neither
+16#FFFE# nor 16#FFFF#.],
+Old=[Any control function,
+other than a @ntf<format_effector>, that is allowed in a comment; the set of
address@hidden<other_control_function>s allowed in comments is implementation 
defined.
address@hidden character],See=(other_control_function)}]}
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,Text=[The control functions allowed in comments.]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,Text=`We considered basing the definition of
+lexical elements on Annex A of ISO/IEC
+TR 10176 (4th edition), which lists the characters which should be supported in
+identifiers for all programming languages, but we finally decided against this
+option. Note that it is not our intent to diverge from ISO/IEC TR 10176,
+except to the extent that ISO/IEC TR 10176 itself diverges from ISO/IEC
+10646:2003 (which is the case at the time of this writing [January 2005]).'}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[More precisely, we intend to align
+strictly with ISO/IEC 10646:2003. It must be
+noted that ISO/IEC TR 10176 is a Technical Report while ISO/IEC 10646:2003 is a
+Standard. If one has to make a choice, one should conform with the Standard
+rather than with the Technical Report. And, it turns out that one @i<must>
+make a choice because there are important differences between the two:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[ISO/IEC TR 10176 is still based on
+ISO/IEC 10646:2000 while ISO/IEC 10646:2003 has already been published
+for a year. We cannot afford to delay
+the adoption of our amendment until ISO/IEC TR 10176 has been revised.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[There are considerable differences between the
+two editions of ISO/IEC 10646,
+notably in supporting characters beyond the BMP (this might be significant for
+some languages, e.g. Korean).]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[ISO/IEC TR 10176 does not define case conversion
+tables, which are essential
+for a case-insensitive language like Ada. To get case conversion tables, we
+would have to reference either ISO/IEC 10646:2003 or Unicode, or we would have
+to invent our own.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[For the purpose of defining the
+lexical elements of the language, we need
+character properties like categorization, as well as case conversion tables.
+These are mentioned in ISO/IEC 10646:2003 as useful for implementations, with a
+reference to Unicode. Machine-readable tables are available on the web at 
URLs:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden://www.unicode.org/Public/4.0-Update/UnicodeData-4.0.0.txt],
+Text=[http://www.unicode.org/Public/4.0-Update/UnicodeData-4.0.0.txt]}
address@hidden://www.unicode.org/Public/4.0-Update/CaseFolding-4.0.0.txt],
+Text=[http://www.unicode.org/Public/4.0-Update/CaseFolding-4.0.0.txt]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[with an explanatory document found at URL:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden://www.unicode.org/Public/4.0-Update/UCD-4.0.0.html],
+Text=[http://www.unicode.org/Public/4.0-Update/UCD-4.0.0.html]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The actual text of the standard only makes
+specific references to the
+corresponding clauses of ISO/IEC 10646:2003, not to Unicode.]}
+
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0266-1]}
address@hidden@Chg{Version=[2],New=[],address@hidden of 
@ntf{special_character}s}
address@hidden,Sec=(names)}]}The
+following names are used when referring to certain
address@hidden,New=[characters (the first name is that given in
+ISO/IEC 10646:@Chg{Version=[3],New=[2011],Old=[2003]})],address@hidden:
address@hidden mark}
address@hidden sign}
address@hidden
address@hidden
address@hidden
address@hidden parenthesis}
address@hidden parenthesis}
address@hidden
address@hidden
address@hidden sign}
address@hidden
address@hidden
address@hidden
address@hidden stop}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden sign}
address@hidden sign}
address@hidden sign}
address@hidden line}
address@hidden
address@hidden line}
address@hidden,address@hidden point}
address@hidden sign}],
address@hidden square bracket}
address@hidden square bracket}
address@hidden curly bracket}
address@hidden curly bracket}]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0266-1]}
address@hidden,address@hidden address@hidden table
+serves to show the correspondence between
+ISO/IEC 10646:@Chg{Version=[3],New=[2011],Old=[2003]} names and the graphic 
symbols (glyphs) used in this
+International Standard. These are the characters],
+Old=[These are the ones]}
+that play a special role in the syntax of address@hidden,New=[],
+Old=[ 95, or in the syntax rules;
+we don't bother to define names for all characters.
+The first name given is the name from ISO 10646-1; the subsequent
+names, if any, are those used within the
+standard, depending on context]}.
address@hidden
address@hidden original version follows here (commented out)
address@hidden
address@hidden()@TabSet(P9)
address@hidden(TwoCol)
address@hidden@;symbol @\name
+
address@hidden@;  " @\quotation mark
+  # @\number sign
+  & @\ampersand
+  ' @\apostrophe, tick
+  ( @\left parenthesis
+  ) @\right parenthesis
+  * @\asterisk, multiply
+  + @\plus sign
+  , @\comma
+  @en@; @\hyphen-minus, minus
+  . @\full stop, dot, point
+  / @\solidus, divide
address@hidden
address@hidden@;symbol @\name
+
address@hidden@;  : @\colon
+  ; @\semicolon
+  < @\less-than sign
+  = @\equals sign
+  > @\greater-than sign
+  _ @\low line, underline
+  | @\vertical line
+  [ @\left square bracket
+  ] @\right square bracket
+  { @\left curly bracket
+  } @\right curly bracket
address@hidden(TwoCol)
address@hidden
address@hidden use this (weird) four column version to make the HTML look much 
better.
+WARNING: The items that go together are in separate columns!!}
address@hidden(FourCol)
address@hidden@;@ @ @Chg{Version=[2],New=[graphic ],Old=[@ @ @ @ ]}symbol
+
address@hidden@;@ @ @ @ @ @ @ @ @ "@*
+@ @ @ @ @ @ @ @ @ address@hidden
+@ @ @ @ @ @ @ @ @ &@*
+@ @ @ @ @ @ @ @ @ '@*
+@ @ @ @ @ @ @ @ @ (@*
+@ @ @ @ @ @ @ @ @ )@*
+@ @ @ @ @ @ @ @ @ address@hidden
+@ @ @ @ @ @ @ @ @ address@hidden
+@ @ @ @ @ @ @ @ @ ,@*
+@ @ @ @ @ @ @ @ @ @en@;@*
+@ @ @ @ @ @ @ @ @ 
address@hidden,New=[],address@hidden@Chg{Version=[2],New=[],Old=[@ @ @ @ @ @ @ 
@ @ /address@hidden layout so HTML and RTF look right}
address@hidden
address@hidden@;name
+
address@hidden@;quotation address@hidden
+number address@hidden
address@hidden
+apostrophe, address@hidden
+left address@hidden
+right address@hidden
+asterisk, address@hidden
+plus address@hidden
address@hidden
+hyphen-minus, address@hidden
+full stop, dot, 
address@hidden,New=[],address@hidden@Chg{Version=[2],New=[],Old=[solidus, 
address@hidden layout so HTML and RTF look right}
+
address@hidden
address@hidden@;@ @ @Chg{Version=[2],New=[graphic ],Old=[@ @ @ @ ]}symbol
+
address@hidden@;@ @ @ @ @ @ @ @ @ :@*
+@ @ @ @ @ @ @ @ @ ;@*
+@ @ @ @ @ @ @ @ @ <@*
+@ @ @ @ @ @ @ @ @ address@hidden
+@ @ @ @ @ @ @ @ @ >@*
+@ @ @ @ @ @ @ @ @ address@hidden
+@ @ @ @ @ @ @ @ @ |@*
+@ @ @ @ @ @ @ @ @ @Chg{Version=[2],New=[/],Old=<[>address@hidden
+@ @ @ @ @ @ @ @ @ @Chg{Version=[2],New=[!],Old=<]>address@hidden
+@ @ @ @ @ @ @ @ @ @Chg<Version=[2],New=[%],Old=<{>>@*
address@hidden<Version=[2],New=[],Old=<@ @ @ @ @ @ @ @ @ }>>
address@hidden
address@hidden@;name
+
address@hidden@;address@hidden
address@hidden
+less-than address@hidden
+equals address@hidden
+greater-than address@hidden
+low line, address@hidden
+vertical address@hidden
address@hidden,New=[solidus, divide],Old=[left square address@hidden
address@hidden,New=[exclamation point],Old=[right square address@hidden
address@hidden,New=[percent sign],Old=[left curly address@hidden
address@hidden,New=[],Old=[right curly bracket]}
address@hidden(FourCol)
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0286-1]}
address@hidden,Text=[An Ada implementation shall accept Ada source code
+in UTF-8 encoding, with or without a BOM (see @RefSecNum{String Encoding}),
+where every character is represented by its code point. The character pair
+CARRIAGE RETURN/LINE FEED (code points 16#0D# 16#0A#) signifies a single end of
+line (see @RefSecNum{Lexical Elements, Separators, and Delimiters}); every 
other
+occurrence of a @ntf{format_effector} other than the character whose code point
+position is 16#09# (CHARACTER TABULATION) also signifies a single end of 
line.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0079-1],ARef=[AI05-0286-1]}
address@hidden,Text=[This is simply requiring that an Ada implementation
+be able to directly process the ACATS, which is provided in the described
+format. Note that files that only contain characters with code points in the
+first 128 (which is the majority of the ACATS) are represented in the same way
+in both UTF-8 and in "plain" string format. The ACATS includes a BOM in files
+that have any characters with code points greater than 127. Note that the BOM
+contains characters not legal in Ada source code, so an implementation can use
+that to automatically distinguish between files formatted as plain Latin-1
+strings and UTF-8 with BOM.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[We allow line endings to be both represented as the
+pair CR LF (as in Windows and the ACATS), and as single @ntf{format_effector}
+characters (usually LF, as in Linux), in order that files created by standard
+tools on most operating systems will meet the standard format. We specify how
+many line endings each represent so that compilers use the same line numbering
+for standard source files.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This requirement increases portability by having a
+format that is accepted by all Ada compilers. Note that implementations can
+support other source representations, including structured representations like
+a parse tree.]}
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00285-01]}
address@hidden,Kind=[AddedNormal],ARef=[AI05-0266-1]}
address@hidden,New=[The categories defined above, as well as case mapping and
+folding, may be based on an implementation-defined version of ISO/IEC 10646
+(2003 edition or later).],address@hidden,New=[],Old=[In a nonstandard
+mode, the implementation may support a different character
address@hidden; in particular,
+the set of characters that are considered @ntf<identifier_letter>s
+can be extended
+or changed to conform to local conventions].]}]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[If an implementation supports
+other character sets,
+it defines which characters fall into each category,
+such as @lquotes@;@ntf{identifier_letter},@rquotes@;
+and what the corresponding rules of this section are,
+such as which characters are allowed in the text of a program.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=<The exact categories, case mapping, and case folding chosen
+affects identifiers, the result of '[[Wide_]Wide_]Image, and packages
+Wide_Characters.Handling and Wide_Wide_Characters.Handling.>}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This permission allows implementations to upgrade
+to using a newer character set standard whenever that makes sense, rather
+than having to wait for the next Ada Standard.
+But the character set standard used cannot be older than ISO/IEC 10646:2003
+(which is essentially similar to Unicode 4.0).]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,New=[The characters in categories @ntf{other_control},
address@hidden, and @ntf{other_surrogate} are only allowed in comments],
+Old=[Every code position of ISO 10646 BMP that is not reserved for a control
+function is defined to be a @nt<graphic_character> by this International 
Standard.
+This includes all code positions other than 0000 - 001F, 007F - 009F,
+and FFFE - FFFF]}.
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0286-1]}
address@hidden,Text=[The language does not specify the source
+representation of programs.]}
address@hidden(Discussion)
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Deleted],ARef=[AI05-0286-1]}
address@hidden,Text=[Any source representation is valid so long
+as the implementer can produce an (information-preserving)
+algorithm for translating both directions
+between the representation and the standard character set.
+(For example, every character in the standard character set has to be
+representable, even if the output devices attached to a given computer
+cannot print all of those characters properly.)
+From a practical point of view, every implementer will have to provide
+some way to process the @Chg{Version=[2],New=[ACATS],Old=[ACVC]}.
+It is the intent to allow source representations, such as parse trees,
+that are not even linear sequences of characters.
+It is also the intent to allow different fonts:
+reserved words might be in bold face,
+and that should be irrelevant to the semantics.]}
address@hidden(Discussion)
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Ada 95 allows 8-bit and 16-bit characters,
+as well as implementation-specified character sets.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The syntax rules in this @Chg{Version=[3],New=[subclause],Old=[clause]} are
+modified to remove the emphasis on basic characters vs. others.
+(In this day and age, there is no need to point out that you can write
+programs without using (for example) lower case letters.)
+In particular, @ntf{character} (representing all characters usable outside
+comments) is added, and @ntf{basic_graphic_character},
address@hidden,
+and @ntf{basic_character} are removed.
address@hidden is expanded to include Ada 83's
address@hidden, as well as new 8-bit characters not
+present in Ada address@hidden,New=[ Ada 2005 removes
address@hidden altogether; we want to stick to ISO/IEC 10646:2003
+character classifications.],Old=[]}
+Note that the term @lquotes@;basic address@hidden@; is used
+in @RefSec{Character Handling}
+to refer to letters without diacritical marks.
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+Character names now come from
address@hidden,New=[ISO/IEC 10646:2003],Old=[ISO 10646]}.
+
address@hidden,Kind=[Deleted],ARef=[AI95-00285-01]}
address@hidden,Text=[We use @ntf<identifier_letter> rather than
address@hidden<letter> since ISO 10646 BMP includes many "letters' that are not
+permitted in identifiers (in the standard mode).]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  Program text can use most characters defined by ISO-10646:2003. This
+  @Chg{Version=[3],New=[subclause],Old=[clause]} has been rewritten to use the 
categories defined in that Standard.
+  This should ease programming in languages other than English.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0266-1]}
+  @ChgAdded{Version=[3],Text=<@Defn{inconsistencies with Ada 2005}An
+  implementation is allowed (but not required) to use a newer character
+  set standard to determine the categories, case mapping, and case folding.
+  Doing so will change the results of attributes '[[Wide_]Wide_]Image and the
+  packages [Wide_]Wide_Characters.Handling in the case of a few rarely used
+  characters. (This also could make some identifiers illegal, for characters
+  that are no longer classified as letters.) This is unlikely to be a problem
+  in practice. Moreover, truly portable Ada 2012 programs should avoid using
+  in these contexts any characters that would have different classifications in
+  any character set standards issued since 10646:2003 (since the compiler can
+  use any such standard as the basis for its classifications).>}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0079-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified that only
+  characters in the categories defined here are allowed in the source
+  of an Ada program. This was clear in Ada 95, but Amendment 1 dropped
+  the wording instead of correcting it.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0286-1]}
+  @ChgAdded{Version=[3],Text=[A standard source representation is defined
+  that all compilers are expected to process. Since this is the same format
+  as the ACATS, it seems unlikely that there are any implementations that
+  don't meet this requirement. Moreover, other representations are still
+  permitted, and the "impossible or impractical" loophole (see
+  @RefSecnum{Conformity of an Implementation with the Standard}) can be
+  invoked for any implementations that cannot directly process the ACATS.]}
address@hidden
+
+
address@hidden Elements, Separators, and Delimiters}
+
address@hidden
address@hidden of a program}
+The text of a program consists of the texts of one or more
address@hidden<compilation>s.
address@hidden element}
address@hidden,See=(lexical element)}
+The text of each @nt<compilation> is a sequence
+of separate @i(lexical elements).
+Each lexical element is formed from a
+sequence of characters, and is
+either a delimiter, an @nt<identifier>, a reserved word,
+a @nt<numeric_literal>, a @nt<character_literal>, a @nt<string_literal>,
+or a comment.
+The meaning of a program depends only on the particular sequences of
+lexical elements that form its @nt{compilation}s, excluding
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
+The text of a @nt<compilation> is divided into @address@hidden
address@hidden of a line}
+In general, the representation for an end of line is implementation defined.
+However, a sequence of one or more @ntf<format_effector>s other
+than @Chg{Version=[2],New=[the character whose code
address@hidden,New=[point],Old=[position]}
+is 16#09# (CHARACTER TABULATION)],Old=[character tabulation (HT)]}
+signifies at least one end of line.
address@hidden representation for an end of line.}
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden@Defn{separator}
address@hidden some cases an explicit @i(separator) is required
+to separate adjacent lexical elements.]
+A separator is
+any of a @Chg{Version=[2],address@hidden,Old=[space character]},
+a @Chg{Version=[2],address@hidden,Old=[format effector]},
+or the end of a line, as follows:
address@hidden(Discussion)
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[It might be useful to define @lquotes@;white 
address@hidden@;
+and use it address@hidden one can figure out why, and it wouldn't match the
+Unicode def of whitespace.}
address@hidden(Discussion)
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+A @Chg{Version=[2],address@hidden,Old=[space character]} is
+a separator except within a @nt{comment}, a @nt{string_literal},
+or a @nt{character_literal}.
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden,New=[The character whose code 
@Chg{Version=[3],New=[point],Old=[position]}
+is 16#09# (CHARACTER TABULATION)],Old=[Character tabulation (HT)]} is a
+separator except within a @nt{comment}.
+
+The end of a line is always a separator.
address@hidden
+
+One or more separators are allowed between any two adjacent lexical
+elements, before the first of each @nt{compilation}, or after the
+last.
+At least one separator is required between an @nt{identifier},
+a reserved word, or a @nt{numeric_literal} and an adjacent
address@hidden, reserved word, or @nt{numeric_literal}.
+
address@hidden,Kind=[Added],ARef=[AI05-0079-1]}
address@hidden,Text=[One or more @ntf{other_format} characters
+are allowed anywhere that a separator address@hidden; any such characters
+have no effect on the meaning of an Ada program].]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden
+A @i{delimiter} is either one of the address@hidden,New=[],Old=[ special]}
address@hidden,New=[:],Old=[]}
address@hidden
+&@ @ @ @ '@ @ @ @ (@ @ @ @ )@ @ @ @ *@ @ @ @ +@ @ @ @ ,@ @ @ @ @en@ @ @ @ .@ @ 
@ @ /@ @ @ @ :@ @ @ @ ;@ @ @ @ <@ @ @ @ =@ @ @ @ >@ @ @ @ |
address@hidden
+
address@hidden delimiter}
+or one of the following @i{compound delimiters} each composed of two
+adjacent special characters
address@hidden
+=>@ @ @ @ ..@ @ @ @ **@ @ @ @ :=@ @ @ @ /=@ @ @ @ >=@ @ @ @ <=@ @ @ @ <<@ @ @ 
@ >>@ @ @ @ <>
address@hidden
+
+Each of the special characters listed for single character delimiters
+is a single delimiter except if this character is used as a character
+of a compound delimiter, or as a character of a @nt{comment},
address@hidden, @nt{character_literal}, or
address@hidden
+
address@hidden@Comment{For printed version of Ada 2005 RM}
+
address@hidden@keepnext@;The following names are used when referring to compound
+delimiters:@table{Columns=[2],
+Alignment=[Allleft],FirstColWidth=[1],LastColWidth=[4],
+NoBreak=[F],Border=[F],SmallSize=[F],Caption=[],
+Headers=[delimiter@ @\name],
+Body=[=>@\arrow
address@hidden dot
address@hidden star, exponentiate
+:address@hidden (pronounced: @lquotes@;address@hidden@;)
+/address@hidden (pronounced: @lquotes@;not address@hidden@;)
+>address@hidden than or equal
+<address@hidden than or equal
+<<@\left label bracket
+>>@\right label bracket
+<>@\box]}
address@hidden
+
address@hidden
+An implementation shall support lines of
+at least 200 characters in length, not counting any characters used to signify
+the end of a line.
+An implementation shall support lexical elements of at least
+200 characters in length.
+The maximum supported line length and lexical element length are
+implementation defined.
address@hidden supported line length and lexical element length.}
address@hidden
+From URG recommendation.
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[The wording was updated to use the new character
+  categories defined in the preceding 
@Chg{Version=[3],New=[subclause],Old=[clause]}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0079-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada address@hidden<Correction:>
+  Clarified that
+  @ntf{other_format} characters are allowed anywhere that separators
+  are allowed. This was intended in Ada 2005, but didn't actually
+  make it into the wording.]}
address@hidden
+
+
+
address@hidden
+
address@hidden
address@hidden<Identifier>s are used as names.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden<identifier>,rhs="
+   @Chg{Version=[2],New=<@Syn2{identifier_start} address@hidden | 
@Syn2{identifier_extend}}>,
+   Old=<@Synf{identifier_letter} address@hidden @Syn2{letter_or_digit}}>}"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden<@Chg{Version=[2],New=<identifier_start>,Old=<letter_or_digit>}>,
+rhs="@Chg{Version=[2],New=<
+     @Synf{letter_uppercase}
+   | @Synf{letter_lowercase}
+   | @Synf{letter_titlecase}
+   | @Synf{letter_modifier}
+   | @Synf{letter_other}
+   | @Synf{number_letter}>,Old=<@Synf{identifier_letter} | @Synf{digit}>}"}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0091-1]}
address@hidden,lhs=<@Chg{Version=[2],New=<identifier_extend>,Old=<>}>,
+rhs="@Chg{Version=[2],New=<
+     @Synf{mark_non_spacing}
+   | @Synf{mark_spacing_combining}
+   | @Synf{number_decimal}
+   | @address@hidden,New=<>,Old=<
+   | @Synf{other_format}>}>,Old=<>}"}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00395-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0091-1]}
address@hidden,address@hidden,New=[An],Old=[After eliminating the
+characters in category @ntf{other_format}, an]} @nt{identifier} shall not
+contain two consecutive characters in category
address@hidden,address@hidden,Old=[punctuation_connector]},
+or end with a character in that category.],Old=[An @nt{identifier} shall not be
+a reserved word.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised]}
+  @ChgAdded{Version=[2],Text=[This rule was stated in the syntax in Ada 95,
+  but that has gotten too complex in Ada address@hidden,New=[],
+  Old=[ Since @ntf{other_format}
+  characters usually do not display, we do not want to count them as separating
+  two underscores.]}]}
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0091-1],ARef=[AI05-0227-1],ARef=[AI05-0266-1],ARef=[AI05-0299-1]}
address@hidden the "Type=[Leading]" along with the bullets. Don't have
+a way to make it doubly conditional (only in Version=[2]), and since it is
+mainly for spacing, we just forget it.}
address@hidden,Text=[Two @nt{identifier}s are address@hidden,
+New=[considered the same if they consist of the same sequence of characters
+after applying @Chg{Version=[3],New=[locale-independent simple case folding,
+as defined by documents referenced in the note in Clause 1 of
+ISO/IEC 10646:address@hidden insensitive}],Old=[the following transformations
+(in this order):]}],Old=[All characters of an @nt{identifier} are significant,
+including any underline character.
address@hidden insensitive}
address@hidden differing only in the use of
+corresponding upper and lower case letters are considered the same.]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Kind=[DeletedAddedNoDelMsg],ARef=[AI05-0091-1]}
address@hidden,address@hidden,New=[],Old=[The characters
+in category @ntf{other_format} are eliminated.]}]}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,Kind=[DeletedAddedNoDelMsg],ARef=[AI05-0091-1]}
address@hidden,address@hidden,New=[],Old=[The remaining sequence of
+characters is converted to upper case.
address@hidden insensitive}]}]}
address@hidden
address@hidden(Discussion)
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0227-1]}
+  @Chg{Version=[3],New=[Simple case folding is a mapping to lower case, so this
+  is matching the defining (lower case) version of a reserved word. We could
+  have mentioned case folding of the reserved words, but as that is an identity
+  function, it would have no effect.],address@hidden,New=[],Old=[Two of
+  the letters of ISO 8859-1 appear only as lower case,
+  "sharp s" and "y with diaeresis." These two letters have
+  no corresponding upper case letter (in particular, they
+  are not considered equivalent to one another).]}]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0227-1]}
+  @ChgAdded{Version=[3],Text=[The @ldquote@;documents address@hidden means
+  Unicode. Note that simple case folding is supposed to be compatible between
+  Unicode versions, so the Unicode version used doesn't
+  matter.]}
address@hidden(Discussion)
address@hidden,Kind=[Added],ARef=[AI95-00395-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0091-1],ARef=[AI05-0227-1]}
address@hidden,Text=[After applying @Chg{Version=[3],New=[simple
+case folding],Old=[these transformations]}, an
address@hidden shall not be identical to a reserved
address@hidden,New=[],Old=[ (in upper case)]}.]}
address@hidden(ImplNote)
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised]}
+  @ChgAdded{Version=[2],Text=[We match the reserved words after
+  @Chg{Version=[3],New=[applying case folding],Old=[doing these
+  transformations]} so that the rules for @nt{identifier}s and reserved words 
are
+  the same. @Chg{Version=[3],New=[],Old=[(This allows @ntf{other_format}
+  characters, which usually don't display, in a reserved word
+  without changing it to an @nt{identifier}.) ]}Since
+  a compiler usually will lexically process @nt{identifier}s and reserved 
words the
+  same way (often with the same code), this will prevent a lot of headaches.]}
address@hidden(ImplNote)
address@hidden(Ramification)
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0227-1]}
+  @ChgAdded{Version=[2],Text=[The rules for reserved words differ in one way:
+  they define case conversion on letters rather than sequences. This means that
+  @Chg{Version=[3],New=[it is possible that there exist ],Old=[]}some
+  unusual sequences @Chg{Version=[3],New=[that ],Old=[]}are neither
+  @nt{identifier}s nor reserved words.
+  @Chg{Version=[3],New=[We are not aware of any such sequences so long as we 
use
+  simple case folding (as opposed to full case folding), but we have defined 
the
+  rules in case any are introduced in future character set standards. This
+  originally was a problem when converting to upper case:],Old=[For instance,]}
+  @lquotes@;@smldotlessi@;address@hidden@; and
+  @lquotes@;address@hidden(223)@rquotes@; have upper case conversions of
+  @lquotes@;address@hidden@; and @lquotes@;address@hidden@; respectively.
+  @Chg{Version=[3],New=[We would not want these to be treated as reserved 
words.
+  But neither of these cases exist when using simple case folding.], Old=[These
+  are not @nt{identifier}s, because the transformed values are
+  identical to a reserved word. But they are not reserved words, either, 
because
+  the original values do not match any reserved word as defined or with any 
number
+  of characters of the reserved word in upper case. Thus, these odd
+  constructions are just illegal, and should not appear in the source of
+  a program.]}]}
address@hidden(Ramification)
address@hidden
+
address@hidden
+In a nonstandard mode,
+an implementation may support other upper/lower case equivalence
+rules for @nt<identifier>address@hidden,
+to accommodate local conventions].
address@hidden
+
address@hidden(Discussion)
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0227-1]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[For instance, in most languages,
+  the @Chg{Version=[3],New=[simple case folded],Old=[uppercase]}
+  equivalent of LATIN @Chg{Version=[3],New=[CAPITAL],Old=[SMALL]} LETTER I
+  (@Chg{Version=[3],New=[an upper],Old=[a lower]} case letter
+  @Chg{Version=[3],New=[without],Old=[with]} a dot above) is
+  LATIN @Chg{Version=[3],New=[SMALL],Old=[CAPITAL]} LETTER I
+  (@Chg{Version=[3],New=[a lower],Old=[an upper]} case letter
+  @Chg{Version=[3],New=[with],Old=[without]} a dot above). In
+  Turkish, though, LATIN @Chg{Version=[3],New=[CAPITAL],Old=[SMALL]} LETTER I
+  and LATIN @Chg{Version=[3],New=[CAPITAL],Old=[SMALL]} LETTER
+  @Chg{Version=[3],New=[],Old=[DOTLESS address@hidden,New=[ WITH DOT
+  ABOVE],Old=[]} are two distinct letters, so the @Chg{Version=[3],New=[case
+  folded],Old=[upper case]} equivalent of LATIN
+  @Chg{Version=[3],New=[CAPITAL],Old=[SMALL]} LETTER I is LATIN
+  @Chg{Version=[3],New=[SMALL],Old=[CAPITAL]} LETTER
+  @Chg{Version=[3],New=[DOTLESS ],address@hidden,New=[],Old=[ WITH DOT
+  ABOVE]}, and the @Chg{Version=[3],New=[case folded],Old=[upper case]}
+  equivalent of LATIN @Chg{Version=[3],New=[CAPITAL],Old=[SMALL]} LETTER
+  @Chg{Version=[3],New=[],Old=[DOTLESS address@hidden,New=[ WITH DOT
+  ABOVE],Old=[]} is LATIN @Chg{Version=[3],New=[SMALL],Old=[CAPITAL]} LETTER I.
+  Take for instance the following identifier (which is the name of a city on 
the
+  Tigris river in Eastern Anatolia):]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,address@hidden,address@hidden@;YARBAKIR],address@hidden@;r]} -- 
@RI[The first i is dotted, the second isn't.]]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised]}
+  @ChgAdded{Version=[2],Type=[Leading],address@hidden,New=[A Turkish
+  reader would expect that the above identifier is equivalent 
to],Old=[Locale-independent conversion to
+  upper case results in]}:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,address@hidden,address@hidden@;r],Old=[DIYARBAKIR -- @RI[Both Is 
are dotless.]]}]}
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[However, locale-independent 
simple case folding (and thus Ada)
+  maps this to:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden@;yarbakir]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised]}
+  @ChgAdded{Version=[2],Type=[Leading],address@hidden,New=[which is
+  different from any of the following identifiers],Old=[This means that the 
four
+  following sequences of characters represent the same identifier, even though
+  for a locutor of Turkish they would probably be considered distinct 
words]}:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[diyarbakir
address@hidden@;r
address@hidden@;yarbakir
address@hidden@;address@hidden@;r]}
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=<including the @ldquote@;address@hidden matching
+  identifier for Turkish. Upper case conversion (used in '[Wide_]Wide_Image)
+  introduces additional problems.>}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised]}
+  @Comment{Removed the "Type=[Leading]" along with the example. Don't have
+  a way to make it doubly conditional (only in Version=[2]), and since it is
+  mainly for spacing, we just forget it.}
+  @ChgAdded{Version=[2],Text=[An implementation targeting the
+  Turkish market is allowed (in fact, expected) to provide a nonstandard mode
+  where case folding is appropriate for address@hidden,New=[],Old=[ This
+  would cause the original identifier to be converted to:]}]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden,New=[],address@hidden@;YARBAKIR -- @RI[The first 
I is dotted, the second isn't.]]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg]}
+  @ChgAdded{Version=[2],address@hidden,New=[],Old=[and the four
+  sequences of characters shown above would represent four distinct
+  identifiers.]}]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Lithuanian and Azeri are two other languages that
+  present similar idiosyncrasies.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],address@hidden differing only in the use of
+  corresponding upper and lower case letters are considered the same.]}
address@hidden
+
address@hidden
address@hidden@address@hidden of identifiers:}
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden version:@begin{Display}
+Count      X    Get_Symbol   Ethelyn   Marion
address@hidden line}
+Snobol_4   X1   Page_Count    Store_Next_Item
address@hidden
address@hidden
+Count      X    Get_Symbol   Ethelyn   Marion
+Snobol_4   X1   Page_Count   address@hidden,New=[
address@hidden(928)@unicode(955)@unicode(940)@unicode(964)@unicode(969)@unicode(957)
      address@hidden Plato]
address@hidden(1063)@unicode(1072)@unicode(1081)@unicode(1082)@unicode(1086)@unicode(1074)@unicode(1089)@unicode(1082)@unicode(1080)@unicode(1081)
  address@hidden Tchaikovsky]
address@hidden(952)  @unicode(966)        address@hidden Angles]],Old=[]}
address@hidden
address@hidden
+
address@hidden
+We no longer include reserved words as @nt<identifier>s.
+This is not a language change.
+In Ada 83, @nt{identifier} included reserved words.
+However, this complicated several other
+rules (for example, regarding implementation-defined
+attributes and pragmas, etc.).
+We now explicitly allow certain reserved words for attribute designators,
+to make up for the loss.
address@hidden
+Because syntax rules are relevant to overload resolution,
+it means that if it looks like a reserved word,
+it is not an @nt<identifier>.
+As a side effect, implementations cannot use reserved words as
+implementation-defined attributes or pragma names.
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  An @nt{identifier} can use any letter defined by ISO-10646:2003, along
+  with several other categories. This should ease programming in languages
+  other than English.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0091-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  @ntf{other_format} characters were removed from identifiers as the Unicode
+  recommendations have changed. This change can only affect programs
+  written for the original Ada 2005, so there should be few such programs.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0227-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> We now specify simple case
+  folding rather than full case folding. That potentially could change
+  identifier equivalence, although it is more likely that identifiers that
+  are considered the same in original Ada 2005 will now be considered 
different.
+  This change was made because the original Ada 2005 definition was 
incompatible
+  (and even inconsistent in unusual cases) with the Ada 95 identifier
+  equivalence rules. As such, the Ada 2005 rules were rarely fully implemented,
+  and in any case, only Ada 2005 identifiers containing wide characters could
+  be affected.]}
address@hidden
+
+
address@hidden Literals}
+
address@hidden
address@hidden, Sec=(numeric)}
+There are two kinds of @nt<numeric_literal>s, @i(real literals) and @i(integer
+literals).
address@hidden literal}
+A real literal is a @nt{numeric_literal} that includes a point;
address@hidden literal}
+an integer literal is a @nt{numeric_literal} without a point.
address@hidden
+
address@hidden
address@hidden<numeric_literal>,rhs="@Syn2{decimal_literal} | 
@Syn2{based_literal}"}
address@hidden
+
address@hidden
+The type of an integer literal is @i{universal_integer}.
+The type of a real literal is @i{universal_real}.
address@hidden
+
address@hidden Literals}
+
address@hidden
address@hidden, Sec=(decimal)}
+A @nt<decimal_literal> is a @nt<numeric_literal> in the conventional
+decimal notation (that is, the base is ten).
address@hidden
+
address@hidden
address@hidden<decimal_literal>,rhs="@Syn2{numeral} address@hidden 
address@hidden"}
+
+
address@hidden<numeral>,rhs="@Syn2{digit} address@hidden @Syn2{digit}}"}
+
address@hidden<exponent>,rhs="E [+] @Syn2{numeral} | E @en@; @Syn2{numeral}"}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,lhs=<@Chg{Version=[2],New=<digit>,Old=<>}>,
+rhs="@Chg{Version=[2],New=<0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9>,Old=<>}"}
+
address@hidden
+An @nt{exponent} for an integer literal shall not have a minus sign.
address@hidden
+Although
+this rule is in this subclause, it applies also to the next subclause.
address@hidden
address@hidden
address@hidden
+
address@hidden
+An underline character in a
address@hidden does not affect its meaning.
+The letter E of an @nt{exponent} can be written either in lower
+case or in upper case, with the same meaning.
address@hidden
+Although these rules are in this subclause,
+they apply also to the next subclause.
address@hidden
+
+An @nt{exponent} indicates the power of ten by which the value of the
address@hidden without the @nt{exponent} is to be multiplied to
+obtain the value of the @nt{decimal_literal} with the @nt{exponent}.
address@hidden
+
address@hidden
address@hidden@address@hidden of decimal literals:}
address@hidden Old version: @begin{Display}
address@hidden()@tabset(P31)
+12        0      1E6    123_456 @address@hidden  integer literals}
address@hidden line}
+12.0      0.0    0.456  3.14159_26 @address@hidden  real literals}
address@hidden
address@hidden
+12        0      1E6    123_456    address@hidden  integer literals}
address@hidden line}
+12.0      0.0    0.456  3.14159_26 address@hidden  real literals}
address@hidden
address@hidden
+
address@hidden
+We have changed the syntactic category name @ntf{integer} to be @nt{numeral}.
+We got this idea from ACID.
+It avoids the confusion between this and integers.
+(Other places don't offer similar confusions.
+For example, a @nt{string_literal} is different from a string.)
address@hidden
+
address@hidden Literals}
+
address@hidden
address@hidden
address@hidden, Sec=(based)}
address@hidden literal}
address@hidden 2 literal}
address@hidden, Sec=(literal)}
address@hidden literal}
address@hidden 8 literal}
address@hidden, Sec=(literal)}
address@hidden literal}
address@hidden 16 literal}
address@hidden, Sec=(literal)}
+A @nt<based_literal> is a @nt<numeric_literal> expressed in a form
+that specifies the base explicitly.]
address@hidden
+
address@hidden
address@hidden<based_literal>,rhs="
+   @Syn2{base} # @Syn2{based_numeral} address@hidden # address@hidden"}
+
+
address@hidden<base>,rhs="@Syn2{numeral}"}
+
address@hidden<based_numeral>,rhs="
+   @Syn2{extended_digit} address@hidden @Syn2{extended_digit}}"}
+
address@hidden<extended_digit>,rhs="@Syn2{digit} | A | B | C | D | E | F"}
+
address@hidden
+
address@hidden
address@hidden
+The @i(base) (the numeric value of the decimal @nt<numeral> preceding
+the first #) shall be at least two and at most sixteen.
+The @nt{extended_digit}s A through F represent the digits ten through
+fifteen, respectively.
+The value of each @nt{extended_digit} of a @nt{based_literal}
+shall be less than the base.
address@hidden
+
address@hidden
+The conventional meaning of based notation is assumed.
+An @nt{exponent} indicates the
+power of the base by which the value of the @nt{based_literal}
+without the @nt{exponent} is to be multiplied to obtain the value of
+the @nt{based_literal} with the @nt{exponent}.
+The @nt{base} and the @nt{exponent}, if any, are in decimal notation.
+
+The @nt{extended_digit}s A through F can be written either in
+lower case or in upper case, with the same meaning.
address@hidden
+
address@hidden
address@hidden@address@hidden of based literals:}
address@hidden Old version: @begin{Display}
address@hidden()@tabset(P16, P45)
+2#1111_1111# @\16#FF#       016#0ff# @address@hidden  integer literals of 
value 255}
+16#E#E1     @\2#1110_0000#     @address@hidden  integer literals of value 224}
+16#F.FF#E+2 @\2#1.1111_1111_1110#E11 @address@hidden  real literals of value 
4095.0}
address@hidden
address@hidden
+2#1111_1111#  16#FF#       016#0ff#   address@hidden  integer literals of 
value 255}
+16#E#E1       2#1110_0000#            address@hidden  integer literals of 
value 224}
+16#F.FF#E+2   2#1.1111_1111_1110#E11  address@hidden  real literals of value 
4095.0}
address@hidden
address@hidden
+
address@hidden
+The rule about which letters are allowed is now encoded in BNF,
+as suggested by Mike Woodger.
+This is clearly more readable.
address@hidden
+
address@hidden Literals}
+
address@hidden
address@hidden @nt<character_literal> is formed by enclosing a graphic
+character between two apostrophe characters.]
address@hidden
+
address@hidden
address@hidden<character_literal>,rhs="@address@hidden@SingleQuote"}
address@hidden@Comment{graphic_character is defined syntactically in Ada 95, 
but not in Ada 2007}
+
address@hidden
+A @nt{character_literal} is an enumeration literal
+of a character type. See @RefSecNum(Character Types).
address@hidden
+
address@hidden
address@hidden@address@hidden of character literals:}
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden Orginal version: @begin{Display}
+'A'@ @ @ @ @ '*'@ @ @ @ @ '''@ @ @ @ @ '@ '
address@hidden
address@hidden
+'A'     '*'     '''     ' '@Chg{Version=[2],New=[
+'L'     '@Unicode(1051)'     '@Unicode(923)'    address@hidden Various els.]
+'@Unicode(8734)'     '@Unicode(1488)'            address@hidden Big numbers - 
infinity and aleph.]],Old=[]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The definitions of the values of literals are in
address@hidden,New=[Clauses],Old=[Sections]} 3 and 4, rather than here,
+since it requires knowledge of types.
address@hidden
+
address@hidden Literals}
+
address@hidden
address@hidden @nt<string_literal> is formed by a sequence of graphic characters
+(possibly none) enclosed between two quotation marks used as
+string brackets. They are used to represent @nt<operator_symbol>s
+(see @RefSecNum(Subprogram Declarations)), values of a string type
+(see @RefSecNum(Literals)), and array subaggregates
+(see @RefSecNum(Array Aggregates)).
address@hidden string],See=(string_literal)}]
address@hidden
+
address@hidden
address@hidden<string_literal>,rhs=<"address@hidden">}
+
address@hidden<string_element>,
+  rhs=<"" | @address@hidden>}
+
address@hidden
+A @nt{string_element} is either a pair of quotation marks (""),
+or a single @ntf{graphic_character} other than a quotation mark.
address@hidden
address@hidden
+
address@hidden
address@hidden of characters], Sec=(of a @nt<string_literal>)}
+The @i(sequence of characters) of a @nt<string_literal> is formed
+from the sequence of @nt<string_element>s between the bracketing
+quotation marks, in the given order,
+with a @nt<string_element> that is "" becoming a single quotation
+mark in the sequence of characters,
+and any other @nt<string_element> being reproduced
+in the sequence.
+
address@hidden string literal}
+A @i(null string literal) is a @nt<string_literal> with no
address@hidden<string_element>s between the quotation marks.
+
address@hidden
+
address@hidden
+An end of line cannot appear in a @nt{string_literal}.
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Text=[No transformation is performed on the
+sequence of characters of a @nt{string_literal}.]}
address@hidden
+
address@hidden
address@hidden@address@hidden of string literals:}
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden< Original version: @begin{Display}
address@hidden()@tabset(P16)
+"Message of the day:"
address@hidden line}
+""   @address@hidden  a null string literal}
+"@ "   "A"   """"     @address@hidden  three string literals of length 1}
address@hidden line}
+"Characters such as $, %, and } are allowed in string literals"
address@hidden>
address@hidden
+"Message of the day:"
address@hidden line}
+""                    address@hidden  a null string literal}
+" "   "A"   """"      address@hidden  three string literals of length 1}
address@hidden line}
+"Characters such as $, %, and } are allowed in string literals"
address@hidden,New=["Archimedes said 
""@unicode(917)@unicode(973)@unicode(961)@unicode(951)@unicode(954)@unicode(945)"""
+"Volume of cylinder (@pi@;address@hidden(178)h) = "],Old=[]}
address@hidden
address@hidden
+
address@hidden
+The wording has been changed to be strictly lexical.
+No mention is made of string or character values, since
address@hidden<string_literal>s are also used to represent 
@nt<operator_symbol>s,
+which don't have a defined value.
+
+The syntax is described differently.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,Text=[We explicitly say that the characters of a
address@hidden should be used as is. In particular, no normalization
+or folding should be performed on a @nt{string_literal}.]}
address@hidden
+
+
address@hidden
+
address@hidden
+A @nt{comment} starts with two adjacent hyphens and extends up to the end
+of the line.
address@hidden
+
address@hidden
address@hidden<comment>,
+  rhs=<address@hidden@Synf{character}}>address@hidden is defined syntactically 
in Ada 95,
+but not in Ada 2007. We assume the worst here.}
+
address@hidden
+A @nt{comment} may appear on any line of a program.
address@hidden
address@hidden
+
address@hidden
+The presence or absence of @nt{comment}s has no influence on whether a program
+is legal or illegal. Furthermore, @nt{comment}s do not influence the meaning
+of a program; their sole purpose is the enlightenment of the human reader.
address@hidden
+
address@hidden
address@hidden@address@hidden of comments:}
address@hidden version: @begin{Display}
address@hidden  the last sentence above echoes the Algol 68 report }
address@hidden line}
address@hidden;  address@hidden  processing of Line is complete }
address@hidden line}
address@hidden  a long comment may be split onto}
address@hidden  two or more consecutive lines   }
address@hidden line}
address@hidden  the first two hyphens start the comment  }
address@hidden
address@hidden
address@hidden  the last sentence above echoes the Algol 68 report ]
address@hidden line}
address@hidden;  address@hidden  processing of Line is complete ]
address@hidden line}
address@hidden  a long comment may be split onto]
address@hidden  two or more consecutive lines   ]
address@hidden line}
address@hidden  the first two hyphens start the comment  ]
address@hidden
address@hidden
+
+
address@hidden
+
address@hidden
address@hidden<Pragma>,
+  Text=<A pragma is a compiler directive.
+  There are language-defined pragmas that give instructions
+  for optimization, listing control, etc.
+  An implementation may support additional
+  (implementation-defined) pragmas.>}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0100-1],ARef=[AI05-0163-1]}
+  @ChgAdded{Version=[3],Text=[In general, if all @nt{pragma}s are treated as
+  unrecognized @nt{pragma}s, the program should remain both syntactically and
+  semantically legal. There are a few exceptions to this general principle (for
+  example, @nt{pragma} Import can eliminate the need for a completion), but the
+  principle remains, and is strictly true at the syntactic level. Certainly any
+  implementation-defined @nt{pragma}s should obey this principle both
+  syntactically and semantically, so that if the @nt{pragma}s are not 
recognized
+  by some other implementation, the program will remain legal.]}
address@hidden
+
address@hidden
address@hidden<pragma>,rhs="
+   @key{pragma} @Syn2{identifier} [(@Syn2{pragma_argument_association} {, 
@Syn2{pragma_argument_association}})];"}
+
address@hidden,Kind=[Revised],ARef=[AI05-0290-1]}
address@hidden<pragma_argument_association>,rhs="
+     address@hidden@Syn2{identifier} =>] @Syn2{name}
+   | address@hidden@Syn2{identifier} =>] @address@hidden,New=[
+   | @address@hidden =>  @Syn2{name}
+   | @address@hidden =>  @Syn2{expression}],Old=[]}"}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0290-1]}
+In a @nt<pragma>, any @nt<pragma_argument_association>s without a
address@hidden@nt<identifier> @Chg{Version=[3],New=[or
address@hidden@nt<aspect_mark> ],Old=[]}shall
+precede any associations with a
address@hidden@nt<identifier>@Chg{Version=[3],New=[ or
address@hidden@nt<aspect_mark>],Old=[]}.
+
address@hidden@address@hidden are only allowed at the following places in a 
program:
address@hidden
+After a semicolon delimiter, but not within a @nt{formal_part}
+or @nt{discriminant_part}.
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0100-1],ARef=[AI05-0163-1]}
+At any place where the syntax rules allow a construct defined by a
+syntactic category whose name ends with @address@hidden@rdquote,
address@hidden,address@hidden@address@hidden, ],address@hidden@address@hidden,
address@hidden@address@hidden, or
address@hidden@address@hidden, or one of the syntactic categories
address@hidden or @nt{exception_handler};
+but not in place of such a address@hidden,New=[ if the construct
+is required, or is part of a list that is required to have at least one such
+construct],Old=[. Also at any place where a @nt{compilation_unit} would be
+allowed]}.
+
address@hidden,Kind=[Added],ARef=[AI05-0163-1]}
address@hidden,Text=[In place of a @nt{statement} in a
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0100-1]}
address@hidden,Text=[At any place where a @nt{compilation_unit}
+is allowed.]}
address@hidden
+
+Additional syntax rules and placement restrictions
+exist for specific pragmas.
address@hidden
address@hidden
+The above rule is written in text,
+rather than in BNF;
+the syntactic category @nt{pragma} is not used in any BNF syntax rule.
address@hidden
address@hidden
+A @nt{pragma} is allowed where a
address@hidden<generic_formal_parameter_declaration> is allowed.
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(of a @nt{pragma})}
address@hidden name}
+The @i{name} of a @nt{pragma} is
+the identifier following the reserved word @key{pragma}.
address@hidden argument}
address@hidden of a pragma}
+The @nt{name} or @nt{expression} of a @nt{pragma_argument_association}
+is a @i{pragma argument}.
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00284-02]}
+  @ChgAdded{Version=[2],Text=[For compatibility with Ada 83, the name of a
+  @nt{pragma} may also be @address@hidden@rquotes@;, which is not an
+  identifier (because it is a reserved word).
+  See @RefSecNum{Pragma Interface}.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0272-1]}
address@hidden specific to a pragma}
address@hidden, identifier specific to}
+An @i{identifier specific to a pragma} is
+an identifier @Chg{Version=[3],New=[or reserved word ],Old=[]}that is
+used in a pragma argument with special meaning
+for that pragma.
address@hidden
+Whenever the syntax rules for a given pragma allow
+"@nt{identifier}" as an argument of the @nt{pragma},
+that @nt{identifier} is an identifier specific to that
+pragma.
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0272-1]}
+  @ChgAdded{Version=[3],Text=[In a few cases, a reserved word is
+  allowed as "an identifier specific to a pragma". Even in these cases,
+  the syntax still is written as @nt{identifier} (the reserved word(s)
+  are not shown). For example, the restriction No_Use_Of_Attribute
+  (see @RefSecNum{Language-Defined Restrictions and Profiles}) allows the
+  reserved words which can be attribute designators, but the syntax for
+  a restriction does not include these reserved words.]}
address@hidden
address@hidden
+
address@hidden
+If an implementation does not recognize the name of a
address@hidden, then it has no effect on the semantics
+of the program.
+Inside such a @nt{pragma}, the only rules that apply are the
address@hidden@;s.
address@hidden
+This rule takes precedence over any other rules that imply otherwise.
address@hidden
address@hidden
+Note well: this rule applies only to @nt{pragma}s whose name is not
+recognized.
+If anything else is wrong with a @nt{pragma} (at compile time),
+the @nt{pragma} is illegal.
+This is true whether the @nt{pragma} is
+language defined or implementation defined.
+
+For example, an expression in an unrecognized @nt{pragma} does
+not cause freezing, even though the rules in
address@hidden Rules} say it does;
+the above rule overrules those other rules.
+On the other hand, an expression in a recognized @nt{pragma} causes
+freezing, even if this makes something illegal.
+
+For another example, an expression that would be ambiguous is not
+illegal if it is inside an unrecognized @nt{pragma}.
+
+Note, however, that implementations have to recognize @key[pragma]
+Inline(Foo) and freeze things accordingly, even if they choose to never
+do inlining.
+
+Obviously, the contradiction needs to be resolved one way or the
+other. The reasons for resolving it this way are: The
+implementation is simple @em the compiler can just ignore the
address@hidden altogether.
+The interpretation of constructs appearing inside
+implementation-defined @nt{pragma}s is implementation defined. For
+example: @lquotes@;@key[pragma] Mumble(X);@rquotes@;. If the current 
implementation has
+never heard of Mumble, then it doesn't know whether X is a name,
+an expression, or an identifier specific to the pragma Mumble.
address@hidden
address@hidden
+The syntax of individual pragmas overrides the general
+syntax for @nt{pragma}.
address@hidden
address@hidden
+Thus, an identifier specific to a @nt{pragma} is not a @nt{name},
+syntactically; if it were, the visibility rules would be invoked,
+which is not what we want.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+This also implies that named associations do not allow one to give the
+arguments in an arbitrary order @em the order given in the syntax rule
+for each individual pragma must be obeyed.
+However, it is generally possible to leave out earlier arguments when
+later ones are given; for example, this is allowed by the syntax rule
+for pragma Import (see @Chg{Version=[3],address@hidden Pragmas}],
address@hidden Aspects}]}).
+As for subprogram calls, positional notation precedes named
+notation.
+
+Note that Ada 83 had no pragmas for which the order of named
+associations mattered, since there was never more than one argument
+that allowed named associations.
address@hidden
address@hidden
+The interpretation of the arguments of implementation-defined pragmas
+is implementation defined.
+However, the syntax rules have to be obeyed.
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(pragma)}
address@hidden, Sec=(pragma)}
+Any @nt{pragma} that appears at the place of an executable construct is
+executed.
+Unless otherwise specified for a particular pragma,
+this execution consists of the evaluation of each evaluable pragma
+argument in an arbitrary address@hidden order],Sec=[allowed]}
address@hidden
+For a @nt{pragma} that appears at the place of an elaborable
+construct, execution is elaboration.
+
+An identifier specific to a pragma is neither a @nt{name} nor an
address@hidden @em such identifiers are not evaluated (unless an
+implementation defines them to be evaluated in the case of an
+implementation-defined @nt{pragma}).
+
+The @lquotes@;unless otherwise address@hidden@; part allows us (and
+implementations) to make exceptions, so a @nt{pragma} can contain an
+expression that is not evaluated.
+Note that @nt{pragma}s in @nt{type_definition}s may contain expressions
+that depend on discriminants.
+
+When we wish to define a pragma with some run-time effect,
+we usually make sure that it appears in an executable context;
+otherwise, special rules are needed to define the run-time effect
+and when it happens.
address@hidden
address@hidden
+
address@hidden
+The implementation shall give a warning message for
+an unrecognized pragma name.
address@hidden
+An implementation is also allowed to have modes in which a warning
+message is suppressed, or in which the presence of an unrecognized
address@hidden is a compile-time error.
address@hidden
address@hidden
+
address@hidden
+An implementation may provide implementation-defined pragmas;
+the name of an implementation-defined pragma shall differ
+from those of the language-defined pragmas.
address@hidden pragmas.}
address@hidden
+The semantics of implementation-defined pragmas, and any associated
+rules (such as restrictions on their placement or arguments),
+are, of course, implementation defined.
+Implementation-defined pragmas may have run-time effects.
address@hidden
+
+An implementation may ignore an unrecognized pragma even if
+it violates some of the @SyntaxName@;s, if detecting the
+syntax error is too complex.
address@hidden
+  Many compilers use extra post-parsing checks to enforce the syntax
+  rules, since the Ada syntax rules are not LR(k) (for any k).
+  (The grammar is ambiguous, in fact.)
+  This paragraph allows them to ignore an unrecognized pragma, without
+  having to perform such post-parsing checks.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0163-1]}
+Normally,
+implementation-defined pragmas should have no semantic effect
+for error-free programs;
+that is, if the implementation-defined pragmas
address@hidden,New=[in a working program are replaced
+with unrecognized pragmas],Old=[are removed from a working program]},
+the program should still be legal, and should still have the same
+semantics.
address@hidden,Kind=[Added],address@hidden,
+Text=[Implementation-defined pragmas should have no semantic effect
+for error-free programs.]}]}
address@hidden
+Note that @lquotes@;address@hidden@; is not the same as 
@lquotes@;effect;@rquotes@;
+as explained in
address@hidden of an Implementation With the Standard},
+the semantics defines a set of possible effects.
+
+Note that adding a @nt{pragma} to a program might cause an error
+(either at compile time or at run time).
+On the other hand, if the language-specified semantics for a
+feature are in part implementation defined,
+it makes sense to support pragmas that control the feature,
+and that have real semantics; thus,
+this paragraph is merely a recommendation.
address@hidden
+
address@hidden@;Normally,
+an implementation should not define pragmas that can make an illegal
+program legal, except as follows:
address@hidden(Itemize)
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  A @nt<pragma> used to complete a
+  address@hidden,New=[],Old=[, such as a @nt{pragma} Import]};
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[There are no language-defined pragmas which
+  can be completions; @nt{pragma} Import was defined this way in Ada 95
+  and Ada 2005, but in Ada 2012 @nt{pragma} Import just sets aspect Import
+  which disallows having any completion.]}
address@hidden
+
+  A @nt<pragma> used to configure the environment
+  by adding, removing, or replacing @nt{library_item}s.
address@hidden(Itemize)
address@hidden,Kind=[Added],address@hidden,
+Text=[Implementation-defined pragmas should not make an illegal program
+legal, unless they complete a declaration or configure the @nt{library_item}s
+in an environment.]}]}
address@hidden(Ramification)
+For example, it is OK to support Interface,
+System_Name, Storage_Unit, and Memory_Size @nt{pragma}s
+for upward compatibility reasons,
+even though all of these @nt{pragma}s can make an illegal program legal.
+(The latter three can affect legality in a rather subtle way:
+They affect the value of named numbers in System,
+and can therefore affect the legality in cases where
+static expressions are required.)
+
+On the other hand,
+adding implementation-defined pragmas to a legal program can make it illegal.
+For example, a common kind of implementation-defined pragma is one that
+promises some property that allows more efficient code to be generated.
+If the promise is a lie,
+it is best if the user gets an error message.
address@hidden(Ramification)
address@hidden
+
address@hidden
address@hidden with Ada 83}
+In Ada 83, @lquotes@;address@hidden@; @nt{pragma}s are ignored.
+In Ada 95, they are illegal,
+except in the case where the name of the @nt{pragma} itself
+is not recognized by the implementation.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Implementation-defined @nt{pragma}s may affect the legality of a program.
address@hidden
+
address@hidden
+Implementation-defined @nt{pragma}s may affect the run-time semantics of
+the program.
+This was always true in Ada 83 (since it was not explicitly forbidden by
+RM83), but it was not clear, because there was no definition of
address@hidden@;address@hidden@; or @lquotes@;address@hidden@; a @nt{pragma}.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0163-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada address@hidden<Correction:>
+  Allow @nt{pragma}s in place of a @nt{statement}, even if there are no
+  other @nt{statement}s in a @nt{sequence_of_statements}.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0272-1]}
+  @ChgAdded{Version=[3],Text=[Identifiers specific to a pragma can be
+  reserved words.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0290-1]}
+  @ChgAdded{Version=[3],Text=[Pragma arguments can be identified with
+  @nt{aspect_mark}s; this allows @nt{identifier}'Class in this context.
+  As usual, this is only allowed if specifically allowed by a particular
+  pragma.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0100-1]}
+  @ChgAdded{Version=[3],address@hidden:} Clarified where @nt{pragma}s
+  are (and are not) allowed.]}
address@hidden
+
+
address@hidden
address@hidden@keepnext@;The forms of List, Page, and Optimize @nt{pragma}s are 
as follows:
+
address@hidden@key{pragma} @prag(List)(@Syn2{identifier});'
+
address@hidden@key{pragma} @prag(Page);'
+
address@hidden@key{pragma} @prag(Optimize)(@Syn2{identifier});'
+
address@hidden
address@hidden pragmas are defined throughout this International Standard,
+and are summarized in
address@hidden Pragmas}.]
address@hidden
+The language-defined pragmas
+are supported by every implementation,
+although @lquotes@;address@hidden@; some of
+them (for example, Inline) requires nothing more than checking the
+arguments, since they act only as advice to the implementation.
address@hidden
+
address@hidden
address@hidden
+
address@hidden
+A @nt{pragma} List
+takes one of the @nt{identifier}s On or Off as the single
+argument. This pragma is allowed anywhere a
address@hidden is allowed. It specifies that listing of the
+compilation is to be continued or suspended until a List
address@hidden with the opposite argument is given within the
+same compilation. The @nt{pragma} itself is always listed if
+the compiler is producing a listing.
+
+A @nt{pragma} Page
+is allowed anywhere a
address@hidden is allowed. It specifies that the program text
+which follows the @nt{pragma} should start on a new page (if
+the compiler is currently producing a listing).
+
+A @nt{pragma} Optimize
+takes one of the @nt{identifier}s Time, Space, or Off as the
+single argument. This @nt{pragma} is allowed anywhere a @nt<pragma>
+is allowed, and it applies until the end of the immediately enclosing
+declarative region,
+or for a @nt{pragma} at the place of a @nt{compilation_unit},
+to the end of the @nt<compilation>.
+It gives advice to the implementation as to
+whether time or space is the primary optimization criterion, or
+that optional optimizations should be turned off.
address@hidden is implementation defined how this advice is followed.]
address@hidden of pragma Optimize.}
address@hidden
+
+For example, a compiler might use Time vs. Space to control whether
+generic instantiations are implemented with a macro-expansion model,
+versus a shared-generic-body model.
+
+
+We don't define what constitutes an @lquotes@;address@hidden@;
address@hidden in fact, it cannot be formally defined in the context of Ada.
+One compiler might call something an optional optimization,
+whereas another compiler might consider that same thing
+to be a normal part of code generation.
+Thus, the programmer cannot rely on this pragma having any
+particular portable effect on the generated code.
+Some compilers might even ignore the pragma altogether.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of pragmas:}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden List(Off); -- @Examcom{turn off listing generation}
address@hidden Optimize(Off); -- @Examcom{turn off optional optimizations}
address@hidden,address@hidden Pure(Rational_Numbers); -- @Examcom{set 
categorization for package}
address@hidden Assert(Exists(File_Name),
+              Message => "Nonexistent file"); -- @Examcom{assert file exists}],
address@hidden Inline(Set_Mask); address@hidden generate code for Set_Mask 
inline}
address@hidden,address@hidden Import(C, Put_Char, External_Name => "putchar"); 
address@hidden import C putchar function}],
address@hidden Suppress(Range_Check, On => Index); -- @Examcom{turn off range 
checking on Index}]}]}
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The Optimize @nt<pragma> now allows the identifier Off
+to request that normal optimization be turned off.
+
+An Optimize @nt<pragma> may appear anywhere pragmas are allowed.
address@hidden
+
address@hidden
+We now describe the pragmas Page, List, and Optimize here,
+to act as examples, and to remove the normative material from
address@hidden Pragmas}, so it can be entirely an
+informative annex.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00433-01]}
+  @ChgAdded{Version=[2],Text=[Updated the example of named pragma parameters,
+  because the second parameter of @nt{pragma} Suppress is obsolescent.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[Updated the example of pragmas, because both
+  @nt{pragma}s Inline and Import are obsolescent.]}
address@hidden
+
+
address@hidden Words}
+
address@hidden
address@hidden
address@hidden, Kind=[Deleted]}
address@hidden,Type=[Leading],Text=<@ @;@comment{Empty paragraph to hang junk 
paragraph number from original RM}>]
+
address@hidden,Kind=[Revised],ARef=[AI95-00284-02],ARef=[AI95-00395-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0091-1]}
address@hidden table of words has no paragraph number, so we need to put the
+change here}
address@hidden
address@hidden word}
+The following are the @i{reserved address@hidden,New=[. Within a program,
+some or all of the letters of a reserved word may be in
+upper address@hidden,New=[],Old=[, and one or
+more characters in category @ntf{other_format} may be inserted within or at the
+end of the reserved word]}.],Old=[ (ignoring upper/lower case distinctions):]}
address@hidden
+  Reserved words have special meaning in the syntax.
+  In addition, certain reserved words are used as attribute names.
+
+  The syntactic category @nt{identifier}
+  no longer allows reserved words. We have added the few reserved
+  words that are legal explicitly to the syntax for @nt{attribute_reference}.
+  Allowing identifier to include reserved words has been a source
+  of confusion for some users, and differs from the way they
+  are treated in the C and Pascal language definitions.
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden@key{abort}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden@key{begin}
address@hidden
+
address@hidden@key{case}
address@hidden
+
address@hidden@key{declare}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden@key{else}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden@key{for}
address@hidden
+
address@hidden@key{generic}
address@hidden
+
address@hidden@key{if}
address@hidden
address@hidden,address@hidden,Old=[]}
address@hidden
+
+
address@hidden@key{limited}
address@hidden
+
address@hidden@key{mod}
address@hidden
+
address@hidden@key{new}
address@hidden
address@hidden
+
+
address@hidden@key{of}
address@hidden
address@hidden
address@hidden
address@hidden,address@hidden,Old=[]}
+
address@hidden@key{package}
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden@key{raise}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden@key{return}
address@hidden
+
address@hidden@key{select}
address@hidden
address@hidden,address@hidden,Old=[]}
address@hidden
address@hidden,address@hidden,Old=[]}
+
address@hidden@key{tagged}
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden@key{until}
address@hidden
+
address@hidden@key{when}
address@hidden
address@hidden
+
address@hidden@key{xor}
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden
+The reserved words appear in @key{lower case boldface}
+in this International Standard,
+except when used in the @nt{designator} of an attribute
+(see @RefSecNum(Attributes)).
+Lower case boldface is also used
+for a reserved word in a
address@hidden used as an @nt{operator_symbol}.
+This is merely a convention @em programs may be written in whatever
+typeface is desired and available.
address@hidden
+
address@hidden
address@hidden with Ada 83}
+The following words are not reserved in Ada 83, but are reserved in Ada
+95: @key{abstract}, @key{aliased}, @key{protected}, @key{requeue},
address@hidden, @key{until}.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The @Chg{Version=[3],New=[subclause],Old=[clause]} entitled @lquotes@;Allowed
+Replacements of address@hidden@; has been moved to
address@hidden(Obsolescent Features).
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00284-02]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  The following words are not reserved in Ada 95, but are reserved in Ada
+  2005: @key{interface}, @key{overriding}, @key{synchronized}. A special
+  allowance is made for @key{pragma} Interface (see @RefSecNum{Pragma 
Interface}).
+  Uses of these words as identifiers will need to be changed, but we do not
+  expect them to be common.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00395-01]}
+  @ChgAdded{Version=[2],Text=[The definition of upper case equivalence has
+  been modified to allow identifiers using all of the characters of ISO 10646.
+  This change has no effect on the character sequences that are reserved
+  words, but does make some unusual sequences of characters illegal.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0091-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Removed @ntf{other_format}
+  characters from reserved words in order to be compatible with the latest
+  Unicode recommendations. This change can only affect programs
+  written for original Ada 2005, and there is little reason to put
+  @ntf{other_format} characters into reserved words in the first place,
+  so there should be very few such programs.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0176-1]}
+  @ChgAdded{Version=[3],Text=[The following word is not reserved in Ada 2005, 
but is
+  reserved in Ada 2012: @key{some}. Uses of this word as an identifier will 
need
+  to be changed, but we do not expect them to be common.]}
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/03a.mss 
b/packages/ada-ref-man/source_2012/03a.mss
new file mode 100755
index 0000000..bf02fbb
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/03a.mss
@@ -0,0 +1,7529 @@
address@hidden(03, Root="ada.mss")
+
address@hidden: 2016/02/12 05:25:37 $}
address@hidden and Types}
+
address@hidden: e:\\cvsroot/ARM/Source/03a.mss,v $}
address@hidden: 1.132 $}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[clause],Old=[section]} describes the types
+in the language and the rules for declaring constants, variables, and
+named numbers.
address@hidden
+
address@hidden
+
address@hidden
address@hidden
+The language defines
+several kinds of named @i(entities) that are declared
+by declarations.
address@hidden
+The entity's @i(name)
+is defined by the declaration, usually by a
address@hidden<address@hidden>,
+but sometimes by a @address@hidden@!literal}
+or @address@hidden@!symbol}.
+
+There are several forms of declaration. A @nt<basic_declaration>
+is a form of declaration defined as follows.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00348-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0177-1]}
address@hidden, lhs=<basic_declaration>,rhs="
+     @address@hidden| @Syn2{subtype_declaration}
+   | @address@hidden| @Syn2{number_declaration}
+   | @address@hidden| @Syn2{abstract_subprogram_declaration}
+   | @Chg{Version=[2],address@hidden@\| 
@Chg{Version=<3>,New=<@Syn2{expression_function_declaration}
+   | 
>,Old=<>}],address@hidden@Chg{Version=[2],address@hidden,address@hidden|],Old=[
+   |]}],address@hidden|]} @address@hidden,address@hidden,New=[
+   | ],address@hidden|]}],Old=[
+   | address@hidden@Chg{Version=[2],address@hidden,address@hidden|],Old=[
+   |]}],address@hidden|]} @address@hidden,address@hidden,New=[
+   | ],address@hidden|]}],Old=[
+   | address@hidden"}
+
address@hidden<defining_identifier>,rhs="@Syn2{identifier}"}
address@hidden
+
address@hidden
address@hidden<Declaration>,
+  Text=<A @i(declaration) is a language construct that associates a name
+with (a view of) an entity.
address@hidden(explicit declaration)
address@hidden(implicit declaration)
+A declaration may appear explicitly in the program
+text (an @i(explicit) declaration), or may be supposed to
+occur at a given place in the text as a
+consequence of the semantics of another construct (an @i(implicit)
+declaration).>}
address@hidden
+  An implicit declaration generally declares
+  a predefined or inherited operation associated with the definition
+  of a type. This term is
+  used primarily when allowing explicit declarations to override
+  implicit declarations, as part of a type declaration.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0255-1],ARef=[AI05-0277-1]}
address@hidden
+Each of the following is defined to be a declaration:
+any @address@hidden;
+an @address@hidden@!specification};
+a @address@hidden;
+a @address@hidden;
+a @address@hidden@!specification};@Chg{Version=[3],New=[
+an @address@hidden;],Old=[]}
+a @address@hidden;
+a @address@hidden;@Chg{Version=[3],New=[
+an @address@hidden@address@hidden;],Old=[]}
+an @address@hidden;
+an @address@hidden@!specification};
+a @address@hidden@!specification};
+a @address@hidden@address@hidden@Chg{Version=[3],New=[],address@hidden,New=[
+In addition, an @nt{extended_return_statement} is a declaration of its
address@hidden,Old=[]}]}
address@hidden(Discussion)
+  This list (when @nt<basic_declaration> is expanded out)
+  contains all syntactic categories that end in "_declaration"
+  or "_specification", except for program unit _specifications.
+  Moreover, it contains @nt{subprogram_body}.
+  A @nt{subprogram_body} is a declaration,
+  whether or not it completes a previous declaration.
+  This is a bit strange, @nt{subprogram_body} is not part of the syntax
+  of @nt{basic_declaration} or @nt{library_unit_declaration}.
+  A renaming-as-body is considered a declaration.
+  An @nt{accept_statement} is not considered a declaration.
+  Completions are sometimes declarations, and sometimes not.
address@hidden(Discussion)
+
address@hidden(view)@Defn(definition)
+All declarations contain a @i(definition) for a @i(view) of an entity.
+A view consists of an identification of the entity
+(the entity @i(of) the view),
+plus view-specific characteristics that affect the use
+of the entity through that view (such as mode of access to an object,
+formal parameter names and defaults for a subprogram, or visibility to
+components of a type).
+In most cases, a declaration also contains the definition for the
+entity itself (a @nt(renaming_declaration) is an example of a declaration
+that does not define a new entity,
+but instead defines a view of an existing entity
+(see @RefSecNum(Renaming Declarations))).
+
address@hidden,Kind=[Revised],Term=<View>,
+Text=<@Chg{Version=[2],New=[A view of an entity reveals some or all of the
+properties of the entity. A single entity may have multiple views.],
+Old=[(See @b[Definition].)]}>}
address@hidden
+  Most declarations define a view (of some entity) whose
+  view-specific characteristics are unchanging for the
+  life of the view. However, subtypes are somewhat unusual
+  in that they inherit characteristics from whatever view
+  of their type is currently visible. Hence, a subtype is not a
+  @i(view) of a type; it is more of an indirect reference.
+  By contrast, a private type provides a single, unchanging (partial)
+  view of its full type.
address@hidden
+
address@hidden,Kind=[Deleted],Term=<Definition>,
+  Text=<@ChgDeleted{Version=[2],address@hidden(view)
+All declarations contain a @i(definition) for a @i(view) of an entity.
+A view consists of an identification of the entity
+(the entity @i(of) the view),
+plus view-specific characteristics that affect the use
+of the entity through that view (such as mode of access to an object,
+formal parameter names and defaults for a subprogram, or visibility to
+components of a type).
+In most cases, a declaration also contains the definition for the
+entity itself (a @nt(renaming_declaration) is an example of a declaration
+that does not define a new entity,
+but instead defines a view of an existing entity
+(see @RefSecNum(Renaming Declarations))).]}>}
+
address@hidden,Kind=[Added],ARef=[AI05-0080-1]}
address@hidden,Text=[When it is clear from context, the term @i<object>
+is used in place of @i<view of an object>. Similarly, the terms @i<type> and
address@hidden<subtype> are used in place of @i<view of a type> and @i<view of 
a subtype>,
address@hidden,Sec=[of an object (implied)address@hidden,
+Sec=[of a type (implied)address@hidden,Sec=[of a subtype (implied)]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Rules interpreted at compile time generally
+  refer to views of entities, rather than the entities themselves. This is
+  necessary to preserve privacy; characteristics that are not visible should
+  not be used in compile-time rules. Thus, @StaticSemTitle and
+  @LegalityTitle generally implicitly have @ldquote@;view address@hidden
+  @LegalityTitle that need to look into the private part
+  are the exception to this interpretation.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[On the other hand, run-time rules can work
+  either way, so @ldquote@;view address@hidden should not be assumed
+  in @RunTimeTitle rules.]}
address@hidden
+
address@hidden, Sec=(informal definition)}
+For each declaration, the language rules define a certain
+region of text called the @i(scope) of the declaration
+(see @RefSecNum(Scope of Declarations)). Most declarations
+associate an @nt<identifier>
+with a declared entity. Within its scope,
+and only there, there are places where it is possible to use the
address@hidden<identifier> to refer to the declaration, the view it defines,
+and the associated entity; these places are defined by
+the visibility rules (see @RefSecNum(Visibility)).
address@hidden, Sec={of (a view of) an entity}}
+At such places
+the @nt<identifier> is said to be a @i(name) of the entity (the
address@hidden<direct_name> or @nt<selector_name>);
address@hidden, Sec={informal definition}}
+the name is said to @i(denote) the declaration,
+the view, and the associated entity
+(see @RefSecNum{The Context of Overload Resolution}).
address@hidden
+The declaration is said
+to @i(declare) the name, the view, and in most cases, the
+entity itself.
+
+As an alternative to an @nt<identifier>,
+an enumeration literal can be declared with a @nt<character_literal>
+as its name (see @RefSecNum(Enumeration Types)),
+and a function can be declared with an @nt<operator_symbol>
+as its name (see @RefSecNum(Subprogram Declarations)).
+
address@hidden name}
+The syntax rules use the terms @nt<defining_identifier>,
address@hidden<address@hidden@!literal>, and @nt<address@hidden@!symbol>
+for the defining occurrence of a name; these are collectively
+called @i(defining names).
address@hidden name}
+The terms @nt<direct_name> and
address@hidden<selector_name> are used for usage occurrences of 
@nt<identifier>s,
address@hidden<character_literal>s, and @nt<operator_symbol>s. These
+are collectively called @i(usage names).
address@hidden(Honest)
+The terms @nt<identifier>,
address@hidden<character_literal>, and @nt<operator_symbol> are used directly
+in contexts where the normal visibility rules do not
+apply (such as the @nt<identifier> that appears after the @key(end) of
+a @nt<task_body>). Analogous conventions apply to the use of @nt<designator>,
+which is the collective term for @nt<identifier> and @nt<operator_symbol>.
address@hidden(Honest)
+
address@hidden
+
address@hidden
address@hidden
+The process by which a construct achieves its run-time effect is
+called @i(execution).
address@hidden
address@hidden
+This process is also called @i(elaboration) for declarations
+and @i(evaluation) for expressions.
+One of the terms execution, elaboration, or evaluation is defined
+by this International Standard for each construct that has a run-time effect.
address@hidden<Execution>,
+  Text=<The process by which a construct achieves its run-time effect is
+  called @i(execution).
+  @Defn(elaboration)
+  @Defn(evaluation)
+  Execution of a declaration is also called @i(elaboration).
+  Execution of an expression is also called @i(evaluation).>}
address@hidden
+The term elaboration is also used for the execution of certain
+constructs that are not declarations,
+and the term evaluation is used for the execution of certain
+constructs that are not expressions.
+For example, @nt{subtype_indication}s are elaborated,
+and @nt{range}s are evaluated.
+
+For bodies, execution and elaboration are both explicitly defined.
+When we refer specifically to the execution of a body,
+we mean the explicit definition of execution for that kind of body,
+not its elaboration.
address@hidden
address@hidden(Discussion)
+Technically, "the execution of a declaration" and "the
+elaboration of a declaration" are synonymous.
+We use the term "elaboration" of a construct when we know the
+construct is elaborable.
+When we are talking about more arbitrary constructs,
+we use the term "execution".
+For example, we use the term "erroneous execution",
+to refer to any erroneous execution, including
+erroneous elaboration or evaluation.
+
+When we explicitly define evaluation or elaboration for a construct,
+we are implicitly defining execution of that construct.
+
+We also use the term "execution" for things like @nt{statement}s,
+which are executable, but neither elaborable nor evaluable.
+We considered using the term "execution" only for nonelaborable,
+nonevaluable constructs, and defining the term "action" to mean what
+we have defined "execution" to mean.
+We rejected this idea because we thought three terms that mean the
+same thing was enough @em four would be overkill.
+Thus, the term "action" is used only informally in the standard
+(except where it is defined as part of a larger term,
+such as "protected action").
address@hidden(Discussion)
address@hidden,Kind=[Added],Term=<Elaboration>,
+Text=<@ChgAdded{Version=[2],Text=[The process by which a declaration achieves
+its run-time effect is called elaboration. Elaboration is one of the forms of
+execution.]}>}
address@hidden,Kind=[Added],Term=<Evaluation>,
+Text=<@ChgAdded{Version=[2],Text=[The process by which an expression achieves
+its run-time effect is called evaluation. Evaluation is one of the forms of
+execution.]}>}
address@hidden
address@hidden
+A construct is @i(elaborable) if elaboration is defined for it.
address@hidden
+A construct is @i(evaluable) if evaluation is defined for it.
address@hidden
+A construct is @i(executable) if execution is defined for it.
address@hidden
address@hidden(Discussion)
+  Don't confuse @lquotes@;address@hidden@; with @lquotes@;address@hidden@; 
(defined
+  in @RefSecNum(Elaboration Control)).
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+  Evaluation of an evaluable construct produces a result that is
+  either a value, a denotation, or a range.
+  The following are evaluable:
+  expression; @nt{name}
+  @nt{prefix}; @nt{range};
+  @Chg{Version=[2],address@hidden,address@hidden;
+  and possibly @nt{discrete_range}.
+  The last one is curious @em RM83 uses the term @lquotes@;evaluation of a
+  @nt{discrete_range},@rquotes@; but never defines it.
+  One might presume that the evaluation of a @nt{discrete_range}
+  consists of the evaluation of the @nt{range} or the
+  @nt{subtype_indication}, depending on what it is.
+  But @nt{subtype_indication}s are not evaluated; they are elaborated.
+
+  Intuitively, an @i(executable) construct is one that has
+  a defined run-time effect (which may be null). Since execution
+  includes elaboration and evaluation as special cases, all
+  elaborable and all evaluable constructs
+  are also executable. Hence, most constructs in Ada are executable.
+  An important exception is that the constructs inside a generic unit are
+  not executable directly, but rather are used as a template for
+  (generally) executable constructs in instances of the generic.
address@hidden(Discussion)
address@hidden
+
address@hidden
address@hidden
+At compile time, the declaration of an entity @i(declares) the entity.
address@hidden
+At run time, the elaboration of the declaration @i(creates) the entity.
address@hidden
+Syntactic categories for declarations are named either
address@hidden(entity_)@ntf<declaration> (if they include a trailing semicolon)
+or @i(entity_)@ntf<specification> (if not).
+
address@hidden
+The various kinds of named entities that can be declared are as
+follows: an object (including components and parameters), a named number,
+a type (the name always refers to its first subtype), a subtype,
+a subprogram (including enumeration literals and operators), a single entry,
+an entry family, a package, a protected or task unit (which corresponds
+to either a type or a single object), an exception,
+a generic unit, a label,
+and the name of a statement.
+
+Identifiers are also associated with names of pragmas, arguments to
+pragmas, and with attributes, but these are not user-definable.
address@hidden
address@hidden
+
address@hidden
+The syntax rule for @nt{defining_identifier} is new.
+It is used for the defining occurrence of an @nt{identifier}.
+Usage occurrences use the @nt{direct_name} or @nt{selector_name}
+syntactic categories.
address@hidden@;Each occurrence of an @nt{identifier} (or @ntf{simple_name}), 
@nt{character_literal}, or
address@hidden in the Ada 83 syntax rules is handled as follows in Ada
+95:
address@hidden
+It becomes a @nt{defining_identifier}, @nt{defining_character_literal}, or
address@hidden (or some syntactic category composed of these),
+to indicate a defining occurrence;
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+It becomes a @nt{direct_name}, in usage occurrences where
+the usage is required (in @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden Rules}) to be directly visible;
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+It becomes a @nt{selector_name}, in usage occurrences
+where the usage is required (in
address@hidden,New=[Clause],Old=[Section]} @RefSecNum{Visibility Rules})
+to be visible but not necessarily directly visible;
+
+It remains an @nt{identifier}, @nt{character_literal}, or @nt{operator_symbol},
+in cases where the visibility rules do not apply
+(such as the @nt{designator} that appears after the
address@hidden of a @nt{subprogram_body}).
address@hidden
+
+For declarations that come in @lquotes@;two address@hidden@;
+(program unit declaration plus body, private or
+incomplete type plus full type, deferred constant plus full constant),
+we consider both to be defining occurrences.
+Thus, for example, the syntax for @nt{package_body} uses
address@hidden after the reserved word @key{body},
+as opposed to @nt{direct_name}.
+
+The defining occurrence of a statement name is in
+its implicit declaration, not where it appears in the program text.
+Considering the statement name itself to be the defining occurrence would
+complicate the visibility rules.
+
+The phrase @lquotes@;visible by address@hidden@;
+is not used in Ada 95. It is subsumed by simply @lquotes@;address@hidden@; and
+the Name Resolution Rules for @nt<selector_name>s.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+(Note that in Ada 95, a declaration is visible at all
+places where one could have used a @nt{selector_name},
+not just at places where a @nt{selector_name} was actually used.
+Thus, the places where a declaration is directly visible are a
+subset of the places where it is visible.
+See @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden Rules} for details.)
+
+We use the term @lquotes@;address@hidden@; to cover @ntf<_specification>s that 
declare
+(views of) objects, such as @nt<parameter_specification>s. In Ada 83,
+these are referred to as a @lquotes@;form of declaration,@rquotes@; but it is 
not
+entirely clear that they are considered simply @lquotes@;address@hidden@;
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+RM83 contains an incomplete definition of "elaborated" in this
address@hidden,New=[subclause],Old=[clause]}:
+it defines "elaborated" for declarations,
address@hidden, @nt{declarative_item}s
+and @nt{compilation_unit}s,
+but "elaboration" is defined elsewhere for various other constructs.
+To make matters worse, Ada 95 has a different set of elaborable
+constructs.
+Instead of correcting the list, it is more maintainable to
+refer to the term "elaborable," which is defined in a distributed
+manner.
+
+RM83 uses the term @lquotes@;has no other address@hidden@; to describe an 
elaboration that
+doesn't do anything except change the state from not-yet-elaborated to
+elaborated. This was a confusing wording, because the answer to 
@lquotes@;other than
address@hidden@; was to be found many pages away.
+In Ada 95, we change this wording to @lquotes@;has no address@hidden@; (for 
things that truly
+do nothing at run time), and @lquotes@;has no effect other than to establish 
that
+so-and-so can happen without failing the
address@hidden@; (for things where it matters).
+
+We make it clearer that the term "execution" covers elaboration and
+evaluation as special cases.
+This was implied in RM83.
+For example, "erroneous execution" can include any execution,
+and RM83-9.4(3) has,
+"The task designated by any other task object depends on the master
+whose execution creates the task object;"
+the elaboration of the master's @nt{declarative_part} is doing
+the task creation.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],Text=[Added @nt{extended_return_statement} to
+  the list of declarations.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00348-01]}
+  @ChgAdded{Version=[2],Text=[Added null procedures
+  (see @RefSecNum{Null Procedures}) to the syntax.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0177-1]}
+  @ChgAdded{Version=[3],Text=[Added expression functions
+  (see @RefSecNum{Expression Functions}) to the syntax.]}
address@hidden
+
+
+
address@hidden and Subtypes}
+
address@hidden
address@hidden
address@hidden operation}
+A @i(type) is characterized by a set of values,
+and a set of @i(primitive operations)
+which implement the fundamental aspects of its semantics.
address@hidden
+An @i(object) of a given type is a run-time entity that contains (has)
+a value of the type.
address@hidden,Kind=[Revised],Term=<Type>,
+  Text=<Each object has a type.
+  A @i(type) has an associated set of values, and a set of @i(primitive
+  operations) which implement the fundamental aspects of its semantics.
+  Types are grouped into @Chg{Version=[2],address@hidden(categories)],
+  address@hidden(classes)]}.
+  @Chg{Version=[2],New=[Most language-defined
+  categories of types are also @i<classes> of types],Old=[The types of a
+  given class share a set of primitive operations.
+  @Defn(closed under derivation) Classes are closed under derivation;
+  that is, if a type is in a class, then all of its derivatives
+  are in that class]}.>}
address@hidden,Kind=[Revised],Term=<Subtype>,
+  Text=<A subtype is a type together with @Chg{Version=[3],New=[optional
+  constraints, null exclusions, and predicates],
+  Old=[a address@hidden,New=[ or null exclusion],Old=[]}]},
+  which @Chg{Version=[3],New=[constrain],Old=[constrains]}
+  the values of the subtype to satisfy @Chg{Version=[3],New=[],Old=[a ]}certain
+  @Chg{Version=[3],New=[conditions],Old=[condition]}. The values of a subtype
+  are a subset of the values of its type.>}
+
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
address@hidden,address@hidden, Sec=(of types)}],
address@hidden, Sec=(of types)}
+Types are grouped into @Chg{Version=[2],address@hidden(categories)],
address@hidden(classes)]} of address@hidden,New=[],Old=[, reflecting the
+similarity of their values and primitive operations]}.
address@hidden class], Sec=(of types)}
+There exist several @i(language-defined @Chg{Version=[2],New=[categories],
+Old=[classes]}) of types (see NOTES below)@Chg{Version=[2],New=[, reflecting
+the similarity of their values and primitive operations],address@hidden,
address@hidden category], Sec=(of types)} @Redundant[Most
+categories of types form @i(classes) of types.]],Old=[]}
address@hidden type}
address@hidden(Elementary) types are those whose values are logically 
indivisible;
address@hidden type}
address@hidden
address@hidden(composite) types are those whose values are composed
+of @i(component) values.
address@hidden,See=(composite type)}
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[The formal definition of @i<category> and
+  @i<class> is found in @RefSecNum{Derived Types and Classes}.]}
address@hidden
address@hidden<The following ought to have the Term be:
address@hidden,New=[ (of types)],Old=[]}
+but that doesn't index properly and it is too much work to fix. See if
+anyone complains.>
address@hidden,Kind=[Revised],Term=<Class (of types)>,
+  Text=<@Defn(closed under derivation)
+  A class is a set of types that is
+  closed under derivation,
+  which means that if a given type is in the class,
+  then all types derived from that type are also in the class.
+  The set of types of a class share common properties,
+  such as their primitive operations.>}
address@hidden,Kind=[Added],Term=<Category (of types)>,
+  Text=<@ChgAdded{Version=[2],Text=[A category of types is a set of types with
+  one or more common properties, such as primitive operations. A
+  category of types that is closed under derivation is also known as
+  a @i<class>.]}>}
address@hidden<Elementary type>,
+  Text=<An elementary type does not have components.>}
address@hidden,Kind=[Revised],Term=<Composite type>,
+  Text=<A composite type @Chg{Version=[2],New=[may have],Old=[has]} 
components.>}
address@hidden<Scalar type>,
+  Text=<A scalar type is either a discrete type or a real type.>}
address@hidden<Access type>,
+  Text=<An access type has values that designate aliased
+  objects.
+  Access types correspond to @lquotes@;pointer address@hidden@;
+  or @lquotes@;reference address@hidden@; in some other languages.>}
address@hidden<Discrete type>,
+  Text=<A discrete type is either an integer type or an enumeration
+  type.
+  Discrete types may be used, for example, in @nt(case_statement)s
+  and as array indices.>}
address@hidden<Real type>,
+  Text=<A real type has values that are approximations
+  of the real numbers.
+  Floating point and fixed point types are real types.>}
address@hidden<Integer type>,
+  Text=<Integer types comprise the signed integer types
+  and the modular types.
+  A signed integer type has a base range that includes both
+  positive and negative numbers,
+  and has operations that may raise an exception when the result
+  is outside the base range.
+  A modular type has a base range whose lower bound is zero,
+  and has operations with @lquotes@;address@hidden@; semantics.
+  Modular types subsume what are called @lquotes@;unsigned address@hidden@;
+  in some other languages.>}
address@hidden<Enumeration type>,
+  Text=<An enumeration type is defined by an enumeration of its values,
+  which may be named by identifiers or character
+  literals.>}
address@hidden<Character type>,
+  Text=<A character type is an enumeration type whose values
+  include characters.>}
address@hidden<Record type>,
+  Text=<A record type is a composite type consisting of zero or more
+  named components, possibly of different types.>}
address@hidden<Record extension>,
+  Text=<A record extension is a type that extends another type by adding
+  additional components.>}
address@hidden<Array type>,
+  Text=<An array type is a composite type whose components are all of
+  the same type. Components are selected by indexing.>}
address@hidden,Kind=[Revised],Term=<Task type>,
+  Text=<A task type is a composite type @Chg{Version=[2],New=[used to
+  represent], Old=[whose values are tasks, which are]} active entities
+  @Chg{Version=[2],New=[which],Old=[that may]} execute concurrently
+  @Chg{Version=[2],New=[and which can communicate via queued task entries],
+  Old=[with other tasks]}.
+  The top-level task of a partition is called the environment task.>}
address@hidden,Kind=[Revised],Term=<Protected type>,
+  Text=<A protected type is a composite type whose components are
+  @Chg{Version=[2],New=[accessible only
+  through one of its protected operations which synchronize],
+  Old=[protected from]} concurrent access by multiple tasks.>}
address@hidden,Kind=[Revised],Term=<Private type>,
+  Text=<A private type @Chg{Version=[2],New=[gives a],Old=[is a partial]} view
+    of a type @Chg{Version=[2],New=[that reveals only some of its properties.
+    The remaining properties are provided by the],Old=[whose]} full view
+    @Chg{Version=[2],New=[given elsewhere. Private types can be used for
+    defining abstractions that hide unnecessary details],Old=[is hidden]} from
+    @Chg{Version=[2],New=[their],Old=[its]} clients.>address@hidden was changed
+    to parallel "incomplete type"}
address@hidden,Kind=[Revised],Term=<Private extension>,
+  Text=<A private extension is @Chg{Version=[2],New=[a type that extends
+  another type, with the additional properties],Old=[like a record extension,
+  except that the components of the extension part
+  are]} hidden from its clients.>}
+
address@hidden,Kind=[AddedNormal],Term=<Incomplete type>,
+  Text=<@ChgAdded{Version=[2],Text=[An incomplete type gives a view of a type
+  that reveals only some of its properties. The remaining properties are
+  provided by the full view given elsewhere. Incomplete types can be used
+  for defining recursive data structures.]}>}
+
address@hidden type}
+The elementary types are the @i(scalar) types (@i(discrete) and @i(real))
+and the @i(access) types (whose values provide access to objects or
+subprograms).
address@hidden type}
address@hidden type}
+Discrete types are either @i(integer) types or are defined by enumeration
+of their values (@i(enumeration) types).
address@hidden type}
+Real types are either @i(floating point) types
+or @i(fixed point) types.
+
address@hidden,Kind=[Revised],ARef=[AI95-00251-01],ARef=[AI95-00326-01]}
+The composite types are the @i(record) types, @i(record extensions),
address@hidden(array) types, @Chg{Version=[2],address@hidden(interface) types, 
],address@hidden(task)
+types, and @i(protected) address@hidden, New=[],
address@hidden type}
address@hidden extension}
+A @i(private) type or @i(private extension) represents a partial view
+(see @RefSecNum{Private Types and Private Extensions})
+of a type, providing support for data abstraction.
+A partial view is a composite type.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Deleted],ARef=[AI95-00442-01]}
+  @ChgDeleted{Version=[2],Text=[The set of all record types do not form a
+  class (because tagged record types can have private extensions), though
+  the set of untagged record types do.
+  In any case, what record types had in common in Ada 83 (component selection)
+  is now a property of the composite class, since all composite types
+  (other than array types) can have discriminants.
+  Similarly, the set of all private types do not form a class (because
+  tagged private types can have record extensions), though
+  the set of untagged private types do.
+  Nevertheless, the set of untagged private types is not particularly
+  @lquotes@;address@hidden@; @em more interesting is the set of
+  all nonlimited
+  types, since that is what a generic formal (nonlimited) private
+  type matches.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00326-01]}
address@hidden,address@hidden type}
address@hidden type}
address@hidden extension}
+There can be multiple views of a type with varying
+sets of operations. @Redundant[An @i(incomplete) type represents an incomplete
+view (see @RefSecNum{Incomplete Type Declarations}) of a type with a
+very restricted usage, providing support for recursive data structures. A
address@hidden(private) type or @i(private extension) represents a partial view
+(see @RefSecNum{Private Types and Private Extensions}) of a
+type, providing support for data abstraction. The full view
+(see @RefSecNum{Type Declarations}) of a
+type represents its complete definition.] An incomplete or partial view is
+considered a composite address@hidden, even if the full view is not].]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[The real definitions of the views are in the
+referenced @Chg{Version=[3],New=[subclauses],Old=[clauses]}.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00326-01]}
address@hidden
+Certain composite types (address@hidden,New=[],Old=[ partial]} views
+thereof) have special
+components called @i(discriminants) whose values affect the
+presence, constraints, or initialization of other components.
+Discriminants can be thought of as parameters of the type.
+
address@hidden,Kind=[Revised],ARef=[AI95-00366-01]}
address@hidden
+The term @i(subcomponent) is used
+in this International Standard in place of the term component
+to indicate either a component, or a component of another
+subcomponent. Where other subcomponents
+are excluded, the term component is used instead.
address@hidden, Sec=(of an object or value)}
+Similarly, a @i(part) of an object or value is used to mean
+the whole object or value, or any set of its address@hidden,
+New=[ The terms component, subcomponent, and part are also applied to a type
+meaning the component, subcomponent, or part of objects and values of the
address@hidden, Sec=(of a type)address@hidden, Sec=(of a type)}],Old=[]}
address@hidden
+  The definition of @lquotes@;address@hidden@; here is designed to simplify 
rules
+  elsewhere. By design, the intuitive meaning of
+  @lquotes@;address@hidden@; will convey the correct result to the casual 
reader,
+  while this formalistic definition will answer the concern of
+  the compiler-writer.
+
+  We use the term @lquotes@;address@hidden@; when talking about the parent 
part,
+  ancestor part, or extension part of a type extension.
+  In contexts such as these, the part might represent an empty
+  set of subcomponents (e.g. in a null record extension, or a
+  nonnull extension of a null record).
+  We also use @lquotes@;address@hidden@; when specifying rules such as
+  those that apply to an object
+  with a @lquotes@;controlled address@hidden@; meaning that it applies if the
+  object as a whole is controlled, or any subcomponent is.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01]}
address@hidden
+The set of possible values for an object of a given type can be
+subjected to a condition that is called a @i(constraint)
address@hidden address@hidden,Sec=[null]}
+(the case
+of a @i(null constraint) that specifies no restriction is also
+included)@Redundant[;
+the rules for which values satisfy a given kind of constraint
+are given in @RefSecNum(Scalar Types) for @nt<range_constraint>s,
address@hidden(Index Constraints and Discrete Ranges)
+for @nt<index_constraint>s, and
address@hidden(Discriminant Constraints) for
address@hidden<discriminant_constraint>address@hidden,New=[ The set of possible 
values
+for an object of an access type can also be subjected to a condition that
+excludes the null value (see @RefSecNum{Access Types}).],Old=[]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01],ARef=[AI95-00415-01]}
address@hidden
+A @i(subtype) of a given type is a combination of the type,
+a constraint on values of the type, and certain
+attributes specific to the subtype.
+The given type is called the @Chg{Version=[2],address@hidden(type of the 
subtype)],
+Old=[type @i(of) the address@hidden,address@hidden, Sec=(of a subtype)}
address@hidden, Sec=(type of)}],Old=[]}
+Similarly, the associated constraint is
+called the @Chg{Version=[2],address@hidden(constraint of the subtype)],
+Old=[constraint @i(of) the address@hidden,address@hidden, Sec=(of a subtype)}
address@hidden, Sec=(constraint of)}],Old=[]} The set of
+values of a subtype consists of the values of its type
+that satisfy its address@hidden,New=[ and any exclusion of the
+null value],
+Old=[]}.
address@hidden, Sec=(to a subtype)}
+Such values @i(belong) to the address@hidden,address@hidden, Sec=(belonging to 
a subtype)}
address@hidden, Sec=(values belonging to)}],Old=[]}
address@hidden
+  We make a strong distinction between a type and its
+  subtypes.
+  In particular, a type is @i(not) a subtype of itself.
+  There is no constraint associated with a type (not even a null one),
+  and type-related attributes are distinct from subtype-specific attributes.
address@hidden
address@hidden
+  We no longer use the term "base type."
+  All types were "base types" anyway in Ada 83, so the term was redundant,
+  and occasionally confusing. In the RM95 we
+  say simply "the type @i(of) the subtype" instead of "the base type
+  of the subtype."
address@hidden
address@hidden
+  The value subset for a subtype might be empty, and need
+  not be a proper subset.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
+Any name of a @Chg{Version=[2],New=[category],Old=[class]} of types (such as
address@hidden@;address@hidden@;@Chg{Version=[2],New=[, ],Old=[ or]}
address@hidden@;address@hidden@;@Chg{Version=[2],New=[, or],Old=[), or other 
category of
+types (such as]} @lquotes@;address@hidden@;@Chg{Version=[2],New=[],
+Old=[ or @lquotes@;address@hidden@;]})
+is also used to qualify its subtypes, as well as its objects, values,
+declarations, and definitions, such as an @lquotes@;integer type
address@hidden@; or an @lquotes@;integer address@hidden@; In addition, if
+a term such as @lquotes@;parent address@hidden@; or @lquotes@;index
address@hidden@; is defined, then the corresponding term for the type of the
+subtype is @lquotes@;parent address@hidden@; or @lquotes@;index 
address@hidden@;
address@hidden
address@hidden
+  We use these corresponding terms without explicitly defining them,
+  when the meaning is obvious.
address@hidden
+
address@hidden
address@hidden
address@hidden, Sec=(subtype)}
address@hidden, Sec=(subtype)}
+A subtype is called an @i(unconstrained) subtype if its
+type has unknown discriminants,
+or if its type allows range, index, or discriminant constraints,
+but the subtype does not impose such a constraint;
+otherwise, the subtype is called a @i(constrained) subtype
+(since it has no unconstrained characteristics).
address@hidden
+  In an earlier version of Ada 9X,
+  "constrained" meant "has a nonnull
+  constraint." However, we changed to this definition
+  since we kept having to special
+  case composite non-array/nondiscriminated types. It also corresponds
+  better to the (now obsolescent) attribute 'Constrained.
+
+  For scalar types, @lquotes@;address@hidden@; means @lquotes@;has a nonnull
+  address@hidden@;.
+  For composite types, in implementation terms, @lquotes@;address@hidden@; 
means
+  that the size of all objects of the subtype is the same, assuming a
+  typical implementation model.
+
+  Class-wide subtypes are always unconstrained.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
address@hidden,New=[Any set of types can be called a
address@hidden@;address@hidden@; of types, and any],Old=[Any]}
+set of types that is closed under derivation
+(see @RefSecNum(Derived Types and Classes)) can be called
+a @lquotes@;address@hidden@; of types. However, only certain
address@hidden,New=[categories and ],Old=[]}classes are used in the
+description of the rules of the language @em generally those
+that have their own particular set of primitive operations
+(see @RefSecNum(Classification of Operations)), or that
+correspond to a set of types that are matched by a given
+kind of generic formal type (see @RefSecNum(Formal Types)).
address@hidden class}
+The following are examples of @lquotes@;address@hidden@; @i(language-defined 
classes):
+elementary, scalar, discrete, enumeration, character, boolean,
+integer, signed integer, modular, real, floating point,
+fixed point, ordinary fixed point, decimal fixed point,
+numeric, access, access-to-object, access-to-subprogram,
+composite, array, string, (untagged) record, tagged, task, protected,
+nonlimited. Special syntax is provided to define types in
+each of these address@hidden,New=[ In addition to these
+classes, the following are examples of @lquotes@;address@hidden@;
address@hidden(language-defined categories): @PDefn{language-defined categories}
+abstract, incomplete, interface, limited, private, record.],Old=[]}
address@hidden
address@hidden
+A @i(value) is a run-time entity with a given type which can be
+assigned to an object of an appropriate subtype of the type.
address@hidden
+An @i(operation) is a program entity that operates on zero or more
+operands to produce an effect, or yield a result, or both.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00442-01]}
+  Note that a type's @Chg{Version=[2],New=[category (and 
],address@hidden,New=[)],Old=[]}
+  depends on the place of the reference @em a
+  private type is composite outside and possibly elementary inside.
+  It's really the @i{view} that is elementary or composite.
+  Note that although private types are composite,
+  there are some properties that
+  depend on the corresponding full view @em for example,
+  parameter passing modes, and
+  the constraint checks that apply in various places.
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00345-01],ARef=[AI95-00442-01]}
+  @Chg{Version=[2],New=[Every property of types forms a category, but not],
+  Old=[Not]} every property of types represents a class.
+  For example, the set of all abstract types does not form a class,
+  because this set is not closed under address@hidden,New=[
+  Similarly, the set of all interface types does not form a class.],Old=[]}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00442-01]}
+  The set of limited types @Chg{Version=[2],New=[does not form a class
+  (since nonlimited types can inherit from limited interfaces), but the
+  set of nonlimited types does. The set of tagged record types and the set
+  of tagged private types do not form a class (because each of them can
+  be extended to create a type of the other category); that implies that
+  the set of record types and the set of private types also do not form a
+  class (even though untagged record types and untagged private types do
+  form a class). In all of these cases, we can talk about the category
+  of the type; for instance, we can talk about the @lquotes@;category
+  of limited address@hidden,
+  Old=[forms a class in the sense that it is closed
+  under derivation, but the more interesting
+  class, from the point of generic formal type matching, is the
+  set of all types, limited and nonlimited, since that is what
+  matches a generic formal @lquotes@;address@hidden@; private type.
+  Note also that a limited type can @lquotes@;become address@hidden@; under
+  certain circumstances, which
+  makes @lquotes@;address@hidden@; somewhat problematic as a class of types]}.
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[Normatively, the @i<language-defined classes>
+  are those that are defined to be inherited on derivation by
+  @RefSecNum{Derived Types and Classes}; other properties either aren't
+  interesting or form categories, not classes.]}
address@hidden
+
address@hidden@;@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00442-01]}
+These language-defined @Chg{Version=[2],New=[categories],Old=[classes]} are
+organized like this:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden
address@hidden, 6, 9, 12, 15, 18, 21}
+all types
address@hidden
address@hidden@\scalar
address@hidden@address@hidden
address@hidden@address@hidden@\enumeration
address@hidden@address@hidden@address@hidden
address@hidden@address@hidden@address@hidden
address@hidden@address@hidden@address@hidden enumeration
address@hidden@address@hidden@\integer
address@hidden@address@hidden@address@hidden integer
address@hidden@address@hidden@address@hidden integer
address@hidden@address@hidden
address@hidden@address@hidden@\floating point
address@hidden@address@hidden@\fixed point
address@hidden@address@hidden@address@hidden fixed point
address@hidden@address@hidden@address@hidden fixed point
address@hidden@\access
address@hidden@address@hidden
address@hidden@address@hidden
address@hidden@Chg{Version=[2],New=[
address@hidden@\untagged],Old=[]}
address@hidden,address@hidden,address@hidden@\array
address@hidden,address@hidden,address@hidden@address@hidden
address@hidden,address@hidden,address@hidden@address@hidden array
address@hidden@address@hidden,address@hidden,Old=[untagged 
address@hidden,New=[],Old=[
address@hidden@\tagged]}
address@hidden,address@hidden,address@hidden@\task
address@hidden,address@hidden,address@hidden@address@hidden,New=[
address@hidden@\tagged (including interfaces)
address@hidden@address@hidden tagged record
address@hidden@address@hidden tagged
address@hidden@address@hidden@\limited tagged record
address@hidden@address@hidden@\synchronized tagged
address@hidden@address@hidden@address@hidden task
address@hidden@address@hidden@address@hidden protected],Old=[]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00345-01],ARef=[AI95-00442-01]}
address@hidden,New=[There are other categories, such as],Old=[The classes]}
address@hidden@;address@hidden@; and
address@hidden@;@Chg{Version=[2],New=[discriminated],address@hidden@;@Chg{Version=[2],
+New=[, which],Old=[]}
+represent other @Chg{Version=[2],New=[categorization],Old=[classification]}
address@hidden,New=[, but],
+Old=[ and]} do not fit into the above strictly hierarchical picture.
address@hidden
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00345-01],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[Note that this is also true for some categories
+  mentioned in the chart. The category @lquotes@;address@hidden@; includes both
+  untagged tasks and tagged tasks. Similarly for @lquotes@;address@hidden@;,
+  @lquotes@;address@hidden@;, and @lquotes@;address@hidden@; (note that
+  limited and nonlimited are not shown for untagged composite types).]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause and its subclauses]}
+now @Chg{Version=[3],New=[precedes],Old=[precede]} the
address@hidden,New=[],Old=[clause and ]}subclauses on objects and
+named numbers, to cut down on the number of forward references.
+
+We have dropped the term "base type" in favor of simply "type" (all
+types in Ada 83 were "base types" so it wasn't clear when it was
+appropriate/necessary to say "base type"). Given a subtype S of
+a type T, we call T the "type of the subtype S."
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],Text=[Added a mention of null exclusions when we're
+  talking about constraints (these are not constraints, but they are 
similar).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Text=[Defined an interface type to be a composite
+  type.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00326-01]}
+  @ChgAdded{Version=[2],Text=[Revised the wording so that it is clear
+  that an incomplete view is similar to a partial view in terms of the
+  language.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00366-01]}
+  @ChgAdded{Version=[2],Text=[Added a definition of component of a type,
+  subcomponent of a type, and part of a type. These are commonly used in
+  the standard, but they were not previously defined.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[Reworded most of this
+  @Chg{Version=[3],New=[subclause],Old=[clause]} to use
+  category rather than class, since so many interesting properties are
+  not, strictly speaking, classes. Moreover, there was no normative
+  description of exactly which properties formed classes, and which did
+  not. The real definition of class, along with a list of properties, is now
+  in @RefSecNum{Derived Types and Classes}.]}
address@hidden
+
+
address@hidden Declarations}
+
address@hidden
+A @nt<type_declaration> declares a type and its first subtype.
address@hidden
+
address@hidden
address@hidden<type_declaration>,rhs=" @Syn2{full_type_declaration}
+   | @Syn2{incomplete_type_declaration}
+   | @Syn2{private_type_declaration}
+   | @Syn2{private_extension_declaration}"}
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<full_type_declaration>,rhs="
+     @key{type} @Syn2{defining_identifier} address@hidden @key{is} 
@address@hidden,New=<
+        address@hidden>,Old=[]};
+   | @Syn2{task_type_declaration}
+   | @Syn2{protected_type_declaration}"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00251-01]}
address@hidden, lhs=<type_definition>,rhs="
+     @address@hidden| @Syn2{integer_type_definition}
+   | @address@hidden| @Syn2{array_type_definition}
+   | @address@hidden| @Syn2{access_type_definition}
+   | @address@hidden,address@hidden| 
@Syn2{interface_type_definition}],Old=[]}"}
address@hidden
+
address@hidden
+A given type shall not have a subcomponent whose type is the given
+type itself.
address@hidden
+
address@hidden
address@hidden subtype}
+The @address@hidden of a @address@hidden denotes
+the @i(first subtype) of the type.
+The @nt<address@hidden@!part>, if any,
+defines the discriminants of the type (see @RefSec(Discriminants)).
+The remainder of the @nt<address@hidden> defines the
+remaining characteristics of (the view of) the type.
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01]}
address@hidden type}
+A type defined by a @nt<address@hidden> is a @i(named) type;
+such a type has one or more nameable subtypes.
address@hidden type}
+Certain other forms of declaration also include type
+definitions as part of the declaration for an address@hidden,New=[],
+Old=[ (including a parameter or a discriminant)]}. The type defined by such
+a declaration is @i(anonymous) @em it has no nameable subtypes.
address@hidden,Sec=(pseudo-names of anonymous types)}
+For explanatory purposes, this International Standard sometimes refers to
+an anonymous type by a pseudo-name, written in italics, and
+uses such pseudo-names at places where the syntax normally requires
+an @nt<identifier>. For a named type whose first subtype is T,
+this International Standard sometimes refers to the type of T
+as simply @lquotes@;the type address@hidden@;.
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00230-01]}
+  The only user-defined types
+  that can be anonymous in the above sense are array,
+  access, task, and protected types.
+  An anonymous array, task, or protected type
+  can be defined as part of an @nt{object_declaration}.
+  An anonymous access type can be defined as part of
+  @Chg{Version=[2],New=[numerous other constructs],Old=[a parameter or
+  discriminant specification]}.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00326-01]}
address@hidden type}
+A named type that is declared by a @nt<address@hidden>,
+or an anonymous type that is defined @Chg{Version=[2],New=[by an
address@hidden or ],Old=[]}as part of declaring an object of the type,
+is called a
address@hidden(full type)address@hidden type definition} 
@Chg{Version=[2],New=[The
+declaration of a full type also declares the @i<full view> of the
address@hidden view],Sec=(of a type)} ],Old=[]}The
address@hidden<address@hidden>, @nt<address@hidden>, @nt<address@hidden>,
+or @nt<address@hidden> that defines a full type is called
+a @i(full type definition).
address@hidden declared by other forms of @nt<address@hidden> are
+not separate types; they are partial or incomplete views
+of some full type.]
address@hidden
+  Class-wide, universal, and root numeric types are full types.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01]}
+  @ChgAdded{Version=[2],Text=[We need to mention @nt{access_definition}
+  separately, as it may occur in renames, which do not declare objects.]}
address@hidden
+
address@hidden operator}
+The definition of a type implicitly declares
+certain @i(predefined operators) that operate on the type,
+according to what classes the type belongs,
+as specified in @RefSec(Operators and Expression Evaluation).
address@hidden
+  We no longer talk about the implicit declaration of basic operations.
+  These are treated like an @nt{if_statement} @em they don't need
+  to be declared, but are still applicable to only certain classes of types.
+
address@hidden
+
address@hidden type}
+The @i{predefined types}
address@hidden(for example the types
+Boolean, Wide_Character, Integer,
address@hidden, and @i{universal_integer})]
+are the types that are defined in
address@hidden predefined library package called] address@hidden;
+this package also includes the @Redundant{(implicit)}
+declarations of their predefined operators].
address@hidden package Standard is described in
address@hidden Package Standard}.]
address@hidden
+We use the term @lquotes@;address@hidden@; to refer to entities declared in the
+visible part of Standard,
+to implicitly declared operators of a type whose semantics are defined
+by the language, to Standard itself,
+and to the @lquotes@;predefined address@hidden@;.
+We do not use this term to refer to library packages other than Standard.
+For example Text_IO is a language-defined package,
+not a predefined package,
+and Text_IO.Put_Line is not a predefined operation.
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(full_type_declaration)}
+The elaboration of a @nt{full_type_declaration} consists of the
+elaboration of the full type definition.
address@hidden, Sec=(full type definition)}
+Each elaboration of a full type definition
+creates a distinct type and its first subtype.
address@hidden
+  The creation is associated with the type @i(definition), rather than
+  the type @i(declaration), because there are types
+  that are created by full type definitions that are
+  not immediately contained within a type declaration (e.g.
+  an array object declaration, a singleton task declaration, etc.).
address@hidden
address@hidden
+  Any implicit declarations that occur immediately following the full
+  type definition are elaborated where they (implicitly) occur.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of type definitions:)
address@hidden(Example)
+(White, Red, Yellow, Green, Blue, Brown, Black)
address@hidden(range) 1 .. 72
address@hidden(array)(1 .. 10) @key(of) Integer
address@hidden(Example)
+
address@hidden
address@hidden@address@hidden(Examples of type declarations:)
address@hidden
address@hidden(Example)
address@hidden(type) Color  @key(is) (White, Red, Yellow, Green, Blue, Brown, 
Black);
address@hidden(type) Column @key(is) @key(range) 1 .. 72;
address@hidden(type) Table  @key(is) @key(array)(1 .. 10) @key(of) Integer;
address@hidden(Example)
address@hidden
+
address@hidden
+Each of the above examples declares a named type. The identifier
+given denotes the first subtype of the type. Other named subtypes of the
+type can be declared with @nt<subtype_declaration>s
+(see @RefSecNum{Subtype Declarations}). Although names do not directly
+denote types, a phrase like @lquotes@;the type address@hidden@; is sometimes 
used
+in this International Standard to refer to the type of Column, where Column 
denotes
+the first subtype of the type. For an example of the definition
+of an anonymous type, see the declaration
+of the array Color_Table in @RefSecNum{Object Declarations}; its type
+is anonymous @em it has no nameable subtypes.
address@hidden
+
address@hidden
+The syntactic category @nt{full_type_declaration} now includes task and
+protected type declarations.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+We have generalized the concept of first-named subtype (now
+called simply @lquotes@;first address@hidden@;) to cover all kinds of types, 
for uniformity
+of description elsewhere.
+RM83 defined first-named subtype in Section 13.
+We define first subtype here, because it is now a more fundamental concept.
+We renamed the term, because in Ada 95 some first subtypes have no
+name.
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00230-01]}
+We no longer elaborate @nt{discriminant_part}s, because
+there is nothing to do, and it was complex to say that you only wanted
+to elaborate it once for a private or incomplete type. This is also
+consistent with the fact that subprogram specifications are not
+elaborated (neither in Ada 83 nor in Ada 95). Note, however, that an
address@hidden<access_definition> appearing in a @nt<discriminant_part> is
address@hidden,New=[ at the @nt{full_type_declaration} (for
+a nonlimited type) or],Old=[]} when an object with such a discriminant is
address@hidden,New=[ (for a limited type)],Old=[]}.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01]}
+  @ChgAdded{Version=[2],Text=[Added wording so that anonymous access types
+  are always full types, even if they appear in renames.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Text=[Added interface types
+  (see @RefSecNum{Interface Types}) to the syntax.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00326-01]}
+  @ChgAdded{Version=[2],Text=[Added a definition of full view, so that
+  all types have a well-defined full view.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a 
@nt{full_type_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
address@hidden Declarations}
+
address@hidden
+A @nt<subtype_declaration> declares a subtype of some previously
+declared type, as defined by a @nt<subtype_indication>.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<subtype_declaration>,rhs="
+   @key{subtype} @Syn2{defining_identifier} @key{is} @address@hidden,New=<
+        address@hidden>,Old=[]};"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01]}
address@hidden<subtype_indication>,rhs=" @Chg{Version=[2],New=<address@hidden 
>,Old=<>address@hidden address@hidden"}
+
address@hidden<subtype_mark>,rhs="@address@hidden"}
address@hidden
+Note that @nt{name} includes @nt{attribute_reference};
+thus, S'Base can be used as a @nt{subtype_mark}.
address@hidden
address@hidden
+We considered changing @nt{subtype_mark} to @ntf{subtype_name}.
+However, existing users are used to the word "mark,"
+so we're keeping it.
address@hidden
+
address@hidden<constraint>,rhs="@Syn2<scalar_constraint> | 
@Syn2<composite_constraint>"}
+
address@hidden<scalar_constraint>,rhs="
+     @Syn2{range_constraint} | @Syn2{digits_constraint} | 
@Syn2{delta_constraint}"}
address@hidden<composite_constraint>,rhs="
+     @Syn2{index_constraint} | @Syn2{discriminant_constraint}"}
address@hidden
+
address@hidden
+A @nt{subtype_mark} shall resolve to denote a subtype.
address@hidden, Sec=(a type by a @nt{subtype_mark})}
+The type @i(determined by) a @nt<subtype_mark> is the
+type of the subtype denoted by the @nt{subtype_mark}.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+  Types are never directly named; all @nt{subtype_mark}s denote
+  subtypes @em possibly an unconstrained (base) subtype,
+  but never the type.
+  When we use the term @i(anonymous type) we really
+  mean a type with no @Chg{Version=[3],New=[nameable],Old=[namable]}
+  subtypes.
address@hidden
address@hidden
+
address@hidden
address@hidden@PDefn2{Term=[elaboration], Sec=(subtype_declaration)}
+The elaboration of a @nt{subtype_declaration} consists of the elaboration
+of the @nt{subtype_indication}.
address@hidden, Sec=(subtype_indication)}
+The elaboration of a @nt{subtype_indication} creates a new subtype.
+If the @nt{subtype_indication} does not include a
address@hidden<constraint>, the new subtype has the same (possibly null)
+constraint as that denoted by the @nt{subtype_mark}.
+The elaboration of a @nt{subtype_indication} that includes a
address@hidden<constraint> proceeds as follows:
address@hidden
+The @nt<constraint> is first elaborated.
+
address@hidden
+A check is then made that
+the @nt<constraint> is @i(compatible) with the
+subtype denoted by the @nt{subtype_mark}.
address@hidden
+  The checks associated with
+  constraint compatibility are all Range_Checks.
+  Discriminant_Checks and Index_Checks are associated only with
+  checks that a value satisfies a constraint.
address@hidden
address@hidden
+
+The condition imposed by a @nt<constraint> is the condition obtained
+after elaboration of the @nt<constraint>.
address@hidden, Sec=(constraint with a subtype)}
+The rules defining compatibility are given for each form of @nt<constraint>
+in the appropriate subclause. These rules are such that if a
address@hidden<constraint> is @i(compatible) with a subtype,
+then the condition imposed by the @nt<constraint> cannot
+contradict any condition already imposed by the subtype on its values.
address@hidden(Constraint_Error),Sec=(raised by failure of run-time check)}
+The exception Constraint_Error is raised if any check of
+compatibility fails.
address@hidden
+The condition imposed by a @nt<constraint> is named after it @em
+a @nt<range_constraint> imposes a range constraint, etc.
address@hidden
address@hidden
+A @nt<range_constraint> causes freezing of its type.
+Other @nt<constraint>s do not.
address@hidden
address@hidden
+
address@hidden
+A @nt<scalar_constraint> may be applied to a subtype of an appropriate
+scalar type (see @RefSecNum{Scalar Types}, @RefSecNum{Fixed Point Types},
+and @RefSecNum{Reduced Accuracy Subtypes}), even if the subtype
+is already constrained. On the other hand, a @nt<composite_constraint>
+may be applied to a composite subtype (or an access-to-composite subtype)
+only if the composite subtype is unconstrained
+(see @RefSecNum{Index Constraints and Discrete Ranges} and
address@hidden Constraints}).
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of subtype declarations:)
address@hidden(Example)
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden(subtype) Rainbow   @key(is) Color @key(range) Red .. Blue;       
 address@hidden  see @RefSecNum(Type Declarations)]
address@hidden(subtype) Red_Blue  @key(is) Rainbow;
address@hidden(subtype) Int       @key(is) Integer;
address@hidden(subtype) Small_Int @key(is) Integer @key(range) -10 .. 10;
address@hidden(subtype) Up_To_K   @key(is) Column @key(range) 1 .. K;           
 address@hidden  see @RefSecNum(Type Declarations)]
address@hidden(subtype) Square    @key(is) Matrix(1 .. 10, 1 .. 10);       
address@hidden  see @RefSecNum(Array Types)]
address@hidden(subtype) Male      @key(is) Person(Sex => M);               
address@hidden  see @RefSecNum(Incomplete Type Declarations)address@hidden,New=[
address@hidden(subtype) Binop_Ref @key(is not null) Binop_Ptr;             
address@hidden  see @RefSecNum(Access Types)]],Old=[]}
address@hidden(Example)
+
address@hidden
+
address@hidden
address@hidden with Ada 83}
+In Ada 95, all @nt<range_constraint>s cause freezing of their type.
+Hence, a type-related representation item for a scalar type has to
+precede any @nt<range_constraint>s whose type is the scalar type.
address@hidden
+
address@hidden
address@hidden allow only subtype names now, since
+types are never directly named.
+There is no need for RM83-3.3.2(3), which says a
address@hidden can denote both the type and the subtype;
+in Ada 95, you denote an unconstrained (base) subtype if you want,
+but never the type.
+
+The syntactic category @ntf{type_mark} is now called @nt{subtype_mark},
+since it always denotes a subtype.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  An optional @nt{null_exclusion} can be used in a @nt{subtype_indication}.
+  This is described in @RefSecNum{Access Types}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a 
@nt{subtype_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
+
+
address@hidden of Operations}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00416-01]}
address@hidden on a type}
+An operation @i(operates
+on a type) @i(T) if it yields a value of type @i(T), if it has an operand
+whose expected type
+(see @RefSecNum{The Context of Overload Resolution})
+is @i(T), or if it has an access address@hidden,New=[ or access result 
type],Old=[]}
+(see @RefSecNum(Subprogram Declarations))
+designating @i(T).
address@hidden operation], Sec=(of a type)}
+A predefined operator, or
+other language-defined operation
+such as assignment or a membership test, that operates
+on a type, is called
+a @i(predefined operation) of the type.
address@hidden operations], Sec=(of a type)}
+The @i(primitive operations) of a type are
+the predefined operations of the type, plus any user-defined
+primitive subprograms.
address@hidden<Primitive operations>,
+  Text=<The primitive operations of a type are the operations
+  (such as subprograms) declared together with
+  the type declaration.
+  They are inherited by other types in the same class of types.
+  For a tagged type,
+  the primitive subprograms are dispatching subprograms,
+  providing run-time polymorphism.
+  A dispatching subprogram may be called with statically
+  tagged operands, in which case the subprogram body invoked
+  is determined at compile time.
+  Alternatively, a dispatching subprogram may be called
+  using a dispatching call,
+  in which case the subprogram body invoked is determined
+  at run time.>}
address@hidden
+  Protected subprograms are not considered to be
+  @lquotes@;primitive subprograms,@rquotes@; even though they are
+  subprograms, and they are inherited by derived types.
address@hidden
address@hidden
+  We use the term
+  @lquotes@;primitive address@hidden@; in most of the rest of the manual.
+  The term @lquotes@;primitive address@hidden@; is used mostly in conceptual
+  discussions.
address@hidden
+
address@hidden@Defn2{Term=[primitive subprograms], Sec=(of a type)}
+The @i(primitive subprograms) of a
+specific type are defined as follows:
address@hidden
+  The predefined operators of the
+  type (see @RefSecNum{Operators and Expression Evaluation});
+
+  For a derived type, the inherited (see @RefSecNum{Derived Types and Classes})
+  user-defined subprograms;
+
+  For an enumeration type, the enumeration literals (which are
+  considered parameterless
+  functions @em see @RefSecNum{Enumeration Types});
+
+  For a specific type declared immediately within
+  a @nt<package_specification>,
+  any subprograms (in addition to the enumeration literals)
+  that are
+  explicitly declared immediately within the same
+  @nt<package_specification> and that operate on the type;
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0128-1]}
+  @ChgAdded{Version=[3],Text=[For a specific type with an
+  explicitly declared primitive "=" operator whose result type
+  is Boolean, the corresponding "/=" operator (see
+  @RefSecNum{Overloading of Operators});]}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00200-01]}
+  @Defn2{Term=[override], Sec=(a primitive subprogram)}
+  @Chg{Version=[2],New=[For a nonformal type, any],Old=[Any]}
+  subprograms not covered above
+  @Redundant[that are explicitly declared immediately within the same
+  declarative region as the type] and that override (see 
@RefSecNum{Visibility})
+  other implicitly declared primitive subprograms of the type.
address@hidden
address@hidden
+  In Ada 83, only subprograms
+  declared in the visible part were @lquotes@;address@hidden@; (i.e.
+  derivable). In Ada 95, mostly because of child library units,
+  we include all operations declared in the private part as well,
+  and all operations that override implicit declarations.
address@hidden
address@hidden
+  It is possible for a subprogram
+  to be primitive for more than one type, though it is illegal
+  for a subprogram to be primitive for more than one tagged type.
+  See @RefSecNum(Tagged Types and Type Extensions).
address@hidden
address@hidden(Discussion)
+  The order of the implicit declarations when there are both
+  predefined operators and inherited subprograms is described in
+  @RefSec(Derived Types and Classes).
address@hidden(Discussion)
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00200-01]}
+  @ChgAdded{Version=[2],Text=[Subprograms declared in a generic package
+  specification are never primitive for a formal type, even if they happen
+  to override an operation of the formal type. This includes formal
+  subprograms, which are never primitive operations (that's true even
+  for an abstract formal subprogram).]}
address@hidden
+
address@hidden operator], Sec=(of a type)}
+A primitive subprogram whose designator is an @nt<operator_symbol>
+is called a @i(primitive operator).
+
address@hidden
+
address@hidden
address@hidden with Ada 83}
+The attribute S'Base is no longer defined for
+nonscalar subtypes. Since this was only permitted
+as the prefix of another attribute, and there are no
+interesting nonscalar attributes defined for an unconstrained
+composite or access subtype, this should not affect any
+existing programs.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The primitive subprograms (derivable subprograms) include
+subprograms declared in the private part of a package
+specification as well, and those that override implicitly declared
+subprograms, even if declared in a body.
address@hidden
+
address@hidden
+We have dropped the confusing
+term @i<operation of a type> in favor of the more useful
address@hidden<primitive operation of a type> and the phrase
address@hidden<operates on a type>.
+
+The description of S'Base has been moved to
address@hidden Types} because it is now defined only for scalar types.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00200-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that a formal subprogram that happens
+  to override a primitive operation of a formal type is not a primitive
+  operation (and thus not a dispatching operation) of the formal type.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[Added wording to include access result types
+  in the kinds of operations that operate on a type T.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0128-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> The implicitly declared 
"/="
+  for a primitive "=" operator is also primitive; this makes it eligible
+  to be made visible by a @key[use type] clause.]}
address@hidden
+
+
address@hidden,Name=[Subtype Predicates]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3],ARef=[AI05-0269-1],ARef=[AI05-0299-1]}
address@hidden,Text=[The language-defined @i{predicate aspects}
+Static_Predicate and Dynamic_Predicate may be used to define properties of
+subtypes. A @i{predicate specification} is an @nt{aspect_specification}
+for one of the two predicate
address@hidden address@hidden 
address@hidden,Sec=(predicate)address@hidden@AspectDefn{Dynamic_Predicate}
+General rules for aspects and @nt{aspect_specification}s are found in
address@hidden,New=[Clause],Old=[Section]} @RefSecNum{Representation Issues} 
(@RefSecNum{Operational and Representation Aspects}
+and @RefSecNum{Aspect Specifications} respectively).]}
address@hidden,Kind=[AddedNormal],Aspect=[Static_Predicate],
+  address@hidden,Text=[Condition that must hold true for objects of
+    a given subtype; the subtype may be static.]}]}
+
address@hidden,Kind=[AddedNormal],Aspect=[Dynamic_Predicate],
+  address@hidden,Text=[Condition that must hold true for objects of
+    a given subtype; the subtype is not static.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3]}
address@hidden,Text=[The expected type for a predicate aspect
address@hidden is any boolean
address@hidden type],address@hidden of a predicate aspect]}]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3]}
address@hidden,Type=[Leading],Text=[A predicate specification may be
+given on a @nt{type_declaration} or a @nt{subtype_declaration}, and applies
+to the declared subtype. In addition, predicate specifications apply to
+certain other subtypes:]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0071-1],ARef=[AI12-0099-1]}
+  @ChgAdded{Version=[3],Text=[For a (first) subtype defined by a
+  @Chg{Version=[4],New=[],Old=[derived ]}type declaration,
+  @Chg{Version=[4],New=[any],Old=[the]}
+  predicates of @Chg{Version=[4],New=[],Old=[the ]}parent
+  @Chg{Version=[4],New=[or],Old=[subtype and the]} progenitor subtypes apply.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[For a subtype created by a 
@nt{subtype_indication},
+  the predicate of the subtype denoted by the @nt{subtype_mark} applies.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3]}
address@hidden,Kind=[Deleted],ARef=[AI12-0071-1]}
address@hidden,address@hidden,New=[],Old=[The @i<predicate>
+of a subtype consists of all
+predicate specifications that apply, and-ed together; if no predicate
+specifications apply, the predicate is True @Redundant[(in particular, the
+predicate of a base subtype is True)address@hidden,Sec=(of a subtype)}]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0290-1]}
address@hidden,Type=[Leading],Text=[Predicate checks are defined to be
address@hidden<enabled> or @i<disabled> for a given subtype as
+follows:@Defn2{Term=[enabled],Sec=[predicate address@hidden,Sec=[predicate 
address@hidden check],Sec=[enabled]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[If a subtype is declared by
+  a @nt{type_declaration} or @nt{subtype_declaration}
+  that includes a predicate specification, then:]}
+  @begin{Itemize}
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[if performing checks is required by the
+      Static_Predicate assertion policy (see @RefSecNum{Pragmas Assert and 
Assertion_Policy})
+      and the declaration includes a Static_Predicate specification, then
+      predicate checks are enabled for the subtype;]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[if performing checks is required by the
+      Dynamic_Predicate assertion policy (see @RefSecNum{Pragmas Assert and 
Assertion_Policy})
+      and the declaration includes a Dynamic_Predicate specification, then
+      predicate checks are enabled for the subtype;]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[otherwise, predicate checks are disabled for 
the
+      address@hidden, regardless of whether predicate checking is enabled
+      for any other subtypes mentioned in the declaration];]}
+  @end{Itemize}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0099-1]}
+  @ChgAdded{Version=[3],Text=[If a subtype is defined by a
+  @Chg{Version=[4],New=[],Old=[derived ]}type declaration
+  that does not include a predicate specification, then predicate
+  checks are enabled for the subtype if and only if
+  @Chg{Version=[4],New=[any ],Old=[]}predicate checks are enabled
+  for @Chg{Version=[4],New=[],Old=[at least one of the ]}parent
+  @Chg{Version=[4],New=[or],Old=[subtype and the]} progenitor subtypes;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If a subtype is created by a
+  @nt{subtype_indication} other than in one of the previous cases, then
+  predicate checks are enabled for the subtype if and only if predicate checks
+  are enabled for the subtype denoted by the @nt{subtype_mark};]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Otherwise, predicate checks are disabled for the
+  given subtype.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[In this case, no predicate specifications can
+    apply to the subtype and so it doesn't typically matter whether predicate
+    checks are enabled. This rule does make a difference, however, when
+    determining whether predicate checks are enabled for another type when this
+    type is one of multiple progenitors. See the @ldquote@;derived type 
address@hidden
+    wording above.]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0071-1]}
+    @ChgAdded{Version=[3],Text=[Even when predicate checks are disabled,
+    a predicate @Chg{Version=[4],New=[can],Old=[cam]} affect various
+    @LegalityTitle, the results of membership
+    tests, the items in a @key[for] loop, and the result of the Valid
+    attribute.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0054-2]}
address@hidden,Text=[For a subtype with a directly-specified predicate
+aspect, the following additional language-defined aspect may be specified with
+an @nt{aspect_specification} (see @RefSecNum{Aspect Specifications}):]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden
+   This aspect shall be specified by an @nt{expression}, which
+   determines the action to be performed when a predicate check fails because a
+   directly-specified predicate aspect of the subtype evaluates to
+   False, as explained below.]}
address@hidden
address@hidden,Kind=[Added],Aspect=[Predicate_Failure],
+  InitialVersion=[4],
+  address@hidden,Text=[Action to be performed when a predicate
+  check fails.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI12-0054-2]}
address@hidden,Text=[The expected type for the Predicate_Failure
address@hidden is String.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3],ARef=[AI05-0269-1]}
address@hidden,Type=[Leading],Text=[The @nt{expression} of a
+Static_Predicate specification shall be @i<predicate-static>; that is, one of
+the following:@address@hidden,Sec=[predicate-static]}]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[a static expression;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0039-1]}
+  @ChgAdded{Version=[3],Text=[a membership test whose
+  
@Chg{Version=[4],address@hidden<tested_>@nt{simple_expression}],address@hidden
+  is the current instance, and whose @nt{membership_choice_list} meets the
+  requirements for a static membership test
+  (see @RefSecNum{Static Expressions and Static Subtypes});]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[a @nt{case_expression} whose
+  @address@hidden is the current instance,
+  and whose @address@hidden are static expressions;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[a call to a predefined equality or ordering
+  operator, where one operand is the current instance, and the other is a
+  static expression;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0262-1]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0099-1]}
+  @ChgAdded{Version=[3],Text=[a call to a predefined boolean
+  @Chg{Version=[4],New=[],Old=[logical address@hidden,New=[
+  @key[and], @key[or], @key[xor], or @key[not]],Old=[]},
+  where each operand is predicate-static;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],Text=[a short-circuit control form where both operands
+  are predicate-static; or]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[a parenthesized predicate-static 
@nt{expression}.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0262-1]}
address@hidden,Text=[A predicate shall not be specified for an incomplete
+subtype.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The expression of such a predicate could not
+  depend on the properties of the value of the type (since it doesn't have
+  any), so it is useless and we don't want to require the added complexity
+  needed to support it.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0287-1]}
address@hidden,Text=[If a predicate applies to a subtype, then that
+predicate shall not mention any other subtype to which the same predicate
+applies.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[This is intended to prevent
+  recursive predicates, which cause definitional problems for static 
predicates.
+  Inside of the predicate, the subtype name refers to the current instance of
+  the subtype, which is an object, so a direct use of the subtype name cannot 
be
+  recursive. But other subtypes naming the same type might:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] Really_Ugly @key[is private];
address@hidden
+   @key[subtype] Ugly @key[is] Really_Ugly;
+   @key[type] Really_Ugly @key[is new] Integer
+      @key[with] Static_Predicate => Really_Ugly @key[not in] Ugly; 
address@hidden Illegal!}]}
address@hidden
address@hidden
+
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3]}
address@hidden,Text=[An index subtype, @nt{discrete_range} of an
address@hidden or @nt{slice}, or a
address@hidden of a @nt{constrained_array_definition},
address@hidden, or @nt{entry_index_specification} shall not denote a
+subtype to which predicate specifications apply.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3]}
address@hidden,Text=[The @nt{prefix} of an @nt{attribute_reference}
+whose @nt{attribute_designator} is First, Last, or Range shall not denote a
+scalar subtype to which predicate specifications apply.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0297-1]}
+  @ChgAdded{Version=[3],Text=[This is to prevent confusion about whether the
+  First value is the lowest value of the subtype (which does not depend on the
+  predicate) or the lowest value of the subtype which meets the predicate.
+  (For a dynamic predicate, determining this latter value is expensive as it
+  would usually require a loop.) For a static subtype that has a static
+  predicate, the First_Valid and Last_Valid attributes (see
+  @RefSecNum{Operations of Discrete Types}) can be used instead.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3],ARef=[AI05-0262-1],ARef=[AI05-0287-1]}
address@hidden,Text=[The @nt{discrete_subtype_definition} of a
address@hidden shall not denote a
+nonstatic subtype to which predicate specifications apply or any
+subtype to which Dynamic_Predicate specifications apply.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3],ARef=[AI05-0262-1]}
address@hidden,Text=[The @nt{discrete_choice} of a
address@hidden shall not denote a nonstatic subtype to which
+predicate specifications apply.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Text=[This rule prevents noncontiguous
+  dynamically bounded array aggregates, which could be expensive to check for.
+  (Array aggregates have rules to prevent problems with static subtypes.) We
+  define this rule here so that the runtime generic body check applies.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0262-1]}
address@hidden,Text=[In addition to the places
+where @LegalityTitle normally apply (see @RefSecNum{Generic Instantiation}),
+these rules apply also in the private part of an instance of a generic
address@hidden contract issue}]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI125-0071]}
address@hidden,Text=[If any of the above @LegalityTitle is violated in an
+instance of a generic unit, Program_Error is raised at the point of the
+violation.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This is the usual way around the contract model;
+  this applies even in instance bodies. Note that errors in instance
+  specifications will be detected at compile-time by the "re-check" of the
+  specification, only errors in the body should raise Program_Error.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0071-1]}
address@hidden,Type=[Leading],Text=[To determine whether a value
address@hidden<satisfies the predicates> of a subtype @i<S>,
+the following tests are performed in the following order, until one of
+the tests fails, in which case the predicates are not satisfied and no further
+tests are performed, or all of the tests succeed, in which case the
+predicates are
+satisfied:@Defn2{Term=[satisfies the predicates],Sec=(of a 
subtype)address@hidden satisfied}]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Text=[the value is first tested to determine whether it
+  satisfies any constraints or any null exclusion of @i<S>;]}
+
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Type=[Leading],Text=[then:]}
+
address@hidden
+    @ChgRef{Version=[4],Kind=[Added]}
+    @ChgAdded{Version=[4],Text=[if @i<S> is a first subtype, the value is
+      tested to determine whether it satisfies the predicates of the parent
+      and progenitor subtypes (if any) of @i<S> (in an arbitrary order);]}
+
address@hidden
+    @ChgRef{Version=[4],Kind=[AddedNormal]}
+    @ChgAdded{Version=[4],Text=[This rule has an effect for derived types
+      (which have a parent subtype and may have progenitors) and for
+      task and protected types (which may have progentitors). Other kinds
+      of type declarations can have neither, and no test is required for
+      other first subtypes.]}
address@hidden
+
+    @ChgRef{Version=[4],Kind=[Added]}
+    @ChgAdded{Version=[4],Text=[if @i<S> is defined by a
+      @nt{subtype_indication}, the value is tested to determine whether it
+      satisfies the predicates of the subtype denoted by the @nt{subtype_mark}
+      of the @nt{subtype_indication};]}
address@hidden
+
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Text=[finally, if @i<S> is defined by a declaration to
+    which one or more predicate specifications apply, the predicates are
+    evaluated (in an arbitrary order) to test that all of them yield True for
+    the given value.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Text=[It is important to stop on the first of the above
+    steps that fails, as later steps might presume that the earlier steps had
+    succeeded.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3],ARef=[AI05-0290-1]}
address@hidden,Type=[Leading],Text=[If predicate checks are enabled for a
+given subtype, then:]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0054-2],ARef=[AI12-0071-1]}
+  @ChgAdded{Version=[3],address@hidden every subtype conversion,
+  @Chg{Version=[4],New=[],Old=[the predicate of the target subtype
+  is evaluated, and ]}a check is performed that
+  the @Chg{Version=[4],New=[operand satisfies the predicates of the target
+  subtype], Old=[predicate is True]}. This includes all parameter passing,
+  except for certain parameters passed by reference, which are covered by the
+  following rule: ] After normal completion and leaving of a subprogram,
+  for each @key[in out] or @key[out] parameter that is passed by reference,
+  @Chg{Version=[4],New=[],Old=[the predicate of the subtype of the actual is
+  evaluated, and ]}a check is performed that the @Chg{Version=[4],New=[value of
+  the parameter satisfies the predicates of the subtype of the
+  actual],Old=[predicate is True]}. For an object created
+  by an @nt{object_declaration} with no explicit initialization 
@nt{expression},
+  or by an uninitialized @nt{allocator}, if any subcomponents have
+  @nt{default_expression}s, @Chg{Version=[4],New=[],Old=[the predicate of the
+  nominal subtype of the created object is evaluated, and ]}a check is 
performed
+  that the @Chg{Version=[4],New=[value of
+  the created object satisfies the predicates of the nominal subtype],
+  Old=[predicate is address@hidden,New=[],Old=[ Assertions.Assertion_Error
+  is raised if any of these checks address@hidden check],
+  address@hidden out] address@hidden check],
+  address@hidden@Defn2{Term=[predicate check],
+  address@hidden@Defn2{Term=[check, language-defined],
+  Sec=[controlled by assertion address@hidden,New=[],
+  address@hidden(Assertion_Error), Sec=(raised by failure of run-time 
check)}]}]}
+
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0054-2]}
+  @ChgAdded{Version=[4],Text=[If any of the predicate checks fail,
+  Assertion_Error is raised, unless the subtype whose directly-specified 
predicate
+  aspect evaluated to False also has a directly-specified Predicate_Failure
+  aspect. In that case, the specified Predicate_Failure @nt{expression} is
+  evaluated; if the evaluation of the Predicate_Failure @nt{expression}
+  propagates an exception occurrence, then this occurrence is propagated for 
the
+  failure of the predicate check; otherwise, Assertion_Error is raised, with an
+  associated message string defined by the value of the Predicate_Failure
+  @nt{expression}. In the absence of such a Predicate_Failure aspect, an
+  implementation-defined message string is associated with the Assertion_Error
+  address@hidden(Assertion_Error), Sec=(raised by failure of run-time check)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=<Predicates are not evaluated at the point of the
+  (sub)type declaration.>}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Static_Predicate checks can be removed even in 
the
+  presence of potentially invalid values, just as constraint checks can be
+  removed.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],address@hidden,
+  Text=[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.]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0262-1]}
address@hidden,Kind=[Deleted],ARef=[AI125-0071]}
address@hidden,address@hidden,New=[],Old=[A value @i<satisfies> a
+predicate if the predicate is True for that
address@hidden, Sec=(a subtype predicate)}]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3],ARef=[AI05-0276-1]}
address@hidden,Kind=[Deleted],ARef=[AI125-0071]}
address@hidden,address@hidden,New=[],Old=[If any of the above
address@hidden is violated in an instance of a generic unit, Program_Error is
+raised at the point of the violation.]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Deleted]}
+  @ChgAdded{Version=[3],address@hidden,New=[],Old=[This is the usual
+  way around the contract model; this applies even in instance bodies. Note
+  that errors in instance specifications will be detected at compile-time
+  by the "re-check" of the specification, only errors in the body should
+  raise Program_Error.]}]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3]}
address@hidden,Text=[A predicate specification does not cause a subtype
+to be considered constrained.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3]}
address@hidden,Text=[A Static_Predicate, like a constraint, always
+remains True for all objects of the subtype, except in the case of 
uninitialized
+variables and other invalid values. A Dynamic_Predicate, on the other hand, is
+checked as specified above, but can become False at other times. For example,
+the predicate of a record subtype is not checked when a subcomponent is
+modified.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0071-1]}
address@hidden,Text=[No predicates apply to the base subtype of a
+scalar type; every value of a scalar type @i<T> is considered to satisfy
+the predicates of @i<T>'Base.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0054-2]}
address@hidden,Text=[Predicate_Failure @nt{expression}s are never
+evaluated during the evaluation of a membership test (see
address@hidden Operators and Membership Tests}) or Valid attribute
+(see @RefSecNum{The Valid Attribute}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0054-2]}
address@hidden,Text=[A Predicate_Failure @nt{expression} can be a
address@hidden (see @RefSecNum{Raise Statements and Raise Expressions}).]}
address@hidden
+
address@hidden
address@hidden(Example)
address@hidden,Kind=[AddedNormal],ARef=[AI12-0054-2]}
address@hidden,address@hidden Basic_Letter @key[is] Character -- @examcom[See 
@RefSecNum{The Package Characters.Handling} for "basic letter".]
+   @key[with] Static_Predicate => Basic_Letter @key[in] 'A'..'Z' | 'a'..'z' | 
'@latin1(198)' | '@latin1(230)' | '@latin1(208)' | '@latin1(240)' | 
'@latin1(222)' | '@latin1(254)' | '@latin1(223)';]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0054-2]}
address@hidden,address@hidden Even_Integer @key[is] Integer
+   @key[with] Dynamic_Predicate => Even_Integer @key[mod] 2 = 0,
+       Predicate_Failure => "Even_Integer must be a multiple of 2";]}
address@hidden(Example)
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0054-2]}
address@hidden,Type=[Leading],address@hidden (see
address@hidden Package Text_IO}) could have used predicates to describe some
+common exceptional conditions as follows:}]}
+
address@hidden(Example)
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.IO_Exceptions;
address@hidden Ada.Text_IO @key[is]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] File_Type @key[is limited private];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[subtype] Open_File_Type @key[is] File_Type
+      @key[with] Dynamic_Predicate => Is_Open (Open_File_Type),
+           Predicate_Failure => @key[raise] Status_Error @key[with] "File not 
open";
+   @key[subtype] Input_File_Type @key[is] Open_File_Type
+      @key[with] Dynamic_Predicate => Mode (Input_File_Type) = In_File,
+           Predicate_Failure => @key[raise] Mode_Error @key[with] "Cannot read 
file: " &
+              Name (Input_File_Type);
+   @key[subtype] Output_File_Type @key[is] Open_File_Type
+      @key[with] Dynamic_Predicate => Mode (Output_File_Type) /= In_File,
+           Predicate_Failure => @key[raise] Mode_Error @key[with] "Cannot 
write file: " &
+              Name (Output_File_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ...]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] Mode (File : @key[in] Open_File_Type) 
@key[return] File_Mode;
+   @key[function] Name (File : @key[in] Open_File_Type) @key[return] String;
+   @key[function] Form (File : @key[in] Open_File_Type) @key[return] String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ...]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] Get (File : @key[in] Input_File_Type; 
Item : @key[out] Character);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] Put (File : @key[in] Output_File_Type; 
Item : @key[in] Character);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ...]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @examcom[Similarly for all of the other input and 
output subprograms.]]}
+
address@hidden
+  @ChgRef{Version=[5],Kind=[AddedNormal]}
+  @ChgAdded{Version=[5],Text=[We didn't change the language-defined Text_IO
+  this way for Ada 202x as it would be incompatible in marginal cases: these
+  subprogram specifications would not be subtype conformant with existing
+  access-to-subprogram types, so Put_Line'Access (for instance) would become
+  illegal in existing code. The gain would not be worth the disruption.]}
address@hidden
+
address@hidden(Example)
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0153-3],ARef=[AI05-0262-1],ARef=[AI05-0276-1],ARef=[AI05-0290-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Predicate aspects are new in Ada 2012.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0054-2]}
+  @ChgAdded{Version=[4],address@hidden to Ada 2012}
+  @b<Corrigendum:> The Predicate_Failure aspect is new. We can consider this
+  a correction as it is always possible for implementers to add
+  implementation-defined aspects, so the same is true for language-defined
+  aspects.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0071-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Specified the order of
+  evaluation of most predicates, by defining the new term "satisfies the
+  predicates of the subtype". This is not inconsistent, as the order
+  previously was unspecified, so any code depending on the order was
+  incorrect. The change is necessary so that the Predicate_Failure
+  aspect has consistent results in cases where multiple predicates and
+  aspects apply; see the Ada.Text_IO example above for such a case.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0099-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Revised wording to ensure 
all
+  kinds of types are covered, including the anonymous task associated with
+  a @nt{single_task_declaration}, and generalized it.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0099-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Revised wording to list 
the
+  boolean operators that can be predicate-static, to eliminate confusion
+  about whether @key[not] is included.]}
address@hidden
+
+
+
address@hidden and Named Numbers}
+
address@hidden
address@hidden are created at run time
+and contain a value of a given type.
address@hidden, Sec=(of an object)}
+An object can be created and
+initialized as part of elaborating a
+declaration, evaluating an @nt<allocator>, @nt<aggregate>,
+or @nt<function_call>, or passing a parameter by copy.
+Prior to reclaiming the storage for an object, it is finalized if
+necessary (see @RefSecNum(Completion and Finalization)).]
address@hidden
+
address@hidden
+
address@hidden@address@hidden
+All of the following are objects:
address@hidden<Object>,
+  Text=<An object is either a constant or a variable.
+  An object contains a value.
+  An object is created by an @nt(object_declaration)
+  or by an @nt(allocator).
+  A formal parameter is (a view of) an object.
+  A subcomponent of an object is an object.>}
address@hidden(itemize)
+  the entity declared by
+  an @nt<object_declaration>;
+
+  a formal parameter of a subprogram, entry, or generic subprogram;
+
+  a generic formal object;
+
+  a loop parameter;
+
+  a choice parameter of an @nt<exception_handler>;
+
+  an entry index of an @nt<entry_body>;
+
+  the result of dereferencing an
+  access-to-object value (see @RefSecNum{Names});
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00416-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0015-1]}
+  the @Chg{Version=[2],New=[return object ],address@hidden,
+  New=[of a function],address@hidden,New=[created as the ],Old=[]}result
+  of evaluating a @nt<function_call> (or the equivalent
+  operator invocation @em see @RefSecNum{Overloading of Operators})]};
+
+  the result of evaluating an @nt<aggregate>;
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0003-1]}
+  @ChgAdded{Version=[3],Text=[a @nt{qualified_expression} whose operand 
denotes an object;]}
+
+  a component, slice, or view conversion of another object.
address@hidden(itemize)
+
address@hidden,Kind=[Revised],ARef=[AI05-0054-2]}
address@hidden
address@hidden
address@hidden object}
address@hidden object}
address@hidden view}
address@hidden view}
+An object is either a @i(constant) object or a @i(variable)
address@hidden,New=[],Old=[ The value of a constant object
+cannot be changed between its initialization
+and its finalization, whereas the value of a variable object can be
+changed.]}
+Similarly, a view of an object is either a @i(constant) or
+a @i(variable). All views of a constant
address@hidden,New=[elementary ],Old=[]}object are constant.
address@hidden,New=[All views of a constant composite object are
+constant, except for parts that are of controlled or immutably limited
+types; variable views of those parts and their subcomponents
+may exist. In this sense, objects of controlled and immutably
+limited types are @i<inherently mutable>@Defn{inherently mutable object}. 
],Old=[]}A
+constant view of @Chg{Version=[3],New=[an],Old=[a variable]} object
+cannot be used to modify @Chg{Version=[3],New=[its value],Old=[the value
+of the variable]}. The terms constant and variable by themselves
+refer to constant and variable views of objects.
+
address@hidden, Sec=(the value of an object)}
+The value of an object
+is @i(read) when the value of any part of the object is evaluated,
+or when the value of an enclosing object is evaluated.
address@hidden, Sec=(the value of an object)}
+The value of a variable
+is @i(updated) when an assignment is performed to any part of the
+variable, or when an assignment is performed to an enclosing object.
address@hidden
+Reading and updating are intended to include read/write references of
+any kind, even if they are not associated with the evaluation of a
+particular construct. Consider, for example, the expression
address@hidden@;address@hidden(F)@rquotes@;,
+where X is an access-to-array object, and F is a function.
+The implementation is allowed to first evaluate 
@lquotes@;address@hidden@rquotes@;
+and then F.
+Finally, a read is performed to get the value of the F'th component of
+the array.
+Note that the array is not necessarily read as part of the evaluation of
address@hidden@;address@hidden@rquotes@;.
+This is important, because if F were to free X using
+Unchecked_Deallocation, we want the execution of the final read to be
+erroneous.
address@hidden
+
address@hidden@;Whether a view of an object is constant or variable is 
determined
+by the definition of the view.
+The following (and no others) represent constants:
address@hidden(itemize)
+  an object declared by an @nt<object_declaration> with the
+  reserved word @key(constant);
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00385-01]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[We mean the word @key{constant}
+  as defined by the grammar for @nt{object_declaration}, not some random word
+  @key{constant}. Thus,]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[X : @key{access constant} T;]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[is not a constant.]}
address@hidden
+
+  a formal parameter or generic formal object of mode @key(in);
+
+  a discriminant;
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Text=[a loop parameter unless specified to be a 
variable
+  for a generalized loop (see @RefSecNum{Generalized Loop Iteration});]}
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0262-1]}
+  a @Chg{Version=[3],New=[],Old=[loop parameter, ]}choice
+  address@hidden,New=[],Old=[,]} or entry index;
+
+  the dereference of an access-to-constant value;
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0015-1]}
+  @ChgAdded{Version=[3],Text=[the return object declared by an
+  @nt{extended_return_statement} with the reserved word @key[constant];]}
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0015-1]}
+  the @Chg{Version=[3],New=[object denoted by],Old=[result of evaluating]}
+  a @nt<function_call> or an @nt<aggregate>;
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0003-1]}
+  @ChgAdded{Version=[3],Text=[the result of evaluating a 
@nt{qualified_expression};]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0120-1]}
+  @ChgAdded{Version=[3],Text=[within the body of a protected function (or a
+  function declared immediately within a @nt{protected_body}), the current
+  instance of the enclosing protected unit;]}
+
+  a @nt<selected_component>, @nt<indexed_component>,
+  @nt<slice>, or view conversion of a constant.
+  @begin{Honest}
+    @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00114-01]}
+    @ChgNote{This is just wrong, even for Ada 95.}
+    @ChgDeleted{Version=[2],Text=[A noninvertible view conversion to a
+    general access type
+    is also defined to be a constant @em see @RefSecNum(Type Conversions).]}
+  @end{Honest}
+
address@hidden(itemize)
+
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden subtype}
+At the place where a view of an
+object is defined, a @i(nominal subtype) is associated
+with the view.
address@hidden subtype}
address@hidden (of an object)],See=(actual subtype of an object)}
+The object's @i(actual subtype) (that is, its
+subtype) can be more restrictive than
+the nominal subtype of the view; it always is if the nominal subtype
+is an @i(indefinite subtype).
address@hidden subtype}
address@hidden subtype}
+A subtype is an indefinite subtype if it is an unconstrained array
+subtype, or if it has unknown discriminants or unconstrained
+discriminants without defaults (see @RefSecNum(Discriminants));
address@hidden,New=[,],Old=[]} the subtype is a @i{definite}
+subtype @Redundant[(all elementary subtypes are definite subtypes)].
address@hidden class-wide subtype is defined to have unknown discriminants,
+and is therefore an indefinite subtype.
+An indefinite subtype does not by itself
+provide enough information to create an object;
+an additional @nt<constraint> or
+explicit initialization @nt<expression>
+is necessary (see @RefSecNum(Object Declarations)).
+A component cannot have an indefinite nominal subtype.]
+
address@hidden,Kind=[Added],ARef=[AI05-0008-1]}
address@hidden,Type=[Leading],Text=[A view of a composite object is
address@hidden<known to be constrained> if:@Defn{known to be 
address@hidden,Sec=[known to be]}]}
+
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Text=[its nominal subtype is constrained, and is not an
+untagged partial view; or]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[its nominal subtype is indefinite; or]}
+
address@hidden,Kind=[Added],ARef=[AI05-0008-1],ARef=[AI05-0093-1]}
address@hidden,Text=[its type is immutably limited (see @RefSecNum{Limited 
Types}); or]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[it is part of a stand-alone constant (including a
+generic formal object of mode @key[in]); or]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[it is part of a formal parameter of mode @key[in]; or]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[it is part of the object denoted by a
address@hidden or @nt{aggregate}; or]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[it is part of a constant return object of an
address@hidden; or]}
+
address@hidden,Kind=[Added],ARef=[AI05-0008-1],ARef=[AI05-0041-1]}
address@hidden,Text=[it is a dereference of a pool-specific access type,
+and there is no ancestor of its type that has a constrained partial view.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[We do not include dereferences of general access
+types because they might denote stand-alone aliased unconstrained variables.
+That's true even for access-to-constant types (the denoted object does not
+have to be a constant).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1],ARef=[AI05-0008-1]}
address@hidden,Text=[There are other cases that could have been
+included in this definition (view conversions, the current instance of
+a type, objects of a formal discriminated
+private type), but these are not relevant to the places this term is
+used, so they were not included. If this term is used in additional places,
+the definition should be checked to see if any of these additional cases
+are relevant and appropriate wording added if necessary.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0008-1],ARef=[AI05-0041-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[For the purposes of
+determining within a generic body whether an object is known
+to be constrained:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[if a subtype is a descendant of an untagged generic
+formal private or derived type, and the subtype is not an unconstrained array
+subtype, it is not considered indefinite and is considered to have a
+constrained partial view;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[if a subtype is a descendant of a formal access type, it 
is not
+considered pool-specific.]}
+
address@hidden
+
+
address@hidden number}
+A @i(named number) provides a name for a numeric value known
+at compile time. It is declared by a @nt<number_declaration>.
address@hidden
+
address@hidden
+A constant cannot be the target of an assignment operation, nor be
+passed as an @key(in) @key(out) or @key(out)
+parameter, between its initialization and finalization, if any.
+
address@hidden,Kind=[Added],ARef=[AI05-0054-2]}
address@hidden,Text=[The value of a constant object cannot be
+changed after its initialization, except in some cases where the
+object has a controlled or immutably limited part (see
address@hidden Types}, @RefSecNum{Assignment and Finalization},
+and @RefSecNum{Data Validity}).]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
+The nominal and actual subtypes of an elementary object are
+always the same. For a discriminated or array object,
+if the nominal subtype is address@hidden,New=[,],Old=[]} then so is
+the actual subtype.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+There are additional kinds of objects (choice parameters and
+entry indices of entry bodies).
+
+The result of a function and of evaluating an aggregate
+are considered (constant) objects. This is necessary to explain
+the action of finalization on such things.
+Because a @nt<function_call> is also syntactically a @nt<name>
+(see @RefSecNum(Names)), the result of a @nt{function_call} can be renamed,
+thereby allowing repeated use of the result without calling
+the function again.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause and its subclauses]}
+now @Chg{Version=[3],New=[follows],Old=[follow]} the
address@hidden,New=[],Old=[clause and ]}subclauses on types and subtypes,
+to cut down on the number of forward references.
+
+The term nominal subtype is new. It is used to distinguish
+what is known at compile time about an object's constraint, versus what
+its "true" run-time constraint is.
+
+The terms definite and indefinite (which apply to
+subtypes) are new.
+They are used to aid in the description of generic formal
+type matching,
+and to specify when an explicit initial value is required
+in an @nt<object_declaration>.
+
+We have moved the syntax for @nt<object_declaration> and
address@hidden<number_declaration> down into their respective subclauses, to
+keep the syntax close to the description of the associated semantics.
+
+We talk about variables and constants here, since the discussion is
+not specific to @nt<object_declaration>s, and it seems
+better to have the list of the kinds of constants juxtaposed
+with the kinds of objects.
+
+We no longer talk about indirect updating due to parameter passing.
+Parameter passing is handled in 6.2 and 6.4.1 in a way that there
+is no need to mention it here in the definition of read and update.
+Reading and updating now includes the case of evaluating or
+assigning to an enclosing object.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that the return object is the object
+  created by a function call.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0015-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Added wording to allow
+  return objects to be declared as constants, and corrected the definition
+  of return objects as objects.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0008-1],ARef=[AI05-0041-1],ARef=[AI05-0093-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a definition of
+  @i<known to be constrained>, for use in other rules.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0054-2]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> We now recognize the fact
+  that not all declared constant objects are immutable; for those that
+  a variable view can be constructed, they can be changed via that view.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0120-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added the current instance 
of
+  a protected object to the list of constant views; since the list
+  claims to include all possibilities, it had better include that one.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0003-1]}
+  @ChgAdded{Version=[3],Text=[The result of a
+  @nt{qualified_expression} is defined to be a constant view and is defined
+  to be an object if the operand of the @nt{qualified_expression} is an object.
+  These definitions, combined with some grammar changes, allow
+  @nt{qualified_expression}s to be used in more places. See
+  @RefSecNum{Names} for address@hidden is defined an extension in 
@RefSecNum{Names}.}
address@hidden
+
+
address@hidden Declarations}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden object}
address@hidden initial value}
address@hidden expression}
+An @nt<object_declaration> declares a @i(stand-alone) object with a given
+nominal subtype and, optionally, an explicit initial
+value given by an initialization expression.
address@hidden array type}
address@hidden task type}
address@hidden protected type}
+For an array, @Chg{Version=[3],New=[access, ],Old=[]}task, or protected object,
+the @nt<object_declaration> may include the definition
+of the (anonymous) type of the object.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00385-01],ARef=[AI95-00406-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<object_declaration>,rhs="
+    @Syn2{defining_identifier_list} : address@hidden address@hidden 
@Syn2{subtype_indication} [:= @address@hidden,New=<
+        address@hidden>,Old=[]};@Chg{Version=[2],New=<
+  | @Syn2{defining_identifier_list} : address@hidden address@hidden 
@Syn2{access_definition} [:= @address@hidden,New=<
+        address@hidden>,Old=[]};>,Old=<>}
+  | @Syn2{defining_identifier_list} : address@hidden address@hidden 
@Syn2{array_type_definition} [:= @address@hidden,New=<
+        address@hidden>,Old=[]};
+  | @Syn2{single_task_declaration}
+  | @Syn2{single_protected_declaration}"}
+
address@hidden<defining_identifier_list>,rhs="
+  @Syn2{defining_identifier} {, @Syn2{defining_identifier}}"}
address@hidden
+
address@hidden
address@hidden type],
+  Sec=(object_declaration initialization expression)}
+For an @nt<object_declaration> with an @nt<expression> following
+the compound delimiter :=,
+the type expected for
+the @nt<expression> is that of the object.
address@hidden expression}
+This @nt<expression> is called the @i(initialization expression).
address@hidden,See=[initialization expression]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
+An @nt<object_declaration> without the reserved word @key(constant)
+declares a variable object. If it has a @nt<subtype_indication> or
+an @nt<array_type_definition> that defines an indefinite subtype,
+then there shall be an initialization address@hidden,New=[],Old=[
+An initialization expression shall not be given if the object is
+of a limited type.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0264-1],ARef=[AI05-0299-1]}
+An @nt<object_declaration> with the reserved word @key(constant)
+declares a constant object.
address@hidden constant declaration}
+If it has an initialization expression,
+then it is called a @i(full constant declaration).
address@hidden constant declaration}
address@hidden,New=[,],Old=[]} it is called
+a @i(deferred constant declaration).
+The rules for deferred constant declarations are given in 
@Chg{Version=[3],New=[subclause],Old=[clause]}
address@hidden(Deferred Constants). The rules for full constant declarations
+are given in this subclause.
+
+Any declaration that includes a @nt{defining_identifier_list}
+with more than one @nt{defining_identifier}
+is equivalent to a series of declarations each containing one
address@hidden from the list,
+with the rest of the text of the declaration copied for each
+declaration in the series, in the same order as the list.
+The remainder of this International Standard relies
+on this equivalence;
+explanations are given for
+declarations with a single @nt<defining_identifier>.
+
address@hidden,Kind=[Revised],ARef=[AI95-00385-01]}
address@hidden subtype}
+The @nt<subtype_indication>@Chg{Version=[2],New=[, 
@nt{access_definition},],Old=[]}
+or full type definition of an
address@hidden<object_declaration> defines the nominal subtype of the object.
+The @nt<object_declaration> declares an object of the type
+of the nominal subtype.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00385-01]}
+The phrase @lquotes@;full type address@hidden@; here includes the
+case of an anonymous array, @Chg{Version=[2],New=[access, ],Old=[]}task, or
+protected type.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00373-01]}
address@hidden,address@hidden late initialization}
+A component of an object is said to
address@hidden late initialization} if it has an access discriminant value
+constrained by a per-object expression, or if it has an initialization
+expression that includes a name denoting the current instance of the type
+or denoting an access discriminant.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Such components can depend on the values of
+other components of the object. We want to initialize them as late and as
+reproducibly as possible.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00363-01]}
address@hidden, Sec=(of an object)}
+If a composite object declared by an
address@hidden has an unconstrained nominal subtype,
+then if this subtype is indefinite
+or the object is constant @Chg{Version=[2],New=[],
+Old=[or aliased (see @RefSecNum(Access Types)) ]}the
+actual subtype of this object is constrained.
+The constraint is determined
+by the bounds or discriminants (if any) of its initial value;
address@hidden by its initial value}
+the object is said to be @i(constrained by its initial value).
address@hidden subtype], Sec=(of an object)}
address@hidden (of an object)],See=(actual subtype of an object)}
address@hidden,New=[],
address@hidden the case of an aliased object,
+this initial value may be either explicit or implicit;
+in the other cases, an explicit initial value is required.] ]}When
+not constrained by its initial value, the actual and nominal
+subtypes of the object are the same.
address@hidden, Sec=(object)}
address@hidden, Sec=(object)}
+If its actual subtype is constrained, the object
+is called a @i(constrained object).
+
address@hidden@Defn2{Term=[implicit initial values], Sec=(for a subtype)}
+For an @nt<object_declaration> without an initialization expression,
+any initial values for the object or its subcomponents
+are determined by the @i(implicit initial values) defined for
+its nominal subtype, as follows:
address@hidden(itemize)
+  The implicit initial value for an access subtype is the
+  null value of the access type.
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0228-1]}
+  @ChgAdded{Version=[3],Text=[The implicit initial value for a scalar subtype
+  that has the Default_Value aspect specified is the value of that aspect
+  converted to the nominal subtype (which might raise Constraint_Error @em see
+  @RefSec{Type Conversions});@PDefn2{Term=[implicit subtype conversion],
+  Sec=(default value of a scalar)}]}
+
+  @begin{Ramification}
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[This is a @RuntimeTitle rule, so the
+    visibility of the @nt{aspect_specification} is not relevant @em if the full
+    type for a private type has the Default_Value aspect specified, partial
+    views of the type also have this implicit initial value.]}
+  @end{Ramification}
+
+  The implicit initial (and only) value for each discriminant
+  of a constrained discriminated subtype is defined by the subtype.
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0228-1]}
+  For a (definite) composite subtype,
+  the implicit initial value of each component
+  with a @nt<default_expression> is obtained by
+  evaluation of this expression and conversion to the
+  component's nominal subtype (which might raise
+  address@hidden,New=[],Old=[ @em see
+  @RefSec{Type Conversions}]}), unless the component is a
+  discriminant of a constrained subtype (the previous case),
+  or is in an excluded @nt<variant>
+  (see @RefSecNum(Variant Parts and Discrete Choices)).
+  @PDefn2{Term=[implicit subtype conversion],Sec=(component defaults)}
+  For each component that does not have a @nt<default_expression>,
+  @Chg{Version=[3],New=[if the composite subtype has the 
Default_Component_Value
+  aspect specified, the implicit initial value is the value of that aspect
+  converted to the component's nominal subtype; otherwise, ],Old=[]}any
+  implicit initial values are those determined by the component's
+  nominal subtype.
+
+  For a protected or task subtype, there is an implicit component
+  (an entry queue) corresponding to each entry, with its implicit
+  initial value being an empty queue.
address@hidden(ImplNote)
+    The implementation may add implicit components for its own use,
+    which might have implicit initial values.
+    For a task subtype, such components might represent the state
+    of the associated thread of control. For a type with dynamic-sized
+    components, such implicit components might be used to hold the offset to
+    some explicit component.
address@hidden(ImplNote)
address@hidden(itemize)
+
address@hidden@PDefn2{Term=[elaboration], Sec=(object_declaration)}
+The elaboration of an @nt{object_declaration} proceeds in the following
+sequence of steps:
address@hidden(enumerate)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00385-01]}
+  The @address@hidden,@Chg{Version=[2],New=[ @address@hidden,],Old=[]}
+  @nt<address@hidden@!definition>, @address@hidden@!declaration},
+  or @address@hidden@!declaration} is first elaborated.
+  This creates the nominal subtype (and the anonymous type in the
+  @Chg{Version=[2],New=[last four],Old=[latter three]} cases).
+
+  If the @nt<object_declaration> includes an initialization expression,
+  the (explicit) initial value is obtained by evaluating the
+  expression and converting it to the nominal subtype (which might
+  raise Constraint_Error @em see @RefSecNum(Type Conversions)).
+  @PDefn2{Term=[implicit subtype conversion],Sec=(initialization expression)}
+
+  @ChgRef{Version=[1],Kind=[Revised],Ref=[8652/0002],ARef=[AI95-00171-01]}
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00373-01]}
+  The object is created, and, if there is not an initialization expression,
+  @Chg{Version=[2],New=[the object is @i{initialized by default}.
+  @Defn{initialized by default}When an object is initialized by
+  default, ],Old=[]}any per-object @Chg{New=[constraints],Old=[expressions]}
+  (see @RefSecNum(Record Types)) are
+  @Chg{New=[elaborated], Old=[evaluated]} and any implicit initial values for
+  the object or for its subcomponents are obtained as determined by
+  the nominal address@hidden,New=[
+  @Defn2{Term=[initialization], Sec=(of an object)}
+  @Defn2{Term=[assignment operation], Sec=(during elaboration of an 
@nt{object_declaration})}
+  Any initial values (whether explicit or implicit) are assigned
+  to the object or to the corresponding subcomponents.
+  As described in @RefSecNum{Assignment Statements}
+  and @RefSecNum{Assignment and Finalization},
+  Initialize and Adjust procedures can be called.
+  @IndexSee{Term=[constructor],See=[initialization]}],Old=[]}
+  @begin(Discussion)
+    For a per-object constraint that contains some per-object
+    expressions and some non-per-object expressions,
+    the values used for the constraint consist of the values
+    of the non-per-object expressions evaluated at the point
+    of the @nt{type_declaration}, and the values of the per-object
+    expressions evaluated at the point of the creation of the
+    object.
+
+    The elaboration of per-object constraints was presumably performed
+    as part of the dependent compatibility check in Ada 83.
+    If the object is of a limited type
+    with an access discriminant, the @nt<access_definition> is elaborated
+    at this time (see @RefSecNum(Discriminants)).
+  @end(Discussion)
+  @begin{Reason}
+    The reason we say that evaluating an explicit initialization
+    expression happens before creating the object is that in some cases
+    it is impossible to know the size of the object being created until
+    its initial value is known, as in
+    @lquotes@;X: String := Func_Call(...);@rquotes@;.
+    The implementation can create the object early in the
+    common case where the size can be known early,
+    since this optimization is semantically neutral.
+  @end{Reason}
+
+  @ChgRef{Version=[2],Kind=[Deleted],ARef=[AI95-00373-01]}
+  @ChgDeleted{Version=[2],address@hidden, Sec=(of an object)}
+  @Defn2{Term=[assignment operation], Sec=(during elaboration of an 
@nt{object_declaration})}
+  Any initial values (whether explicit or implicit) are assigned
+  to the object or to the corresponding subcomponents.
+  As described in @RefSecNum{Assignment Statements}
+  and @RefSecNum{Assignment and Finalization},
+  Initialize and Adjust procedures can be called.
+  @IndexSee{Term=[constructor],See=[initialization]}]}
+  @begin(Ramification)
+    Since the initial values have already been converted to the appropriate
+    nominal subtype, the only Constraint_Errors that might
+    occur as part of these assignments are for values outside their
+    base range that are used to initialize unconstrained numeric
+    subcomponents. See @RefSecNum{Scalar Types}.
+  @end(Ramification)
address@hidden(enumerate)
+
address@hidden,Kind=[Revised],ARef=[AI95-00373-01]}
address@hidden,Type=[Leading],address@hidden to get conditional Leading here.}
+For the third step above, @Chg{Version=[2],New=[],Old=[the object creation and
+any elaborations and ]}evaluations @Chg{Version=[2],New=[and assignments 
],Old=[]}are
+performed in an arbitrary
address@hidden,New=[ subject to the following restrictions:],Old=[,
+except that if the @nt<default_expression> for a discriminant is
+evaluated to obtain its initial value, then this evaluation
+is performed before that of
+the @nt<default_expression> for any component that depends on the
+discriminant,
+and also before that of any @nt<default_expression> that
+includes the name of the discriminant.
+The evaluations of the third step and the assignments of the fourth step
+are performed in an arbitrary order,
+except that each evaluation is performed before the resulting value is
address@hidden order],Sec=[allowed]}
address@hidden(Itemize)
+
address@hidden,Kind=[Added],ARef=[AI95-00373-01]}
address@hidden,Text=[Assignment to any part of the object
+is preceded by the evaluation of the value that is to be assigned.]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[Duh. But we ought to say it. Note that, like
+any rule in the International Standard, it doesn't prevent
+an @lquotes@;address@hidden optimization; as long as the semantics as observed
+from the program are correct, the compiler can generate any code it wants.]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00373-01]}
address@hidden,Text=[The evaluation of a @nt{default_expression} that
+includes the name of a discriminant is preceded by the assignment to that
+discriminant.]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[Duh again. But we have to say this, too. It's
+odd that Ada 95 only required the default expressions to be evaluated before
+the discriminant is used; it says nothing about discriminant values that
+come from @nt{subtype_indication}s.]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00373-01]}
address@hidden,Text=[The evaluation of the @nt{default_expression}
+for any component that depends on a discriminant is preceded by the assignment
+to that discriminant.]}
address@hidden
address@hidden@keepnext@;For example:
address@hidden
address@hidden R(D : Integer := F) @key[is]
+    @key[record]
+        S : String(1..D) := (@key[others] => G);
+    @key[end] @key[record];
+
+X : R;
address@hidden
+
+For the elaboration of the declaration of X,
+it is important that F be evaluated before the aggregate.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00373-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0092-1]}
address@hidden,Text=[The assignments to any components, including
+implicit components, not requiring late initialization
address@hidden,New=[],Old=[must ]}precede the
+initial value evaluations for any components requiring late initialization;
+if two components both require late initialization, then assignments to parts
+of the component occurring earlier in the order of the component declarations
address@hidden,New=[],Old=[must ]}precede the
+initial value evaluations of the component occurring later.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[Components that require late
+initialization can refer to the entire object during their initialization.
+We want them to be initialized as late as possible to reduce the chance
+that their initialization depends on uninitialized components. For instance:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden T (D : Natural) @key{is}
+  @key{limited record}
+    C1 : T1 (T'Access);
+    C2 : Natural := F (D);
+    C3 : String (1 .. D) := (others => ' ');
+  @key{end record};]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Component C1 requires late initialization. The
+initialization could depend on the values of any component of T, including D,
+C2, or C3. Therefore, we want to it to be initialized last. Note that C2 and
+C3 do not require late initialization; they only have to be initialized after
+D.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[It is possible for there to be more than one
+component that requires late initialization. In this case, the language can't
+prevent problems, because all of the components can't be the last one
+initialized. In this case, we specify the order of initialization for
+components requiring late initialization; by doing so, programmers can
+arrange their code to avoid accessing uninitialized components, and such
+arrangements are portable. Note that if the program accesses an uninitialized
+component, @RefSecNum{Data Validity} defines the execution to be erroneous.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0228-1]}
address@hidden is no implicit initial
+value defined for a scalar address@hidden,New=[ unless the
+Default_Value aspect has been specified for the type],Old=[]}.]
address@hidden variables}
+In the absence of an explicit address@hidden,New=[ or the
+specification of the Default_Value aspect],Old=[]}, a newly created
+scalar object might have a value that does not belong to its subtype
+(see @RefSecNum{Data Validity} and @RefSecNum{Pragma Normalize_Scalars}).
address@hidden
+It could even be represented by a bit pattern that doesn't
+actually represent any value of the type at all,
+such as an invalid internal code for an enumeration type,
+or a NaN for a floating point type.
+It is a generally a bounded error to reference scalar objects with
+such @lquotes@;invalid address@hidden@;, as explained in
address@hidden Validity}.
address@hidden
address@hidden
+There is no requirement that two objects of the same scalar subtype have
+the same implicit initial @lquotes@;address@hidden@; (or representation).
+It might even be the case that two elaborations of the same
address@hidden produce two different initial values.
+However, any particular uninitialized object is default-initialized to a
+single value (or invalid representation).
+Thus, multiple reads of such an uninitialized object will produce the
+same value each time
+(if the implementation chooses not to detect the error).
address@hidden
address@hidden
+
address@hidden
+Implicit initial values are not defined
+for an indefinite subtype,
+because if an object's nominal subtype is indefinite,
+an explicit initial value is required.
+
address@hidden,Kind=[Revised],ARef=[AI05-0092-1],ARef=[AI05-0255-1]}
address@hidden constant}
address@hidden variable}
+As indicated above,
+a stand-alone object is an object declared by an @nt<object_declaration>.
+Similar definitions apply to
address@hidden@;stand-alone address@hidden@; and @lquotes@;stand-alone 
address@hidden@;
+A subcomponent of an object is not a stand-alone object,
+nor is an object that is created by an @nt<allocator>.
+An object declared by a
address@hidden<loop_parameter_specification>,
address@hidden,address@hidden, ],address@hidden<parameter_specification>,
address@hidden<entry_index_specification>, @nt<choice_parameter_specification>,
address@hidden,address@hidden, ],Old=[]}or
+a @nt{formal_object_declaration} @Chg{Version=[3],New=[of mode @key[in out] 
],Old=[]}is
+not @Chg{Version=[3],New=[considered],Old=[called]} a stand-alone object.
+
+The type of a stand-alone object cannot
+be abstract (see @RefSecNum{Abstract Types and Subprograms}).
address@hidden
+
address@hidden
address@hidden@address@hidden(Example of a multiple object declaration:)
address@hidden(Example)
address@hidden  the multiple object declaration ]
+
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
+John, Paul : @Chg{Version=[2],address@hidden null} ],Old=[]}Person_Name := 
@key(new) Person(Sex => M);  address@hidden  see @RefSecNum(Incomplete Type 
Declarations)]
+
address@hidden  is equivalent to the two single object declarations in the 
order given]
+
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
+John : @Chg{Version=[2],address@hidden null} ],Old=[]}Person_Name := @key(new) 
Person(Sex => M);
+Paul : @Chg{Version=[2],address@hidden null} ],Old=[]}Person_Name := @key(new) 
Person(Sex => M);
address@hidden(Example)
+
address@hidden
address@hidden@address@hidden(Examples of variable declarations:)
address@hidden
address@hidden(Example)
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
+Count, Sum  : Integer;
+Size        : Integer @key(range) 0 .. 10_000 := 0;
+Sorted      : Boolean := False;
+Color_Table : @key(array)(1 .. Max) @key(of) Color;
+Option      : Bit_Vector(1 .. 10) := (@key(others) => True);
+Hello       : 
@Chg{Version=[2],address@hidden(aliased)],address@hidden(constant)]} String := 
"Hi, world.";@Chg{Version=[2],New=[
address@hidden(952), @unicode(966)        : Float @b<range> address@hidden .. 
address@hidden;],Old=[]}
address@hidden(Example)
+
address@hidden
address@hidden@address@hidden(Examples of constant declarations:)
address@hidden
address@hidden(Example)
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
+Limit     : @key(constant) Integer := 10_000;
+Low_Limit : @key(constant) Integer := Limit/10;
+Tolerance : @key(constant) Real := Dispersion(1.15);@Chg{Version=[2],New=[
+Hello_Msg : @key(constant access) String := Hello'Access; address@hidden see 
@RefSecNum{Operations of Access Types}]],Old=[]}
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax rule for @nt{object_declaration} is modified to allow the
address@hidden reserved word.
+
+A variable declared by an @nt<object_declaration> can be constrained
+by its initial value; that is, a variable of a nominally unconstrained
+array subtype, or discriminated type without defaults, can
+be declared so long as it has an explicit initial value.
+In Ada 83, this was permitted for constants, and for variables
+created by allocators, but not for variables declared by
address@hidden<object_declaration>s. This is particularly important
+for tagged class-wide types, since there is no way to constrain
+them explicitly, and so an initial value is the only way
+to provide a constraint. It is also important for generic formal
+private types with unknown discriminants.
+
+We now allow an @nt{unconstrained_array_definition}
+in an @nt{object_declaration}.
+This allows an object of an anonymous array type to have its
+bounds determined by its initial value.
+This is for uniformity: If one can write @lquotes@;X: @key[constant]
address@hidden(Integer @key[range] 1..10) @key[of] Integer := ...;@rquotes@; 
then
+it makes sense to also allow
address@hidden@;X: @key[constant] @key[array](Integer @key[range] <>) @key[of] 
Integer := ...;@rquotes@;.
+(Note that if anonymous array types are
+ever sensible, a common situation is for a table implemented as an array.
+Tables are often constant, and for constants, there's usually no point in
+forcing the user to count the number of elements in the value.)
address@hidden
+
address@hidden
+We have moved the syntax for @nt{object_declaration}s into this subclause.
+
+Deferred constants no longer have a separate syntax rule, but rather
+are incorporated in @nt<object_declaration> as constants declared
+without an initialization expression.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00363-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  Unconstrained aliased objects of types
+  with discriminants with defaults are no longer
+  constrained by their initial values. This means that a program that
+  raised Constraint_Error from an attempt to change the discriminants
+  will no longer do so. The change only affects programs that depended
+  on the raising of Constraint_Error in this case, so the inconsistency
+  is unlikely to occur outside of the ACATS. This change may however cause
+  compilers to implement these objects differently, possibly taking additional
+  memory or time. This is unlikely to be worse than the differences caused by
+  any major compiler upgrade.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  A constant may have a limited type; the initialization @nt{expression}
+  has to be built-in-place (see @RefSecNum{Limited Types}).]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00385-01],ARef=[AI95-00406-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  A stand-alone object may have an anonymous access type.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0002],ARef=[AI95-00171-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected wording to say 
that
+  per-object constraints are elaborated (not evaluated).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00373-01]}
+  @ChgAdded{Version=[2],Text=[The rules for evaluating default initialization
+  have been tightened. In particular, components whose default initialization
+  can refer to the rest of the object are required to be initialized last.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00433-01]}
+  @ChgAdded{Version=[2],Text=[Added examples of various new constructs.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in an 
@nt{object_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0228-1]}
+  @ChgAdded{Version=[3],Text=[Implicit initial values can now be given
+  for scalar types and for scalar array components, using the Default_Value
+  (see @RefSecNum{Scalar Types}) and Default_Component_Value
+  (see @RefSecNum{Array Types}) aspects; the extension is documented there.]}
address@hidden
+
+
+
address@hidden@Comment{For ISO version of Ada 2012 Standard}
address@hidden Declarations}
+
address@hidden
+A @nt<number_declaration> declares a named number.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden
+If a value or other property of a construct is required to be
address@hidden(static) that means it is required to be determined prior
+to execution. A @i(static) expression is an expression
+whose value is computed
+at compile time and is usable in contexts where the actual value
+might affect the legality of the construct.
+This is fully defined in @Chg{Version=[3],New=[subclause],Old=[clause]}
address@hidden(Static Expressions and Static Subtypes).
address@hidden
address@hidden
+
address@hidden
address@hidden<number_declaration>,rhs="
+     @Syn2{defining_identifier_list} : @key{constant} := @address@hidden;"}
address@hidden
+
address@hidden
address@hidden type],
+  Sec=(number_declaration expression)}
+The @SynI(static_)@nt{expression} given for
+a @nt{number_declaration} is expected to be of any numeric type.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The @i(static_)@nt{expression} given for a number declaration
+shall be a static expression, as defined by 
@Chg{Version=[3],New=[subclause],Old=[clause]}
address@hidden(Static Expressions and Static Subtypes).
address@hidden
+
address@hidden
+The named number denotes a value of type @i(universal_integer) if
+the type of the @i(static_)@address@hidden is an integer type.
+The named number denotes a value of type @i(universal_real) if
+the type of the @i(static_)@address@hidden is a real type.
+
+The value denoted by the named number is the value of the
address@hidden(static_)@nt{expression}, converted to the corresponding
+universal type.
address@hidden subtype conversion],Sec=(named number value)}
address@hidden
+
address@hidden
address@hidden, Sec=(number_declaration)}
+The elaboration of a @nt<number_declaration> has no effect.
address@hidden(TheProof)
+  Since the @i(static_)@nt<expression> was evaluated at compile time.
address@hidden(TheProof)
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of number declarations:)
address@hidden(Example)
+Two_Pi        : @key(constant) := 2.0*Ada.Numerics.Pi;   address@hidden a real 
number (see @RefSecNum{The Numerics Packages})]
+
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
+Max           : @key(constant) := 500;                   address@hidden an 
integer number]
+Max_Line_Size : @key(constant) := Max/address@hidden,New=[;],Old=[ ]}          
       address@hidden the integer 83]
+Power_16      : @key(constant) := 2**16;                 address@hidden the 
integer 65_536]
+One, Un, Eins : @key(constant) := 1;                     address@hidden three 
different names for 1]
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden to Ada 83}
+We now allow a static expression of any numeric type
+to initialize a named
+number. For integer types, it was possible in Ada 83
+to use 'Pos to define a named number, but there was
+no way to use a static expression of some nonuniversal
+real type to define a named number. This change is
+upward compatible because of the preference rule for
+the operators of the root numeric types.
address@hidden
+
address@hidden
+We have moved the syntax rule into this subclause.
+
+AI83-00263 describes the elaboration of a number declaration
+in words similar to that of an @nt{object_declaration}. However, since
+there is no expression to be evaluated and no object to be created,
+it seems simpler to say that the elaboration has no effect.
address@hidden
+
+
address@hidden Types and Classes}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00401-01],ARef=[AI95-00419-01]}
address@hidden type}
+A @nt<derived_type_definition> defines a @Chg{Version=[2],
address@hidden type}],Old=[new type]} (and its first subtype)
+whose characteristics are @i(derived) from those of a
address@hidden,New=[parent type, and possibly from progenitor types],
address@hidden(parent type)]}.
address@hidden,See=[derived types and classes]}
address@hidden,Kind=[Revised],Term=<Derived type>,
+  Text=<A derived type is a type defined in terms of @Chg{Version=[2],
+  New=[one or more other types given in a derived type definition. The
+  first of those types],Old=[another type, which]}
+  is the parent type of the derived address@hidden,New=[ and
+  any others are progenitor types],Old=[]}.
+  Each class containing the parent type @Chg{Version=[2],New=[or a progenitor
+  type ],Old=[]}also contains the derived type.
+  The derived type inherits properties such as components and
+  primitive operations from the address@hidden,New=[ and progenitors],Old=[]}.
+  A type together with the types derived from it
+  (directly or indirectly) form a derivation class.>}
+
address@hidden,Kind=[Added],ARef=[AI95-00442-01]}
address@hidden,address@hidden,Sec=[of types]}
address@hidden,Sec=[of types]}
+A @i<class of types> is a set of types that is closed under
+derivation; that is, if the parent or a progenitor type of a
+derived type belongs to a class, then so does the derived type.
+By saying that a particular group of types forms a class,
+we are saying that all derivatives of a type in the set inherit
+the characteristics that define that set. The
+more general term @i<category of types> is used for a set of types
+whose defining characteristics are not necessarily inherited by
+derivatives; for example, limited, abstract, and interface are all
+categories of types, but not classes of types.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[A class of types is also a category of types.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00251-01],ARef=[AI95-00419-01]}
address@hidden<derived_type_definition>,rhs="@Chg{Version=[2],New=<
+    >,Old=<>address@hidden @Chg{Version=[2],New=<address@hidden 
>,Old=<>address@hidden @address@hidden address@hidden,New=<address@hidden 
@Syn2{interface_list}] >,Old=<>address@hidden"}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00251-01],ARef=[AI95-00401-01],ARef=[AI95-00419-01]}
address@hidden subtype}
address@hidden type}
+The @Syni(parent_)@nt<subtype_indication> defines the @i(parent subtype);
+its type is the @Chg{Version=[2],address@hidden(parent type)],Old=[parent 
type]}.
address@hidden,New=[The @nt{interface_list} defines the progenitor types
+(see @RefSecNum{Interface Types}). A derived type
+has one parent type and zero or more progenitor types.],Old=[]}
+
address@hidden,Kind=[AddedNormal],Term=<Parent>,
+  Text=<@ChgAdded{Version=[2],Text=[The parent of a derived type is the
+  first type given in the definition of the derived type. The parent
+  can be almost any kind of type, including an interface type.]}>}
+
+
+A type shall be completely defined
+(see @RefSecNum(Completions of Declarations))
+prior to being specified as the parent type
+in a @nt<derived_type_definition> @em @Redundant[the
address@hidden<full_type_declaration>s for the parent
+type and any of its subcomponents have to
+precede the @nt<derived_type_definition>.]
address@hidden
+  This restriction does not apply to the ancestor type of a private
+  extension @em see @RefSecNum(Private Types and Private Extensions);
+  such a type need not be completely defined prior to the
+  @nt<private_extension_declaration>. However, the restriction
+  does apply to record extensions, so the ancestor type will
+  have to be completely defined prior to the @nt<full_type_declaration>
+  corresponding to the @nt<private_extension_declaration>.
address@hidden
address@hidden
+  We originally hoped we could relax this restriction.
+  However, we found it too complex to specify the rules for
+  a type derived from an incompletely defined limited type that
+  subsequently became nonlimited.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00401-01]}
address@hidden extension}
+If there is a @nt<record_extension_part>, the derived type is
+called a @i(record extension) of the parent type.
+A @nt<record_extension_part> shall be provided if and only if
+the parent type is a tagged address@hidden,New=[ @Redundant[An
address@hidden shall be provided only if
+the parent type is a tagged type.]],Old=[]}
address@hidden(TheProof)
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00401-01]}
+  @ChgAdded{Version=[2],Text=[The syntax only allows an @nt{interface_list}
+  to appear with a @nt{record_extension_part}, and a @nt{record_extension_part}
+  can only be provided if the parent type is a tagged type. We give the last
+  sentence anyway for completeness.]}
address@hidden(TheProof)
address@hidden(ImplNote)
+  We allow a record extension to inherit discriminants;
+  an early version of Ada 9X did not.
+  If the parent subtype is unconstrained, it can be implemented
+  as though its discriminants were repeated in a new
+  @nt{known_discriminant_part} and then used to constrain the old ones
+  one-for-one.
+  However, in an extension aggregate, the discriminants in this case
+  do not appear in the component association list.
address@hidden(ImplNote)
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00114-01]}
+  @ChgAdded{Version=[2],Type=[Leading],address@hidden leading}
+  This rule needs to be rechecked in the visible
+  part of an instance of a generic address@hidden,New=[ because of the
+  @lquotes@;only address@hidden@; part of the rule. For example:],Old=[]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key{type} T @key{is private};
address@hidden P @key{is}
+   @key{type} Der @key{is new} T;
address@hidden P;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden I @key{is new} P (Some_Tagged_Type); -- 
@RI[illegal]]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00114-01]}
+  @ChgAdded{Version=[2],Text=[The instantiation is illegal because a tagged
+  type is being extended in the visible part without a
+  @nt{record_extension_part}. Note that this is legal in the private part or
+  body of an instance, both to avoid a contract model violation, and because
+  no code that can see that the type is actually tagged can also see the
+  derived type declaration.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[No recheck is needed for derived types with
+  a @nt{record_extension_part}, as that has to be derived from something that
+  is known to be tagged (otherwise the template is illegal).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00419-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0096-1]}
address@hidden,Text=[If the reserved word @key{limited} appears in a
address@hidden, the parent type shall be a limited
address@hidden,New=[ If the parent type is a tagged formal type,
+then in addition to the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}), this rule applies also in
+the private part of an instance of a
+generic address@hidden contract issue}],Old=[]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We allow @key{limited} because we don't inherit
+  limitedness from interfaces, so we must have a way to derive a limited type
+  from interfaces. The word @key{limited} has to be legal when the parent
+  @i{could be} an interface, and that includes generic formal abstract types.
+  Since we have to allow it in this case, we might as well allow it everywhere
+  as documentation, to make it explicit that the type is limited.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[However, we do not want to allow @key{limited}
+  when the parent is nonlimited: limitedness cannot change in a derivation
+  tree.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If the parent type is an untagged limited formal
+  type with an actual type that is nonlimited, we allow derivation as a limited
+  type in the private part or body as no place could have visibility on the
+  resulting type where it was known to be nonlimited (outside of the instance).
+  (See the previous paragraph's annotations for an explanation of this.)
+  However, if the parent type is a tagged limited formal type with an actual
+  type that is nonlimited, it would be possible to pass a value of the limited
+  type extension to a class-wide type of the parent, which would be nonlimited.
+  That's too weird to allow (even though all of the extension components would
+  have to be nonlimited because the rules of @RefSecNum{Type Extensions} are
+  rechecked), so we have a special rule to prevent that in the private part
+  (type extension from a formal type is illegal in a generic package body).]}
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(subtype)}
address@hidden, Sec=(subtype)}
+The first subtype of the derived type is
+unconstrained if a @nt{known_discriminant_part}
+is provided in the declaration of the derived type, or if the
+parent subtype is unconstrained.
address@hidden constraint}
+Otherwise, the constraint
+of the first subtype @i(corresponds) to that of the parent subtype
+in the following sense: it is the same as that of the parent subtype
+except that for a range constraint (implicit or explicit), the value of
+each bound of its range is replaced by the corresponding value
+of the derived type.
address@hidden(Discussion)
+  A @nt<digits_constraint> in a @nt<subtype_indication> for
+  a decimal fixed point subtype always imposes a range constraint,
+  implicitly if there is no explicit one given.
+  See @RefSec(Fixed Point Types).
address@hidden(Discussion)
+
address@hidden,Kind=[Added],ARef=[AI95-00231-01]}
address@hidden,Text=[The first subtype of the derived type excludes null
+(see @RefSecNum{Access Types}) if and only if the parent subtype excludes 
null.]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0110-1]}
address@hidden@keepnext@;The 
@Chg{Version=[3],address@hidden@PDefn{characteristics}
+and implicitly declared primitive subprograms],Old=[characteristics]} of the
+derived type are defined as follows:
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0110-1]}
+  @ChgAdded{Version=[3],Text=[The characteristics of a type do not include its
+  primitive subprograms (primitive subprograms include predefined operators).
+  The rules governing availability/visibility and inheritance of 
characteristics
+  are separate from those for primitive subprograms.]}
address@hidden
+
address@hidden(itemize)
address@hidden,Kind=[Revised],ARef=[AI95-00251-01],ARef=[AI95-00401-01],ARef=[AI95-00442-01]}
address@hidden,address@hidden the parent type or a progenitor type
+belongs to a class of types, then the derived type also belongs to that class.]
+The following sets of types, as well as any higher-level sets composed from
+them, are classes in this address@hidden, and hence the characteristics
+defining these classes are inherited by derived types from their parent or
+progenitor types]: signed integer, modular integer, ordinary fixed, decimal
+fixed, floating point, enumeration, boolean, character, access-to-constant,
+general access-to-variable, pool-specific access-to-variable,
+access-to-subprogram, array, string, non-array composite, nonlimited, untagged
+record, tagged, task, protected, and synchronized tagged],
+Old=[Each class of types that includes the parent type also includes
+the derived type]}.
address@hidden
+  This is inherent in our notion
+  of a @lquotes@;address@hidden@; of types. It is not mentioned in the
+  initial definition of @lquotes@;address@hidden@; since at that point
+  type derivation has not been defined. In any case, this rule
+  ensures that every class of types is closed under
+  derivation.
address@hidden
+
+If the parent type is an elementary type or an array type, then the
+set of possible values of the derived type
+is a copy of the set of possible values of the parent type.
+For a scalar type, the base range of the derived type is the same
+as that of the parent type.
address@hidden
+  The base range of a type defined by an @nt<integer_type_definition>
+  or a @nt<real_type_definition> is determined by the @ntf<_definition>,
+  and is not necessarily the same as that of the corresponding
+  root numeric type from which the newly defined type is implicitly
+  derived. Treating numerics types as implicitly derived from one of
+  the two root numeric types is simply to link them into a type hierarchy;
+  such an implicit derivation does not follow all the rules given here
+  for an explicit @nt<derived_type_definition>.
address@hidden
+
+If the parent type is a composite type other than an array type,
+then the components,
+protected subprograms, and entries
+that are declared for the derived type are as follows:
address@hidden(inneritemize)
+  The discriminants specified by a new @nt{known_discriminant_part},
+  if there is one;
+  otherwise, each discriminant of the parent type
+  (implicitly declared in the same order with the same specifications) @em
+  @Defn{inherited discriminant}
+  @Defn{inherited component}
+  in the latter case, the discriminants are said to be @i(inherited),
+  or if unknown in the parent, are also unknown in the derived type;
+
+  Each nondiscriminant component, entry, and protected subprogram
+  of the parent type, implicitly declared in the same order
+  with the same declarations;
+  @Defn{inherited component}
+  @Defn{inherited protected subprogram}
+  @Defn{inherited entry}
+  these components, entries, and protected subprograms are said to be 
@i(inherited);
+  @begin{Ramification}
+
+    The profiles of entries and protected subprograms do
+    not change upon type derivation, although the type of the
+    @lquotes@;address@hidden@; parameter identified by the @nt<prefix> of
+    the @nt<name> in a call address@hidden
+  @begin{Honest}
+
+  Any name in the parent @nt{type_declaration} that denotes the
+  current instance of the type is replaced with a name denoting the
+  current instance of the derived type, converted to the parent type.
+
+  @end{Honest}
+
+  Each component declared in a
+  @nt<record_extension_part>, if any.
address@hidden(inneritemize)
+
address@hidden@;Declarations of components, protected subprograms,
+and entries, whether implicit or explicit,
+occur immediately within the declarative region of
+the type, in the order indicated above,
+following the parent @nt<subtype_indication>.
address@hidden(Discussion)
+  The order of declarations within the region matters
+  for @nt{record_aggregate}s and @nt<extension_aggregate>s.
address@hidden(Discussion)
address@hidden
+  In most cases, these things are implicitly declared
+  @i{immediately} following the parent @nt<subtype_indication>.
+  However, @RefSec{Private Operations} defines some cases in which
+  they are implicitly declared later, and some cases in which
+  the are not declared at all.
address@hidden
address@hidden
+  The place of the implicit declarations of inherited components matters
+  for visibility @em they are not visible in the
+  @nt<known_discriminant_part> nor in the parent @nt<subtype_indication>,
+  but are usually visible within the
+  @nt<record_extension_part>, if any
+  (although there are restrictions on their use).
+  Note that a discriminant specified in a new
+  @nt<known_discriminant_part> is
+  not considered @lquotes@;address@hidden@; even if it has the same name
+  and subtype as a discriminant of the parent type.
address@hidden
+
address@hidden,Kind=[Deleted],ARef=[AI95-00419-01]}
address@hidden,Text=[The derived type is limited if and
+only if the parent type is limited.]}
address@hidden rule is normatively in @RefSecNum{Limited Types}, and we don't
+want it scattered everywhere.}
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00419-01]}
+  @ChgDeleted{Version=[2],Text=[The derived type can become nonlimited if
+  the derivation takes place in the visible part of a child package,
+  and the parent type is nonlimited as viewed from the
+  private part of the child package @em see @RefSecNum(Limited Types).]}
address@hidden
+
address@hidden each predefined operator of the parent type,
+there is a corresponding predefined operator of the derived type.]
address@hidden(TheProof)
+  This is a ramification of the fact that each class that includes
+  the parent type also includes the derived type,
+  and the fact that the set of predefined operators that is defined for
+  a type, as described in
+  @RefSecNum(Operators and Expression Evaluation), is determined by
+  the classes to which it belongs.
address@hidden(TheProof)
address@hidden(Reason)
+  Predefined operators are handled separately because
+  they follow a slightly different rule
+  than user-defined primitive subprograms. In particular
+  the systematic replacement described below does not apply fully to the
+  relational operators for Boolean and the exponentiation
+  operator for Integer. The relational operators for a type
+  derived from Boolean still return Standard.Boolean. The
+  exponentiation operator for a type derived from Integer
+  still expects Standard.Integer for the right operand.
+  In addition, predefined operators "reemerge" when a type
+  is the actual type corresponding to a generic formal type,
+  so they need to be well defined even if hidden by user-defined
+  primitive subprograms.
address@hidden(Reason)
+
address@hidden,Kind=[Revised],ARef=[AI95-00401-01]}
address@hidden subprogram}
+For each user-defined primitive subprogram (other than a user-defined
+equality operator @em see below) of the parent address@hidden,New=[ or of a
+progenitor type],Old=[]} that already exists at the place of the
address@hidden, there exists a corresponding @i(inherited)
+primitive subprogram of the derived type
+with the same defining name.
address@hidden operator],Sec=(special inheritance rule for tagged types)}
+Primitive user-defined equality operators of the parent
address@hidden,New=[ and any progenitor types],Old=[]} are also
+inherited by the derived type, except when
+the derived type is a nonlimited record extension, and
+the inherited operator would have a profile that is type
+conformant with the profile of the corresponding
+predefined equality operator; in this case, the user-defined
+equality operator is not inherited, but is rather incorporated into
+the implementation of the predefined equality operator of the record extension
+(see @RefSecNum(Relational Operators and Membership Tests)).
address@hidden conformance}
address@hidden
+  We say @lquotes@;...already address@hidden@; rather than @lquotes@;is 
address@hidden@; or @lquotes@;has
+  been address@hidden@; because there are certain operations that are declared
+  later, but still exist at the place of the
+  @nt{derived_type_definition},
+  and there are operations that are never declared, but still exist.
+  These cases are explained in @RefSecNum{Private Operations}.
+
+  Note that nonprivate extensions can appear only after the last
+  primitive subprogram of the parent @em the freezing rules ensure this.
address@hidden
address@hidden
+  A special case is made for the equality operators on nonlimited
+  record extensions
+  because their predefined equality operators are already defined in terms
+  of the primitive equality operator of their parent type (and of the
+  tagged components of the extension part). Inheriting the parent's
+  equality operator as is would be undesirable, because it would ignore
+  any components of the extension part.
+  On the other hand, if the parent type is limited, then any user-defined
+  equality operator is inherited as is, since there is no predefined
+  equality operator to take its place.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00114-01]}
+  Because user-defined equality operators are not inherited
+  by @Chg{Version=[2],New=[nonlimited ],Old=[]}record extensions, the
+  formal parameter names of = and /=
+  revert to Left and Right, even if different formal parameter names
+  were used in the user-defined equality operators of the parent type.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00401-01]}
+  @ChgAdded{Version=[2],Text=[This rule only describes what operations
+  are inherited; the rules that describe what happens when there are
+  conflicting inherited subprograms are found in @RefSecNum{Visibility}.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00401-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0164-1],ARef=[AI05-0240-1]}
address@hidden@;The profile of an inherited subprogram
+(including an inherited enumeration literal) is obtained
+from the profile of the corresponding
+(user-defined) primitive subprogram of the address@hidden,New=[ or 
progenitor],Old=[]}
+type, after systematic replacement of each
+subtype of its profile (see
address@hidden Declarations})
+that is of the address@hidden,New=[ or progenitor],Old=[]}
address@hidden,New=[, other than those subtypes
+found in the designated profile of an @nt{access_definition},],Old=[]}
+with a @i(corresponding subtype) of the derived type.
address@hidden subtype}
+For a given subtype of the address@hidden,New=[ or progenitor],Old=[]} type,
+the corresponding subtype of the derived type is defined as follows:
address@hidden(inneritemize)
+  If the declaration of the derived type has neither a
+  @nt<known_discriminant_part> nor a @nt<record_extension_part>,
+  then the corresponding subtype
+  has a constraint that corresponds (as defined above for the first
+  subtype of the derived type) to that of the given subtype.
+
+  If the derived type is a record extension, then the
+  corresponding subtype is the first subtype of the derived type.
+
+  If the derived type has a new @nt<known_discriminant_part>
+  but is not a record extension,
+  then the corresponding subtype is constrained
+  to those values that when converted to the parent type belong to
+  the given subtype (see @RefSecNum(Type Conversions)).
+  @PDefn2{Term=[implicit subtype conversion],Sec=(derived type discriminants)}
+  @begin{Reason}
+    An inherited subprogram of an untagged type has an Intrinsic
+    calling convention, which precludes the use of the Access
+    attribute.
+    We preclude 'Access because correctly performing
+    all required constraint checks on an indirect call to such
+    an inherited subprogram was felt to impose an undesirable
+    implementation burden.
+
+    @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0164-1]}
+    @ChgAdded{Version=[3],Text=[Note that the exception to substitution of the
+    parent or progenitor type applies only in the profiles of anonymous
+    access-to-subprogram types. The exception is necessary to avoid calling
+    an access-to-subprogram with types and/or constraints different than
+    expected by the actual routine.]}
+  @end{Reason}
address@hidden(inneritemize)
+
address@hidden,Kind=[Revised],ARef=[AI95-00401-01]}
address@hidden@;The same formal parameters have @nt<default_expression>s in
+the profile of the inherited subprogram. @Redundant[Any type mismatch due
+to the systematic replacement of the address@hidden,New=[ or 
progenitor],Old=[]}
+type by the derived type is handled as part of the normal
+type conversion associated with parameter
+passing @em see @RefSecNum(Parameter Associations).]
address@hidden(Reason)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00401-01]}
+  We don't introduce the type conversion explicitly here
+  since conversions to record extensions or on access parameters
+  are not generally legal. Furthermore, any type conversion would
+  just be "undone" since the @Chg{Version=[2],New=[],Old=[parent's ]}subprogram
+  @Chg{Version=[2],New=[of the parent or progenitor ],Old=[]}is ultimately 
being
+  called address@hidden,New=[ (Null procedures can be inherited from
+  a progenitor without being overridden, so it is possible to call subprograms
+  of an interface.)],Old=[]}
address@hidden(Reason)
+
address@hidden(itemize)  @Comment{end of characteristics of derived type}
+
address@hidden,Kind=[Revised],ARef=[AI95-00401-01]}
+If a primitive subprogram of the address@hidden,New=[ or progenitor],
+Old=[]} type is visible at the
+place of the @nt{derived_type_definition},
+then the corresponding inherited subprogram is implicitly declared
+immediately after the @nt{derived_type_definition}.
+Otherwise, the inherited subprogram is implicitly declared later
+or not at all,
+as explained in @RefSecNum{Private Operations}.
+
address@hidden type}
+A derived type can also be defined by a @nt<address@hidden@!declaration>
+(see @RefSecNum(Private Types and Private Extensions))
+or a @nt<address@hidden@address@hidden>
+(see @RefSecNum(Formal Private and Derived Types)).
+Such a derived type is a partial
+view of the corresponding full or actual type.
+
+All numeric types are derived types, in that
+they are implicitly derived from a corresponding
+root numeric type (see @RefSecNum(Integer Types) and @RefSecNum(Real Types)).
+
address@hidden
+
address@hidden
address@hidden, Sec=(derived_type_definition)}
+The elaboration of a @nt<derived_type_definition>
+creates the derived type and its first subtype,
+and consists of the elaboration of the @nt<address@hidden>
+and the @nt<address@hidden@!part>, if any.
+If the @address@hidden depends on a discriminant,
+then only those expressions that do not depend on a discriminant
+are evaluated.
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Text=[We don't mention the @nt{interface_list}, because
+  it does not need elaboration (see @RefSecNum{Interface Types}). This is
+  consistent with the handling of @nt{discriminant_part}s, which aren't
+  elaborated either.]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00391-01],ARef=[AI95-00401-01]}
address@hidden, Sec=(call on an inherited subprogram)}
+For the execution of a call on an inherited subprogram,
+a call on the corresponding primitive subprogram of the
address@hidden,New=[ or progenitor],Old=[]} type is
+performed; the normal conversion of each actual parameter
+to the subtype of the corresponding formal parameter
+(see @RefSecNum(Parameter Associations))
+performs any necessary type conversion as well.
+If the result type of the inherited subprogram
+is the derived type, the result of calling the
address@hidden,New=[],Old=[parent's address@hidden,
+New=[ of the parent or progenitor],Old=[]} is converted to the
+derived address@hidden,New=[, or in the case of a
+null extension, extended to the derived type using the equivalent of an
address@hidden with the original result as the @nt{ancestor_part}
+and @key{null record} as the @nt{record_component_association_list}],Old=[]}.
address@hidden subtype conversion],Sec=(result of inherited function)}
address@hidden(Discussion)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00391-01]}
+  If an inherited function returns the derived type, and the type
+  is a @Chg{Version=[2],New=[nonnull ],Old=[]}record extension, then the
+  inherited function @Chg{Version=[2],New=[shall be overridden, unless
+  the type is abstract (in which case the function ],Old=[]}is abstract,
+  and (unless overridden) cannot be called except via
+  a dispatching address@hidden,New=[)],Old=[]}.
+  See @RefSecNum(Abstract Types and Subprograms).
address@hidden(Discussion)
address@hidden
+
address@hidden
address@hidden under derivation}
+Classes are closed under derivation @em
+any class that contains a type also contains its derivatives.
+Operations available for a given class of types
+are available for the derived types in that class.
+
+Evaluating an inherited enumeration literal
+is equivalent to evaluating the corresponding enumeration literal
+of the parent type, and then converting the result to
+the derived type. This follows from their equivalence to
+parameterless functions.
address@hidden subtype conversion],Sec=(inherited enumeration literal)}
+
+A generic subprogram is not a subprogram,
+and hence cannot be a primitive subprogram and
+cannot be inherited by a derived type. On the other hand,
+an instance of a generic subprogram can be a primitive subprogram,
+and hence can be inherited.
+
+If the parent type is an access type, then the parent
+and the derived type share the same storage pool;
+there is a @key{null} access value for the derived type
+and it is the implicit initial value for the type.
+See @RefSecNum(Access Types).
+
+If the parent type is a boolean type, the predefined relational operators
+of the derived type deliver a result of the predefined type Boolean
+(see @RefSecNum(Relational Operators and Membership Tests)).
+If the parent type is an integer type, the right operand of the
+predefined exponentiation operator is of the predefined type Integer
+(see @RefSecNum(Highest Precedence Operators)).
+
+Any discriminants of the parent type are either all inherited, or
+completely replaced with a new set of discriminants.
+
+For an inherited subprogram, the subtype of a formal parameter
+of the derived type need not have any value in common with the first
+subtype of the derived type.
address@hidden(TheProof)
+  @Leading@;This happens when the parent subtype is constrained to a range
+  that does not overlap with the range of a subtype of the parent
+  type that appears in the profile of
+  some primitive subprogram of the parent type.
+  For example:
address@hidden(example)
address@hidden(type) T1 @key(is range) 1..100;
address@hidden(subtype) S1 @key(is) T1 @key(range) 1..10;
address@hidden(procedure) P(X : @key[in] S1);  @RI{-- P is a primitive 
subprogram}
address@hidden(type) T2 @key(is new) T1 @key(range) 11..20;
address@hidden(-- implicitly declared:)
address@hidden @key(procedure) P(X : @key[in] T2'Base @key(range) 1..10);}
address@hidden      X cannot be in T2'First .. T2'Last}
address@hidden(example)
address@hidden(TheProof)
+
+If the reserved word @key{abstract} is given in the declaration of a
+type, the type is abstract (see @RefSecNum{Abstract Types and Subprograms}).
+
address@hidden,Kind=[Added],ARef=[AI95-00251-01],ARef=[AI95-00401-01]}
address@hidden,Text=[An interface type that has a progenitor type
address@hidden@;is derived address@hidden@; that type.
+A @nt{derived_type_definition}, however, never defines an interface type.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01]}
address@hidden,Text=[It is illegal for the parent type of a
address@hidden to be a synchronized tagged type.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],address@hidden extensions} prohibits record
+  extensions whose parent type is a synchronized tagged type, and this
+  @Chg{Version=[3],New=[subclause],Old=[clause]}
+  requires tagged types to have a record extension. Thus there are no legal
+  derivations. Note that a synchronized interface can be used as a progenitor
+  in an @nt{interface_type_definition} as well as in task and protected types,
+  but we do not allow concrete extensions of any synchronized tagged type.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of derived type declarations:)
address@hidden(Example)
address@hidden(type) Local_Coordinate @key(is) @key(new) Coordinate;   
address@hidden  two different types]
address@hidden(type) Midweek @key(is) @key(new) Day @key(range) Tue .. Thu;  
address@hidden  see @RefSecNum(Enumeration Types)]
address@hidden(type) Counter @key(is) @key(new) Positive;              
address@hidden  same range as Positive ]
+
address@hidden(type) Special_Key @key(is) @key(new) Key_Manager.Key;   
address@hidden  see @RefSecNum(Private Operations)]
+  address@hidden the inherited subprograms have the following specifications: ]
+  address@hidden         procedure Get_Key(K : out Special_Key);]
+  address@hidden         function "<"(X,Y : Special_Key) return Boolean;]
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden with Ada 83}
+When deriving from a (nonprivate, nonderived) type in the same
+visible part in which it is defined, if a predefined
+operator had been overridden prior to the derivation,
+the derived type will inherit the user-defined operator rather
+than the predefined operator. The work-around (if the new behavior
+is not the desired behavior) is to move the definition of the
+derived type prior to the overriding of any predefined operators.
+
address@hidden
+
address@hidden
address@hidden with Ada 83}
address@hidden@;When deriving from a (nonprivate, nonderived) type in the same
+visible part in which it is defined, a primitive subprogram of the
+parent type declared before the derived type will be inherited by the
+derived type. This can cause upward incompatibilities in cases like
+this:
address@hidden
+   @key[package] P @key[is]
+      @key[type] T @key[is] (A, B, C, D);
+      @key[function] F( X : T := A ) @key[return] Integer;
+      @key[type] NT @key[is] @key[new] T;
+      address@hidden inherits F as}
+      address@hidden function F( X : NT := A ) return Integer;}
+      address@hidden in Ada 95 only}
+      ...
+   @key[end] P;
+   ...
+   @key[use] P;  address@hidden Only one declaration of F from P is 
use-visible in}
+           address@hidden Ada 83;  two declarations of F are use-visible in}
+           address@hidden Ada 95.}
address@hidden
+   ...
+   @key[if] F > 1 @key[then] ... address@hidden legal in Ada 83, ambiguous in 
Ada 95}
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax for a @nt{derived_type_definition} is amended to
+include an optional @nt{record_extension_part}
+(see @RefSecNum(Type Extensions)).
+
+A derived type may override the discriminants of the parent by giving a
+new @nt{discriminant_part}.
+
+The parent type in a @nt<derived_type_definition>
+may be a derived type defined
+in the same visible part.
+
+When deriving from a type in the same visible part in which it is defined,
+the primitive subprograms declared prior to the derivation
+are inherited as primitive subprograms of the derived type.
+See @RefSecNum(Classification of Operations).
address@hidden
+
address@hidden
+We now talk about the classes to which a type belongs, rather than
+a single class.
+
address@hidden,Kind=[Revised],address@hidden here,
+and broken since 7.6.1 defined "collection"}
address@hidden,Text=[As explained in Section 13, the concept of
+"storage pool" replaces the Ada 83 concept of "collection." These concepts are
+similar, but not the same.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01],ARef=[AI95-00401-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  A derived type may inherit from multiple (interface) progenitors,
+  as well as the parent type @em see @RefSec{Interface Types}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00419-01]}
+  @ChgAdded{Version=[2],Text=[A derived type may specify that it is a limited
+  type. This is required for interface ancestors (from which limitedness is
+  not inherited), but it is generally useful as documentation of limitedness.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00391-01]}
+  @ChgAdded{Version=[2],Text=[Defined the result of functions for
+  null extensions (which we no longer require to be overridden - see
+  @RefSecNum{Abstract Types and Subprograms}).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[Defined the term @lquotes@;category of
+  address@hidden and used it in wording elsewhere; also specified the
+  language-defined categories that form classes of types (this was never
+  normatively specified in Ada 95).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0096-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Added a (re)check that limited type extensions never are derived from
+  nonlimited types in generic private parts. This is disallowed as it would
+  make it possible to pass a limited object to a nonlimited class-wide type,
+  which could then be copied. This is only possible using Ada 2005 syntax,
+  so examples in existing programs should be rare.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0110-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added wording to clarify 
that
+  the characteristics of derived types are formally defined here. (This is the
+  only place in the Standard that actually spells out what sorts of things
+  are actually characteristics, which is rather important.)]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0164-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added wording to ensure 
that
+  anonymous access-to-subprogram types don't get modified on derivation.]}
address@hidden
+
+
address@hidden Classes}
+
address@hidden
+In addition to the various language-defined classes of types,
+types can be grouped into @i(derivation classes).
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00251-01],ARef=[AI95-00401-01]}
address@hidden from], Sec=(directly or indirectly)}
+A derived type is @i(derived from) its parent type @i(directly);
+it is derived
address@hidden(indirectly) from any type from which its parent type is 
address@hidden,
+New=[ A derived type, interface type, type extension, task type, protected 
type,
+or formal derived type is also derived from every ancestor of each of its
+progenitor types, if any.],Old=[]}
address@hidden class], Sec=(for a type)}
address@hidden type], Sec=(of a class)}
address@hidden at a type}
+The derivation class of types for a type @i(T) (also called
+the class @i(rooted) at @i(T)) is
+the set consisting of @i(T) (the @i(root type) of the class)
+and all types derived from @i(T) (directly or indirectly) plus
+any associated universal or class-wide types (defined below).
address@hidden
+  Note that the definition of @lquotes@;derived address@hidden@; is a recursive
+  definition.
+  We don't define a root type for all interesting
+  language-defined classes, though presumably we could.
address@hidden
address@hidden
+  By the class-wide type @lquotes@;address@hidden@; with a type @i(T),
+  we mean the type @i(T)'Class.
+  Similarly, the universal type associated with
+  @i{root_integer}, @i{root_real}, and @i{root_fixed} are
+  @i{universal_integer}, @i{universal_real}, and @i{universal_fixed},
+  respectively.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01]}
+Every type is either a @i(specific) type, a @i(class-wide) type,
+or a @i(universal) type.
address@hidden type}
+A specific type is
+one defined by a @nt<type_declaration>,
+a @nt<formal_type_declaration>, or a full type definition
+embedded in @Chg{Version=[2],New=[another construct],Old=[a declaration
+for an object]}.
+Class-wide and universal types are implicitly defined, to act
+as representatives for an entire class of types, as follows:
address@hidden(Honest)
+  The root types @i(root_integer), @i(root_real), and
+  @i(root_fixed) are also specific
+  types. They are declared in the specification of package Standard.
address@hidden(Honest)
address@hidden(Description)
address@hidden type}Class-wide types
address@hidden types are defined for @Redundant[(and belong to)]
+each derivation class rooted
+at a tagged type (see @RefSecNum(Tagged Types and Type Extensions)).
+Given a subtype S of a tagged type @i(T),
+S'Class is the @nt<subtype_mark> for a corresponding
+subtype of the tagged class-wide
+type @i(T)'Class. Such types are called
address@hidden@;address@hidden@; because when a formal parameter is defined
+to be of a class-wide type @i(T)'Class, an actual parameter
+of any type in the derivation class rooted at @i(T) is acceptable
+(see @RefSecNum(The Context of Overload Resolution)).
+
address@hidden@Defn{first subtype}
+The set of values for a class-wide type @i(T)'Class is the discriminated
+union of the set of values of each specific type in the
+derivation class rooted at @i(T) (the tag acts as the implicit discriminant
address@hidden see @RefSecNum(Tagged Types and Type Extensions)).
+Class-wide types have no primitive subprograms of their own.
+However, as explained in @RefSecNum(Dispatching Operations of Tagged Types),
+operands of a class-wide type @i(T)'Class can be used as part
+of a dispatching call on a primitive subprogram of the type @i(T).
+The only components @Redundant[(including discriminants)] of
address@hidden(T)'Class that are visible are those of @i(T).
+If S is a first subtype,
+then S'Class is a first subtype.
address@hidden
+We want S'Class to be a first subtype when S is,
+so that an @address@hidden@!clause} like
address@hidden@key[for] S'Class'Output @key[use] ...;@rquotes@;
+will be legal.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01]}
address@hidden type}Universal types
address@hidden types
+are defined for @Redundant[(and belong to)] the integer,
+real, @Chg{Version=[2],New=[],Old=[and ]}fixed address@hidden,
+New=[, and access],Old=[]} classes,
+and are referred to in this standard as respectively,
address@hidden(universal_integer), @i(universal_real), @Chg{Version=[2],New=[],
+Old=[and address@hidden(universal_fixed)@Chg{Version=[2],
+New=[, and @i(universal_access)@Chg{Version=[3],
address@hidden@address@hidden@PDefn{universal_access}],Old=[]}],Old=[]}.
+These are analogous to class-wide types for these language-defined
address@hidden,New=[elementary],Old=[numeric]} classes.
+As with class-wide types, if a formal parameter is of a universal type,
+then an actual parameter of any type in the corresponding class
+is acceptable. In addition, a value of a universal type
+(including an integer or real @nt<numeric_literal>@Chg{Version=[2],New=[, or
+the literal @key{null}],Old=[]}) is @lquotes@;address@hidden@;
+in that it is acceptable where some particular type in the
+class is expected
+(see @RefSecNum(The Context of Overload Resolution)).
+
address@hidden@;The set of values of a universal type is the undiscriminated 
union
+of the set of values possible for any definable type in the associated class.
+Like class-wide types, universal types have no
+primitive subprograms of their own. However, their @lquotes@;address@hidden@; 
allows
+them to be used as operands with the primitive subprograms of any
+type in the corresponding class.
address@hidden(Discussion)
+  A class-wide type is only class-wide in one direction,
+  from specific to class-wide, whereas
+  a universal type is class-wide (universal) in both directions,
+  from specific to universal and back.
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00230-01]}
+  We considered defining class-wide or perhaps universal types for
+  all derivation classes, not just tagged classes and these @Chg{Version=[2],
+  New=[four elementary],Old=[three numeric]} classes. However, this was felt
+  to overly weaken the strong-typing model in some situations. Tagged types
+  preserve strong type distinctions thanks to the run-time tag. Class-wide
+  or universal types for untagged types would weaken the compile-time
+  type distinctions without providing a compensating run-time-checkable
+  distinction.
+
+  We considered defining standard names for the universal
+  numeric types so they could be used in formal parameter specifications.
+  However, this was felt to impose an undue implementation burden for
+  some implementations.
address@hidden(Discussion)
address@hidden(Honest)
+  Formally, the set of values of a universal type is actually a @i(copy) of
+  the undiscriminated union of the values of the types in its
+  class. This is because we
+  want each value to have exactly one type, with explicit or implicit
+  conversion needed to go between types. An alternative,
+  consistent model would be to associate a class, rather than
+  a particular type, with a value,
+  even though any given expression would have a particular type.
+  In that case, implicit type conversions would not generally need to
+  change the value, although an associated subtype conversion might
+  need to.
address@hidden(Honest)
address@hidden(Description)
+
address@hidden
address@hidden
+The integer and real numeric classes each have a specific root type in
+addition to their universal type, named respectively @i(root_integer)
+and @i(root_real).
+
address@hidden, Sec=(a type)}
+A class-wide or universal type is said to @i(cover) all of the types
+in its class. A specific type covers only itself.
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00251-01]}
address@hidden, Sec=(of a type)}
+A specific type @i(T2) is defined to be a @i(descendant) of a
+type @i(T1) if @i(T2) is the same as @i(T1), or if @i(T2) is derived
+(directly or indirectly) from @i(T1). A class-wide type @i(T2)'Class is
+defined to be a descendant of type @i(T1) if @i(T2) is a descendant of @i(T1).
+Similarly, the @Chg{Version=[2],New=[numeric ],Old=[]}universal types are
+defined to be descendants of the root types of their classes.
address@hidden, Sec=(of a type)}
+If a type @i(T2) is a descendant of a type @i(T1),
+then @i(T1) is called an @i(ancestor) of @i(T2).
address@hidden ancestor], Sec=(of a type)}
address@hidden, Sec=(ultimate)}
address@hidden,New=[An],Old=[The]} @i(ultimate ancestor) of a type
+is @Chg{Version=[2],New=[an],Old=[the]} ancestor of
address@hidden,New=[that],Old=[the]} type that is not
address@hidden,New=[itself ],Old=[]}a descendant of any other
address@hidden,New=[ Every untagged type
+has a unique ultimate ancestor.],Old=[]}
address@hidden
+  A specific type is a descendant of itself.
+  Class-wide types are considered descendants of the corresponding
+  specific type, and do not have any descendants of their own.
+
+  A specific type is an ancestor of itself.
+  The root of a derivation class is an ancestor of all types in the
+  class, including any class-wide types in the class.
address@hidden
address@hidden(Discussion)
+  @address@hidden@;The terms root, parent, ancestor, and ultimate ancestor
+  are all related. For example:
+  @begin(Itemize)
+    @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00251-01]}
+    Each type has at most one parent, and one
+    or more ancestor types; each @Chg{Version=[2],New=[untagged ],Old=[]}type
+    has exactly one ultimate ancestor.
+    In Ada 83, the term @lquotes@;parent address@hidden@; was sometimes used
+    more generally to include any ancestor type
+    (e.g. RM83-9.4(14)). In Ada 95, we restrict
+    parent to mean the immediate ancestor.
+
+    A class of types has at most one root type; a derivation class
+    has exactly one root type.
+
+    The root of a class is an ancestor of all of the types in the class
+    (including itself).
+
+    The type @i(root_integer) is the root of the integer class,
+    and is the ultimate ancestor of all integer types.
+    A similar statement applies to @i(root_real).
+  @end(Itemize)
address@hidden(Discussion)
+
address@hidden,Kind=[AddedNormal],Term=<Ancestor>,
+  Text=<@ChgAdded{Version=[2],Text=[An ancestor of a type is the type itself
+  or, in the case of a type derived from other types, its parent type or one
+  of its progenitor types or one of their ancestors. Note that ancestor and
+  descendant are inverse relationships.]}>}
+
address@hidden,Kind=[AddedNormal],Term=<Descendant>,
+  Text=<@ChgAdded{Version=[2],Text=[A type is a descendant of itself, its
+  parent and progenitor types, and their ancestors. Note that descendant and
+  ancestor are inverse relationships.]}>}
+
address@hidden, Sec=(from an ancestor type)}
+An inherited component @Redundant[(including an inherited discriminant)] of a
+derived type is inherited @i(from) a given
+ancestor of the type
+if the corresponding component was inherited by each derived type in the
+chain of derivations going back to the given ancestor.
+
address@hidden
+
address@hidden
+Because operands of a universal type are acceptable to the
+predefined operators of any type in their class, ambiguity can
+result. For @i(universal_integer) and @i(universal_real), this
+potential ambiguity is resolved by giving a preference
+(see @RefSecNum{The Context of Overload Resolution})
+to the predefined operators
+of the corresponding root types (@i(root_integer)
+and @i(root_real), respectively).
+Hence, in an apparently ambiguous expression like
address@hidden(Display)
+1 + 4 < 7
address@hidden(Display)
+
address@hidden@;where each of the literals is of type @i(universal_integer),
+the predefined operators of @i(root_integer) will be preferred over those
+of other specific integer types, thereby resolving the ambiguity.
address@hidden(Ramification)
+  Except for this preference, a root numeric type
+  is essentially like any other specific type in the
+  associated numeric class. In particular, the result of a
+  predefined operator of a root numeric type is not @lquotes@;address@hidden@;
+  (implicitly convertible) even if both operands were.
address@hidden(Ramification)
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01]}
+  @ChgAdded{Version=[2],Text=[Updated the wording to define the
+  @i{universal_access} type. This was defined to make @key{null} for
+  anonymous access types sensible.]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01],ARef=[AI95-00401-01]}
+  @ChgAdded{Version=[2],Text=[The definitions of ancestors and descendants
+  were updated to allow multiple ancestors (necessary to support interfaces).]}
address@hidden
+
+
address@hidden Types}
+
address@hidden
address@hidden type}
address@hidden(Scalar) types comprise enumeration types, integer types, and 
real types.
address@hidden type}
+Enumeration types and integer types are called @i(discrete) types;
address@hidden number}
+each value of a discrete type has a @i(position number) which is an integer
+value.
address@hidden type}
+Integer types and real types are called @i(numeric) types.
address@hidden scalar types are ordered, that is, all
+relational operators are predefined for their values.]
+
address@hidden
+
address@hidden
address@hidden<range_constraint>,rhs=" @key{range} @Syn2{range}"}
+
+
address@hidden<range>,rhs=" @Syn2{range_attribute_reference}
+   | @Syn2{simple_expression} .. @Syn2{simple_expression}"}
address@hidden
address@hidden(Discussion)
+        These need to be @nt<simple_expression>s rather than
+        more general @nt<expression>s because ranges appear in
+        membership tests and other contexts where
+        @nt<expression> .. @nt<expression> would
+        be ambiguous.
address@hidden(Discussion)
+
address@hidden
address@hidden
address@hidden bound], Sec=(of a range)}
address@hidden bound], Sec=(of a range)}
address@hidden of a range}
+A @i(range) has a @i(lower bound) and an @i(upper bound) and
+specifies a subset of the values of some scalar type
+(the @i(type of the range)).
+A range with lower bound L and upper bound R is described by @lquotes@;L .. 
address@hidden@;.
address@hidden range}
+If R is less than L, then
+the range is a @i(null range), and specifies an
+empty set of values.
+Otherwise, the range specifies the values of the type from
+the lower bound to the upper bound, inclusive.
address@hidden, Sec=(to a range)}
+A value @i(belongs) to a range if it is of the type of the
+range, and is in the subset of values specified by the range.
address@hidden, Sec=(a range constraint)}
+A value @i(satisfies) a range constraint if it belongs to
+the associated range.
address@hidden, Sec=(one range in another)}
+One range is @i(included) in another if all values that
+belong to the first range also belong to the second.
address@hidden
+
address@hidden
address@hidden type], Sec=(range_constraint range)}
+For a @nt<subtype_indication> containing a @nt<range_constraint>, either
+directly or as part of some other @nt<scalar_constraint>,
+the type of the @nt<range> shall resolve to that of the type determined by
+the @nt<subtype_mark> of the @nt<subtype_indication>.
address@hidden type], Sec=(range simple_expressions)}
+For a @nt<range> of a given type,
+the @nt<simple_expression>s of the @nt<range> (likewise, the
address@hidden<simple_expression>s of the equivalent @nt<range> for a
address@hidden<range_attribute_reference>)
+are expected to be of the type of the @nt<range>.
address@hidden(Discussion)
+  In Ada 95, @nt<constraint>s
+  only appear within @nt<subtype_indication>s; things that look
+  like constraints that appear in type declarations are called
+  something else like @nt<real_range_specification>s.
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  We say "the expected type is ..." or "the type is expected to be ..."
+  depending on which reads better. They are fundamentally equivalent,
+  and both feed into the type resolution rules of 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+  @RefSecNum(The Context of Overload Resolution).
+
+  In some cases, it doesn't work to use expected types.
+  For example, in the above rule, we say that
+  the @lquotes@;type of the @nt<range> shall resolve to address@hidden@;
+  rather than @lquotes@;the expected type for the @nt<range> is 
address@hidden@;.
+  We then use @lquotes@;expected address@hidden@; for the bounds.
+  If we used @lquotes@;address@hidden@; at both points, there
+  would be an ambiguity, since one could apply the rules of
+  @RefSecNum{The Context of Overload Resolution}
+  either on determining the type of the range, or on determining the
+  types of the individual bounds. It is clearly important
+  to allow one bound to be of a universal type, and the other of
+  a specific type, so we need to use @lquotes@;expected address@hidden@; for 
the bounds.
+  Hence, we used @lquotes@;shall resolve address@hidden@; for the type of the 
range as a
+  whole.
+  There are other situations where @lquotes@;expected address@hidden@; is not 
quite
+  right, and we use @lquotes@;shall resolve address@hidden@; instead.
address@hidden(Discussion)
address@hidden
+
address@hidden
address@hidden range], Sec=(of a scalar type)}
+The @i(base range) of a scalar type is the range of
+finite values of the type that can be represented
+in every unconstrained object of the type;
+it is also the range supported at a minimum for
+intermediate values during the evaluation of expressions involving
+predefined operators of the type.
address@hidden
+Note that in some machine architectures intermediates
+  in an expression (particularly if static),
+  and register-resident variables might accommodate
+  a wider range. The base range does not include the values
+  of this wider range that are not assignable without overflow to
+  memory-resident address@hidden
address@hidden(Ramification)
+  @PDefn2{Term=[base range], Sec=(of an enumeration type)}
+  The base range of an enumeration type is the range of values
+  of the enumeration type.
address@hidden(Ramification)
address@hidden
+
+  If the representation supports infinities,
+  the base range is nevertheless restricted
+  to include only the representable finite values,
+  so that 'Base'First and 'Base'Last are always guaranteed to be address@hidden
address@hidden(Honest)
+  By a "value that can be assigned without overflow" we don't mean
+  to restrict ourselves to values that can be represented exactly.
+  Values between machine representable values can be assigned,
+  but on subsequent reading, a slightly different value might
+  be retrieved, as (partially) determined by the number of digits of
+  precision of the type.
address@hidden(Honest)
+
address@hidden, Sec=(subtype)}
address@hidden, Sec=(subtype)}
address@hidden constrained scalar subtype is one to which a range constraint
+applies.]
address@hidden, Sec=(of a scalar subtype)}
+The @i(range) of a constrained scalar subtype
+is the range associated with the range constraint of the subtype.
+The @i(range) of an unconstrained scalar subtype is the base range of
+its type.
address@hidden
+
address@hidden
address@hidden, Sec=(range with a scalar subtype)}
+A range is @i(compatible) with a scalar subtype if and only
+if it is either a null range
+or each bound of the range belongs to the range of the subtype.
address@hidden, Sec=(range_constraint with a scalar subtype)}
+A @nt<range_constraint> is @i(compatible) with a scalar subtype if and only if
+its range is compatible with the subtype.
address@hidden(Ramification)
+  Only @nt<range_constraint>s (explicit or implicit) impose conditions
+  on the values of a scalar subtype. The other @nt<scalar_constraint>s,
+  @nt<digits_constraint>s and @nt<delta_constraint>s impose conditions
+  on the subtype denoted by the @nt<subtype_mark> in a @nt<subtype_indication>,
+  but don't impose a condition on the values of the subtype being
+  defined. Therefore, a scalar subtype is not called @i(constrained)
+  if all that applies to it is a @nt<digits_constraint>.
+  Decimal subtypes are subtle, because a @nt<digits_constraint> without
+  a @nt<range_constraint> nevertheless includes an implicit
+  @nt<range_constraint>.
address@hidden(Ramification)
+
address@hidden, Sec=(range_constraint)}
+The elaboration of a @nt{range_constraint} consists of the
+evaluation of the @nt{range}.
address@hidden, Sec=(range)}
+The evaluation of a @nt{range} determines a lower bound and an upper bound.
+If @nt<simple_expression>s are given to specify bounds, the evaluation of
+the @nt<range> evaluates these @nt<simple_expression>s in an arbitrary order,
+and converts them to the type of the @nt<range>address@hidden 
order],Sec=[allowed]}
address@hidden subtype conversion],Sec=(bounds of a range)}
+If a @nt<range_attribute_reference> is given, the evaluation
+of the @nt<range>
+consists of the evaluation of the @nt<range_attribute_reference>.
+
address@hidden@i(Attributes)
+
address@hidden@keepnext@;For @PrefixType{every scalar subtype S},
+the following attributes are defined:
address@hidden(description)
address@hidden<S>, AttrName=<First>,
+  Text=[S'First denotes the lower bound of
+     the range of S. The value of this attribute is of the type
+     of S.]}
+     @begin{Ramification}
+Evaluating S'First never raises address@hidden
+
address@hidden<S>, AttrName=<Last>,
+  Text=[S'Last denotes the upper bound of
+     the range of S. The value of this attribute is of the type
+     of S.]}
+     @begin{Ramification}
+Evaluating S'Last never raises address@hidden
+
address@hidden<S>, AttrName=<Range>,
+  Text=[S'Range is equivalent to the @nt<range> S'First .. S'Last.]}
+
address@hidden<S>, AttrName=<Base>,
+  Text=[S'Base denotes an
+     unconstrained subtype of the type of S.
+     This unconstrained subtype is called the @i(base subtype) of the type.
+     address@hidden(base subtype), Sec=(of a type)}
+
address@hidden<S>, AttrName=<Min>,
+  Text=[S'Min denotes a function with the following specification:
address@hidden(Descexample)
address@hidden(function) S'Min(@RI(Left), @RI(Right) : S'Base)
+  @b(return) S'Base
address@hidden(Descexample)
+
+     @NoPrefix@;The function returns the lesser of the values
+     of the two parameters.]}
+     @begin{Discussion}
+     @Defn2{Term=[italics],Sec=(formal parameters of attribute functions)}
+     The formal parameter names are italicized because they cannot be
+     used in calls @em
+     see @RefSecNum{Subprogram Calls}.
+     Such a specification
+     cannot be written by the user because an @nt<attribute_reference>
+     is not permitted as the designator of a user-defined function, nor
+     can its formal parameters be anonymous.
+     @end{Discussion}
+
address@hidden<S>, AttrName=<Max>,
+  Text=[S'Max denotes a function with the following specification:
address@hidden(Descexample)
address@hidden(function) S'Max(@RI(Left), @RI(Right) : S'Base)
+  @b(return) S'Base
address@hidden(Descexample)
+
+     @NoPrefix@;The function returns the greater of the values of the two 
parameters.]}
+
address@hidden<S>, AttrName=<Succ>,
+  Text=[S'Succ denotes a function with the following specification:
address@hidden(Descexample)
address@hidden(function) S'Succ(@RI(Arg) : S'Base)
+  @b(return) S'Base
address@hidden(Descexample)
+
+     @address@hidden(Constraint_Error),Sec=(raised by failure of run-time 
check)}
+     For an enumeration type, the function returns the value
+     whose position number is one more than that of the value of @i(Arg);
+     @IndexCheck{Range_Check}
+     Constraint_Error is raised if there is no such value of the type.
+     For an integer type, the function returns the result of
+     adding one to the value of @i(Arg).
+     For a fixed point type, the function returns the result of
+     adding @i(small) to the value of @i(Arg).
+     For a floating point type, the
+     function returns the machine number (as defined
+     in @RefSecNum(Floating Point Types))
+     immediately above the value of @i(Arg);
+     @IndexCheck{Range_Check}
+     Constraint_Error is raised if there is no such machine number.]}
+     @begin{Ramification}
+S'Succ for a modular integer subtype wraps around
+       if the value of @i(Arg) is S'Base'Last. S'Succ for a signed integer
+       subtype might raise Constraint_Error if the value of @i(Arg) is
+       S'Base'Last, or it might return the out-of-base-range value
+       S'Base'Last+1, as is permitted for all predefined numeric address@hidden
+
address@hidden<S>, AttrName=<Pred>,
+  Text=[S'Pred denotes a function with
+     the following specification:
address@hidden(Descexample)
address@hidden(function) S'Pred(@RI(Arg) : S'Base)
+  @b(return) S'Base
address@hidden(Descexample)
+
+     @address@hidden(Constraint_Error),Sec=(raised by failure of run-time 
check)}
+     For an enumeration type, the function returns the value
+     whose position number is one less than that of the value of @i(Arg);
+     @IndexCheck{Range_Check}
+     Constraint_Error is raised if there is no such value of the type.
+     For an integer type, the function returns the result of
+     subtracting one from the value of @i(Arg).
+     For a fixed point type, the function returns the result of
+     subtracting @i(small) from the value of @i(Arg).
+     For a floating point type, the
+     function returns the machine number (as defined
+     in @RefSecNum(Floating Point Types))
+     immediately below the value of @i(Arg);
+     @IndexCheck{Range_Check}
+     Constraint_Error is raised if there is no such machine number.]}
+     @begin{Ramification}
+S'Pred for a modular integer subtype wraps around
+       if the value of @i(Arg) is S'Base'First. S'Pred for a signed integer
+       subtype might raise Constraint_Error if the value of @i(Arg) is
+       S'Base'First, or it might return the out-of-base-range value
+       S'Base'address@hidden@;1, as is permitted for all predefined numeric 
address@hidden
+
address@hidden,Kind=[Added],ChginAnnex=[T],
+  Leading=<T>, Prefix=<S>, AttrName=<Wide_Wide_Image>, ARef=[AI95-00285-01],
+  address@hidden,New=[S'Wide_Wide_Image denotes a function
+     with the following specification:],Old=[]}
address@hidden(Descexample)
address@hidden,Kind=[Added]}
address@hidden,address@hidden(function) S'Wide_Wide_Image(@RI(Arg) : S'Base)
+  @b(return) Wide_Wide_String]}
address@hidden(Descexample)
+
+     @ChgRef{Version=[2],Kind=[Added]}
+     @ChgAdded{Version=[2],NoPrefix=[T],address@hidden, Sec=(of a value)}
+     The function returns an @i(image) of the value of @i(Arg),
+     that is, a sequence of characters representing the value in display
+     address@hidden of Annex text here.}
+     @ChgAdded{Version=[2],NoPrefix=[T],Text=[The lower bound of the result is 
one.]}
+
+     @ChgRef{Version=[2],Kind=[Added]}
+     @ChgAdded{Version=[2],NoPrefix=[T],Text=[The image of an integer value is
+     the corresponding decimal literal,
+     without underlines, leading zeros, exponent, or trailing spaces, but
+     with a single leading character that is either a minus sign or
+     a space.]}
+     @begin{ImplNote}
+         @ChgRef{Version=[2],Kind=[AddedNormal]}
+         @ChgAdded{Version=[2],Text=[
+         If the machine supports negative zeros for signed integer types,
+         it is not specified whether "@ 0" or "@en@;0" should be returned
+         for negative zero. We don't have enough experience with
+         such machines to know what is appropriate, and what other
+         languages do. In any case, the implementation should be
+         consistent.]}
+     @end{implnote}
+
+     @ChgRef{Version=[2],Kind=[Added]}
+     @ChgAdded{Version=[2],NoPrefix=[T],address@hidden character}
+     The image of an enumeration value is either the corresponding
+     identifier in upper case or the corresponding character literal
+     (including the two apostrophes); neither leading nor trailing
+     spaces are included.
+     For a @i(nongraphic character) (a value of
+     a character type that has no
+     enumeration literal associated with it), the
+     result is a corresponding language-defined
+     name in upper case (for example, the image
+     of the nongraphic character identified as @i(nul) is 
@lquotes@;address@hidden@; @em the
+     quotes are not part of the image).]}
+     @begin{ImplNote}
+       @ChgRef{Version=[2],Kind=[AddedNormal]}
+       @ChgAdded{Version=[2],Text=[
+       For an enumeration type T that has @lquotes@;address@hidden@;
+       (caused by an @address@hidden@!clause}),
+       @Defn2{Term=[Program_Error],Sec=(raised by failure of run-time check)}
+       T'Wide_Image should raise Program_Error if the value
+       is one of the holes (which is a bounded error anyway,
+       since holes can be generated only via uninitialized variables and
+       similar things).]}
+     @end{ImplNote}
+
+     @ChgRef{Version=[2],Kind=[Added]}
+     @ChgAdded{Version=[2],NoPrefix=[T],Text=[The image of a
+     floating point value is a decimal real literal
+     best approximating the value (rounded away from zero if halfway between)
+     with a single leading character that is either a minus sign
+     or a space, a single digit (that is nonzero unless the value is zero),
+     a decimal point, S'address@hidden@;1
+     (see @RefSecNum(Operations of Floating Point Types)) digits
+     after the decimal point (but one if S'Digits is one),
+     an upper case E, the sign of the
+     exponent (either + or @en), and two or more digits
+     (with leading zeros if necessary)
+     representing the exponent.
+     If S'Signed_Zeros is True, then the leading character is a minus
+     sign for a negatively signed zero.]}
+     @begin{Honest}
+       @ChgRef{Version=[2],Kind=[AddedNormal]}
+       @ChgAdded{Version=[2],Text=[
+       Leading zeros are present in the exponent only if necessary to make
+       the exponent at least two digits.]}
+     @end{Honest}
+     @begin{Reason}
+       @ChgRef{Version=[2],Kind=[AddedNormal]}
+       @ChgAdded{Version=[2],Text=[
+       This image is intended to conform to that produced by
+       Text_IO.Float_IO.Put in its default format.]}
+     @end{reason}
+     @begin{ImplNote}
+       @ChgRef{Version=[2],Kind=[AddedNormal]}
+       @ChgAdded{Version=[2],Text=[The rounding direction is specified here
+       to ensure portability of output results.]}
+     @end{implnote}
+
+     @ChgRef{Version=[2],Kind=[Added]}
+     @ChgAdded{Version=[2],NoPrefix=[T],Text=[The image of a fixed point value
+     is a decimal real literal
+     best approximating the value (rounded away from zero if halfway between)
+     with a single leading character that is either a minus sign
+     or a space, one or more digits before the decimal point
+     (with no redundant leading zeros),
+     a decimal point, and S'Aft (see @RefSecNum(Operations of Fixed Point 
Types))
+     digits after the decimal point.]}
+     @begin{Reason}
+       @ChgRef{Version=[2],Kind=[AddedNormal]}
+       @ChgAdded{Version=[2],Text=[This image is intended to conform to
+       that produced by Text_IO.Fixed_IO.Put.]}
+     @end{reason}
+     @begin{ImplNote}
+       @ChgRef{Version=[2],Kind=[AddedNormal]}
+       @ChgAdded{Version=[2],Text=[The rounding direction is specified here
+       to ensure portability of output results.]}
+     @end{implnote}
+     @begin{ImplNote}
+       @ChgRef{Version=[2],Kind=[AddedNormal]}
+       @ChgAdded{Version=[2],Text=[For a machine that supports negative zeros,
+       it is not specified whether "@ 0.000" or "@en@;0.000" is returned.
+       See corresponding comment above about integer types with
+       signed zeros.]}
+     @end{implnote}
+
address@hidden<S>, AttrName=<Wide_Image>,
+  Text=[S'Wide_Image denotes a function
+     with the following specification:
address@hidden(Descexample)
address@hidden(function) S'Wide_Image(@RI(Arg) : S'Base)
+  @b(return) Wide_String
address@hidden(Descexample)
+
+     @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00285-01]}
+     @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0262-1],ARef=[AI05-0264-1]}
+     @address@hidden, Sec=(of a value)}
+     The function returns an 
@Chg{Version=[2],New=[image],address@hidden(image)]} of
+     the value of @i(Arg)@Chg{Version=[2],New=[ as a Wide_String],Old=[,
+     that is, a sequence of characters representing the value in display
+     form]}.]}
+     The lower bound of the result is address@hidden,
+     New=[ The image has the same sequence of @Chg{Version=[3],New=[graphic
+     characters],Old=[character]} as
+     defined for S'Wide_Wide_Image if all the graphic characters are defined in
+     Wide_Character; address@hidden,New=[,],Old=[]}
+     the sequence of characters is
+     implementation defined (but no shorter than that of S'Wide_Wide_Image for
+     the same value of Arg).],Old=[]}
+     @ChgImplDef{Version=[2],Kind=[AddedNormal],address@hidden,
+     Text=[The sequence of characters of the value returned by
+     S'Wide_Image when some of the graphic characters of S'Wide_Wide_Image
+     are not defined in Wide_Character.]}]}
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 31
+through 34 were moved to Wide_Wide_Image.>address@hidden message should be
+deleted if the paragraphs are ever renumbered.}
address@hidden
+
+     @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01]}
+     @ChgDeleted{Version=[2],NoPrefix=[T],Text=[The image of an integer value 
is
+     the corresponding decimal literal,
+     without underlines, leading zeros, exponent, or trailing spaces, but
+     with a single leading character that is either a minus sign or
+     a space.]}
+     @begin{ImplNote}
+         @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+         @ChgDeleted{Version=[2],Text=[
+         If the machine supports negative zeros for signed integer types,
+         it is not specified whether "@en@;0" or " 0" should be returned
+         for negative zero. We don't have enough experience with
+         such machines to know what is appropriate, and what other
+         languages do. In any case, the implementation should be
+         consistent.]}
+     @end{implnote}
+
+     @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01]}
+     @ChgDeleted{Version=[2],NoPrefix=[T],address@hidden character}
+     The image of an enumeration value is either the corresponding
+     identifier in upper case or the corresponding character literal
+     (including the two apostrophes); neither leading nor trailing
+     spaces are included.
+     For a @i(nongraphic character) (a value of
+     a character type that has no
+     enumeration literal associated with it), the
+     result is a corresponding language-defined or implementation-defined
+     name in upper case (for example, the image
+     of the nongraphic character identified as @i(nul) is 
@lquotes@;address@hidden@; @em the
+     quotes are not part of the image).]}
+     @begin{ImplNote}
+       @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+       @ChgDeleted{Version=[2],Text=[For an enumeration type T
+       that has @lquotes@;address@hidden@;
+       (caused by an @nt{enumeration_representation_clause}),
+       @Defn2{Term=[Program_Error],Sec=(raised by failure of run-time check)}
+       T'Wide_Image should raise Program_Error if the value
+       is one of the holes (which is a bounded error anyway,
+       since holes can be generated only via uninitialized variables and
+       similar things).]}
+     @end{ImplNote}
+
+     @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01]}
+     @ChgDeleted{Version=[2],NoPrefix=[T],Text=[The image of a
+     floating point value is a decimal real literal
+     best approximating the value (rounded away from zero if halfway
+     between)
+     with a single leading character that is either a minus sign
+     or a space, a single digit (that is nonzero unless the value is zero),
+     a decimal point, S'address@hidden@;1
+     (see @RefSecNum(Operations of Floating Point Types)) digits
+     after the decimal point (but one if S'Digits is one),
+     an upper case E, the sign of the
+     exponent (either + or @en), and two or more digits
+     (with leading zeros if necessary)
+     representing the exponent.
+     If S'Signed_Zeros is True, then the leading character is a minus
+     sign for a negatively signed zero.]}
+     @begin{Honest}
+       @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+       @ChgDeleted{Version=[2],Text=[Leading zeros are present in the
+       exponent only if necessary to make the exponent at least two digits.]}
+     @end{Honest}
+     @begin{Reason}
+       @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+       @ChgDeleted{Version=[2],Text=[This image is intended to conform to
+       that produced by
+        Text_IO.Float_IO.Put in its default format.]}
+     @end{reason}
+     @begin{ImplNote}
+       @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+       @ChgDeleted{Version=[2],Text=[The rounding direction is specified here
+       to ensure portability of output results.]}
+     @end{implnote}
+
+     @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01]}
+     @ChgDeleted{Version=[2],NoPrefix=[T],Text=[The image of a
+     fixed point value is a decimal real literal
+     best approximating the value (rounded away from zero if halfway between)
+     with a single leading character that is either a minus sign
+     or a space, one or more digits before the decimal point
+     (with no redundant leading zeros),
+     a decimal point, and S'Aft (see @RefSecNum(Operations of Fixed Point 
Types))
+     digits after the decimal point.]}
+     @begin{Reason}
+       @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+       @ChgDeleted{Version=[2],Text=[This image is intended to conform to
+       that produced by Text_IO.Fixed_IO.Put.]}
+     @end{reason}
+     @begin{ImplNote}
+       @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+       @ChgDeleted{Version=[2],Text=[The rounding direction is specified here
+       to ensure portability of output results.]}
+     @end{implnote}
+     @begin{ImplNote}
+       @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+       @ChgDeleted{Version=[2],Text=[For a machine that supports negative 
zeros,
+       it is not specified whether "@en@;0.000" or " 0.000" is returned.
+       See corresponding comment above about integer types with
+       signed zeros.]}
+    @end{implnote}
+
address@hidden<S>, AttrName=<Image>,
+  Text=[S'Image denotes a function with
+    the following specification:
address@hidden(Descexample)
address@hidden(function) S'Image(@RI(Arg) : S'Base)
+  @b(return) String
address@hidden(Descexample)
+
+     @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00285-01]}
+     @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+     @NoPrefix@;The function returns an image of the value of @i(Arg)
+     as a String.]}
+     The lower bound of the result is one. The image has the
+     same sequence of graphic characters as that defined
+     for S'@Chg{Version=[2],New=[Wide_Wide_Image],Old=[Wide_Image]} if all
+     the graphic characters are defined in Character;
+     address@hidden,New=[,],Old=[]}
+     the sequence of characters is implementation defined (but
+     no shorter than that of S'@Chg{Version=[2],New=[Wide_Wide_Image],
+     Old=[Wide_Image]} for the same value of @i(Arg)).
+     @ChgImplDef{Version=[2],Kind=[Revised],InitialVersion=[0],Text=[The
+     sequence of characters of the value returned by
+     S'Image when some of the graphic characters of
+     S'@Chg{Version=[2],New=[Wide_Wide_Image],Old=[Wide_Image]} are not
+     defined in Character.]}
+
address@hidden,Kind=[Added],ChginAnnex=[T],
+  Leading=<T>, Prefix=<S>, AttrName=<Wide_Wide_Width>, ARef=[AI95-00285-01],
+  address@hidden,New=[S'Wide_Wide_Width denotes the
+     maximum length of a Wide_Wide_String
+     returned by S'Wide_Wide_Image over all values of the
+     subtype S. It denotes zero for a subtype that has
+     a null range. Its type is @i(universal_integer).],Old=[]}]}
+
address@hidden<S>, AttrName=<Wide_Width>,
+  Text=[S'Wide_Width denotes the maximum length of a Wide_String
+     returned by S'Wide_Image over all values of the
+     subtype S. It denotes zero for a subtype that has
+     a null range. Its type is @i(universal_integer).]}
+
address@hidden<S>, AttrName=<Width>,
+  Text=[S'Width denotes the maximum length of a String
+     returned by S'Image over all values of the
+     subtype S. It denotes zero for a subtype that has
+     a null range. Its type is @i(universal_integer).]}
+
address@hidden,Kind=[Added],ChginAnnex=[T],
+  Leading=<T>, Prefix=<S>, AttrName=<Wide_Wide_Value>, ARef=[AI95-00285-01],
+  address@hidden,New=[S'Wide_Wide_Value denotes a function
+     with the following specification:],Old=[]}
address@hidden(Descexample)
address@hidden,Kind=[Added]}
address@hidden,address@hidden(function) S'Wide_Wide_Value(@RI(Arg) : 
Wide_Wide_String)
+  @b(return) S'Base]}
address@hidden(Descexample)
+    @ChgRef{Version=[2],Kind=[Added]}
+    @ChgAdded{Version=[2],NoPrefix=[T],Text=[This function returns
+    a value given an image of the value
+    as a Wide_Wide_String, ignoring any leading or trailing spaces.]}]}
+
+    @ChgRef{Version=[2],Kind=[Added]}
+    @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0264-1]}
+    @ChgAdded{Version=[2],NoPrefix=[T],address@hidden, Sec=(Wide_Wide_Value)}
+    @Defn2{Term=(Constraint_Error),Sec=(raised by failure of run-time check)}
+    For the evaluation of a call on S'Wide_Wide_Value
+    for an enumeration subtype S,
+    if the sequence of characters of the parameter (ignoring
+    leading and trailing spaces) has the syntax
+    of an enumeration literal and if it corresponds to a literal of the
+    type of S (or corresponds to the result of S'Wide_Wide_Image
+    for a nongraphic character of the type),
+    the result is the corresponding enumeration value;
+    @IndexCheck{Range_Check}
+    address@hidden,New=[,],Old=[]}
+    Constraint_Error is raised.]}
+    @begin{Discussion}
+      @ChgRef{Version=[2],Kind=[Added]}
+      @ChgAdded{Version=[2],Text=[It's not crystal clear that Range_Check
+      is appropriate here,
+      but it doesn't seem worthwhile to invent a whole new check name
+      just for this weird case, so we decided to lump it in with
+      Range_Check.]}
+    @end{discussion}
+    @begin{Honest}
+      @ChgRef{Version=[2],Kind=[Added],Ref=[8652/0096],ARef=[AI95-00053-01]}
+      @ChgAdded{Version=[2],Text=[A sequence of
+      characters corresponds to the result of
+      S'Wide_Wide_Image if it is the same ignoring case. Thus, the case of an
+      image of a nongraphic character does not matter. For example,
+      Character'Wide_Wide_Value("nul") does not raise Constraint_Error, even 
though
+      Character'Wide_Wide_Image returns "NUL" for the nul character.]}
+    @end{Honest}
+
+    @ChgRef{Version=[2],Kind=[Added]}
+    @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0264-1]}
+    @ChgAdded{Version=[2],NoPrefix=[T],address@hidden(Constraint_Error),
+    Sec=(raised by failure of run-time check)}
+    For the evaluation of a call on S'Wide_Wide_Value for an integer
+    subtype S, if the sequence of characters of the
+    parameter (ignoring leading and trailing spaces)
+    has the syntax of an integer literal,
+    with an optional leading sign character
+    (plus or minus for a signed type;
+    only plus for a modular type), and the
+    corresponding numeric value belongs to the base range of the
+    type of S, then that value is the result;
+    @IndexCheck{Range_Check}
+    address@hidden,New=[,],Old=[]}
+    Constraint_Error is raised.]}
+
+    @begin(Discussion)
+      @ChgRef{Version=[2],Kind=[Added]}
+      @ChgAdded{Version=[2],Text=[We considered allowing 'Value
+      to return a representable but out-of-range
+      value without a Constraint_Error. However, we currently require
+      (see @RefSecNum(Static Expressions and Static Subtypes))
+      in an @nt{assignment_statement} like "X := <numeric_literal>;" that
+      the value of the
+      numeric-literal be in X's base range (at compile time), so it seems
+      unfriendly and confusing to have a different range allowed for 'Value.
+      Furthermore, for modular types, without the requirement for being
+      in the base range, 'Value would have to handle arbitrarily long
+      literals (since overflow never occurs for modular types).]}
+    @end(Discussion)
+
+    @ChgRef{Version=[2],Kind=[Added]}
+    @ChgAdded{Version=[2],NoPrefix=[T],Type=[Leading],Text=[For the
+    evaluation of a call on S'Wide_Wide_Value for a
+    real subtype S, if the sequence of characters of the
+    parameter (ignoring leading and trailing spaces)
+    has the syntax of one of the following:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Text=<@address@hidden>}
+
address@hidden,Kind=[Added]}
address@hidden,Text=<address@hidden@nt[exponent]]>}
+
address@hidden,Kind=[Added]}
address@hidden,Text=<@address@hidden@nt[exponent]]>}
+
address@hidden,Kind=[Added]}
address@hidden,Text=<@address@hidden@nt[exponent]]>}
address@hidden
+
+    @ChgRef{Version=[2],Kind=[Added]}
+    @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0264-1]}
+    @ChgAdded{Version=[2],NoPrefix=[T],address@hidden(Constraint_Error),
+    Sec=(raised by failure of run-time check)}
+    with an optional leading sign character (plus or minus), and if the
+    corresponding numeric value belongs to the base range of the
+    type of S, then that value is the result;
+    @IndexCheck{Range_Check}
+    address@hidden,New=[,],Old=[]}
+    Constraint_Error is raised.
+    The sign of a zero value is preserved
+    (positive if none has been specified)
+    if S'Signed_Zeros is True.]}
+
+
address@hidden<S>, AttrName=<Wide_Value>,
+  Text=[S'Wide_Value denotes a function with
+     the following specification:
address@hidden(Descexample)
address@hidden(function) S'Wide_Value(@RI(Arg) : Wide_String)
+  @b(return) S'Base
address@hidden(Descexample)
+
+    @NoPrefix@;This function returns a value given an image of the value
+    as a Wide_String, ignoring any leading or trailing
+    address@hidden marks the end of the Annex text.}
+
+    @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00285-01]}
+    @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+    @address@hidden, Sec=(Wide_Value)}
+    @Defn2{Term=(Constraint_Error),Sec=(raised by failure of run-time check)}
+    For the evaluation of a call on S'Wide_Value
+    for an enumeration subtype S,
+    if the sequence of characters of the parameter (ignoring
+    leading and trailing spaces) has the syntax
+    of an enumeration literal and if it corresponds to a literal of the
+    type of S (or corresponds to the result of S'Wide_Image
+    for a @Chg{Version=[2],New=[value],Old=[nongraphic character]} of the 
type),
+    the result is the corresponding enumeration value;
+    @IndexCheck{Range_Check}
+    address@hidden,New=[,],Old=[]} Constraint_Error is raised.
+    @Chg{Version=[2],New=[For a numeric subtype S,
+    the evaluation of a call on S'Wide_Value with @i(Arg) of type Wide_String
+    is equivalent to a call on S'Wide_Wide_Value for a corresponding
+    @i(Arg) of type Wide_Wide_String.],Old=[]}
+    @begin{Discussion}
+      @ChgRef{Version=[2],Kind=[Deleted]}
+      @ChgDeleted{Version=[2],Text=[It's not crystal clear that Range_Check
+      is appropriate here,
+      but it doesn't seem worthwhile to invent a whole new check name
+      just for this weird case, so we decided to lump it in with
+      Range_Check.]}
+    @end{discussion}
+    @begin{Honest}
+      @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0096],ARef=[AI95-00053-01]}
+      @ChgRef{Version=[2],Kind=[DeletedAdded]}
+      @ChgDeleted{Version=[2],Text=[
+      @Chg{Version=[1],New=[A sequence of characters corresponds to the result 
of
+      S'Wide_Image if it is the same ignoring case. Thus, the case of an
+      image of a nongraphic character does not matter. For example,
+      Character'Wide_Value("nul") does not raise Constraint_Error, even though
+      Character'Wide_Image returns "NUL" for the nul character.],Old=[]}]}
+    @end{Honest}
+    @begin(Reason)
+      @ChgRef{Version=[2],Kind=[AddedNormal]}
+      @ChgAdded{Version=[2],Text=[S'Wide_Value is subtly different from
+       S'Wide_Wide_Value for enumeration
+       subtypes since S'Wide_Image might produce a different sequence of
+       characters than S'Wide_Wide_Image if the enumeration literal
+       uses characters outside of the predefined type Wide_Character.
+       That is why we don't just define S'Wide_Value in terms of
+       S'Wide_Wide_Value for enumeration subtypes.
+       S'Wide_Value and S'Wide_Wide_Value for numeric subtypes yield
+       the same result given the same sequence of characters.]}
+    @end(Reason)
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 44
+through 51 were moved to Wide_Wide_Value.>address@hidden message should be 
deleted if the
+paragraphs are ever renumbered.}
address@hidden
+
+    @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01]}
+    @ChgDeleted{Version=[2],NoPrefix=[T],address@hidden(Constraint_Error),
+    Sec=(raised by failure of run-time check)}
+    For the evaluation of a call on S'Wide_Value (or S'Value) for an integer
+    subtype S, if the sequence of characters of the
+    parameter (ignoring leading and trailing spaces)
+    has the syntax of an integer literal,
+    with an optional leading sign character
+    (plus or minus for a signed type;
+    only plus for a modular type), and the
+    corresponding numeric value belongs to the base range of the
+    type of S, then that value is the result;
+    @IndexCheck{Range_Check}
+    otherwise Constraint_Error is raised.]}
+
+    @begin(Discussion)
+      @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+      @ChgDeleted{Version=[2],Text=[We considered allowing 'Value
+      to return a representable but out-of-range
+      value without a Constraint_Error. However, we currently require
+      (see @RefSecNum(Static Expressions and Static Subtypes))
+      in an @nt{assignment_statement} like "X := <numeric_literal>;" that
+      the value of the
+      numeric-literal be in X's base range (at compile time), so it seems
+      unfriendly and confusing to have a different range allowed for 'Value.
+      Furthermore, for modular types, without the requirement for being
+      in the base range, 'Value would have to handle arbitrarily long
+      literals (since overflow never occurs for modular types).]}
+    @end(Discussion)
+
+    @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+    @ChgDeleted{Version=[2],NoPrefix=[T],Type=[Leading],Text=[For the
+    evaluation of a call on S'Wide_Value (or S'Value) for a
+    real subtype S, if the sequence of characters of the
+    parameter (ignoring leading and trailing spaces)
+    has the syntax of one of the following:]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=<@nt[numeric_literal]>}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=<@address@hidden>}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=<address@hidden@nt[exponent]]>}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=<@address@hidden@nt[exponent]]>}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden@address@hidden
address@hidden
+
+    @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+    @ChgDeleted{Version=[2],NoPrefix=[T],address@hidden(Constraint_Error),
+    Sec=(raised by failure of run-time check)}
+    with an optional leading sign character (plus or minus), and if the
+    corresponding numeric value belongs to the base range of the
+    type of S, then that value is the result;
+    @IndexCheck{Range_Check}
+    otherwise Constraint_Error is raised.
+    The sign of a zero value is preserved
+    (positive if none has been specified)
+    if S'Signed_Zeros is True.]}
+
address@hidden<S>, AttrName=<Value>,
+  Text=[S'Value denotes a function with
+     the following specification:
address@hidden(Descexample)
address@hidden(function) S'Value(@RI(Arg) : String)
+  @b(return) S'Base
address@hidden(Descexample)
+
+    @NoPrefix@;This function returns a value given an image of the value
+    as a String, ignoring any leading or trailing spaces.]}
+
+    @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00285-01]}
+    @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+    @address@hidden, Sec=(Value)}
+    @Defn2{Term=(Constraint_Error),Sec=(raised by failure of run-time check)}
+    For the evaluation of a call on S'Value
+    for an enumeration subtype S,
+    if the sequence of characters of the parameter (ignoring
+    leading and trailing spaces) has the syntax
+    of an enumeration literal and if it corresponds to a literal of the
+    type of S (or corresponds to the result of S'Image
+    for a value of the type),
+    the result is the corresponding enumeration value;
+    @IndexCheck{Range_Check}
+    address@hidden,New=[,],Old=[]} Constraint_Error is raised.
+    For a numeric subtype S,
+    the evaluation of a call on S'Value with @i(Arg) of type String
+    is equivalent to a call on 
S'@Chg{Version=[2],New=[Wide_Wide_Value],Old=[Wide_Value]} for a corresponding
+    @i(Arg) of type @Chg{Version=[2],New=[Wide_Wide_String],Old=[Wide_String]}.
+    @begin(Reason)
+      @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00285-01]}
+       S'Value is subtly different from 
S'@Chg{Version=[2],New=[Wide_Wide_Value],Old=[Wide_Value]} for enumeration
+       address@hidden,New=[; see the discussion under S'Wide_Value],
+       Old=[since S'Image might produce a different sequence of
+       characters than S'Wide_Image if the enumeration literal
+       uses characters outside of the predefined type Character.
+       That is why we don't just define S'Value in terms of S'Wide_Value
+       for enumeration subtypes.
+       S'Value and S'Wide_Value for numeric subtypes yield
+       the same result given the same sequence of characters]}.
+    @end(Reason)
+
address@hidden
address@hidden(description)
+
address@hidden,Kind=[Added],ARef=[AI12-0124-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[For @PrefixType{a
address@hidden X that denotes an object of a scalar address@hidden (after
+any implicit dereference)]}, the following attributes are defined:]}
+
address@hidden(description)
address@hidden,Kind=[Added],ChginAnnex=[T],
+  Leading=<F>, Prefix=<X>, AttrName=<Wide_Wide_Image>,
+  InitialVersion=[4], ARef=[AI12-0124-1],
+  address@hidden,New=[X'Wide_Wide_Image denotes the result of
+  calling function S'Wide_Wide_Image with @i<Arg> being X, where S is the
+  nominal subtype of X.],Old=[]}]}
+
address@hidden,Kind=[Added],ChginAnnex=[T],
+  Leading=<F>, Prefix=<X>, AttrName=<Wide_Image>,
+  InitialVersion=[4], ARef=[AI12-0124-1],
+  address@hidden,New=[X'Wide_Image denotes the result of
+  calling function S'Wide_Image with @i<Arg> being X, where S is the
+  nominal subtype of X.],Old=[]}]}
+
address@hidden,Kind=[Added],ChginAnnex=[T],
+  Leading=<F>, Prefix=<X>, AttrName=<Image>,
+  InitialVersion=[4], ARef=[AI12-0124-1],
+  address@hidden,New=[X'Image denotes the result of
+  calling function S'Image with @i<Arg> being X, where S is the
+  nominal subtype of X.],Old=[]}]}
+
address@hidden
address@hidden(description)
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+An implementation may extend the @Chg{Version=[2],New=[Wide_Wide_Value, ],
+Old=[Wide_Value, ]}
address@hidden@Chg{Version=[2],New=[Wide_Value, ],Old=[]}Value,
address@hidden,New=[Wide_Wide_Image, ],
+Old=[]}Wide_Image, and Image] attributes
+of a floating point type
+to support special values such as infinities and NaNs.
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+The permission is really only necessary for 
@Chg{Version=[2],New=[Wide_Wide_Value],
+Old=[Wide_Value]},
+because Value @Chg{Version=[2],New=[and Wide_Value are],Old=[is]} defined in
+terms of @Chg{Version=[2],New=[Wide_Wide_Value],
+Old=[Wide_Value]},
+and because the behavior of @Chg{Version=[2],New=[Wide_Wide_Image, ],
address@hidden,New=[,],Old=[]} and Image is already
+unspecified for things like infinities and NaNs.
address@hidden
address@hidden
+This is to allow implementations to define full support for IEEE
+arithmetic.
+See also the similar permission for Get in
address@hidden for Real Types}.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0182-1],ARef=[AI05-0262-1],ARef=[AI05-0269-1]}
address@hidden,Text=[An implementation may extend the Wide_Wide_Value,
+Wide_Value, and Value attributes of a character type to accept
+strings of the form @ldquote@;address@hidden<hhhhhhhh>@rdquote (ignoring case) 
for any
+character (not just the ones for which Wide_Wide_Image would produce that form
address@hidden see @RefSecNum{Character Types}), as well as three-character 
strings of
+the form @ldquote@;'@i<X>'@rdquote, where @i<X> is any character, including
+nongraphic characters.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0228-1]}
address@hidden,Type=[Leading],Text=[For a scalar type,
+the following language-defined representation aspect
+may be specified with an @nt{aspect_specification} (see
address@hidden Specifications}):]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden aspect
+shall be specified by a static expression, and that
+expression shall be explicit, even if the aspect has a boolean type.
+Default_Value shall be specified only on a
address@hidden@AspectDefn{Default_Value}]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The part about requiring an explicit expression 
is
+  to disallow omitting the value for this aspect, which would otherwise be
+  allowed by the rules of @RefSecNum{Aspect Specifications}.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is a representation aspect in order to
+  disallow specifying it on a derived type that has inherited primitive
+  subprograms; that is necessary as the sizes of @key[out] parameters could be
+  different whether or not a Default_Value is specified (see 
@RefSecNum{Parameter Associations}).]}
address@hidden
address@hidden,Kind=[AddedNormal],Aspect=[Default_Value],
+  address@hidden,Text=[Default value for a scalar subtype.]}]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0228-1]}
address@hidden,Text=[If a derived type with no primitive subprograms
+inherits a boolean Default_Value aspect, the aspect may be specified to have 
any
+value for the derived type.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This overrides the
+  @RefSecNum{Aspect Specifications} rule that says that a boolean aspect
+with a value True cannot be changed.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0228-1]}
address@hidden,Text=[The expected type for the @nt{expression}
+specified for the Default_Value aspect is the type defined by the
address@hidden on which it
address@hidden type],address@hidden of a Default_Value aspect]}]}
address@hidden
+
address@hidden
+The evaluation of S'First or S'Last never raises an exception.
+If a scalar subtype S has a nonnull range, S'First and S'Last
+belong to this range. These values can, for example, always be
+assigned to a variable of subtype S.
address@hidden(Discussion)
+  This paragraph addresses an issue that came up with Ada 83,
+  where for fixed point types, the end points of the range
+  specified in the type definition were not necessarily within
+  the base range of the type. However, it was later clarified (and
+  we reconfirm it in @RefSec(Fixed Point Types)) that the First and
+  Last attributes reflect the true bounds chosen for the type, not the
+  bounds specified in the type definition (which might be outside
+  the ultimately chosen base range).
address@hidden(Discussion)
+
+For a subtype of a scalar type, the result delivered by the attributes
+Succ, Pred, and Value might not belong to the subtype; similarly,
+the actual parameters
+of the attributes Succ, Pred, and Image need not belong to the subtype.
+
+For any value V (including any nongraphic character) of an
+enumeration subtype S, S'Value(S'Image(V)) equals V,
+as @Chg{Version=[2],New=[do],Old=[does]} 
S'Wide_Value(S'Wide_Image(V))@Chg{Version=[2],
+New=[ and S'Wide_Wide_Value(S'Wide_Wide_Image(V))],Old=[]}.
address@hidden,New=[None of these
+expressions],Old=[Neither expression]} ever 
@Chg{Version=[2],New=[raise],Old=[raises]}
+Constraint_Error.
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of ranges:)
address@hidden
+-10 .. 10
+X .. X + 1
+0.0 .. 2.0*Pi
+Red .. Green     address@hidden see @RefSecNum{Enumeration Types}]
+1 .. 0           address@hidden a null range]
+Table'Range      address@hidden a range attribute reference (see 
@RefSecNum{Array Types})]
+
address@hidden
address@hidden@address@hidden(Examples of range constraints:)
address@hidden
address@hidden(range) -999.0 .. +999.0
address@hidden(range) S'First+1 .. S'Last-1
address@hidden
address@hidden
+
address@hidden
address@hidden,address@hidden be consistent with 8652/0006}
address@hidden with Ada 83}
+S'Base is no longer defined for nonscalar types.
+One conceivable existing use of S'Base for nonscalar types is
+S'Base'Size where S is a generic formal private type.
+However, that is not generally useful because the actual
+subtype corresponding to S might be a constrained array
+or discriminated type, which would mean that S'Base'Size might
+very well overflow (for example, S'Base'Size where S is
+a constrained subtype of String will generally be 8 * (Integer'Last + 1)).
+For derived discriminated types that are packed, S'Base'Size might not even
+be well defined if the first subtype is constrained, thereby allowing
+some amount of normally required @lquotes@;address@hidden@; to have been 
squeezed out
+in the packing. Hence our conclusion is that S'Base'Size is
+not generally useful in a generic, and does not justify keeping
+the attribute Base for nonscalar types just so it can be used
+as a @address@hidden,Old=[prefix]}.
+
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The attribute S'Base for a scalar subtype is now permitted
+anywhere a @nt{subtype_mark} is permitted.
+S'Base'First .. S'Base'Last
+is the base range of the type.
+Using an @address@hidden@!clause},
+one cannot specify any subtype-specific attributes
+for the subtype denoted by S'Base
+(the base subtype).
+
+The attribute S'Range is now allowed for scalar subtypes.
+
+The attributes S'Min and S'Max are now defined, and made available for all
+scalar types.
+
+The attributes S'Succ, S'Pred, S'Image, S'Value, and S'Width are
+now defined for real types as well as discrete types.
+
+Wide_String versions of S'Image and S'Value are defined.
+These are called S'Wide_Image and S'Wide_Value to avoid
+introducing ambiguities involving uses of these attributes
+with string literals.
address@hidden
+
address@hidden
+We now use the syntactic category @nt<range_attribute_reference> since
+it is now syntactically distinguished from other attribute references.
+
+The definition of S'Base has been moved here from
+3.3.3 since it now applies only to scalar types.
+
+More explicit rules are provided for nongraphic characters.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The attributes Wide_Wide_Image, Wide_Wide_Value, and Wide_Wide_Width are new.
+  Note that Wide_Image and Wide_Value are now defined in terms of
+  Wide_Wide_Image and Wide_Wide_Value, but the image of types other than
+  characters have not changed.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[
+  The Wide_Image and Wide_Value attributes are now defined in terms of
+  Wide_Wide_Image and Wide_Wide_Value, but the images of numeric types
+  have not changed.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0181-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Soft hyphen (code point 173) is nongraphic in ISO/IEC 10646:2011 (and also
+  in the 2003 version of that standard). Thus, we
+  have given it the language-defined name @i{soft_hyphen}. This changes the
+  result of Character'Image (and all of the related types and Image attributes)
+  for this character, and changes the behavior of Character'Value (and all of
+  the related types and Value attributes) for this character, and
+  (in unusual circumstances), changes the result for Character'Width (and all
+  of the related types and Width attributes). The vast majority of programs
+  won't see any difference, as they are already prepared to handle nongraphic
+  characters.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0182-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:>
+  Added an @ImplPermTitle to let Wide_Wide_Value, Wide_Value, and Value accept
+  strings in the form of literals containing nongraphic characters and
+  "Hex_hhhhhhhh" for Latin-1 and graphic characters. These were required to
+  raise Constraint_Error in Ada 2005. Since these attributes aren't very
+  useful, implementations were inconsistent as to whether these were accepted,
+  and since code that would care why the attribute failed seems unlikely,
+  this should not be a problem in practice.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0228-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The new aspect Default_Value allows defining implicit initial values (see
+  @RefSecNum{Object Declarations}) for scalar types.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0124-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada 2012}
+  @b<Corrigendum:> An object can be now used as the prefix of the Image
+  attribute (as well as Wide_Image and Wide_Wide_Image), a
+  convenience feature already present in some implementations.]}
address@hidden
+
+
+
address@hidden Types}
+
address@hidden
address@hidden@Defn{enumeration type}
+An @nt<enumeration_type_definition> defines an enumeration type.]
address@hidden
+
address@hidden
address@hidden<enumeration_type_definition>,rhs="
+   (@Syn2{enumeration_literal_specification} {, 
@Syn2{enumeration_literal_specification}})"}
+
+
address@hidden<enumeration_literal_specification>,
+  rhs=" @Syn2{defining_identifier} | @Syn2{defining_character_literal}"}
+
address@hidden<defining_character_literal>,rhs="@Syn2{character_literal}"}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0227-1],ARef=[AI05-0299-1]}
+The @nt<defining_identifier>address@hidden,New=[ in upper case],Old=[]}
address@hidden@Chg{Version=[3],New=[ the],Old=[]}
address@hidden<defining_character_literal>s] listed in an
address@hidden<enumeration_type_definition> shall be distinct.
+  @begin{TheProof}
+    @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0227-1]}
+    @Chg{Version=[3],New=[For character literals, this],Old=[This]}
+    is a ramification of the normal disallowance
+    of homographs explicitly declared immediately in the same
+    declarative region.
+  @end{TheProof}
+  @begin{Reason}
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0227-1]}
+    @ChgAdded{Version=[3],Text=[To ease implementation of the attribute
+    Wide_Wide_Value, we require that all enumeration literals have distinct
+    images.]}
+  @end{Reason}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0006-1]}
address@hidden literal}
+Each @nt<enumeration_literal_specification> is the explicit declaration
+of the corresponding @i(enumeration literal): it declares
+a parameterless function,
+whose defining name is the @nt<address@hidden>
+or @nt<address@hidden@!literal>, and whose result
address@hidden,New=[subtype is the base subtype of],Old=[type
+is]} the enumeration type.
address@hidden
+  This rule defines the profile of the enumeration literal,
+  which is used in the various types of conformance.
address@hidden
address@hidden
+  The parameterless function associated with an enumeration literal
+  is fully defined by the @nt<enumeration_type_definition>;
+  a body is not permitted for it,
+  and it never fails the Elaboration_Check when called.
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0006-1]}
+  @ChgAdded{Version=[3],Text=[The result subtype is primarily a concern
+  when an enumeration literal is used as the @nt{expression} of a
+  case statement, due to the full coverage requirement based on the
+  nominal subtype.]}
address@hidden
+
+Each enumeration literal corresponds to a distinct value
+of the enumeration type, and to a distinct position number.
address@hidden number], Sec=(of an enumeration value)}
+The position number of the value of
+the first listed enumeration literal
+is zero; the position number of the value of each
+subsequent enumeration literal
+is one more than that of its predecessor in the list.
+
address@hidden predefined order relations between values of
+the enumeration type follow the
+order of corresponding position numbers.]
+
address@hidden@PDefn2{Term=[overloaded], Sec=(enumeration literal)}
+If the same @nt<defining_identifier> or
address@hidden<defining_character_literal> is specified in more than one
address@hidden<address@hidden@!definition>, the corresponding enumeration 
literals
+are said to be @i(overloaded). At any place where an overloaded
+enumeration literal occurs in the text of a program, the type
+of the enumeration literal has to be determinable from the context
+(see @RefSecNum(The Context of Overload Resolution)).]
address@hidden
+
address@hidden
address@hidden, Sec=(enumeration_type_definition)}
address@hidden, Sec=(subtype)}
address@hidden, Sec=(subtype)}
+The elaboration of an @nt<enumeration_type_definition> creates
+the enumeration type and its first subtype,
+which is constrained to the base range of the type.
address@hidden
+The first subtype of a discrete type is always constrained,
+except in the case of a derived type whose parent subtype
+is Whatever'Base.
address@hidden
+
+When called, the parameterless function associated with an enumeration literal
+returns the corresponding value of the enumeration type.
address@hidden
+
address@hidden
+If an enumeration literal occurs in a context that does not
+otherwise suffice to determine the type of the literal, then qualification
+by the name of the enumeration type is one way to resolve
+the ambiguity (see @RefSecNum(Qualified Expressions)).
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of enumeration types and subtypes: )
address@hidden(Example)
address@hidden(type) Day    @key(is) (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
address@hidden(type) Suit   @key(is) (Clubs, Diamonds, Hearts, Spades);
address@hidden(type) Gender @key(is) (M, F);
address@hidden(type) Level  @key(is) (Low, Medium, Urgent);
address@hidden(type) Color  @key(is) (White, Red, Yellow, Green, Blue, Brown, 
Black);
address@hidden(type) Light  @key(is) (Red, Amber, Green); address@hidden Red 
and Green are overloaded]
+
address@hidden(type) Hexa   @key(is) ('A', 'B', 'C', 'D', 'E', 'F');
address@hidden(type) Mixed  @key(is) ('A', 'B', '*', B, None, '?', '%');
+
address@hidden(subtype) Weekday @key(is) Day   @key(range) Mon .. Fri;
address@hidden(subtype) Major   @key(is) Suit  @key(range) Hearts .. Spades;
address@hidden(subtype) Rainbow @key(is) Color @key(range) Red .. Blue;  
address@hidden  the Color Red, not the Light]
address@hidden(Example)
address@hidden
+
address@hidden
+The syntax rule for @nt{defining_character_literal} is new.
+It is used for the defining occurrence of a @nt{character_literal},
+analogously to @nt{defining_identifier}.
+Usage occurrences use the @nt{name} or @nt{selector_name}
+syntactic categories.
+
+We emphasize the fact that an enumeration literal denotes
+a function, which is called to produce a value.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0227-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Required that all enumeration
+  literals in a type have distinct images; this might not be the case since
+  upper case conversion can map distinct characters to the same upper case
+  character. This can only happen for identifiers using Unicode characters 
first
+  allowed by Ada 2005; moreover, the original definition of Ada 2005 was
+  confused and appeared to require inconsistent results from the Image
+  attribute, so implementations that allowed problematic cases are rare; the
+  problematic cases are very rare; so it is expected that this change would
+  only affect test programs.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0006-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Defined the result
+  subtype of an enumeration literal to close a minor language hole.]}
address@hidden
+
+
address@hidden Types}
+
address@hidden
address@hidden type}
+An enumeration type is said to be a @i(character type) if at least
+one of its enumeration literals is a @nt<character_literal>.
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0181-1],ARef=[AI05-0262-1],ARef=[AI05-0266-1]}
address@hidden
address@hidden
address@hidden,address@hidden,address@hidden/IEC 10646:2011}],
address@hidden/IEC 10646:2003}]}],address@hidden 10646}]}
address@hidden
+The predefined type Character is a character type whose values
+correspond to the 256 code @Chg{Version=[3],New=[points],Old=[positions]}
+of Row 00 (also known as Latin-1) of the
address@hidden,New=[ISO/IEC 
10646:@Chg{Version=[3],New=[2011],Old=[2003]}],Old=[ISO 10646]}
+Basic Multilingual Plane (BMP).
+Each of the graphic characters of Row 00 of the BMP has
+a corresponding @nt<character_literal> in Character.
+Each of the nongraphic @Chg{Version=[3],New=[characters],Old=[positions]}
+of Row address@hidden,New=[],Old=[ (0000-001F and 007F-009F)]}
+has a corresponding language-defined name, which is not usable as an
+enumeration literal,
+but which is usable with the attributes @Chg{Version=[2],New=[Image,
+Wide_Image, Wide_Wide_Image, Value, Wide_Value, and Wide_Wide_Value],
+Old=[(Wide_)Image and (Wide_)Value]};
+these names are given in the definition of type Character
+in @RefSec{The Package Standard}, but are set in @i{italics}.
address@hidden,Sec=(nongraphic characters)}
address@hidden,address@hidden point],Sec=[for characters]}],Old=[]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0262-1]}
address@hidden,address@hidden point} is defined in ISO/IEC 10646:2011.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden
address@hidden
address@hidden,address@hidden,address@hidden/IEC 10646:2011}],
address@hidden/IEC 10646:2003}]}],address@hidden 10646}]}
+The predefined type Wide_Character is a character type whose
+values correspond to the 65536 code
address@hidden,New=[points],Old=[positions]} of the @Chg{Version=[2],
+New=[ISO/IEC 10646:@Chg{Version=[3],New=[2011],Old=[2003]}],Old=[ISO 10646]}
+Basic Multilingual Plane (BMP).
+Each of the graphic characters of the BMP has
+a corresponding @nt<character_literal> in Wide_Character.
+The first 256 values of Wide_Character
+have the same @nt<character_literal> or language-defined
+name as defined for Character. @Chg{Version=[2],New=[Each of the
address@hidden has],Old=[The last 2 values
+of Wide_Character correspond to the nongraphic
+positions FFFE and FFFF of the BMP,
+and are assigned
+the language-defined names @i(FFFE) and @i(FFFF). As with the other
+language-defined names for nongraphic characters,
+the names @i(FFFE) and @i(FFFF) are usable only with the attributes
+(Wide_)Image and (Wide_)Value; they are not usable as enumeration
+literals.
+All other values of Wide_Character are considered graphic characters,
+and have]} a corresponding @nt<character_literal>.
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden,address@hidden
address@hidden,address@hidden,address@hidden/IEC 10646:2011}],
address@hidden/IEC 10646:2003}]}],address@hidden 10646}]}
+The predefined type Wide_Wide_Character is a character type whose values
+correspond to the 2147483648 code 
@Chg{Version=[3],New=[points],Old=[positions]}
+of the ISO/IEC 10646:@Chg{Version=[3],New=[2011],Old=[2003]} character set.
+Each of the @ntf{graphic_character}s
+has a corresponding @nt{character_literal} in
+Wide_Wide_Character. The first 65536 values of Wide_Wide_Character have the
+same @nt{character_literal} or language-defined name as defined for
+Wide_Character.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden,Text=[The characters whose code
address@hidden,New=[point],Old=[position]} is larger
+than 16#FF# and which are not @ntf{graphic_character}s have language-defined
+names which are formed by appending to the string "Hex_" the
+representation of their code @Chg{Version=[3],New=[point],Old=[position]}
+in hexadecimal as eight extended digits.
+As with other language-defined names, these names are usable only with the
+attributes (Wide_)Wide_Image and (Wide_)Wide_Value; they are not usable as
+enumeration literals.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00285-01]}
+  The language-defined names are not usable as
+  enumeration literals to avoid "polluting" the name space. Since
+  Wide_Character @Chg{Version=[2],New=[and Wide_Wide_Character ],Old=[]}are
+  defined in Standard, if the @Chg{Version=[2],New=[language-defined ],
+  Old=[]}names @Chg{Version=[2],New=[],Old=[FFFE and FFFF ]}were usable
+  as enumeration literals, they would hide other nonoverloadable declarations
+  with the same names in @key[use]-d packages.]}
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01]}
+  @ChgDeleted{Version=[2],Text=[ISO 10646 has not defined the meaning of
+  all of the code positions
+  from 0100 through FFFD, but they are all considered graphic characters by
+  Ada to simplify the implementation, and to allow for revisions to ISO 10646.
+  In ISO 10646, FFFE and FFFF are special, and will never be associated
+  with graphic characters in any revision.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01]}
address@hidden,address@hidden
+In a nonstandard mode, an implementation may provide
+other interpretations for the predefined types Character and
address@hidden, to conform to local conventions].]}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraphs 6 and 7
+were deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered.}
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01]}
address@hidden,address@hidden
+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 @lquotes@;address@hidden@; should be reflected in the 
results of
+the subprograms defined in the language-defined package Characters.Handling
+(see @RefSecNum{Character Handling}) 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 @ntf<identifier_letter>.]}
address@hidden won't add an ChgImplAdvice here, because we would need to add
+and remove it in the same command.}
address@hidden
+
address@hidden
+The language-defined library package Characters.Latin_1
+(see @RefSecNum(The Package Characters.Latin_1))
+includes the declaration of constants
+denoting control characters, lower case characters, and special characters
+of the predefined type Character.
address@hidden
+  The package ASCII does the same, but only for the first
+  128 characters of Character. Hence, it is an obsolescent
+  package, and we no longer mention it here.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+A conventional character set such as @i(EBCDIC) can be declared as
+a character type; the internal codes of the characters can be specified
+by an @nt<enumeration_representation_clause> as explained in
address@hidden,New=[subclause],Old=[clause]} @RefSecNum(Enumeration 
Representation Clauses).
address@hidden
+
address@hidden
address@hidden@address@hidden(Example of a character type: )
address@hidden(Example)
address@hidden(type) Roman_Digit @key(is) ('I', 'V', 'X', 'L', 'C', 'D', 'M');
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden with Ada 83}
+The declaration of Wide_Character in package Standard hides
+use-visible declarations with the same defining identifier.
+In the unlikely event that an Ada 83 program had depended on
+such a use-visible declaration, and the program remains
+legal after the substitution of Standard.Wide_Character,
+the meaning of the program will be different.
address@hidden
+
address@hidden
address@hidden with Ada 83}
+The presence of Wide_Character in package Standard means that
+an expression such as
address@hidden(Example)
+'a' = 'b'
address@hidden(Example)
+
+is ambiguous in Ada 95, whereas in Ada 83 both
+literals could be resolved to be of type Character.
+
+The change in visibility rules (see @RefSecNum(Literals))
+for character literals means
+that additional qualification might be necessary to resolve
+expressions involving overloaded subprograms and
+character literals.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The type Character has been extended to have 256 positions,
+and the type Wide_Character has been added.
+Note that this change was already approved by the ARG
+for Ada 83 conforming compilers.
+
+The rules for referencing character literals are changed
+(see @RefSecNum(Literals)),
+so that the declaration of the character type need
+not be directly visible to use its literals,
+similar to @b(null) and string literals.
+Context is used to resolve their type.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  Ada 95 defined most characters in Wide_Character to be graphic characters,
+  while Ada 2005 uses the categorizations from ISO-10646:2003. It also
+  provides language-defined names for all nongraphic characters. That
+  means that in Ada 2005, Wide_Character'Wide_Value will raise Constraint_Error
+  for a string representing a @nt{character_literal} of a nongraphic character,
+  while Ada 95 would have accepted it. Similarly, the result of
+  Wide_Character'Wide_Image will change for such nongraphic characters.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00395-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[2],Text=[The language-defined names FFFE and FFFF were
+  replaced by a consistent set of language-defined names for all nongraphic
+  characters with @Chg{Version=[3],New=[code points],Old=[positions]}
+  greater than 16#FF#. That means that
+  in Ada 2005, Wide_Character'Wide_Value("FFFE") will raise Constraint_Error
+  while Ada 95 would have accepted it. Similarly, the result of
+  Wide_Character'Wide_Image will change for the position numbers 16#FFFE#
+  and 16#FFFF#. It is very unlikely that this will matter in practice,
+  as these names do not represent @Chg{Version=[3],New=[usable],Old=[useable]}
+  characters.]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
+  @ChgAdded{Version=[2],Text=[Because of the previously mentioned changes to
+  the Wide_Character'Wide_Image of various character values, the value of
+  attribute Wide_Width will change for some subtypes of Wide_Character.
+  However, the new language-defined names were chosen so that the value of
+  Wide_Character'Wide_Width itself does not change.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[The declaration of Wide_Wide_Character in
+  package Standard hides use-visible declarations with the same defining
+  identifier. In the (very) unlikely event that an Ada 95 program had
+  depended on such a use-visible declaration, and the program remains
+  legal after the substitution of Standard.Wide_Wide_Character,
+  the meaning of the program will be different.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The type Wide_Wide_Character is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[Characters are now defined in terms of
+  the entire ISO/IEC 10646:2003 character set.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[2],Text=[We dropped the @ImplAdviceTitle for
+  @Chg{Version=[3],New=[nonstandard],Old=[non-standard]} interpretation of
+  character sets; an implementation can do what it wants in a
+  @Chg{Version=[3],New=[nonstandard],Old=[non-standard]} mode, so there isn't
+  much point to any advice.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0181-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Removed the position 
numbers
+  of nongraphic characters from the text, as it is wrong and thus
+  misleading.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Text=[Changed "code position" to "code point"
+  consistently throughout the standard, as ISO/IEC 10646:2011 prefers
+  "code point" and we are referring to the definition in that Standard.
+  This change also reduces confusion between "code point"
+  and "position number"; while these have the same values for the predefined
+  character types, there is no required relationship for other character
+  address@hidden point],Sec=[for characters]}]}
address@hidden
+
+
address@hidden Types}
+
address@hidden
address@hidden
+There is a predefined enumeration type named Boolean,
address@hidden in the visible part of package Standard].
address@hidden
address@hidden
+It has the two enumeration literals False and True ordered
+with the relation False < True.
address@hidden type}
+Any descendant of the predefined type Boolean is called
+a @i(boolean) type.
address@hidden
+  An implementation is not required to support
+  enumeration representation clauses on boolean types that
+  impose an unacceptable implementation burden.
+  See @RefSec(Enumeration Representation Clauses).
+  However, it is generally straightforward to support representations
+  where False is zero and True is 2**n @en@; 1 for some n.
address@hidden
address@hidden
+
address@hidden Types}
+
address@hidden
address@hidden type}
address@hidden integer type}
address@hidden type}
+An @nt<integer_type_definition> defines an integer type;
+it defines either a @i(signed)
+integer type, or a @i(modular) integer type.
+The base range
+of a signed integer type includes at
+least the values of the specified
+range.
+A modular type is an integer type with all arithmetic modulo
+a specified positive @i(modulus);
+such a type corresponds to an unsigned
+type with wrap-around semantics.
address@hidden type],See=(modular type)}
address@hidden
+
address@hidden
address@hidden<integer_type_definition>,
+  rhs="@Syn2{signed_integer_type_definition} | @Syn2{modular_type_definition}"}
+
address@hidden<signed_integer_type_definition>,
+rhs="@key(range) @address@hidden .. @address@hidden"}
address@hidden
+  We don't call this a @nt<range_constraint>,
+  because it is rather different @em not only is
+  it required to be static, but the associated overload resolution rules are
+  different than for normal range constraints. A similar comment applies to
+  @nt{real_range_specification}.
+  This used to be @ntf<integer_range_specification> but when we
+  added support for modular types, it seemed overkill to have three levels
+  of syntax rules, and just calling these
+  @ntf<signed_integer_range_specification>
+  and @ntf<modular_range_specification> loses the fact that they
+  are defining different classes of types, which is important for
+  the generic type matching rules.
address@hidden
+
address@hidden<modular_type_definition>,
+  rhs="@key(mod) @address@hidden"}
address@hidden
+
address@hidden
address@hidden type],
+  Sec=(signed_integer_type_definition simple_expression)}
+Each @nt<simple_expression> in a
address@hidden<signed_integer_type_definition> is expected to be of any integer 
type;
+they need not be of the same type.
address@hidden type],
+  Sec=(modular_type_definition expression)}
+The @nt<expression> in a
address@hidden<modular_type_definition> is likewise expected to be of any 
integer type.
address@hidden
+
address@hidden
+The @nt<simple_expression>s of a
address@hidden<signed_integer_type_definition>
+shall be static, and their values shall be in the
+range System.Min_Int .. System.Max_Int.
+
address@hidden, Sec=(of a modular type)}
address@hidden
address@hidden
+The @nt<expression> of a @nt<modular_type_definition> shall be static,
+and its value (the @i(modulus)) shall be positive,
+and shall be no greater than System.Max_Binary_Modulus if a power of 2,
+or no greater than System.Max_Nonbinary_Modulus if not.
address@hidden(Reason)
+  For a 2's-complement machine, supporting nonbinary moduli greater
+  than System.Max_Int can be quite difficult, whereas essentially any
+  binary moduli are straightforward to support, up to 2*System.Max_Int+2,
+  so this justifies having two separate limits.
address@hidden(Reason)
address@hidden
+
address@hidden
+The set of values for a signed integer type is the (infinite)
+set of mathematical
address@hidden, though only values of the base range of the type
+are fully supported for run-time operations].
+The set of values for a modular integer type are the values from
+0 to one less than the modulus,
+inclusive.
+
address@hidden range], Sec=(of a signed integer type)}
+A @nt<signed_integer_type_definition> defines an integer type whose
+base range
+includes at least the values of the @nt<simple_expression>s and
+is symmetric about zero, excepting possibly an extra negative value.
address@hidden, Sec=(subtype)}
address@hidden, Sec=(subtype)}
+A @nt<signed_integer_type_definition> also defines a constrained first
+subtype of the type, with a range whose bounds are given by
+the values of the @nt<simple_expression>s, converted to the type being defined.
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00114-01]}
+  The base range of a signed integer type might be much larger than is
+  necessary to satisfy the @Chg{Version=[2],New=[above],Old=[aboved]}
+  requirements.
address@hidden
address@hidden
+  @ChgRef{Version=[1],address@hidden is discussed in AC-00002, which we can't 
reference here}
+  @ChgAdded{Version=[1],Text=[The conversion mentioned above is not
+  an @i{implicit subtype conversion} (which is something that happens at
+  overload resolution, see
+  @RefSecNum{Type Conversions}), although it happens implicitly. Therefore,
+  the freezing rules are not invoked on the type (which is important so that
+  representation items can be given for the type).
+  @PDefn2{Term=[subtype conversion],Sec=(bounds of signed integer type)}]}
address@hidden
+
address@hidden range], Sec=(of a modular type)}
+A @nt<modular_type_definition> defines a modular type whose base range
+is from zero to one less than the given modulus.
address@hidden, Sec=(subtype)}
address@hidden, Sec=(subtype)}
+A @nt<modular_type_definition> also defines a constrained first
+subtype of the type with a range that is the same as the base range of
+the type.
+
address@hidden
+There is a predefined signed integer subtype named
address@hidden,
+declared in the visible part of
+package Standard].
+It is constrained to the base range of its type.
address@hidden
+  Integer is a constrained subtype, rather than an unconstrained
+  subtype. This means that on assignment to an object of subtype Integer,
+  a range check is required. On the other hand, an object of subtype
+  Integer'Base is unconstrained, and no range check (only overflow check)
+  is required on assignment. For example, if the object is held in an
+  extended-length register, its value might be outside of
+  Integer'First .. Integer'Last. All parameter and result subtypes
+  of the predefined integer operators are of such unconstrained subtypes,
+  allowing extended-length registers to be used as operands or
+  for the result.
+  In an earlier version of Ada 95, Integer was unconstrained. However,
+  the fact that certain Constraint_Errors might be omitted or appear
+  elsewhere was felt to be an undesirable upward inconsistency in this case.
+  Note that for Float, the opposite conclusion was reached, partly because
+  of the high cost of performing range checks when not actually necessary.
+  Objects of subtype Float are unconstrained, and no range checks, only
+  overflow checks, are performed for them.
address@hidden
+
address@hidden@Defn{Natural}
address@hidden
+Integer has two predefined subtypes,
address@hidden in the visible part of package Standard:]
address@hidden
address@hidden Natural  @key[is] Integer @key[range] 0 .. Integer'Last;
address@hidden Positive @key[is] Integer @key[range] 1 .. Integer'Last;
address@hidden
+
address@hidden
address@hidden
address@hidden
+A type defined by an @nt<integer_type_definition> is implicitly
+derived from @i(root_integer), an anonymous
+predefined (specific) integer type, whose base
+range is System.Min_Int .. System.Max_Int.
+However, the base range of the new type is not inherited from
address@hidden, but is instead determined by the range or modulus
+specified by the @nt{integer_type_definition}.
address@hidden
address@hidden literals}
address@hidden literals are all of the type @i(universal_integer),
+the universal type (see @RefSecNum(Derivation Classes)) for the
+class rooted at @i(root_integer), allowing their use with
+the operations of any integer type.]
address@hidden
+  This implicit derivation is not considered exactly equivalent to
+  explicit derivation via a @nt<derived_type_definition>. In particular,
+  integer types defined via a @nt<derived_type_definition> inherit their
+  base range from their parent type. A type defined by
+  an @nt<integer_type_definition> does not necessarily inherit
+  its base range from @i(root_integer).
+  It is not specified whether the implicit derivation from
+  @i(root_integer) is direct or indirect, not that it really matters.
+  All we want is for all integer types to be descendants of @i(root_integer).
+
+  @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0099],ARef=[AI95-00152-01]}
+  @Chg{New=[Note that this derivation does not imply any inheritance of
+  subprograms. Subprograms are inherited only for types derived by a
+  @address@hidden@!definition} (see @RefSecNum{Derived Types and Classes}),
+  or a @address@hidden@!declaration} (see
+  @RefSecNum{Private Types and Private Extensions}, @RefSecNum{Private 
Operations},
+  and @RefSecNum{Formal Private and Derived Types}).],Old=[]}
address@hidden
address@hidden
+  It is the intent that even nonstandard integer
+  types (see below) will be descendants of @i(root_integer), even though they
+  might have a base range that exceeds that of @i(root_integer).
+  This causes no problem for static calculations, which
+  are performed without range restrictions
+  (see @RefSecNum(Static Expressions and Static Subtypes)). However
+  for run-time calculations, it is possible that Constraint_Error
+  might be raised when using an operator of @i(root_integer)
+  on the result of 'Val applied to a value of a nonstandard integer type.
address@hidden
+
address@hidden number], Sec=(of an integer value)}
+The @i(position number) of an integer value is equal to the value.
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00340-01]}
address@hidden@keepnext@;For @PrefixType{every modular subtype S},
+the following @Chg{Version=[2],New=[attributes are],Old=[attribute is]} 
defined:
address@hidden
address@hidden(description)
address@hidden,Kind=[Added],ChginAnnex=[T],
+  Leading=<T>, Prefix=<S>, AttrName=<Mod>, ARef=[AI95-00340-01],
+  address@hidden,New=[S'Mod denotes a function with the following 
specification:],Old=[]}
+
address@hidden(Descexample)
address@hidden,Kind=[Added]}
address@hidden,address@hidden S'Mod (@RI{Arg} : @RI{universal_integer})
+  @key{return} S'Base]}
address@hidden(Descexample)
+
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],NoPrefix=[T],Text=[This function returns @i{Arg}
+  @key{mod} S'Modulus, as a value of the type of address@hidden attribute Mod}
+
address@hidden<S>, AttrName=<Modulus>,
+  Text=[S'Modulus yields the modulus of the type of S, as a value of the
+        type @i(universal_integer).]}
address@hidden(description)
+
address@hidden
+
address@hidden
address@hidden, Sec=(integer_type_definition)}
+The elaboration of an @nt<integer_type_definition> creates the
+integer type and its first subtype.
+
+For a modular type, if the result of the execution of a
+predefined operator (see @RefSecNum(Operators and Expression Evaluation))
+is outside the base range of the type, the result is reduced
+modulo the modulus of the type to a value that is within the
+base range of the type.
+
address@hidden
address@hidden(Constraint_Error),Sec=(raised by failure of run-time check)}
+For a signed integer type,
+the exception Constraint_Error is raised by the execution of
+an operation that cannot deliver the correct result because
+it is outside the base range of the type.
address@hidden@IndexCheck{Division_Check}
address@hidden(Constraint_Error),Sec=(raised by failure of run-time check)}
+For any integer type, Constraint_Error is raised by the operators
+"/", "@key(rem)", and "@key(mod)" if the right operand is zero.]
+
address@hidden
+
address@hidden
address@hidden
+In an implementation, the range of Integer shall include the range
address@hidden@;2**15+1 .. address@hidden@;1.
+
address@hidden
+If Long_Integer is predefined for an implementation, then its
+range shall include the range @en@;2**31+1 .. address@hidden@;1.
+
+System.Max_Binary_Modulus shall be at least 2**16.
address@hidden
+
address@hidden
+For the execution of a predefined operation of a signed integer type,
+the implementation need not raise Constraint_Error if the result is
+outside the base range of the type, so long as the correct result
+is produced.
address@hidden
+  Constraint_Error is never raised for operations on modular types,
+  except for divide-by-zero (and @key[rem]/@key[mod]-by-zero).
address@hidden
+
address@hidden
address@hidden
+An implementation may provide additional predefined signed integer
address@hidden, declared in the visible part of Standard], whose first
+subtypes have names of the form Short_Integer,
+Long_Integer, Short_Short_Integer, Long_Long_Integer, etc.
+Different predefined integer types are allowed to have the same base range.
+However, the range of Integer should be no wider than that of Long_Integer.
+Similarly, the range of Short_Integer (if provided) should be no wider
+than Integer.
+Corresponding recommendations apply to any other predefined integer types.
+There need not be a named integer type corresponding to each
+distinct base range supported by an implementation.
+The range of each first subtype should be the base range of its type.
address@hidden predefined integer types declared in Standard.}
+
address@hidden integer type}
+An implementation may provide @i(nonstandard integer types),
+descendants of @i(root_integer) that are
+declared outside of the specification of package Standard,
+which need not have all the standard characteristics
+of a type defined by an @nt<integer_type_definition>.
+For example, a nonstandard integer type
+might have an asymmetric base range
+or it might not be allowed as
+an array or loop index (a very long integer).
+Any type descended from a nonstandard integer type is also nonstandard.
+An implementation may place arbitrary restrictions on the use of such types;
+it is implementation defined whether operators that are predefined
+for @lquotes@;any integer address@hidden@; are defined for a particular
+nonstandard integer type.
address@hidden any case, such types are not permitted as
address@hidden for formal scalar types @em
+see @RefSecNum(Formal Scalar Types).]
address@hidden nonstandard integer types and the operators defined for them.}
+
address@hidden's complement], Sec=(modular types)}
+For a one's complement machine, the high bound of the base range
+of a modular type whose modulus is one less than a power of 2
+may be equal to the modulus, rather than one less than the modulus.
+It is implementation defined for which powers of 2, if any, this
+permission is exercised.
+
address@hidden,Kind=[Added],Ref=[8652/0003],ARef=[AI95-00095-01]}
address@hidden a one's complement machine, implementations may support nonbinary
+modulus values greater than System.Max_Nonbinary_Modulus. It is implementation
+defined which specific values greater than System.Max_Nonbinary_Modulus, if
+any, are supported.],Old=[]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[On a one's complement machine, the natural full word
+type would have
+a modulus of address@hidden@;1. However, we would want to allow the all-ones
+bit pattern (which represents negative zero as a number) in logical operations.
+These permissions are intended to allow that and the natural modulus value
+without burdening implementations with supporting expensive modulus values.]}
address@hidden
address@hidden
+
address@hidden
address@hidden
+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 @RefSecNum{The Package Interfaces}).
address@hidden,Kind=[Added],address@hidden,
+Text=[Long_Integer should be declared in Standard if the target supports
+32-bit arithmetic. No other named integer subtypes should be declared in
+Standard.]}]}
address@hidden
+To promote portability, implementations should explicitly declare the integer
+(sub)types Integer and Long_Integer in Standard, and leave other
+predefined integer types anonymous.
+For implementations
+that already support Byte_Integer, etc., upward compatibility
+argues for keeping such declarations in Standard during the
+transition period, but perhaps generating a warning on use.
+A separate package Interfaces in the predefined environment
+is available for pre-declaring types such as Integer_8, Integer_16, etc.
+See @RefSecNum(The Package Interfaces).
+In any case, if the user declares a subtype (first or not)
+whose range fits in, for example, a byte, the implementation can
+store variables of the subtype in a single byte, even if the
+base range of the type is wider.
address@hidden
+
address@hidden's complement],Sec=(modular 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 nonbinary modulus up to Integer'Last.
address@hidden,Kind=[Added],address@hidden,
+Text=[For a two's complement target, modular types with a binary modulus
+up to System.Max_Int*2+2 should be supported. A nonbinary modulus up
+to Integer'Last should be supported.]}]}
address@hidden
+  Modular types provide bit-wise "@key{and}", "@key{or}", "@key{xor}",
+  and "@key{not}" operations.
+  It is important for systems programming that these be available for all
+  integer types of the target hardware.
address@hidden
address@hidden
+  Note that on a one's complement machine,
+  the largest supported modular type would normally have a nonbinary
+  modulus. On a two's complement machine, the largest supported
+  modular type would normally have a binary modulus.
address@hidden
address@hidden
+  Supporting a nonbinary modulus greater than Integer'Last can
+  impose an undesirable implementation burden on some machines.
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden literals}
+Integer literals are of the anonymous predefined
+integer type @i(universal_integer). Other integer types
+have no literals. However, the overload resolution rules
+(see @RefSec(The Context of Overload Resolution))
+allow expressions of the type @i(universal_integer)
+whenever an integer type is expected.
+
+The same arithmetic operators are predefined for all signed integer types
+defined by a @nt<signed_integer_type_definition>
+(see @RefSec(Operators and Expression Evaluation)).
+For modular types, these same operators are predefined, plus
+bit-wise logical operators (@key(and), @key(or), @key(xor), and @key(not)).
+In addition, for the unsigned types declared in the language-defined
+package Interfaces (see @RefSecNum(The Package Interfaces)),
+functions are defined that provide
+bit-wise shifting and rotating.
+
+Modular types match a @nt{generic_formal_parameter_declaration} of the
+form "@key(type) T @key(is mod) <>;";
+signed integer types match "@key(type) T @key(is range) <>;"
+(see @RefSecNum{Formal Scalar Types}).
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of integer types and subtypes: )
address@hidden(Example)
address@hidden(type) Page_Num  @key(is) @key(range) 1 .. 2_000;
address@hidden(type) Line_Size @key(is) @key(range) 1 .. Max_Line_Size;
+
address@hidden(subtype) Small_Int   @key(is) Integer   @key(range) -10 .. 10;
address@hidden(subtype) Column_Ptr  @key(is) Line_Size @key(range) 1 .. 10;
address@hidden(subtype) Buffer_Size @key(is) Integer   @key(range) 0 .. Max;
+
address@hidden(type) Byte        @key(is) @key(mod) 256; address@hidden an 
unsigned byte]
address@hidden(type) Hash_Index  @key(is) @key(mod) 97;  address@hidden modulus 
is prime]
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden to Ada 83}
+An implementation is allowed to support any number of distinct
+base ranges for integer types, even if fewer
+integer types are explicitly declared in Standard.
+
+Modular (unsigned, wrap-around) types are new.
address@hidden
+
address@hidden
+Ada 83's integer types are now called "signed" integer types,
+to contrast them with "modular" integer types.
+
+Standard.Integer, Standard.Long_Integer, etc., denote
+constrained subtypes of predefined integer types, consistent
+with the Ada 95 model that only subtypes have names.
+
+We now impose minimum requirements on the base range of
+Integer and Long_Integer.
+
+We no longer explain integer type definition in terms
+of an equivalence to a normal type derivation, except to say that all
+integer types are by definition implicitly derived from @i(root_integer).
+This is for various reasons.
+
+First of all, the equivalence with a type derivation and a subtype
+declaration was not perfect, and was the source of various AIs (for example,
+is the conversion of the bounds static? Is a numeric type a derived
+type with respect to other rules of the language?)
+
+Secondly, we don't want to require that every integer size supported
+shall have a corresponding named type in Standard. Adding named
+types to Standard creates nonportabilities.
+
+Thirdly, we don't want the set of types that match
+a formal derived type "type T is new Integer;" to
+depend on the particular underlying integer representation chosen
+to implement a given user-defined integer type. Hence, we
+would have needed anonymous integer types as parent types for
+the implicit derivation anyway. We have simply chosen to identify
+only one anonymous integer type @em @i(root_integer), and stated
+that every integer type is derived from it.
+
+Finally, the @lquotes@;address@hidden@; that there were distinct
+preexisting predefined types
+for every supported representation breaks down for fixed point
+with arbitrary smalls, and was never exploited for enumeration
+types, array types, etc. Hence, there seems little benefit
+to pushing an explicit equivalence between integer type
+definition and normal type derivation.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00340-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The Mod attribute is new. It eases mixing of signed and unsigned values in
+  an expression, which can be difficult as there may be no type which
+  can contain all of the values of both of the types involved.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0003],ARef=[AI95-00095-01]}
+  @Chg{Version=[2],address@hidden<Corrigendum:> Added additional permissions 
for
+  modular types on one's complement machines.],Old=[]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden of Discrete Types}
+
address@hidden
address@hidden@;For @PrefixType{every discrete subtype S},
+the following attributes are defined:
address@hidden(description)
address@hidden<S>, AttrName=<Pos>,
+  Text=[S'Pos denotes a function with the following specification:
address@hidden(Descexample)
address@hidden(function) S'Pos(@RI(Arg) : S'Base)
+  @b(return) @RI(universal_integer)
address@hidden(Descexample)
+
+     @NoPrefix@;This function returns the position number of the value
+     of @i(Arg), as a value of type @i(universal_integer).]}
+
address@hidden<S>, AttrName=<Val>,
+  Text=[S'Val denotes a function with the following specification:
address@hidden(Descexample)
address@hidden(function) S'Val(@RI(Arg) : @RI(universal_integer))
+  @b(return) S'Base
address@hidden(Descexample)
+
+     @address@hidden(evaluation), Sec=(Val)}
+     @Defn2{Term=(Constraint_Error),Sec=(raised by failure of run-time check)}
+     This function returns a value of the type of S
+     whose position number equals the value of @i(Arg).]}
+     @IndexCheck{Range_Check}
+     For the evaluation of a call on S'Val, if there
+     is no value in the base range of its type with the given
+     position number, Constraint_Error is raised.
+     @begin{Ramification}
+
+        By the overload resolution rules, a formal parameter of type
+        @i(universal_integer) allows an actual parameter of any
+        integer address@hidden
+     @begin{Reason}
+We considered allowing
+        S'Val for a signed integer subtype S to return an out-of-range value,
+        but since checks were required for enumeration and modular types
+        anyway, the allowance didn't seem worth the complexity of the 
address@hidden
address@hidden(description)
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0297-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0071-1]}
address@hidden,Type=[Leading],Text=[For @ChgPrefixType{Version=[4],
+Kind=[Revised],Text=[every static discrete subtype S for which there exists
+at least one value belonging to S that satisfies
address@hidden<Version=[4],New=[the predicates],Old=[any predicate]> of S]},
+the following attributes are defined:]}
+
address@hidden(Description)
address@hidden: @ChgAttribute{Version=[3],Kind=[Added],ChginAnnex=[T],
+  Leading=<F>, Prefix=<S>, AttrName=<First_Valid>, ARef=[AI05-0297-1],
+  We don't have a way to change multiple versions for attributes.}}
address@hidden,Kind=[RevisedAdded],ChginAnnex=[T],
+  Leading=<F>, Prefix=<S>, AttrName=<First_Valid>,
+  InitialVersion=[3], ARef=[AI05-0297-1], ARef=[AI12-0071-1],
+  address@hidden,New=[S'First_Valid denotes the smallest value
+        that belongs to S and satisfies the
+        @Chg{Version=[4],New=[predicates],Old=[predicate]} of S.
+        The value of this attribute is of the type of S.],Old=[]}]}
+
address@hidden: @ChgAttribute{Version=[3],Kind=[Added],ChginAnnex=[T],
+  Leading=<F>, Prefix=<S>, AttrName=<Last_Valid>, ARef=[AI05-0297-1],
+  We don't have a way to change multiple versions for attributes.}}
address@hidden,Kind=[RevisedAdded],ChginAnnex=[T],
+  Leading=<F>, Prefix=<S>, AttrName=<Last_Valid>,
+  InitialVersion=[3], ARef=[AI05-0297-1], ARef=[AI12-0071-1],
+  address@hidden,New=[S'Last_Valid denotes the largest value
+        that belongs to S and satisfies the
+        @Chg{Version=[4],New=[predicates],Old=[predicate]} of S. The value of
+        this attribute is of the type of S.],Old=[]}]}
address@hidden(Description)
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0297-1]}
address@hidden,address@hidden and Last_Valid
address@hidden are always static expressions. Any explicit predicate
+of S can only have been specified by a Static_Predicate aspect.]]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[An @nt{attribute_reference} is static if the
+  prefix is a static subtype (see @RefSecNum{Static Expressions and Static 
Subtypes}),
+  (true by definition) and any arguments are static (there are none). 
Similarly,
+  a dynamic predicate always makes a subtype nonstatic. QED.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We require there to be at least one value so that
+  these are always values of the subtype. (This sidesteps the question of what
+  to return for a subtype with no values.)]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[These attributes are intended primarily for use 
in
+  the case where the Static_Predicate aspect of S has been specified; First and
+  Last are equivalent if these are allowed and there is no predicate.]}
address@hidden
address@hidden
+
address@hidden
+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
address@hidden(perhaps due to an uninitialized variable)],
+then the implementation should raise Program_Error.
address@hidden,Sec=(raised by failure of run-time check)}
+This is particularly important for enumeration types with
+noncontiguous internal codes specified by an
address@hidden<address@hidden@!clause>.
address@hidden,Kind=[Added],address@hidden,
+Text=[Program_Error should be raised for the evaluation of S'Pos for an
+enumeration type, if the value of the operand does not correspond
+to the internal code for any enumeration literal of the type.]}]}
address@hidden
+We say Program_Error here, rather than Constraint_Error,
+because the main reason for such values is uninitialized variables,
+and the normal way to indicate such a use (if detected) is to raise
+Program_Error.
+(Other reasons would involve the misuse of low-level features such as
+Unchecked_Conversion.)
address@hidden
address@hidden
+
address@hidden
+Indexing and loop iteration use values of discrete types.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden operations],Sec=(of a discrete type)}
+The predefined operations of a discrete type include the assignment
+operation, qualification, the membership tests, and the
+relational operators; for a boolean type
+they include the short-circuit control forms and the
+logical operators; for an integer
+type they include type conversion to and from other numeric types,
+as well as the binary and unary adding operators @en@; and +, the multiplying
+operators, the unary operator @key(abs),
+and the exponentiation operator.
+The assignment operation is described in @RefSecNum(Assignment Statements).
+The other predefined operations are described in
address@hidden,New=[Clause],Old=[Section]} @RefSecNum{Names and Expressions}.
+
+As for all types, objects of a discrete type
+have Size and Address attributes (see @RefSecNum(Operational and 
Representation Attributes)).
+
address@hidden@;For a subtype of a discrete type, the result delivered by the
+attribute Val might not belong to the subtype; similarly, the actual parameter
+of the attribute Pos need not belong to the subtype. The following relations
+are satisfied (in the absence of an exception) by these attributes:
address@hidden(Example)
+   S'Val(S'Pos(X)) = X
+   S'Pos(S'Val(N)) = N
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of attributes of discrete subtypes: )
address@hidden(Example)
address@hidden  For the types and subtypes declared in subclause 
@RefSecNum(Enumeration Types) the following hold: ]
+
+--  Color'First   = White,   Color'Last   = Black
+--  Rainbow'First = Red,     Rainbow'Last = Blue
+
+--  Color'Succ(Blue) = Rainbow'Succ(Blue) = Brown
+--  Color'Pos(Blue)  = Rainbow'Pos(Blue)  = 4
+--  Color'Val(0)     = Rainbow'Val(0)     = White
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The attributes S'Succ, S'Pred, S'Width, S'Image, and S'Value have
+been generalized to apply to real types as well
+(see @RefSec{Scalar Types}).
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0297-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The attributes S'First_Valid and S'Last_Valid are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0071-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Updated wording of the
+  attributes S'First_Valid and S'Last_Valid to use the new term
+  "satisfies the predicates" (see @RefSecNum{Subtype Predicates}).]}
address@hidden
+
+
address@hidden Types}
+
address@hidden
address@hidden type}
+Real types provide approximations to the real numbers, with relative bounds
+on errors for floating point types, and with absolute bounds for fixed
+point types.
address@hidden
+
address@hidden
address@hidden<real_type_definition>,rhs="
+   @Syn2{floating_point_definition} | @Syn2{fixed_point_definition}"}
address@hidden
+
address@hidden
address@hidden
+A type defined by a @nt<real_type_definition> is implicitly
+derived from @i(root_real), an anonymous
+predefined (specific) real type.
address@hidden, all real types, whether floating point or fixed point,
+are in the derivation class rooted at @i(root_real).]
address@hidden
+  It is not specified whether the derivation from @i(root_real) is
+  direct or indirect, not that it really matters.
+  All we want is for all real types to be descendants of @i(root_real).
+
+  @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0099],ARef=[AI95-00152-01]}
+  @Chg{New=[Note that this derivation does not imply any inheritance of
+  subprograms. Subprograms are inherited only for types derived by a
+  @address@hidden@!definition} (see @RefSecNum{Derived Types and Classes}),
+  or a @address@hidden@!declaration} (see
+  @RefSecNum{Private Types and Private Extensions}, @RefSecNum{Private 
Operations},
+  and @RefSecNum{Formal Private and Derived Types}).],Old=[]}
+
address@hidden
+
address@hidden@PDefn{universal_real}
address@hidden literals}
+Real literals are all of the type @i(universal_real),
+the universal type (see @RefSecNum(Derivation Classes)) for the
+class rooted at @i(root_real), allowing their use with
+the operations of any real type.
address@hidden
+Certain multiplying operators have a result type of @i(universal_fixed)
+(see @RefSecNum{Multiplying Operators}),
+the universal type for the class of fixed point types, allowing
+the result of the multiplication or division to be used where any
+specific fixed point type is expected.]
address@hidden
+
address@hidden
address@hidden, Sec=(real_type_definition)}
+The elaboration of a @nt<real_type_definition> consists of the
+elaboration of the @nt<floating_point_definition> or the
address@hidden<fixed_point_definition>.
address@hidden
+
address@hidden
+An implementation shall perform the run-time evaluation
+of a use of a predefined operator of @i(root_real)
+with an accuracy at least as great as that of any floating point
+type definable by a @nt<floating_point_definition>.
address@hidden
+  Static calculations using the operators of @i(root_real) are
+  exact, as for all static calculations.
+  See @RefSecNum(Static Expressions and Static Subtypes).
address@hidden
address@hidden(ImplNote)
+  The Digits attribute of the type used to represent @i(root_real)
+  at run time is at least as great as that of any other floating
+  point type defined by a @nt<floating_point_definition>,
+  and its safe range includes that of any such floating point type
+  with the same Digits attribute.
+  On some machines, there might be real types with less accuracy but
+  a wider range, and hence run-time calculations with @i(root_real)
+  might not be able to accommodate all values that can be represented
+  at run time in such floating point or fixed point types.
address@hidden(ImplNote)
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
address@hidden the execution of a predefined operation of a real type,
+the implementation need not raise Constraint_Error if the result is
+outside the base range of the type, so long as the correct result
+is produced, or the Machine_Overflows attribute of the type is 
@Chg{Version=[2],
+New=[False],Old=[false]}
+(see @RefSecNum{Numeric Performance Requirements}).]
+
address@hidden real type}
+An implementation may provide @i(nonstandard real types),
+descendants of @i(root_real) that are
+declared outside of the specification of package Standard,
+which need not have all the standard characteristics
+of a type defined by a @nt<real_type_definition>. For
+example, a nonstandard real type
+might have an asymmetric or unsigned base range,
+or its predefined operations might wrap around or @lquotes@;address@hidden@; 
rather
+than overflow (modular or saturating arithmetic), or it might not
+conform to the accuracy
+model (see @RefSecNum{Numeric Performance Requirements}).
+Any type descended from a nonstandard real type is also nonstandard.
+An implementation may place arbitrary restrictions on the use of such types;
+it is implementation defined whether operators that are predefined
+for @lquotes@;any real address@hidden@; are defined for a particular 
nonstandard real type.
address@hidden any case, such types are not permitted as 
@nt{explicit_generic_actual_parameter}s for formal scalar types @em see 
@RefSecNum(Formal Scalar Types).]
address@hidden nonstandard real types and the operators defined for them.}
address@hidden
+
address@hidden
+As stated, real literals are of the anonymous predefined
+real type @i(universal_real). Other real types
+have no literals. However, the overload resolution rules
+(see @RefSecNum(The Context of Overload Resolution))
+allow expressions of the type @i(universal_real)
+whenever a real type is expected.
+
address@hidden
+
address@hidden
+The syntax rule for @nt{real_type_definition} is modified to use
+the new syntactic categories
address@hidden and @nt{fixed_point_definition},
+instead of @ntf{floating_point_constraint} and
address@hidden, because the semantics of a type
+definition are significantly different than the semantics of a
+constraint.
+
+All discussion of model numbers, safe ranges, and machine numbers
+is moved to @RefSecNum{Floating Point Types},
address@hidden of Floating Point Types}, and
address@hidden Performance Requirements}.
+Values of a fixed point type are now described as being multiples of
+the @i(small) of the fixed point type, and we have no need for model
+numbers, safe ranges, etc. for fixed point types.
+
address@hidden
+
address@hidden Point Types}
+
address@hidden
address@hidden point type}
+For floating point types, the error bound is specified as a relative
+precision by giving the required minimum number of significant decimal
+digits.
address@hidden
+
address@hidden
address@hidden<floating_point_definition>,rhs="
+  @key{digits} @address@hidden address@hidden"}
+
address@hidden<real_range_specification>,rhs="
+  @key{range} @address@hidden .. @address@hidden"}
address@hidden
+
address@hidden
address@hidden decimal precision], Sec=(of a floating point type)}
+The @i(requested decimal precision), which is the minimum
+number of significant decimal digits required for the floating point type,
+is specified by the
+value of the @nt<expression> given after
+the reserved word @key(digits).
address@hidden type], Sec=(requested decimal precision)}
+This @nt<expression>
+is expected to be of any integer type.
+
address@hidden type], Sec=(real_range_specification bounds)}
+Each @nt<simple_expression> of a
address@hidden<real_range_specification> is expected to be of any real
address@hidden; the types need not be the same].
address@hidden
+
address@hidden
address@hidden
+The requested decimal precision shall be specified by a static @nt<expression>
+whose value is positive and no greater than
+System.Max_Base_Digits.
+Each @nt<simple_expression> of a @nt<real_range_specification>
+shall also be static.
address@hidden
+If the @nt<real_range_specification> is omitted,
+the requested decimal precision shall be no greater than System.Max_Digits.
address@hidden(Reason)
+  We have added Max_Base_Digits to package System. It corresponds
+  to the requested decimal precision of
+  @i(root_real). System.Max_Digits
+  corresponds to the maximum value for Digits that may be specified
+  in the absence of a @nt<real_range_specification>, for upward
+  compatibility. These might not be the same if @i<root_real>
+  has a base range that does not include @PorM 10.0**(4*Max_Base_Digits).
address@hidden(Reason)
+
+A @nt<floating_point_definition> is illegal if the
+implementation does not support a floating point type that
+satisfies the requested decimal precision and range.
address@hidden combinations of requested decimal precision and range
+  are supported for floating point types.}
address@hidden
+
address@hidden
+The set of values for a floating point type is the (infinite) set of rational
+numbers.
address@hidden numbers], Sec=(of a floating point type)}
+The @i(machine numbers) of a floating point type are the values
+of the type that can be represented exactly in every
+unconstrained variable of the type.
address@hidden range], Sec=(of a floating point type)}
+The base range (see @RefSecNum{Scalar Types})
+of a floating point type is symmetric around zero,
+except that it can include some extra negative values
+in some address@hidden
+For example, if a 2's complement
+  representation is used for the mantissa rather than a sign-mantissa or
+  1's complement representation, then there is usually one extra
+  negative machine address@hidden
address@hidden
+
+  If the Signed_Zeros attribute is True,
+  then minus zero could in a sense be considered a value of the type.
+  However, for most purposes, minus zero behaves the same as plus zero.
+
address@hidden
+
address@hidden decimal precision], Sec=(of a floating point type)}
+The @i(base decimal precision) of a floating point type is the number
+of decimal digits of precision representable in objects
+of the type.
address@hidden range], Sec=(of a floating point type)}
+The @i(safe range) of a floating point type is that part of its
+base range for which the accuracy corresponding to the base decimal precision
+is preserved by all predefined operations.
address@hidden
+In most cases,
+  the safe range and base range are the same.
+  However, for some hardware, values near the boundaries of
+  the base range might result in excessive
+  inaccuracies or spurious overflows when used with
+  certain predefined operations. For such hardware, the safe
+  range would omit such address@hidden
+
address@hidden decimal precision], Sec=(of a floating point type)}
+A @nt<floating_point_definition> defines a floating point type
+whose base decimal precision is no less than the requested
+decimal precision.
address@hidden range], Sec=(of a floating point type)}
address@hidden range], Sec=(of a floating point type)}
+If a @nt<real_range_specification> is given,
+the safe range of the floating point type (and hence, also its base range)
+includes at least the
+values of the simple expressions
+given in the @nt<real_range_specification>.
+If a @nt<real_range_specification> is not given,
+the safe (and base) range of the type includes at least the values of the range
address@hidden@;10.0**(4*D) .. +10.0**(4*D) where D is the requested decimal 
precision.
address@hidden safe range might include
+other values as well. The attributes Safe_First and Safe_Last
+give the actual bounds of the safe range.]
+
+A @nt<floating_point_definition> also defines a first
+subtype of the type.
address@hidden, Sec=(subtype)}
address@hidden, Sec=(subtype)}
+If a @nt<real_range_specification> is given, then
+the subtype is constrained to a range whose bounds are
+given by a conversion of the values of the @nt<simple_expression>s
+of the @nt<real_range_specification> to the type being defined.
+Otherwise, the subtype is unconstrained.
+
address@hidden
+  @ChgRef{Version=[1],address@hidden is discussed in AC-00002, which we can't 
reference here}
+  @ChgAdded{Version=[1],Text=[The conversion mentioned above is not an 
@i{implicit subtype
+  conversion} (which is something that happens at overload resolution, see
+  @RefSecNum{Type Conversions}), although it happens implicitly. Therefore,
+  the freezing rules are not invoked on the type (which is important so that
+  representation items can be given for the type).
+  @PDefn2{Term=[subtype conversion],Sec=(bounds of a floating point type)}]}
address@hidden
+
address@hidden
+There is a predefined, unconstrained, floating point subtype
+named address@hidden, declared in the visible part of
+package Standard].
address@hidden
+
address@hidden
address@hidden, Sec=(floating_point_definition)}
address@hidden elaboration of a @nt<floating_point_definition> creates
+the floating point type and its first subtype.]
address@hidden
+
address@hidden
address@hidden
+In an implementation that supports floating point types with
+6 or more digits of precision, the requested
+decimal precision for Float shall be at least 6.
+
address@hidden
+If Long_Float is predefined for an implementation, then its
+requested decimal precision shall be at least 11.
address@hidden
+
address@hidden
address@hidden
address@hidden
+An implementation is
+allowed to provide additional predefined floating point
address@hidden, declared in the visible part of Standard], whose
+(unconstrained) first subtypes have names of the form Short_Float,
+Long_Float, Short_Short_Float, Long_Long_Float, etc.
+Different predefined floating point types are allowed to
+have the same base decimal precision.
+However, the precision of Float should be no greater than that of Long_Float.
+Similarly, the precision of Short_Float (if provided) should be no greater
+than Float.
+Corresponding recommendations apply to any other predefined floating point
+types.
+There need not be a named floating point type corresponding to each
+distinct base decimal precision supported by an implementation.
address@hidden predefined floating point types declared in Standard.}
address@hidden
+
address@hidden
address@hidden
+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 @RefSecNum(The Package Interfaces)).
address@hidden,Kind=[Added],address@hidden,
+Text=[Long_Float should be declared in Standard if the target supports
+11 or more digits of precision. No other named float subtypes should be
+declared in Standard.]}]}
address@hidden
+To promote portability, implementations should explicitly declare the floating
+point (sub)types Float and Long_Float in Standard, and leave other
+predefined float types anonymous.
+For implementations
+that already support Short_Float, etc., upward compatibility
+argues for keeping such declarations in Standard during the
+transition period, but perhaps generating a warning on use.
+A separate package Interfaces in the predefined environment
+is available for pre-declaring types such as Float_32, IEEE_Float_64, etc.
+See @RefSecNum(The Package Interfaces).
address@hidden
address@hidden
+
address@hidden
+If a floating point subtype is unconstrained,
+then assignments to variables of the subtype involve only
+Overflow_Checks, never Range_Checks.
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of floating point types and subtypes:)
address@hidden(Example)
address@hidden(type) Coefficient @key(is) @key(digits) 10 @key(range) -1.0 .. 
1.0;
+
address@hidden(type) Real @key(is) @key(digits) 8;
address@hidden(type) Mass @key(is) @key(digits) 7 @key(range) 0.0 .. 1.0E35;
+
address@hidden(subtype) Probability @key(is) Real @key(range) 0.0 .. 1.0;   
address@hidden   a subtype with a smaller range]
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden with Ada 83}
+No Range_Checks, only Overflow_Checks, are performed on
+variables (or parameters) of an
+unconstrained floating point subtype. This is upward
+compatible for programs that do not raise Constraint_Error.
+For those that do raise Constraint_Error, it is possible
+that the exception will be raised at a later point, or
+not at all, if extended range floating point registers are used to hold
+the value of the variable (or parameter).
address@hidden(Reason)
+  This change was felt to be justified by the possibility
+  of improved performance on machines with extended-range
+  floating point registers. An implementation need not
+  take advantage of this relaxation in the range checking; it
+  can hide completely the use of extended range registers if desired,
+  presumably at some run-time expense.
address@hidden(Reason)
address@hidden
+
address@hidden
+The syntax rules for @ntf{floating_point_constraint} and
address@hidden are removed. The syntax rules for
address@hidden and
address@hidden are new.
+
+A syntax rule for @nt<digits_constraint> is given in
address@hidden Point Types}. In @RefSecNum{Reduced Accuracy Subtypes}
+we indicate that a @nt<digits_constraint>
+may be applied to a floating point @nt<subtype_mark> as well
+(to be compatible with Ada 83's @ntf<floating_point_constraint>).
+
+Discussion of model numbers is postponed to
address@hidden of Floating Point Types} and
address@hidden Performance Requirements}.
+The concept of safe numbers has been replaced by the concept
+of the safe range of values. The bounds of the safe range are
+given by T'Safe_First .. T'Safe_Last, rather than -T'Safe_Large ..
+T'Safe_Large, since on some machines the safe range is not
+perfectly symmetric.
+The concept of machine numbers is new, and is relevant to
+the definition of Succ and Pred for floating point numbers.
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden of Floating Point Types}
+
address@hidden
address@hidden@;The following attribute is defined for
address@hidden floating point subtype S}:
+
address@hidden(description)
address@hidden, Kind=[Revised], ChginAnnex=[F], Leading=[F],
+  Prefix=<S>, AttrName=<Digits>, Ref=[8652/0004], ARef=[AI95-00203-01],
+  Text=[S'Digits denotes the requested decimal precision
+  for the subtype S. The value of this attribute
+  is of the type @i(universal_integer).]}
+The requested decimal precision of the base subtype of a floating
+point type @i{T} is defined to be the largest value of @i{d} for which
address@hidden@*],Old=[]}
+ceiling(@i{d} * log(10) / log(T'Machine_Radix)) + @address@hidden,Old=[1]}
+<= T'address@hidden@*
+where g is 0 if Machine_Radix is a positive power of 10 and 1 
otherwise],Old=[]}.
address@hidden(description)
address@hidden
address@hidden
+
address@hidden
address@hidden operations],Sec=(of a floating point type)}
+The predefined operations of a floating point type include the assignment
+operation, qualification, the membership tests, and
+explicit conversion to and from other numeric types. They also
+include the relational operators and the following predefined
+arithmetic operators:
+the binary and unary adding operators @en@; and +,
+certain multiplying
+operators, the unary operator @key(abs),
+and the exponentiation operator.
+
+As for all types, objects of a floating point type
+have Size and Address attributes
+(see @RefSecNum(Operational and Representation Attributes)).
+Other attributes of floating point types are defined in
address@hidden of Floating Point Types}.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],Ref=[8652/0004],ARef=[AI95-00203-01]}
address@hidden,address@hidden<Corrigendum:> Corrected the formula for Digits 
when
+the Machine_Radix is 10.]}
address@hidden
+
+
address@hidden Point Types}
+
address@hidden
address@hidden point type}
address@hidden fixed point type}
address@hidden fixed point type}
+A fixed point type is either an ordinary fixed point type,
+or a decimal fixed point type.
address@hidden, Sec=(of a fixed point type)}
+The error bound of a fixed point type is specified as an
+absolute value, called the @i(delta) of the fixed point type.
address@hidden
+
address@hidden
address@hidden<fixed_point_definition>,rhs="@Syn2{ordinary_fixed_point_definition}
 | @Syn2{decimal_fixed_point_definition}"}
+
+
address@hidden<ordinary_fixed_point_definition>,rhs="
+   @key{delta} @address@hidden  @Syn2{real_range_specification}"}
+
address@hidden<decimal_fixed_point_definition>,rhs="
+   @key{delta} @address@hidden @key{digits} @address@hidden address@hidden"}
+
address@hidden,Kind=[Revised],ARef=[AI12-0152-1]}
address@hidden<digits_constraint>,rhs="
+   @key{digits} @address@hidden,address@hidden,address@hidden address@hidden"}
address@hidden
+
address@hidden
address@hidden type], Sec=(fixed point type delta)}
+For a type defined by a @nt<fixed_point_definition>,
+the @i(delta) of the type is specified by the value of
+the @nt<expression> given after the
+reserved word @key(delta); this @nt<expression> is expected
+to be of any real type.
address@hidden type], Sec=(decimal fixed point type digits)}
address@hidden, Sec=(of a decimal fixed point subtype)}
address@hidden fixed point type}
+For a type defined by a @nt<decimal_fixed_point_definition>
+(a @i(decimal) fixed point type),
+the number of significant decimal digits
+for its first subtype (the @i(digits) of the first subtype)
+is specified by the @nt<expression> given
+after the reserved word @key(digits); this @nt<expression>
+is expected to be of any integer type.
+
address@hidden,Kind=[Added],ARef=[AI12-0159-1]}
address@hidden,Text=[The @nt{simple_expression} of a
address@hidden is expected to be of any integer type.]}
address@hidden
+
address@hidden
+In a @nt<fixed_point_definition> or @nt<digits_constraint>,
+the @nt<expression>s given after the
+reserved words @key(delta) and @key(digits) shall be static; their
+values shall be positive.
+
address@hidden,Kind=[Revised],ARef=[AI95-00100-01]}
address@hidden, Sec=(of a fixed point type)}
+The set of values of a fixed point type comprise the integral multiples
+of a number called the @i(small) of the
address@hidden,address@hidden numbers],Sec=[of a fixed point type]}
+The @i{machine numbers} of a fixed point type are the values of the type that
+can be represented exactly in every unconstrained variable of the 
type.],Old=[]}
address@hidden fixed point type}
+For a type defined by an @nt<ordinary_fixed_point_definition>
+(an @i(ordinary) fixed point type), the @i(small) may be specified
+by an @nt<address@hidden@!clause>
+(see @RefSecNum{Operational and Representation Attributes});
+if so specified, it shall be no greater than the @i(delta) of the type.
+If not specified, the @i(small) of an ordinary fixed
+point type is an implementation-defined
+power of two less than or equal to the @i(delta).
address@hidden @i(small) of an ordinary fixed point type.}
+
+For a decimal fixed point type,
+the @i(small) equals the @i(delta);
+the @i(delta)
+shall be a power of 10.
+If a @nt<real_range_specification> is given,
+both bounds of the range shall be in
+the range @en@;(address@hidden(digits)@en@;1)address@hidden(delta) .. 
+(address@hidden(digits)@en@;1)address@hidden(delta).
+
+A @nt<fixed_point_definition> is illegal if the implementation
+does not support a fixed point type with the given @i(small) and
+specified range or @i(digits).
address@hidden combinations of @i(small), range, and @i(digits)
+  are supported for fixed point types.}
+
+For a @nt<subtype_indication> with a @nt<digits_constraint>, the
address@hidden<subtype_mark> shall denote a decimal fixed point subtype.
address@hidden(Honest)
+  Or, as an obsolescent feature, a floating point subtype is permitted
+  @em see @RefSecNum(Reduced Accuracy Subtypes).
address@hidden(Honest)
address@hidden
+
address@hidden
address@hidden range], Sec=(of a fixed point type)}
+The base range (see @RefSecNum{Scalar Types}) of a fixed point type
+is symmetric around zero, except possibly for an extra negative
+value in some implementations.
+
address@hidden@PDefn2{Term=[base range], Sec=(of an ordinary fixed point type)}
+An @nt<ordinary_fixed_point_definition> defines an
+ordinary fixed point type whose base range
+includes at least all multiples of @i(small) that are between the
+bounds specified
+in the @nt<real_range_specification>. The base range of the
+type does not necessarily include the specified bounds themselves.
address@hidden, Sec=(subtype)}
address@hidden, Sec=(subtype)}
+An @nt<address@hidden@address@hidden> also defines a constrained first
+subtype of the type, with each bound of its range
+given by the closer to zero of:
address@hidden(itemize)
+  the value of the conversion to the fixed point type
+  of the corresponding @nt<expression> of the
+  @nt<real_range_specification>;
+  @PDefn2{Term=[implicit subtype conversion],Sec=(bounds of a fixed point 
type)}
+
+  @begin{Honest}
+    @ChgRef{Version=[1],address@hidden is discussed in AC-00002, which we 
can't reference here}
+    @ChgAdded{Version=[1],Text=[The conversion mentioned above is not an 
@i{implicit subtype
+    conversion} (which is something that happens at overload resolution, see
+    @RefSecNum{Type Conversions}), although it happens implicitly. Therefore,
+    the freezing rules are not invoked on the type (which is important so that
+    representation items can be given for the type).
+    @PDefn2{Term=[subtype conversion],Sec=(bounds of a fixed point type)}]}
+  @end{Honest}
+
+  the corresponding bound of the base range.
address@hidden(itemize)
+
address@hidden range], Sec=(of a decimal fixed point type)}
+A @nt<decimal_fixed_point_definition> defines a decimal fixed point
+type whose base range includes at least
+the range @en@;(address@hidden(digits)@en@;1)address@hidden(delta) .. 
+(address@hidden(digits)@en@;1)address@hidden(delta).
address@hidden, Sec=(subtype)}
address@hidden, Sec=(subtype)}
+A @nt<decimal_fixed_point_definition> also defines a constrained first
+subtype of the type. If a @nt<real_range_specification> is given,
+the bounds of the first subtype are given by a conversion
+of the values of the @nt<expression>s of the
address@hidden<real_range_specification>.
address@hidden subtype conversion],Sec=(bounds of a decimal fixed point type)}
+Otherwise, the range of the first subtype is
address@hidden@;(address@hidden(digits)@en@;1)address@hidden(delta) .. 
+(address@hidden(digits)@en@;1)address@hidden(delta).
+
address@hidden
+  @ChgRef{Version=[1],address@hidden is discussed in AC-00002, which we can't 
reference here}
+  @ChgAdded{Version=[1],Text=[The conversion mentioned above is not an 
@i{implicit subtype
+  conversion} (which is something that happens at overload resolution, see
+  @RefSecNum{Type Conversions}), although it happens implicitly. Therefore,
+  the freezing rules are not invoked on the type (which is important so that
+  representation items can be given for the type).
+  @PDefn2{Term=[subtype conversion],Sec=(bounds of a decimal fixed point 
type)}]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden, Sec=(fixed_point_definition)}
+The elaboration of a @nt<fixed_point_definition>
+creates the fixed point type and its first subtype.
+
address@hidden,Kind=[Revised],ARef=[AI12-0152-1]}
+For a @nt<digits_constraint> on a decimal fixed point subtype with
+a given @i(delta), if it does not have a @nt<range_constraint>,
+then it specifies an implicit range
address@hidden@;(address@hidden(D)@en@;1)address@hidden(delta) .. 
+(address@hidden(D)@en@;1)address@hidden(delta),
+where @i(D) is the value of the
address@hidden,address@hidden<simple_expression>],address@hidden<expression>]}.
address@hidden,
+  Sec=(digits_constraint with a decimal fixed point subtype)}
+A @nt<digits_constraint> is @i(compatible) with a decimal
+fixed point subtype if the value of the
address@hidden,address@hidden<simple_expression>],address@hidden<expression>]}
+is no greater than the @i(digits) of the subtype,
+and if it specifies (explicitly
+or implicitly) a range that is compatible with the subtype.
address@hidden(Discussion)
+  Except for the requirement that the @i(digits) specified be
+  no greater than the @i(digits) of the subtype being
+  constrained, a @nt<digits_constraint> is essentially
+  equivalent to a @nt<range_constraint>.
+
+  @address@hidden@;Consider the following example:
address@hidden
address@hidden D @key[is] @key[delta] 0.01 @key[digits] 7 @key[range] -0.00 .. 
9999.99;
address@hidden
+
+  @ChgRef{Version=[1],address@hidden AI-00008}
+  The compatibility rule implies that the @nt{digits_constraint}
+  "@key[digits] 6" specifies an implicit range of
+  "@en@;@Chg{New=[9999.99],Old=[99.9999]} .. 
@Chg{New=[9999.99],Old=[99.9999]}".
+  Thus, "@key[digits] 6" is not compatible with the constraint of D, but
+  "@key[digits] 6 range 0.00 .. 9999.99" is compatible.
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00114-01]}
+  A value of a scalar type
+  belongs to a constrained subtype of the type if it belongs to the
+  range of the subtype. Attributes like Digits and Delta have no
+  @Chg{Version=[2],New=[effect],Old=[affect]} on this fundamental rule.
+  So the obsolescent forms of
+  @nt<digits_constraint>s and @nt<delta_constraint>s that are
+  called @lquotes@;accuracy address@hidden@; in RM83 don't really
+  represent constraints on the values of the subtype, but rather primarily
+  affect compatibility of the @lquotes@;address@hidden@; with the subtype
+  being @lquotes@;address@hidden@; In this sense, they might better
+  be called @lquotes@;subtype address@hidden@; rather than 
@lquotes@;address@hidden@;
+
+  Note that the @nt<digits_constraint> on a decimal fixed point subtype
+  is a combination of an assertion about the @i(digits) of the
+  subtype being further constrained, and a constraint on the range of
+  the subtype being defined, either explicit or implicit.
address@hidden(Discussion)
+
address@hidden,Kind=[Revised],ARef=[AI12-0152-1]}
address@hidden, Sec=(digits_constraint)}
+The elaboration of a @nt<digits_constraint> consists of the
+elaboration of the @nt<range_constraint>, if any.
address@hidden
+If a @nt<range_constraint> is given, a check is made that
+the bounds of the range are both in the range
address@hidden@;(address@hidden(D)@en@;1)address@hidden(delta) .. 
+(address@hidden(D)@en@;1)address@hidden(delta),
+where @i(D) is the value of the (static)
address@hidden,address@hidden<simple_expression>],address@hidden<expression>]}
+given after the reserved word @key(digits).
address@hidden(Constraint_Error),Sec=(raised by failure of run-time check)}
+If this check fails, Constraint_Error is raised.
address@hidden
+
address@hidden
+The implementation shall support at least 24 bits of precision
+(including the sign bit) for fixed point types.
address@hidden
+This is sufficient to represent Standard.Duration with a @i(small)
+no more than 50 milliseconds.
address@hidden
address@hidden
+
address@hidden
+Implementations are permitted to support only
address@hidden(small)s that are a power of two. In particular,
+all decimal fixed point type declarations can be disallowed.
+Note however that conformance with the Information Systems Annex
+requires support for decimal @i(small)s, and decimal fixed point
+type declarations with @i(digits) up to at least 18.
address@hidden
+The accuracy requirements for multiplication, division, and conversion
+(see @RefSec{Model of Floating Point Arithmetic})
+are such that
+support for arbitrary @i(small)s should be practical without undue
+implementation effort. Therefore, implementations should support fixed point
+types with arbitrary values for @i(small) (within reason).
+One reasonable limitation would be to limit support to fixed point types
+that can be converted to the most precise floating point type
+without loss of precision (so that Fixed_IO is implementable in terms
+of Float_IO).
address@hidden
address@hidden
+
address@hidden
+  @Leading@;The base range of
+  an ordinary fixed point type need not include the specified bounds
+  themselves
+  so that the range specification can be given in a natural way, such as:
+  @address@hidden(Example)
+   @b(type) Fraction @b(is delta) 2.0**(-15) @b(range) -1.0 .. 1.0;
+  @end(Example)
+
+  @NoPrefix@;With 2's complement hardware, such a type could have a
+  signed 16-bit representation, using 1 bit for the sign
+  and 15 bits for fraction, resulting in a base range of
+  @en@;1.0 .. address@hidden@;2.0**(@en@;15).
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of fixed point types and subtypes:)
address@hidden(Example)
address@hidden(type) Volt @key(is) @key(delta) 0.125 @key(range) 0.0 .. 255.0;
+
+  -- @RI[A pure fraction which requires all the available]
+  -- @RI[space in a word can be declared as the type Fraction:]
address@hidden(type) Fraction @key(is) @key(delta) System.Fine_Delta 
@key(range) -1.0 .. 1.0;
+  -- @RI[Fraction'Last = 1.0 @en System.Fine_Delta]
+
address@hidden(type) Money @key(is) @key(delta) 0.01 @key(digits) 15;  -- 
@RI[decimal fixed point]
address@hidden(subtype) Salary @key(is) Money @key(digits) 10;
+  -- @RI[Money'Last = 10.0**13 @en 0.01, Salary'Last = 10.0**8 @en 0.01]
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden with Ada 83}
+In Ada 95, S'Small always equals S'Base'Small,
+so if an implementation chooses a @i(small) for a fixed point type smaller
+than required by the @i(delta), the value of S'Small in Ada 95 might not be
+the same as it was in Ada 83.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
address@hidden to Ada 83}
+Decimal fixed point types are new, though their
+capabilities are essentially similar to that available
+in Ada 83 with a fixed point type whose @i(small) equals its @i(delta)
address@hidden,New=[and both are],Old=[equals]}
+a power of 10. However, in the Information Systems Annex, additional
+requirements are placed on the support of decimal fixed point types
+(e.g. a minimum of 18 digits of precision).
address@hidden
+
address@hidden
+The syntax rules for @ntf{fixed_point_constraint} and
address@hidden are removed. The syntax rule for
address@hidden is new.
+A syntax rule for @nt<delta_constraint> is included in the
+Obsolescent features (to be compatible with Ada 83's
address@hidden<fixed_point_constraint>).
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00100-01]}
address@hidden,Text=[Added wording to define the
+machine numbers of fixed point types; this is needed by the static
+evaluation rules.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0152-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Changed the syntax so that the value following @key[digits] in a
+  @nt<digits_constraint> is a @nt<simple_expression>. This is compatible
+  with one very unlikely exception: if the @key[digits] expression is
+  a static expression of a modular type using an unparenthesized logical
+  operator (like @key[and] or @key[or]). Parenthesizing the expression
+  will make it legal in that case. The change is necessary to eliminate
+  syntax ambguities in @nt<derived_type_definition>s.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0159-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum>:Added wording to define the
+  expected type for a @nt{digits_constraint}. This was missing since Ada 95,
+  but as it is obvious and unchanged from Ada 83, we don't consider it an
+  incompatibility.]}
address@hidden
+
+
+
address@hidden of Fixed Point Types}
+
address@hidden
address@hidden@;The following attributes are defined for
address@hidden fixed point subtype S}:
address@hidden(description)
address@hidden, Kind=[Revised], ChginAnnex=[F], Leading=[F],
+  Prefix=<S>, AttrName=<Small>, Ref=[8652/0005], ARef=[AI95-00054-01],
+  Text=[S'Small
+     denotes the @i(small) of the type of S.
+     The value of this attribute is of the type @i(universal_real).]}
+     @PDefn2{Term=[specifiable], Sec=(of Small for fixed point types)}
+     @Defn{Small clause}
+     Small may be specified
+     for address@hidden ordinary],Old=[]} fixed point types
+     via an @address@hidden@!clause}
+     (see @RefSecNum{Operational and Representation Attributes});
+     the expression of such a clause shall be
+     address@hidden,address@hidden,Old=[]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Small],
+    address@hidden,Text=[Scale factor for a fixed point type.]}]}
+
address@hidden<S>, AttrName=<Delta>,
+  Text=[S'Delta
+     denotes the @i(delta) of the fixed point subtype S.
+     The value of this attribute is of the type @i(universal_real).]}
+     @begin{Reason}
+
+       The @i(delta) is associated with the @i(sub)type as opposed
+       to the type,
+       because of the possibility of an (obsolescent) 
@nt<delta_constraint>address@hidden
+
address@hidden<S>, AttrName=<Fore>,
+  Text=[S'Fore yields the minimum number of characters needed
+     before the decimal point
+     for the decimal representation of any value of the subtype S, assuming
+     that the representation does not include an exponent, but includes
+     a one-character prefix that is either a minus sign or a space.
+     (This minimum number does not include superfluous zeros or
+     underlines, and is at least 2.) The value of this attribute
+     is of the type @i(universal_integer).]}
+
address@hidden<S>, AttrName=<Aft>,
+  Text=<S'Aft yields the number of decimal digits needed after
+     the decimal point to accommodate the @i(delta) of the subtype
+     S, unless the @i(delta) of the subtype S is greater than 0.1,
+     in which case the attribute yields the value one. @Redundant[(S'Aft
+     is the smallest positive integer N for which (10**N)*S'Delta is
+     greater than or equal to one.)] The value of this attribute is of
+     the type @i(universal_integer).>}
address@hidden(description)
address@hidden
+
address@hidden
address@hidden@;The following additional attributes are defined for
address@hidden decimal fixed point subtype S}:
address@hidden
address@hidden(description)
address@hidden<S>, AttrName=<Digits>,
+  Text=[S'Digits denotes the @i(digits) of the decimal
+     fixed point subtype S, which corresponds to the number
+     of decimal digits that are representable in objects of the
+     subtype.
+     The value of this attribute is of the type @i(universal_integer).]}
+     Its value is determined as follows:
address@hidden, Sec=(of a decimal fixed point subtype)}
address@hidden(itemize)
+  For a first subtype or a subtype
+  defined by a @nt<subtype_indication> with
+  a @nt<digits_constraint>, the digits is the value
+  of the expression given after the reserved word @key(digits);
+
+  For a subtype defined by a @nt<subtype_indication> without
+  a @nt<digits_constraint>, the digits of the subtype
+  is the same as that of the subtype denoted
+  by the @nt<subtype_mark> in the @nt<subtype_indication>.
address@hidden(ImplNote)
+  Although a decimal subtype can be both range-constrained
+  and digits-constrained, the digits constraint is intended
+  to control the Size attribute of the subtype. For decimal
+  types, Size can be important because input/output of decimal types
+  is so common.
address@hidden(ImplNote)
+
+  The digits of a base subtype is the largest integer
+  @i(D) such that the range
+  @en@;(address@hidden(D)@en@;1)address@hidden(delta) .. 
+(address@hidden(D)@en@;1)address@hidden(delta)
+  is included in the base range of the type.
+
address@hidden(itemize)
+
address@hidden<S>, AttrName=<Scale>,
+  Text=[S'Scale denotes the @i(scale) of the subtype S,
+ defined as the value N such that S'Delta = 10.0**(@en@;N).
+ @Defn2{Term=[scale], Sec=(of a decimal fixed point subtype)}
+ @Redundant{The scale indicates the position of the point relative
+ to the rightmost significant digits of values of subtype S.}
+ The value of this attribute is of the type @i{universal_integer}.]}
+ @begin{Ramification}
+   S'Scale is negative if S'Delta is greater than one.
+   By contrast, S'Aft is always positive.
+ @end{Ramification}
+
address@hidden<S>, AttrName=<Round>,
+  Text=[S'Round denotes a function with
+     the following specification:
address@hidden(Descexample)
address@hidden(function) S'Round(@RI(X) : @RI(universal_real))
+  @b(return) S'Base
address@hidden(Descexample)
+
+     @NoPrefix@;The function returns the value obtained by rounding X (away
+     from 0, if X is midway between two values of the type of S).]}
address@hidden(description)
address@hidden
address@hidden
+
address@hidden
+All subtypes of a fixed point type will have the same value
+for the Delta attribute, in the absence of @nt<delta_constraint>s
+(see @RefSecNum(Reduced Accuracy Subtypes)).
+
+S'Scale is not always the same as S'Aft for a decimal subtype;
+for example, if S'Delta = 1.0 then
+S'Aft is 1 while S'Scale is 0.
+
address@hidden operations],Sec=(of a fixed point type)}
+The predefined operations of a fixed point type include the assignment
+operation, qualification, the membership tests, and
+explicit conversion to and from other numeric types. They also
+include the relational operators and the following predefined
+arithmetic operators:
+the binary and unary adding operators @en@; and +, multiplying
+operators, and the unary operator @key(abs).
+
+As for all types, objects of a fixed point type
+have Size and Address attributes
+(see @RefSecNum(Operational and Representation Attributes)).
+Other attributes of fixed point types are defined in
address@hidden of Fixed Point Types}.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],Ref=[8652/0005],ARef=[AI95-00054-01]}
address@hidden,address@hidden<Corrigendum:> Clarified that @i<small> may be
+specified only for ordinary fixed point types.]}
address@hidden
diff --git a/packages/ada-ref-man/source_2012/03b.mss 
b/packages/ada-ref-man/source_2012/03b.mss
new file mode 100755
index 0000000..4f2140b
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/03b.mss
@@ -0,0 +1,2745 @@
address@hidden(03, Root="ada.mss")
+
address@hidden: 2014/07/24 04:20:38 $}
+
address@hidden: e:\\cvsroot/ARM/Source/03b.mss,v $}
address@hidden: 1.103 $}
+
address@hidden Types}
+
address@hidden
address@hidden
address@hidden type}
+An @i(array) object is a composite object consisting of components
+which all have the same subtype.
+The name for a component of an array uses one or more
+index values belonging to specified discrete types.
+The value of an array object is a composite
+value consisting of the values of the components.
address@hidden
+
address@hidden
address@hidden<array_type_definition>,rhs="
+   @Syn2{unconstrained_array_definition} | 
@Syn2{constrained_array_definition}"}
+
+
address@hidden<unconstrained_array_definition>,rhs="
+   @key{array}(@Syn2{index_subtype_definition} {, 
@Syn2{index_subtype_definition}}) @key{of} @Syn2{component_definition}"}
+
address@hidden<index_subtype_definition>,rhs="@Syn2{subtype_mark} @key{range} 
<>"}
+
address@hidden<constrained_array_definition>,rhs="
+   @key{array} (@Syn2{discrete_subtype_definition} {, 
@Syn2{discrete_subtype_definition}}) @key{of} @Syn2{component_definition}"}
+
address@hidden<discrete_subtype_definition>,rhs="@address@hidden | 
@Syn2{range}"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00406-01]}
address@hidden<component_definition>,rhs="@Chg{Version=[2],New=<
+   >,Old=<>address@hidden @address@hidden,New=<
+ | address@hidden @Syn2{access_definition}>,Old=<>}"}
address@hidden
+
address@hidden
address@hidden type], Sec=(discrete_subtype_definition range)}
+For a @nt<discrete_subtype_definition> that is a @nt<range>, the
address@hidden<range> shall resolve to be of some specific discrete
address@hidden; which
+  discrete type shall be determined without using any context other than
+  the bounds of the @nt<range> itself (plus the preference
+  for @i(root_integer) @em
+  see @RefSecNum(The Context of Overload Resolution)).]
address@hidden
+
address@hidden
address@hidden subtype}
+Each @nt{index_subtype_definition}
+or @nt{discrete_subtype_definition} in an @nt{array_type_definition}
+defines an @i(index subtype);
address@hidden type}
+its type (the @i(index type)) shall be discrete.
address@hidden
address@hidden, Sec=(of an array)}
+An @i(index) is a discrete quantity used to select along a given
+dimension of an array. A component is selected by specifying corresponding
+values for each of the indices.
address@hidden
+
address@hidden subtype}
+The subtype defined by the @nt<subtype_indication> of a
address@hidden<component_definition> (the @i(component subtype)) shall be
+a definite subtype.
address@hidden
+
+  This applies to all uses of @nt<component_definition>,
+  including in @nt<record_type_definition>s and 
@nt<protected_definition>address@hidden
+
address@hidden,Kind=[Deleted],ARef=[AI95-00363-01]}
address@hidden,Text=[Within the definition of a
+nonlimited composite type
+(or a limited composite type that later in its immediate
+scope becomes nonlimited @em see @RefSecNum{Private Operations}
+and @RefSecNum{Limited Types}),
+if a @nt{component_definition} contains the reserved word
address@hidden and the type of the component is discriminated,
+then the nominal subtype of the component shall be constrained.]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden rule's gone, we might as well clobber all the notes.}
address@hidden,Text=[If we allowed the subtype to be unconstrained,
+then the discriminants might change because of
+an assignment to the containing (nonlimited) object,
+thus causing a potential violation of an access subtype constraint
+of an access value designating the aliased component.]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[Note that the rule elsewhere defining all aliased
+discriminated objects to be constrained does not help @em that rule prevents
+assignments to the component itself from doing any harm, but not assignments to
+the containing object.]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Type=[Leading],Text=[We allow this
+for components within limited types since assignment to
+the enclosing object is not a problem. Furthermore, it is
+important to be able to use a default expression for a discriminant
+in arrays of limited components, since that is the only way
+to give the components different values for their discriminants.
+For example:]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden @key[type] Counter_Type(Initial_Value : Integer 
:= 1) @key[is]
+   @key[procedure] Get_Next(Next_Value : @key[out] Integer);
+     address@hidden Returns the next value on each call, bumping Count}
+     address@hidden before returning.}
address@hidden
+   Count : Integer := Initial_Value;
address@hidden Counter_Type;
address@hidden @key[body] Counter_Type @key[is] ...]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden Next_Id(Counter : @key[access] Counter_Type) 
@key[return] Integer @key[is]
+    Result : Integer;
address@hidden
+    Counter.Get_Next(Result);
+    @key[return] Result;
address@hidden Next_Id;]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[C : @key[aliased] Counter_Type;
address@hidden @key[type] T(Who_Am_I : Integer := Next_Id(C'Access));
address@hidden @key[body] T @key[is] ...]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[Task_Array : @key[array](1..100) @key[of] @key[aliased] T;
+  address@hidden Array of task elements, each with its own unique ID.}
+  address@hidden We specify "aliased" so we can use Task_Array(I)'Access.}
+  address@hidden This is safe because Task_Array is of a limited type,}
+  address@hidden so there is no way an assignment to it could change}
+  address@hidden the discriminants of one of its components.}]}
address@hidden
address@hidden
address@hidden
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[Note that this rule applies to array components
+and record components, but not to protected type components (since
+they are always limited).]}
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(of an array)}
address@hidden array}
address@hidden array}
+An array is characterized by the number of indices
+(the @i(dimensionality) of the array), the type and position
+of each index, the lower and upper bounds for each index, and
+the subtype of the components.
+The order of the indices is significant.
+
+A one-dimensional array has a distinct component for each possible index
+value. A multidimensional array has a distinct component for each possible
+sequence of index values that can be formed by selecting one value for
+each index position (in the given order).
+The possible values for a given index are all the values between the
+lower and upper bounds, inclusive;
address@hidden range}
+this range of values is called the @i(index range).
address@hidden, Sec=(of an array)}
+The @i(bounds) of an array are the bounds of its index ranges.
address@hidden, Sec=(of a dimension of an array)}
+The @i(length) of a dimension of an array is
+the number of values of the index range of the dimension (zero for
+a null range).
address@hidden, Sec=(of a one-dimensional array)}
+The @i(length) of a one-dimensional array is
+the length of its only dimension.
+
+An @nt<array_type_definition> defines an array type and its first subtype.
+For each object of this array type, the number of indices, the type
+and position of each index, and the subtype of the components
+are as in the type address@hidden; the values of the lower
+and upper bounds for each index belong to
+the corresponding index subtype of its type, except for null arrays
+(see @RefSecNum(Index Constraints and Discrete Ranges))].
+
address@hidden, Sec=(subtype)}
address@hidden, Sec=(subtype)}
+An @nt{unconstrained_array_definition} defines an array type with
+an unconstrained first subtype.
+Each @address@hidden@!definition} defines the
+corresponding index subtype to be the subtype denoted
+by the @address@hidden
address@hidden@PDefn2{Term=[box], Sec=(compound delimiter)}
+The compound delimiter <> (called a @i(box)) of an
address@hidden<index_subtype_definition> stands for an undefined range
+(different objects of the type need not have the same bounds).]
+
address@hidden, Sec=(subtype)}
address@hidden, Sec=(subtype)}
+A @nt{constrained_array_definition} defines an array type with
+a constrained first subtype.
+Each @address@hidden@!definition}
+defines the corresponding index subtype,
+as well as the corresponding index range for the
+constrained first subtype.
address@hidden, Sec=(of a first array subtype)}
+The @i(constraint) of the first subtype consists of the bounds
+of the index ranges.
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  Although there is no @Chg{Version=[3],New=[nameable],Old=[namable]}
+  unconstrained array subtype in this case, the predefined slicing
+  and concatenation operations can operate on and yield
+  values that do not necessarily belong to the first array subtype.
+  This is also true for Ada 83.
address@hidden
+
address@hidden@;The discrete subtype defined by a @address@hidden@!definition} 
is
+either that defined by the @address@hidden, or a subtype
+determined by the @nt{range} as follows:
address@hidden(itemize)
+  If the type of the @nt{range} resolves to @i(root_integer), then
+  the @nt{discrete_subtype_definition} defines a subtype of the
+  predefined type Integer with bounds given by a conversion to Integer
+  of the bounds of the @nt<range>;
+  @PDefn2{Term=[implicit subtype conversion],Sec=(bounds of a range)}
+  @begin{Reason}
+    This ensures that
+    indexing over the discrete subtype can be performed with
+    regular Integers, rather than only @i(universal_integer)s.
+  @end{Reason}
+  @begin{Discussion}
+    We considered doing this by simply creating
+    a @lquotes@;address@hidden@; for Integer when resolving the @nt<range>.
+    @PDefn{Beaujolais effect}
+    However, this can introduce @i(Beaujolais) effects when the
+    @nt<simple_expression>s involve calls on functions visible
+    due to @key(use) clauses.
+  @end{Discussion}
+
+  Otherwise, the @nt{discrete_subtype_definition} defines
+  a subtype of the type of the @nt{range}, with the bounds given
+  by the @nt<range>.
address@hidden(itemize)
+
address@hidden subtype], Sec=(of a component)}
+The @nt{component_definition} of an @nt<array_type_definition>
+defines the nominal subtype of the components.
+If the reserved word @key(aliased) appears in the @nt{component_definition},
+then each component of the array is aliased
+(see @RefSecNum{Access Types}).
address@hidden(Ramification)
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00363-01]}
+  @ChgDeleted{Version=[2],Text=[In this case, the nominal subtype cannot be an
+  unconstrained discriminated subtype. See @RefSecNum{Record Types}.]}
address@hidden(Ramification)
+
address@hidden
+
address@hidden
address@hidden, Sec=(array_type_definition)}
+The elaboration of an @nt{array_type_definition}
+creates the array type and its first subtype,
+and consists of the elaboration of any @address@hidden@!definition}s
+and the @address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0002],ARef=[AI95-00171-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00230-01]}
address@hidden, Sec=(discrete_subtype_definition)}
+The elaboration of a @nt{discrete_subtype_definition}
address@hidden does not contain any per-object expressions],Old=[]}
+creates the discrete subtype, and consists
+of the elaboration of the @address@hidden or the
+evaluation of the @nt{range}.
address@hidden elaboration of a @nt{discrete_subtype_definition} that contains
+one or more per-object expressions is defined in @RefSecNum{Record 
Types}.],Old=[]}
address@hidden, Sec=(component_definition)}
+The elaboration of a @address@hidden in an
address@hidden@address@hidden consists of the elaboration
+of the @address@hidden@Chg{Version=[2],New=[ or 
@nt{access_definition}],Old=[]}.
+The elaboration of any @address@hidden@!definition}s
+and the elaboration of the
address@hidden@!definition} are performed in an arbitrary address@hidden 
order],Sec=[allowed]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0228-1]}
address@hidden,Type=[Leading],Text=[For an array type with a
+scalar component type, the following language-defined representation aspect
+may be specified with an @nt{aspect_specification} (see
address@hidden Specifications}):]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden aspect
+shall be specified by a static expression, and that
+expression shall be explicit, even if the aspect has a boolean type.
+Default_Component_Value shall be specified only on
+a @address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The part about requiring an explicit expression 
is
+  to disallow omitting the value for this aspect, which would otherwise be
+  allowed by the rules of @RefSecNum{Aspect Specifications}.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is a representation attribute in order to
+  disallow specifying it on a derived type that has inherited primitive
+  subprograms; that is necessary as the sizes of @key[out] parameters could be
+  different whether or not a Default_Value is specified (see
+  @RefSecNum{Parameter Associations}).]}
address@hidden
+
address@hidden,Kind=[AddedNormal],Aspect=[Default_Component_Value],
+  address@hidden,Text=[Default value for the components of an
+    array-of-scalar subtype.]}]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0228-1]}
address@hidden,Text=[If a derived type with no primitive subprograms
+inherits a boolean Default_Component_Value aspect, the aspect may be specified 
to have any
+value for the derived type.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This overrides the
+  @RefSecNum{Aspect Specifications} rule that says that a boolean aspect
+with a value True cannot be changed.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0228-1]}
address@hidden,Text=[The expected type for the @nt{expression}
+specified for the Default_Component_Value aspect is the component type of the
+array type defined by the
address@hidden on which it
address@hidden type],address@hidden of a Default_Component_Value aspect]}]}
address@hidden
+
address@hidden
+All components of an array have the same subtype. In particular, for an array
+of components that are one-dimensional arrays, this means that all components
+have the same bounds and hence the same length.
+
+Each elaboration of an @nt<array_type_definition> creates
+a distinct array type. A consequence of this is that each
+object whose @nt<object_declaration> contains an @nt<array_type_definition>
+is of its own unique type.
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of type declarations with unconstrained 
array definitions: )
address@hidden(Example)
address@hidden(type) Vector     @key(is) @key(array)(Integer  @key(range) <>) 
@key(of) Real;
address@hidden(type) Matrix     @key(is) @key(array)(Integer  @key(range) <>, 
Integer @key(range) <>) @key(of) Real;
address@hidden(type) Bit_Vector @key(is) @key(array)(Integer  @key(range) <>) 
@key(of) Boolean;
address@hidden(type) Roman      @key(is) @key(array)(Positive @key(range) <>) 
@key(of) Roman_Digit; address@hidden see @RefSecNum(Character Types)]
address@hidden(Example)
+
address@hidden
address@hidden@address@hidden(Examples of type declarations with constrained 
array definitions: )
address@hidden
address@hidden(Example)
address@hidden(type) Table    @key(is) @key(array)(1 .. 10) @key(of) Integer;
address@hidden(type) Schedule @key(is) @key(array)(Day) @key(of) Boolean;
address@hidden(type) Line     @key(is) @key(array)(1 .. Max_Line_Size) @key(of) 
Character;
address@hidden(Example)
+
address@hidden
address@hidden@address@hidden(Examples of object declarations with array type 
definitions: )
address@hidden
address@hidden(Example)
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
+Grid @Chg{Version=[2],New=[     ],Old=[]}: @key(array)(1 .. 80, 1 .. 100) 
@key(of) Boolean;
+Mix  @Chg{Version=[2],New=[     ],Old=[]}: @key(array)(Color @key(range) Red 
.. Green) @key(of) Boolean;@Chg{Version=[2],New=[
+Msg_Table : @key(constant array)(Error_Code) @key(of access constant) String :=
+      (Too_Big => @key(new) String'("Result too big"), Too_Small => 
...);],Old=[]}
+Page @Chg{Version=[2],New=[     ],Old=[]}: @key(array)(Positive @key(range) 
<>) @key(of) Line :=  address@hidden  an array of arrays]
+  (1 | 50  => Line'(1 | Line'Last => '+', @key(others) => '-'),  
address@hidden see @RefSecNum(Array Aggregates)]
+   2 .. 49 => Line'(1 | Line'Last => '|', @key(others) => ' '));
+    address@hidden Page is constrained by its initial value to (1..50)]
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax rule for @nt{component_definition} is modified to allow
+the reserved word @key{aliased}.
+
+The syntax rules for @nt{unconstrained_array_definition} and
address@hidden are modified to use
address@hidden (instead of
address@hidden(component_)@nt{subtype_indication}). The effect of this change 
is to allow
+the reserved word @key{aliased} before the
+component @nt{subtype_indication}.
+
+A @nt{range} in a @nt{discrete_subtype_definition}
+may use arbitrary
+universal expressions for each bound (e.g. @en@;1 .. 3+5), rather
+than strictly "implicitly convertible" operands. The subtype
+defined will still be a subtype of Integer.
address@hidden
+
address@hidden
+We introduce a new syntactic category, @nt{discrete_subtype_definition},
+as distinct from @nt{discrete_range}. These two constructs have
+the same syntax, but their semantics
+are quite different (one defines a subtype, with
+a preference for Integer subtypes, while the
+other just selects a subrange of an existing subtype).
+We use this new syntactic category in @key(for) loops
+and entry families.
+
+The syntax for @nt{index_constraint} and @nt{discrete_range}
+have been moved to their own subclause, since they are no
+longer used here.
+
+The syntax rule for @nt{component_definition} (formerly
address@hidden<component_subtype_definition>) is moved here from
+RM83-3.7.
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01],ARef=[AI95-00406-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Array components can have an anonymous access type.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00363-01]}
+  @ChgAdded{Version=[2],Text=[The prohibition against unconstrained
+  discriminated aliased components has been lifted. It has been replaced
+  by a prohibition against the actual troublemakers: general access
+  discriminant constraints (see @RefSecNum{Discriminant Constraints}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0002],ARef=[AI95-00171-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added wording to allow
+  the elaboration of per-object constraints for constrained arrays.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0228-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The new aspect Default_Component_Value allows defining implicit initial
+  values (see @RefSecNum{Object Declarations}) for arrays of scalar types.]}
address@hidden
+
+
address@hidden Constraints and Discrete Ranges}
+
address@hidden
+An @nt<index_constraint> determines the range of possible values for every
+index of an array subtype, and thereby the corresponding array bounds.
address@hidden
+
address@hidden
address@hidden<index_constraint>,rhs=" (@Syn2{discrete_range} {, 
@Syn2{discrete_range}})"}
+
address@hidden<discrete_range>,rhs="@address@hidden | @Syn2{range}"}
address@hidden
+
address@hidden
address@hidden of a @nt{discrete_range}}
+The type of a @nt<discrete_range> is the
+type of the subtype defined by the @nt<subtype_indication>,
+or the type of the @nt<range>.
address@hidden type], Sec=(index_constraint discrete_range)}
+For an @nt{index_constraint},
+each @nt{discrete_range} shall resolve to be of the type of the
+corresponding index.
address@hidden(Discussion)
+  In Ada 95, @nt{index_constraint}s only appear in
+  a @nt{subtype_indication}; they no longer appear in
+  @nt<constrained_array_definition>s.
address@hidden(Discussion)
+
address@hidden
+
address@hidden
+An @nt{index_constraint} shall appear only in a
address@hidden whose @nt{subtype_mark} denotes
+either an unconstrained array subtype, or an
+unconstrained access subtype whose designated subtype is
+an unconstrained array subtype; in either case,
+the @nt{index_constraint} shall provide a @nt{discrete_range}
+for each index of the array type.
address@hidden
+
address@hidden
address@hidden, Sec=(of a @nt<discrete_range>)}
+A @nt{discrete_range} defines a range whose bounds are given
+by the @nt{range}, or by the range of the subtype defined by the
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(index constraint with a subtype)}
+An @nt{index_constraint} is @i(compatible) with an unconstrained array subtype
+if and only if the index range defined by each @nt{discrete_range}
+is compatible (see @RefSecNum(Scalar Types)) with the corresponding index 
subtype.
address@hidden array}
+If any of the @nt<discrete_range>s defines a null range, any array thus
+constrained is a @i(null array), having no components.
address@hidden, Sec=(an index constraint)}
+An array value @i(satisfies) an @nt{index_constraint} if at each index position
+the array value and the @nt{index_constraint} have the same index
+bounds.
address@hidden
+
+  There is no need to define compatibility with a constrained
+  array subtype, because one is not allowed to constrain it address@hidden
+
address@hidden, Sec=(index_constraint)}
+The elaboration of an @nt{index_constraint} consists
+of the evaluation of the @nt{discrete_range}(s), in an arbitrary order.
address@hidden, Sec=(discrete_range)}
+The evaluation of a @nt{discrete_range}
+consists of the elaboration of the @nt{subtype_indication}
+or the evaluation of the @nt{range}.
address@hidden
+
address@hidden
+The elaboration of a @nt<subtype_indication> consisting
+of a @nt<subtype_mark> followed
+by an @nt<index_constraint> checks the compatibility of the
address@hidden<index_constraint> with the @nt<subtype_mark>
+(see @RefSecNum(Subtype Declarations)).
+
+Even if an array value does not satisfy the index constraint
+of an array subtype, Constraint_Error is not
+raised on conversion to the array subtype, so long as
+the length of each dimension of the array value and the
+array subtype match. See @RefSecNum(Type Conversions).
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of array declarations including an index 
constraint: )
address@hidden(Example)
+Board     : Matrix(1 .. 8,  1 .. 8);  address@hidden  see @RefSecNum(Array 
Types)]
+Rectangle : Matrix(1 .. 20, 1 .. 30);
+Inverse   : Matrix(1 .. N,  1 .. N);  address@hidden  N need not be static ]
+
+Filter    : Bit_Vector(0 .. 31);
address@hidden(Example)
+
address@hidden
address@hidden@address@hidden(Example of array declaration with a constrained 
array subtype: )
address@hidden
address@hidden(Example)
+My_Schedule : Schedule;  address@hidden  all arrays of type Schedule have the 
same bounds]
address@hidden(Example)
+
address@hidden
address@hidden@address@hidden(Example of record type with a component that is 
an array: )
address@hidden
address@hidden(Example)
address@hidden(type) Var_Line(Length : Natural) @key(is)
+   @key(record)
+      Image : String(1 .. Length);
+   @key(end) @key(record);
+
+Null_Line : Var_Line(0);  address@hidden  Null_Line.Image is a null array]
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden to Ada 83}
+We allow the declaration of a variable with
+a nominally unconstrained array subtype, so long as
+it has an initialization expression to determine
+its bounds.
address@hidden
+
address@hidden
+We have moved the syntax for @nt{index_constraint} and
address@hidden here since they are no longer
+used in @nt{constrained_array_definition}s.
+We therefore also no longer have to describe the
+(special) semantics of @nt{index_constraint}s and @nt{discrete_range}s
+that appear in @nt{constrained_array_definition}s.
+
+The rules given in RM83-3.6.1(5,7-10),
+which define the bounds of an array object, are redundant
+with rules given elsewhere, and so are not repeated here.
+RM83-3.6.1(6), which requires that the (nominal) subtype of
+an array variable be constrained, no longer applies,
+so long as the variable is explicitly initialized.
address@hidden
+
address@hidden of Array Types}
+
address@hidden
address@hidden argument N used in the @nt<attribute_designator>s for
+the N-th dimension of an array shall be a static @nt<expression> of
+some integer type.] The value of N shall be positive (nonzero)
+and no greater than the dimensionality of the array.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0006],ARef=[AI95-00030-01]}
+The following attributes are defined for
address@hidden,Kind=[Revised],Text=[a @address@hidden,
+Old=[prefix]} A that is of an array type
address@hidden(after any implicit dereference)], or denotes
+a constrained array subtype]}:
address@hidden
+These attributes are not defined if A is a subtype-mark
+  for an access-to-array subtype. They are defined (by implicit
+  dereference) for access-to-array address@hidden
address@hidden(description)
address@hidden<A>, AttrName=<First>,
+  Text=[A'First denotes the lower bound of the first index range; its
+  type is the corresponding index type.]}
+
address@hidden<A>, AttrName=<First(N)>,
+  Text=[A'First(N) denotes the lower bound of the N-th index range; its
+  type is the corresponding index type.]}
+
address@hidden<A>, AttrName=<Last>,
+  Text=[A'Last denotes the upper bound of the first index range; its
+  type is the corresponding index type.]}
+
address@hidden<A>, AttrName=<Last(N)>,
+  Text=[A'Last(N) denotes the upper bound of the N-th index range; its
+  type is the corresponding index type.]}
+
address@hidden<A>, AttrName=<Range>,
+  Text=[A'Range is equivalent to the range A'First .. A'Last,
+  except that the @nt<prefix> A is only evaluated once.]}
+
address@hidden<A>, AttrName=<Range(N)>,
+  Text=[A'Range(N) is equivalent to the range A'First(N) .. A'Last(N),
+  except that the @nt<prefix> A is only evaluated once.]}
+
address@hidden<A>, AttrName=<Length>,
+  Text=[A'Length denotes the number of values of the first index
+  range (zero for a null range); its type is @i(universal_integer).]}
+
address@hidden<A>, AttrName=<Length(N)>,
+  Text=[A'Length(N) denotes the number of values of the N-th index
+  range (zero for a null range); its type is @i(universal_integer).]}
address@hidden(description)
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+An implementation should normally represent
+multidimensional arrays in row-major order, consistent with the notation used
+for multidimensional array aggregates (see @RefSecNum(Array Aggregates)).
+However, if @Chg{Version=[3],New=[convention ],Old=[a @key<pragma>
+Convention(address@hidden,New=[ is specified
+for],Old=[, ...) applies to]} a
+multidimensional array type, then column-major order should be used
+instead (see @RefSec{Interfacing with Fortran}).
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Multidimensional arrays should be represented in row-major order,
+unless the array has convention Fortran.]}]}
address@hidden
+
address@hidden
address@hidden@;The @nt<attribute_reference>s A'First and A'First(1) denote the 
same value.
+A similar relation exists for the @nt<attribute_reference>s A'Last,
+A'Range, and A'Length. The following relation is satisfied (except
+for a null array) by the above attributes if the index type is an
+integer type:
address@hidden(example)
+   A'Length(N) = A'Last(N) - A'First(N) + 1
address@hidden(example)
+
+An array type is limited if its component type is limited
+(see @RefSecNum(Limited Types)).
+
address@hidden operations],Sec=(of an array type)}
+The predefined operations of an array type include the
+membership tests, qualification, and explicit conversion.
+If the array type is not limited, they also include assignment
+and the predefined
+equality operators. For a one-dimensional array type,
+they include the predefined concatenation operators (if nonlimited) and,
+if the component type is discrete, the predefined relational operators;
+if the component type is boolean, the predefined
+logical operators are also included.
+
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
+A component of an array can be named with an @nt<indexed_component>.
+A value of an array type can be specified with an
address@hidden<array_aggregate>@Chg{Version=[2],New=[],Old=[, unless the array 
type
+is limited]}.
+For a one-dimensional array type, a slice of the array can be named;
+also, string literals are defined if the component type is
+a character type.
address@hidden
+
address@hidden
address@hidden@address@hidden (using arrays declared in the examples of 
subclause @RefSecNum(Index Constraints and Discrete Ranges)):}
address@hidden(Example)
+--  Filter'First      =   0   Filter'Last       =  31   Filter'Length =  32
+--  Rectangle'Last(1) =  20   Rectangle'Last(2) =  30
address@hidden(Example)
+
address@hidden
+
address@hidden Types}
+
address@hidden
address@hidden type}
+A one-dimensional array type whose component type is a character type
+is called a @i(string) type.
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden@redundant[There are @Chg{Version=[2],New=[three],Old=[two]} 
predefined
+string types, address@hidden,New=[,],Old=[ and]}
address@hidden,New=[, and Wide_Wide_String],Old=[]},
+each indexed by values of the predefined subtype Positive;
+these are declared in the visible part of package Standard:]
address@hidden(example)
address@hidden@key(subtype) Positive @key(is) Integer @key(range) 1 .. 
Integer'Last;
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden(type) String @key(is) @key(array)(Positive @key(range) <>) 
@key(of) Character;
address@hidden(type) Wide_String @key(is) @key(array)(Positive @key(range) <>) 
@key(of) Wide_Character;
address@hidden,address@hidden(type) Wide_Wide_String @key(is) 
@key(array)(Positive @key(range) <>) @key(of) Wide_Wide_Character;],Old=[]}
address@hidden(example)
address@hidden
+
address@hidden
+String literals (see @RefSecNum(String Literals) and
address@hidden(Literals)) are defined for all string types.
+The concatenation operator & is predefined
+for string types, as for all nonlimited
+one-dimensional array types.
+The ordering operators <, <=, >, and >= are predefined
+for string types, as for all one-dimensional discrete array types;
+these ordering operators correspond to lexicographic order
+(see @RefSecNum(Relational Operators and Membership Tests)).
+
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of string objects:)
address@hidden(Example)
address@hidden()@TabSet(P50)
+Stars      : String(1 .. 120) := (1 .. 120 => '*' );
+Question   : @key(constant) String  := "How many characters?";
address@hidden@RI[ Question'First = 1, Question'Last = 20]
address@hidden@RI[ Question'Length = 20 (the number of characters)]
+
+Ask_Twice  : String  := Question & Question;@address@hidden constrained to 
(1..40)]
+Ninety_Six : @key(constant) Roman   := "XCVI";@address@hidden see 
@RefSecNum(Character Types) and @RefSecNum(Array Types)]
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden with Ada 83}
+The declaration of Wide_String in Standard hides a use-visible
+declaration with the same @nt<defining_identifier>.
+In rare cases, this might result in an inconsistency between
+Ada 83 and Ada 95.
address@hidden
+
address@hidden
address@hidden with Ada 83}
+Because both String and Wide_String are always directly visible,
+an expression like
address@hidden(Example)
+"a" < "bc"
address@hidden(Example)
+
+is now ambiguous, whereas in Ada 83 both string literals could
+be resolved to type String.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The type Wide_String is new (though it was approved by
+ARG for Ada 83 compilers as well).
address@hidden
+
address@hidden
+We define the term @i(string type) as a natural analogy
+to the term @i(character type).
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,address@hidden with Ada 95}
+The declaration of Wide_Wide_String in Standard hides a use-visible
+declaration with the same @nt<defining_identifier>.
+In the (very) unlikely event that an Ada 95 program had
+depended on such a use-visible declaration, and the program remains
+legal after the substitution of Standard.Wide_Wide_String,
+the meaning of the program will be different.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The type Wide_Wide_String is new.]}
address@hidden
+
address@hidden@Comment{For printed version of Ada 2012 RM}
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00251-01],ARef=[AI95-00326-01]}
address@hidden@Defn{discriminant}
address@hidden parameter],See=(discriminant)}
address@hidden,See=(discriminant)}
+A composite type (other than an address@hidden,New=[ or
+interface],Old=[]} type) can have discriminants,
+which parameterize the type.
+A @nt<known_discriminant_part> specifies the discriminants
+of a composite type.
+A discriminant of an object is a component of the object,
+and is either of a discrete type or an access type.
+An @nt<unknown_discriminant_part> in the declaration of
address@hidden,New=[],Old=[ partial]} view of a type
+specifies that the discriminants of the type are unknown
+for the given view;
+all subtypes of such address@hidden,New=[],Old=[ partial]} view
+are indefinite subtypes.]
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised],Term=<Discriminant>,
+  Text=<A discriminant is a parameter @Chg{Version=[2],New=[for],Old=[of]} a 
composite type.
+  It can control, for example, the bounds of a component
+  of the type if @Chg{Version=[2],New=[the component is],Old=[that type is]}
+  an address@hidden,New=[],Old=[ type]}.
+  A discriminant @Chg{Version=[2],New=[for],Old=[of]} a task type can be
+  used to pass data to a task of the type upon creation.>}
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00114-01]}
+  @PDefn{unknown discriminants}
+  @PDefn2{Term=[discriminants], Sec=(unknown)}
+  A @Chg{Version=[2],New=[view of a ],Old=[]}type, and all 
@Chg{Version=[2],New=[],
+  Old=[of its address@hidden,New=[ of the view],Old=[]}, have
+  @i(unknown discriminants)
+  when the number or names of the discriminants, if any, are unknown at
+  the point of the type address@hidden,New=[ for the view],Old=[]}.
+  A @nt<discriminant_part> of (<>) is used to indicate unknown discriminants.
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00402-01]}
+  @ChgAdded{Version=[2],Text=[When an access discriminant
+  is initialized at the time of object creation with an allocator
+  of an anonymous type, the allocated object and the object
+  with the discriminant are tied together for their lifetime.
+  They should be allocated out of the same storage pool,
+  and then at the end of the lifetime of the enclosing object, finalized
+  and reclaimed together. In this case, the allocated object is called
+  a coextension (see @RefSecNum{Operations of Access Types}).]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The above principle when applied to a
+  nonlimited type implies that such an object may be copied only to a
+  shorter-lived object, because attempting to assign it to a longer-lived
+  object would fail because the access discriminants would not match.
+  In a copy, the lifetime connection between the enclosing object
+  and the allocated object does not exist. The allocated object is
+  tied in the above sense only to the original object. Other copies
+  have only secondary references to it.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Note that when an @nt{allocator} appears as a
+  constraint on an access discriminant in a @nt{subtype_indication}
+  that is elaborated independently from object creation,
+  no such connection exists. For example, if a named constrained
+  subtype is declared via
+  "@key{subtype} Constr @key{is} Rec(Acc_Discrim => @key{new} T);"
+  or if such an @nt{allocator} appears in the @nt{subtype_indication} for
+  a component, the allocator is evaluated when the @nt{subtype_indication}
+  is elaborated, and hence its lifetime is typically longer than
+  the objects or components that will later be subject to the
+  constraint. In these cases, the allocated object should not
+  be reclaimed until the @nt{subtype_indication} goes out of scope.]}
address@hidden
address@hidden
+
address@hidden
address@hidden<discriminant_part>,rhs="@Syn2{unknown_discriminant_part} | 
@Syn2{known_discriminant_part}"}
+
address@hidden<unknown_discriminant_part>,rhs="(<>)"}
+
address@hidden<known_discriminant_part>,rhs="
+   (@Syn2{discriminant_specification} {; @Syn2{discriminant_specification}})"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01]}
address@hidden<discriminant_specification>,rhs="
+   @Syn2{defining_identifier_list} : @Chg{Version=[2],New=<address@hidden 
>,Old=<>address@hidden [:= @Syn2{default_expression}]
+ | @Syn2{defining_identifier_list} : @Syn2{access_definition} [:= 
@Syn2{default_expression}]"}
+
address@hidden<default_expression>,rhs="@Syn2{expression}"}
address@hidden
+
address@hidden
address@hidden type], Sec=(discriminant default_expression)}
+The expected type for the @nt{default_expression}
+of a @nt{discriminant_specification} is that of the corresponding
+discriminant.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0007],ARef=[AI95-00098-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00251-01]}
+A @address@hidden,address@hidden is only
+permitted in a declaration for a composite type that is not an
address@hidden,New=[ or interface],Old=[]} type
address@hidden(this includes generic formal types)address@hidden A],Old=[; a]}
+type declared with a @nt<known_discriminant_part> is called
+a @i(discriminated) type,@Defn{discriminated type} as is a type that inherits
+(known) discriminants.
address@hidden
+  Discriminants on array types were considered,
+  but were omitted to ease (existing) implementations.
address@hidden
address@hidden(Discussion)
+  Note that the above definition for @lquotes@;discriminated address@hidden@; 
does
+  not include types declared with an @nt<unknown_discriminant_part>.
+  This seems consistent with Ada 83, where such types (in a generic
+  formal part) would not be considered discriminated types.
+  Furthermore, the full type for a type with unknown discriminants
+  need not even be composite, much less have any discriminants.
+
+  @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0007],ARef=[AI95-00098-01]}
+  @Chg{New=[On the other hand, @nt<unknown_discriminant_part>s cannot be
+  applied to type declarations that cannot have a @nt<known_discriminant_part>.
+  There is no point in having unknown discriminants on a type that can never
+  have discriminants (for instance, a formal modular type), even when these
+  are allowed syntactically.],Old=[]}
address@hidden(Discussion)
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01],ARef=[AI95-00254-01]}
+The subtype of a discriminant may be defined
address@hidden,New=[ an optional @nt{null_exclusion} and],Old=[]} a
address@hidden<subtype_mark>, in which case the @nt<subtype_mark> shall denote
+a discrete or access subtype, or it may be defined by an
address@hidden<access_definition>@Chg{Version=[2],New=[],Old=[ @Redundant[(in 
which case
+the @nt<subtype_mark> of the @nt<access_definition> may denote
+any kind of subtype)]]}.
address@hidden discriminant}
+A discriminant that is defined by an @nt<access_definition>
+is called an @i(access discriminant)
+and is of an anonymous @Chg{Version=[2],New=[access],
+Old=[general access-to-variable]} address@hidden,New=[],Old=[ whose
+designated subtype is
+denoted by the @nt<subtype_mark> of the @nt<access_definition>]}.
address@hidden(Reason)
+  @ChgRef{Version=[2],Kind=[Deleted],ARef=[AI95-00230-01]}
+  @ChgNote{It still does cause complexities. :-)address@hidden don't
+  want to delete "Reason:" here, thus we use @Chg and not @ChgDeleted}
+  @Chg{Version=[2],New=[],Old=[In an early version of Ada 9X,
+  we allowed access discriminants on nonlimited types,
+  but this created unpleasant complexities.
+  It turned out to be simpler and more uniform to allow discriminants
+  of a named access type on any discriminated type, and keep access
+  discriminants just for limited types.]}
+
+  Note that discriminants of a named access type are not
+  considered @lquotes@;access address@hidden@;
+  Similarly, @lquotes@;access address@hidden@;
+  only refers to a formal parameter defined by an @nt<access_definition>.
address@hidden(Reason)
+
address@hidden paragraph is just moved up}
address@hidden,Kind=[Added],ARef=[AI95-00402-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0214-1]}
address@hidden,address@hidden shall be provided either
+for all or for none
+of the discriminants of a @address@hidden@!part}.
+No @nt<address@hidden>s are permitted in a
address@hidden<address@hidden@!part> in a declaration of a
address@hidden,New=[nonlimited ],Old=[]}tagged
+type @Redundant[or a generic formal type].]}
+
address@hidden(Reason)
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The all-or-none rule
+  is related to the rule that a discriminant constraint shall specify
+  values for all discriminants. One could imagine a different rule
+  that allowed a constraint to specify only some of the discriminants,
+  with the others provided by default. Having defaults for discriminants
+  has a special significance @em it allows objects of the type to
+  be unconstrained, with the discriminants alterable as part of
+  assigning to the object.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0214-1]}
+  @ChgAdded{Version=[2],Text=[Defaults for discriminants of tagged types
+  are disallowed so that every object of a
+  @Chg{Version=[3],New=[nonlimited ],Old=[]}tagged type is constrained,
+  either by an explicit constraint,
+  or by its initial discriminant values.
+  This substantially simplifies the semantic rules
+  and the implementation of inherited
+  dispatching operations. @Chg{Version=[3],New=[We don't need this rule for
+  limited tagged types, as the discriminants of such objects cannot be changed
+  after the object is created in any case @em no full-object assignment is
+  supported, and that is required to change discriminant values. ],Old=[]}For
+  generic formal types, the restriction simplifies the type matching rules.
+  If one simply wants a "default" value for the discriminants,
+  a constrained subtype can be declared for future use.]}
address@hidden(Reason)
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00402-01],ARef=[AI95-00419-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0063-1]}
+A @nt<discriminant_specification> for
+an access discriminant
address@hidden,New=[may have a @nt{default_expression}],Old=[shall appear]}
+only in the declaration for @Chg{Version=[3],New=[an immutably limited type
+(see @RefSecNum{Limited Types})],Old=[a task or protected type,
+or for a type @Chg{Version=[2],New=[that is a descendant of an explicitly
+limited record type],Old=[with the reserved word @key[limited] in its
address@hidden(full)] definition
+or in that of one of its ancestors]}]}.
+In addition to the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}),
+this rule applies also in the private part of an
+instance of a generic address@hidden contract issue}
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised]}
+  @ChgRef{Version=[3],Kind=[Revised]}
+  This rule implies that a type can have @Chg{Version=[2],
+  New=[a default for ],Old=[]}an access discriminant
+  if the type is limited,
+  but not if the only reason it's limited is because of a limited component.
+  Compare @Chg{Version=[3],New=[],Old=[with ]}the definition of limited type
+  @Chg{Version=[3],New=[and immutably limited type ],Old=[]}in
+  @RefSecNum{Limited address@hidden,New=[],address@hidden,New=[ Also,
+  recall that a @ldquote@;address@hidden includes the type itself, so
+  an explicitly limited record type can have defaults.],Old=[]}]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised]}
+  @ChgRef{Version=[3],Kind=[Revised]}
+  @ChgDeleted{Version=[2],Text=[It is a consequence
+  of this rule that only a return-by-reference
+  type can have an access discriminant (see @RefSecNum{Return Statements}).
+  This is important to avoid dangling references to local variables.]}
+  @ChgAdded{Version=[3],Text=[A (nonformal) limited private type can always
+  have a default for an access discriminant, because having the default itself
+  makes the type immutably limited. Such a private type must necessarily
+  have a full type with the same access discriminant with a default, and
+  thus the full type will always be immutably limited (if legal).]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00230-01]}
+  @address@hidden@;We @Chg{Version=[2],New=[],Old=[also ]}considered the
+  following address@hidden,New=[ for access discriminants],Old=[]}:
+  @begin{Itemize}
+    If a type has an access discriminant,
+    this automatically makes it limited,
+    just like having a limited component automatically
+    makes a type limited.
+    This was rejected because it decreases program readability,
+    and because it seemed error prone (two bugs in a previous
+    version of the RM9X were attributable to this rule).
+
+    @ChgRef{Version=[2],Kind=[Revised]}
+    A type with an access discriminant shall be limited.
+    This is equivalent to the rule we actually address@hidden,New=[ for Ada 
95],Old=[]},
+    except that it allows a type to have an access discriminant
+    if it is limited just because of a limited component.
+    For example, any record containing a task would be allowed to have
+    an access discriminant, whereas the actual rule requires
+    @address@hidden @address@hidden@;.
+    This rule was also rejected due to readability concerns,
+    and because would interact badly with the rules for
+    limited types that @lquotes@;become address@hidden@;.
+
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0063-1]}
+    @ChgAdded{Version=[2],Text=[A type may have an access discriminant if
+    it is @Chg{Version=[3],New=[an immutably limited],Old=[a limited partial
+    view, or a task, protected, or explicitly limited record]} type. This
+    was the rule chosen for Ada 95.]}
+
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[Any type may have an access discriminant.
+    For nonlimited type, there is no special accessibility for access
+    discriminants; they're the same as any other anonymous access component.
+    For a limited type, they have the special accessibility of Ada 95. However,
+    this doesn't work because a limited partial view can have a nonlimited
+    full view -- giving the two views different accessibility.]}
+
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0063-1]}
+    @ChgAdded{Version=[2],Text=[Any type may have an access discriminant,
+    as above. However, special accessibility rules only apply to types
+    that are 
@Chg{Version=[3],New=[immutably],address@hidden@;address@hidden@;]}
+    limited (task, protected, and
+    explicitly limited records). However, this breaks privacy; worse,
+    @LegalityTitle depend on the definition of accessibility.]}
+
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0063-1]}
+    @ChgAdded{Version=[2],Text=[Any type may have an access discriminant,
+    as above. Limited types have special accessibility, while nonlimited
+    types have normal accessibility. However, a limited partial view with an
+    access discriminant can only be completed by @Chg{Version=[3],New=[an
+    immutably limited],Old=[a task, protected, or
+    explicitly limited record]} type. That prevents accessibility from 
changing.
+    A runtime accessibility check is required on generic formal types with
+    access discriminants. However, changing between limited and nonlimited
+    types would have far-reaching consequences for access discriminants @em
+    which is uncomfortable.]}
+
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[Any type may have an access discriminant.
+    All types have special accessibility. This was considered early during
+    the Ada 9X process, but was dropped for @lquotes@;unpleasant
+    address@hidden@;, which unfortunately aren't recorded. It does
+    seem that an accessibility check would be needed on assignment of such
+    a type, to avoid copying an object with a discriminant pointing to a
+    local object into a more global object (and thus creating a dangling
+    pointer).]}
+
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[Any type may have an access discriminant,
+    but access discriminants cannot have defaults. All types have special
+    accessibility. This gets rid of the problems on assignment (you couldn't
+    change such a discriminant), but it would be horribly incompatible with
+    Ada 95.]}
+
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0063-1]}
+    @ChgAdded{Version=[2],Text=[Any type may have an access discriminant,
+    but access discriminants may have defaults only if they are
+    @Chg{Version=[3],New=[of an immutably], Old=[a
+    @lquotes@;address@hidden@;]} limited type. This is the rule chosen for
+    Ada 2005, as it is not incompatible, and it doesn't require weird
+    accessibility checks.]}
+  @end{Itemize}
address@hidden
+
address@hidden,Kind=[Deleted],ARef=[AI95-00402-01]}
address@hidden,address@hidden shall be provided either for all or for none
+of the discriminants of a @address@hidden@!part}.
+No @nt<address@hidden>s are permitted in a
address@hidden<address@hidden@!part> in a declaration of a tagged
+type @Redundant[or a generic formal type].]}
address@hidden(Reason)
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[The all-or-none rule
+  is related to the rule that a discriminant constraint shall specify
+  values for all discriminants. One could imagine a different rule
+  that allowed a constraint to specify only some of the discriminants,
+  with the others provided by default. Having defaults for discriminants
+  has a special significance @em it allows objects of the type to
+  be unconstrained, with the discriminants alterable as part of
+  assigning to the object.]}
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[Defaults for discriminants of tagged types
+  are disallowed so that every object of a
+  tagged type is constrained,
+  either by an explicit constraint,
+  or by its initial discriminant values.
+  This substantially simplifies the semantic rules
+  and the implementation of inherited
+  dispatching operations. For generic formal types,
+  the restriction simplifies the type matching rules.
+  If one simply wants a "default" value for the discriminants,
+  a constrained subtype can be declared for future use.]}
address@hidden(Reason)
+
address@hidden@;For a type defined by a @nt<derived_type_definition>,
+if a @nt<known_discriminant_part> is provided in its declaration, then:
address@hidden
+The parent subtype shall be constrained;
+
+If the parent type is not a tagged type, then each discriminant
+of the derived type shall be used in the constraint defining
+the parent subtype;@begin{ImplNote}
+
+  This ensures that the new discriminant can share storage with
+  an existing address@hidden
+
+If a discriminant is used in the constraint defining the parent subtype,
+the subtype of the discriminant shall be statically compatible
+(see @RefSecNum{Statically Matching Constraints and Subtypes}) with the
+subtype of the corresponding parent discriminant.
address@hidden(Reason)
+  This ensures that on conversion
+  (or extension via an extension aggregate) to a distantly related type,
+  if the discriminants satisfy the target type's requirements they satisfy
+  all the intermediate types' requirements as well.
address@hidden(Reason)
address@hidden(Ramification)
+  There is no requirement that the new discriminant have the
+  same (or any) @nt<default_expression> as the parent's discriminant.
address@hidden(Ramification)
address@hidden
+
address@hidden,Kind=[Deleted],ARef=[AI05-0102-1]}
address@hidden,Text=[The type of the @nt<default_expression>, if any,
+for an access discriminant shall be convertible to the anonymous access type of
+the discriminant (see @RefSecNum{Type Conversions}).
address@hidden,Sec=(required)}]}
address@hidden
address@hidden,Kind=[Deleted]}
address@hidden,Text=[This requires convertibility
+of the designated subtypes.]}
address@hidden
address@hidden
+
address@hidden
+A @nt{discriminant_specification} declares a discriminant;
+the @nt{subtype_mark}
+denotes its subtype unless it is an access discriminant, in which case
+the discriminant's subtype is the anonymous access-to-variable subtype
+defined by the @nt{access_definition}.
+
address@hidden a type defined by a @nt<derived_type_definition>,
+each discriminant of the parent type
+is either inherited,
+constrained to equal some new discriminant of the derived type,
+or constrained to the value of an expression.]
address@hidden discriminants}
+When inherited or constrained to equal some new discriminant,
+the parent discriminant and the discriminant of the derived type are said
+to @i(correspond).
+Two discriminants also correspond
+if there is some common discriminant to which they
+both correspond. A discriminant corresponds to itself
+as well.
address@hidden discriminant}
+If a discriminant of a parent type is constrained to a specific value
+by a @nt<derived_type_definition>,
+then that discriminant is said to be @i(specified)
+by that @nt<derived_type_definition>.
address@hidden
+
+  The correspondence relationship is transitive, symmetric,
+  and reflexive. That is,
+  if A corresponds to B, and B corresponds to C, then
+  A, B, and C each corresponds to A, B, and C in all address@hidden
+
address@hidden on a discriminant],
+  Sec=(for a @nt<constraint> or @nt<component_definition>)}
+A @nt{constraint} that appears
+within the definition of a discriminated
+type @i(depends on a discriminant) of the type if it names the
+discriminant as a bound or discriminant value.
+A @nt{component_definition} depends on a discriminant if its
address@hidden depends on the discriminant, or on a discriminant
+that corresponds to it.
address@hidden(Ramification)
+  A @nt{constraint} in a @nt{task_body} is not considered to
+  @i(depend) on a discriminant of the task type, even if it
+  names it. It is only the @nt<constraint>s in the type definition
+  itself that are considered dependents. Similarly for protected types.
address@hidden(Ramification)
+
address@hidden@address@hidden on a discriminant], Sec=(for a component)}
+A component @i(depends on a discriminant) if:
address@hidden(itemize)
+  Its @nt{component_definition} depends on the discriminant; or
+  @begin{Ramification}
+A component does @i(not) depend on a discriminant just because
+  its @nt<default_expression> refers to the address@hidden
+
+  It is declared in a @nt{variant_part} that is governed by the
+  discriminant; or
+
+  It is a component inherited as part of a @nt<derived_type_definition>,
+  and the @nt<constraint> of the @i(parent_)@nt<subtype_indication>
+  depends on the discriminant; or
+  @begin{Reason}
+    When the parent subtype depends on a discriminant, the parent
+    part of the derived type is treated like a discriminant-dependent
+    component.
+  @end{Reason}
+  @begin{Ramification}
+    Because of this rule, we don't really need to worry about 
@lquotes@;address@hidden@;
+    discriminants, since all the inherited components will be
+    discriminant-dependent if there is a new @nt<known_discriminant_part>
+    whose discriminants are used to constrain the old discriminants.
+  @end{Ramification}
+
+  It is a subcomponent of a component that depends on the discriminant.
address@hidden(itemize)
address@hidden
+  The concept of discriminant-dependent (sub)components is primarily used
+  in various rules that disallow renaming or 'Access, or specify that
+  certain discriminant-changing assignments are erroneous.
+  The goal is to allow implementations to move around or change the size
+  of discriminant-dependent subcomponents upon a discriminant-changing
+  assignment to an enclosing object. The above definition specifies that
+  all subcomponents of a discriminant-dependent component or parent part
+  are themselves discriminant-dependent, even though their presence
+  or size does not in fact depend on a discriminant. This is because
+  it is likely that they will move in a discriminant-changing assignment
+  if they are a component of one of several discriminant-dependent
+  parts of the same record.
address@hidden
+
+Each value of a discriminated type includes a value for
+each component
+of the type that does not depend
+on a address@hidden; this includes the discriminants
+themselves]. The values
+of discriminants determine which other component values are present
+in the value of the discriminated type.
address@hidden
+Which values are present might depend on discriminants of
+  some ancestor type that are constrained in an intervening
+  @nt<derived_type_definition>. That's why we say "values of discriminants"
+  instead of "values of @i(the) discriminants" @em a subtle address@hidden
+
address@hidden discriminants}
address@hidden, Sec=(known)}
address@hidden, Sec=(subtype)}
address@hidden, Sec=(subtype)}
+A type declared with a @nt<known_discriminant_part> is said to have
address@hidden(known discriminants); its first subtype is unconstrained.
address@hidden discriminants}
address@hidden, Sec=(unknown)}
+A type declared with an
address@hidden<unknown_discriminant_part> is said to have @i(unknown 
discriminants).
+A type declared without a @nt<discriminant_part> has
+no discriminants, unless it is a derived type; if derived,
+such a type has the same sort of discriminants (known, unknown, or none)
+as its parent (or ancestor) type.
+A tagged class-wide type also has unknown discriminants.
address@hidden type}
address@hidden subtype}
address@hidden subtype of a type with unknown discriminants
+is an unconstrained and indefinite
+subtype (see @RefSecNum{Types and Subtypes}
+and @RefSecNum{Objects and Named Numbers}).]
address@hidden(Discussion)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00114-01]}
+  An @nt<unknown_discriminant_part> @lquotes@;(<>)@rquotes@; is only permitted 
in
+  the declaration of a (generic or nongeneric) private type,
+  private extension, @Chg{Version=[2],New=[incomplete type, ],Old=[]}or
+  formal derived address@hidden was always intended,
+  but 8652/0007 was needed to make it true.}
+  Hence, only such types, descendants thereof, and class-wide
+  types can have unknown discriminants.
+  An @nt<unknown_discriminant_part> is used to indicate that the corresponding
+  actual or full type might have discriminants without defaults,
+  or be an unconstrained array subtype. Tagged class-wide types
+  are also considered to have unknown discriminants because discriminants
+  can be added by type extensions, so the total number of
+  discriminants of any given value of a tagged class-wide type
+  is not known at compile time.
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00287-01]}
+  A subtype with unknown discriminants
+  is indefinite, and hence an object of such a subtype needs
+  explicit address@hidden,New=[],Old=[ If the subtype is
+  limited, no (stand-alone) objects
+  can be declared since initialization is not permitted (though
+  formal parameters are permitted, and objects of the actual/full type
+  will generally be declarable).]} A limited private type with
+  unknown discriminants is @lquotes@;address@hidden@;
+  limited;@Chg{Version=[2],New=[ objects of],Old=[]} such a type
+  @Chg{Version=[2],New=[ can be initialized only by subprograms (either
+  procedures with a parameter of the type, or a function returning the
+  type) declared in the package. Subprograms declared elsewhere can operate on
+  and even return the type, but they can only initialize the object by calling
+  (ultimately) a subprogram in the package declaring the type. Such a 
type],Old=[]} is useful for
+  keeping complete control over object creation within the package declaring
+  the type.
+
+  A partial view of a type might have unknown discriminants, while
+  the full view of the same type might have known, unknown, or no
+  address@hidden,Old=[,]}
address@hidden(Discussion)
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00416-01]}
address@hidden,New=[For an access discriminant, its],
+Old=[An]} @nt<access_definition> is
+elaborated when the value of @Chg{Version=[2],New=[the],Old=[a corresponding]}
+access discriminant is address@hidden,New=[:],Old=[, either]}
+by evaluation of its @nt<default_expression>@Chg{Version=[2],New=[,],Old=[ or]}
+by elaboration of a @nt<discriminant_constraint>@Chg{Version=[2],New=[, or
+by an assignment that initializes the enclosing object.],Old=[.
address@hidden elaboration of an @nt<access_definition> creates the
+anonymous access type. When the expression defining the
+access discriminant is evaluated, it is converted to this
+anonymous access type (see @RefSecNum{Type Conversions}).]]}
address@hidden subtype conversion],Sec=(access discriminant)}
address@hidden(Ramification)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00231-01],ARef=[AI95-00416-01]}
+  @Chg{Version=[2],New=[The],Old=[This]} address@hidden,New=[
+  of the @nt{expression} defining the access discriminant to the anonymous
+  access type],Old=[]} raises @Chg{Version=[2],New=[Program_Error],
+  Old=[Constraint_Error if the initial value is @key(null), or,]} for an
+  object created by an allocator of an access type T, if the
+  initial value is an access parameter that designates a view whose
+  accessibility level is deeper than that of T.
address@hidden(Ramification)
address@hidden
+
address@hidden
+If a discriminated type has @nt<default_expression>s for its
+discriminants, then unconstrained variables of the type are permitted,
+and the values of the discriminants can be changed by an assignment
+to such a variable.
+If defaults are not provided for the discriminants, then all
+variables of the type are constrained, either by explicit
+constraint or by their initial value; the values of the discriminants
+of such a variable cannot be changed after initialization.
address@hidden(Discussion)
+  This connection between discriminant defaults and unconstrained variables
+  can be a source of confusion. For Ada 95, we considered various
+  ways to break the connection between defaults and unconstrainedness,
+  but ultimately gave up for lack of a sufficiently simple and intuitive
+  alternative.
+
+
+  @Defn{mutable}
+  An unconstrained discriminated subtype with defaults is called
+  a @i{mutable} subtype, and a variable of such a subtype is called
+  a mutable variable,
+  because the discriminants of such a variable can change.
+  There are no mutable arrays (that is, the bounds of an array
+  object can never change), because there is no way in the language
+  to define default values for the bounds.
+  Similarly, there are no mutable class-wide subtypes,
+  because there is no way to define the default tag,
+  and defaults for discriminants are not allowed in the
+  tagged case.
+  Mutable tags would also require a way for the
+  maximum possible size of such a class-wide subtype to be known.
+  (In some implementations, all mutable variables are allocated
+  with the maximum possible size. This approach is appropriate
+  for real-time applications where implicit use of the heap
+  is inappropriate.)
+
address@hidden(Discussion)
+
+The @nt{default_expression} for a discriminant of a type is evaluated
+when an object of an unconstrained subtype of the type is created.
+
+Assignment to a discriminant of an object (after its
+initialization) is not allowed,
+since the name of a discriminant is a constant; neither
address@hidden
+nor assignments inherent in passing as an @key(in out)
+or @key(out) parameter
+are allowed.
+Note however that the value of a discriminant
+can be changed by assigning to the enclosing object, presuming it
+is an unconstrained variable.
address@hidden(Discussion)
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+An @nt{unknown_discriminant_part} is permitted only in the
+declaration of a private type (including generic formal private),
+private extension, @Chg{Version=[2],New=[incomplete type, ],Old=[]}or
+generic formal derived type.
+These are the things that will have a corresponding completion or
+generic actual, which will either define the discriminants,
+or say there are none.
+The (<>) indicates that the actual/full subtype might be an indefinite subtype.
+An @nt{unknown_discriminant_part} is not permitted in a normal
+untagged derived type declaration, because there is no separate
+full type declaration for such a type.
+Note that (<>) allows unconstrained array bounds;
+those are somewhat like undefaulted discriminants.
+
+For a derived type, either the discriminants are inherited as is,
+or completely respecified in a new @nt<discriminant_part>. In this
+latter case, each discriminant of the parent type shall be constrained,
+either to a specific value, or to equal one of the new discriminants.
+Constraining a parent type's discriminant to equal one of the new
+discriminants is like a renaming of the discriminant, except that
+the subtype of the new discriminant can be more restrictive than
+that of the parent's one.
+In any case, the new discriminant can share storage with the
+parent's discriminant.
address@hidden(Discussion)
+
+A discriminant that is of a named access type is not called
+an access discriminant; that term is
+used only for discriminants defined by an @nt<access_definition>.
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of discriminated types:)
address@hidden(Example)
address@hidden(type) Buffer(Size : Buffer_Size := 100)  @key(is)        
address@hidden see @RefSecNum(Integer Types)]
+   @key(record)
+      Pos   : Buffer_Size := 0;
+      Value : String(1 .. Size);
+   @key(end) @key(record);
+
address@hidden(type) Matrix_Rec(Rows, Columns : Integer) @key(is)
+   @key(record)
+      Mat : Matrix(1 .. Rows, 1 .. Columns);       address@hidden see 
@RefSecNum(Array Types)]
+   @key(end) @key(record);
+
address@hidden(type) Square(Side : Integer) @key(is) @key(new)
+   Matrix_Rec(Rows => Side, Columns => Side);
+
address@hidden(type) Double_Square(Number : Integer) @key(is)
+   @key(record)
+      Left  : Square(Number);
+      Right : Square(Number);
+   @key(end) @key(record);
+
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,address@hidden(task type) Worker(Prio : System.Priority; Buf : 
@key(access) Buffer)@Chg{Version=[3],New=[
+   @key(with) Priority => Prio @key(is) address@hidden see @RefSecNum{Task 
Priorities}]],address@hidden(is)]}
+   address@hidden discriminants used to parameterize the task type (see 
@RefSecNum{Task Units and Task Objects})address@hidden,New=[],Old=[
+   @key(pragma) Priority(Prio);  address@hidden see @RefSecNum{Task 
Priorities}]]}
+   @key(entry) Fill;
+   @key(entry) Drain;
address@hidden(end) Worker;],address@hidden(type) Item(Number : Positive) 
@key(is)
+   @key(record)
+      Content : Integer;
+      address@hidden  no component depends on the discriminant]
+   @key(end) @key(record);]}
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax for a @nt{discriminant_specification}
+is modified to allow an @i{access discriminant},
+with a type specified by an @nt{access_definition}
+(see @RefSecNum{Access Types}).
+
address@hidden,Kind=[Revised],ARef=[AI95-00251-01]}
+Discriminants are allowed on all composite types other than 
address@hidden,New=[ and
+interface],Old=[]} types.
+
+Discriminants may be of an access type.
address@hidden
+
address@hidden
address@hidden are not elaborated,
+though an @nt<access_definition> is elaborated
+when the discriminant is initialized.
+
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01],ARef=[AI95-00402-01],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[Access discriminants (anonymous access types
+  used as a discriminant) can be used on any type allowing discriminants.
+  Defaults aren't allowed on discriminants of nonlimited types, however, so
+  that accessibility problems don't happen on assignment.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],Text=[
+  @nt{null_exclusion} can be used in the declaration of a discriminant.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0007],ARef=[AI95-00098-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> The wording was clarified 
so
+  that types that cannot have discriminants cannot have an
+  @nt{unknown_discriminant_part}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Text=[Added wording to prevent interfaces from
+  having discriminants. We don't want interfaces to have any components.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00254-01]}
+  @ChgAdded{Version=[2],Text=[Removed wording which implied or required an
+  access discriminant to have an access-to-object type (anonymous access
+  types can now be access-to-subprogram types as well).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00326-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[Fixed the wording of the introduction to this
+  @Chg{Version=[3],New=[subclause],Old=[clause]} to reflect that both 
incomplete
+  and partial views can have unknown discriminants. That was always true,
+  but for some reason this wording specified partial views.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00419-01]}
+  @ChgAdded{Version=[2],Text=[Changed the wording to use the new term
+  @lquotes@;explicitly limited address@hidden, which makes the intent
+  much clearer (and eliminates confusion with derived types that happen to
+  contain the reserved word @key[limited]).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0063-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Changed the rules for when access discriminants can have defaults to depend
+  on the new definition for immutably limited types; this will help ensure that
+  unusual corner cases are properly handled. Note that the Ada 2005 rule was
+  unintentionally incompatible with the Ada 95 rule (as enforced by the ACATS);
+  this change brings it back into alignment with actual practice. So there
+  should be no practical incompatibility.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0214-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  A limited tagged type may now have defaults for its discriminants.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0102-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Moved implicit conversion
+  @LegalityName to @RefSecNum{The Context of Overload Resolution}.]}
address@hidden
+
+
address@hidden@Comment{For ISO version of Ada 2012 Standard}
address@hidden Constraints}
+
address@hidden
+A @nt<discriminant_constraint> specifies the values of the discriminants
+for a given discriminated type.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The rules in this @Chg{Version=[3],New=[subclause],Old=[clause]} are
+intentionally parallel to those given in @RefSec{Record Aggregates}.
address@hidden
+
address@hidden
address@hidden<discriminant_constraint>,rhs="
+   (@Syn2{discriminant_association} {, @Syn2{discriminant_association}})"}
+
+
address@hidden<discriminant_association>,rhs="
+   address@hidden@Syn2{selector_name} {| @address@hidden =>] 
@Syn2{expression}"}
+
address@hidden
address@hidden discriminant association}
+A @nt<discriminant_association>
+is said to be @i(named) if it has one or more
address@hidden(discriminant_)@nt<selector_name>s;
address@hidden discriminant association}
+it is otherwise said to be @i(positional).
+In a @nt<discriminant_constraint>,
+any positional associations shall precede any named
+associations.
address@hidden
+
address@hidden
+
address@hidden
+Each @nt<selector_name> of a named @nt<address@hidden> shall
+resolve to denote a discriminant of the subtype being constrained;
address@hidden discriminants],
+  Sec=(of a named @nt<discriminant_association>)}
+the discriminants so named are the @i(associated discriminants) of
+the named association.
address@hidden discriminants],
+  Sec=(of a positional @nt<discriminant_association>)}
+For a positional association, the @i(associated discriminant)
+is the one whose @nt<address@hidden> occurred in
+the corresponding position in the @nt<address@hidden@!part>
+that defined the discriminants of the subtype being constrained.
+
address@hidden type], Sec=(discriminant_association expression)}
+The expected type for the @nt{expression} in
+a @nt{discriminant_association}
+is that of the associated discriminant(s).
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0008],ARef=[AI95-00168-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00363-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0041-1]}
+A @nt{discriminant_constraint} is only allowed in a
address@hidden whose @nt{subtype_mark} denotes
+either an unconstrained discriminated subtype, or an
+unconstrained access subtype whose designated subtype is
+an unconstrained discriminated subtype.
address@hidden, in the case of @Chg{Version=[2],New=[an],Old=[a general]}
+access subtype, a @address@hidden is
address@hidden,New=[legal only if any dereference of a value of the access
+type is known to be constrained (see @RefSecNum{Objects and Named Numbers})],
+Old=[illegal if @Chg{Version=[2],New=[the
+designated type has a partial view that is constrained or, for a general
+access subtype, has @nt{default_expression}s for its discriminants],Old=[]}]}],
+Old=[there is a place within the
+immediate scope of the designated subtype where the designated subtype's view
+is constrained]}.
address@hidden,New=[In addition to the places where @LegalityTitle@;
+normally apply (see @RefSecNum{Generic Instantiation}),
+these rules apply also in the private part of an instance
+of a generic address@hidden contract issue}],address@hidden,
+New=[],address@hidden,
+New=[ In a generic body, this rule is checked presuming all
+formal access types of the generic might be general access types, and all
+untagged discriminated formal types of the generic might have
address@hidden for their discriminants.],Old=[]}]}
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0008],ARef=[AI95-00168-01]}
address@hidden,Kind=[DeletedAdded],ARef=[AI95-00363-01]}
address@hidden,address@hidden second rule is necessary to
+prevent assignments that change the discriminant of a constrained object.
+See the defect report for examples.],Old=[]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00363-01]}
address@hidden,Text=[The second rule is necessary to prevent objects
+from changing so that they no longer match their constraint. In Ada 95, we
+attempted to prevent this by banning every case where an aliased object
+could be unconstrained or be changed by an enclosing assignment. New ways
+to cause this problem were being discovered frequently, meaning that new rules
+had to be dreamed up to cover them. Meanwhile, aliased objects and components
+were getting more and more limited. In Ada 2005, we sweep away all of that
+cruft and replace it by a simple rule @lquotes@;thou shalt not create an
+access subtype that can point to an item whose discriminants can be changed by
address@hidden@;.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0041-1]}
address@hidden,Text=[The second rule will only use the indefinite or
+dereference bullets in the definition of @ldquote@;known to be address@hidden
+The rule is worded in terms of @ldquote@;known to be address@hidden in
+order to capture the special rules that apply in generic bodies (rather than
+repeating them and getting them subtly wrong).]}
address@hidden
+
+A named @nt<discriminant_association> with more than one
address@hidden<selector_name> is allowed only if the named discriminants
+are all of the same type.
+A @nt<discriminant_constraint> shall provide exactly one value for each
+discriminant of the subtype being constrained.
+
address@hidden,Kind=[Deleted],ARef=[AI05-0102-1]}
address@hidden,Text=[The @nt<expression> associated with an access
+discriminant shall be of a type convertible to the anonymous access type.
address@hidden,Sec=(required)}]}
+
address@hidden(Ramification)
+
+  @ChgRef{Version=[3],Kind=[Revised]}
+  @Chg{Version=[3],New=[In addition, @RefSecNum{The Context of Overload 
Resolution}
+  requires that the @nt{expression} associated with an access discriminant
+  is convertible (see @RefSecNum{Type Conversions}) to the anonymous
+  access type. ],Old=[]}This implies both convertibility of designated
+  types, and static accessibility.
+  This implies that if an object of type T with an
+  access discriminant is created
+  by an allocator for an access type A, then it requires that the
+  type of the @nt<expression> associated
+  with the access discriminant have an accessibility level
+  that is not statically deeper than that of A.
+  This is to avoid dangling references.
+
address@hidden(Ramification)
address@hidden
+
address@hidden
address@hidden, Sec=(discriminant constraint with a
+subtype)}
+A @nt{discriminant_constraint} is @i(compatible) with an unconstrained
+discriminated subtype if each discriminant value belongs to the
+subtype of the corresponding discriminant.
address@hidden
+The "dependent
+  compatibility check" has been eliminated in Ada 95. Any checking
+  on subcomponents is performed when (and if) an object is address@hidden
address@hidden
+  There is no need to define compatibility with a constrained
+  discriminated subtype, because one is not allowed to constrain it 
address@hidden
+
address@hidden, Sec=(a discriminant constraint)}
+A composite value @i(satisfies) a discriminant constraint if and only
+if each discriminant of the composite value has the value imposed
+by the discriminant constraint.
+
address@hidden, Sec=(discriminant_constraint)}
+For the elaboration of a @nt{discriminant_constraint}, the @nt{expression}s
+in the @nt{discriminant_association}s are evaluated in an arbitrary
+order and converted to the type of the associated
+discriminant (which might raise Constraint_Error @em
+see @RefSecNum{Type Conversions});
+the @nt{expression} of a named association is evaluated
+(and converted) once for each associated discriminant.
address@hidden subtype conversion],Sec=(discriminant values)}
+The result of each evaluation and conversion is the
+value imposed by the constraint for the associated discriminant.
address@hidden
+
+  We convert to the type, not the subtype, so that the definition
+  of compatibility of discriminant constraints is not address@hidden
+
address@hidden
+
address@hidden
+The rules of the language ensure that
+a discriminant of an object always has a value, either
+from explicit or implicit initialization.
address@hidden(Discussion)
+Although it is illegal to constrain a class-wide tagged subtype, it
+is possible to have a partially constrained class-wide
+subtype: If the subtype S is defined by T(A => B),
+then S'Class is partially constrained in the sense that objects of
+subtype S'Class have to have discriminants corresponding
+to A equal to B,
+but there can be other discriminants defined
+in extensions that are not constrained to any particular value.
address@hidden(Discussion)
address@hidden
+
address@hidden
address@hidden@address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden (using types declared above in
address@hidden,New=[subclause],Old=[clause]} @RefSecNum(Discriminants)):}
address@hidden(Example)
+Large   : Buffer(200);  address@hidden  constrained, always 200 characters]
+                        address@hidden   (explicit discriminant value)]
+Message : Buffer;       address@hidden  unconstrained, initially 100 
characters]
+                        address@hidden   (default discriminant value)]
+Basis   : Square(5);    address@hidden  constrained, always 5 by 5]
+Illegal : Square;       address@hidden  illegal, a Square has to be 
constrained]
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden with Ada 83}
+Dependent compatibility checks are no longer performed on
+subtype declaration. Instead they are deferred until
+object creation (see @RefSecNum(Object Declarations)).
+This is upward compatible for a program
+that does not raise Constraint_Error.
address@hidden
+
address@hidden
+Everything in RM83-3.7.2(7-12), which specifies the
+initial values for discriminants, is now redundant
+with 3.3.1, 6.4.1, 8.5.1, and 12.4. Therefore, we don't
+repeat it here. Since the material is largely intuitive,
+but nevertheless complicated to state formally, it doesn't
+seem worth putting it in a "NOTE."
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],Ref=[8652/0008],ARef=[AI95-00168-01],ARef=[AI95-00363-01]}
address@hidden,address@hidden with Ada 95}
+The Corrigendum added a restriction on @nt{discriminant_constraint}s for
+general access subtypes. Such constraints are prohibited
+if the designated type can be treated as constrained somewhere in the program.
+Ada 2005 goes further and prohibits such @nt{discriminant_constraint}s if
+the designated type has (or might have, in the case of a formal type)
+defaults for its discriminants. The use of general access subtypes is rare,
+and this eliminates a boatload of problems that required many restrictions
+on the use of aliased objects and components (now lifted). Similarly,
+Ada 2005 prohibits @nt{discriminant_constraint}s on any access type whose
+designated type has a partial view that is constrained. Such a type will
+not be constrained in the heap to avoid privacy problems. Again, the use
+of such subtypes is rare (they can only happen within the package and its
+child units).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0041-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Revised the rules on
+  access subtypes having discriminant constraints to depend on the
+  @ldquote@;known to be address@hidden rules. This centralizes
+  the rules so that future fixes need to be made in only one place,
+  as well as fixing bugs in obscure cases.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0102-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Moved implicit conversion
+  @LegalityName to @RefSecNum{The Context of Overload Resolution}.]}
address@hidden
+
+
address@hidden of Discriminated Types}
+
address@hidden
address@hidden a discriminated type has @nt<default_expression>s for its
+discriminants, then unconstrained variables of the type are permitted,
+and the discriminants of such a variable can be changed by assignment to
+the variable. For a formal parameter of such a type, an attribute
+is provided to determine whether the corresponding actual parameter
+is constrained or unconstrained.]
address@hidden
+
address@hidden
address@hidden@Keepnext@;For @PrefixType{a @nt<prefix> A that is of a
+discriminated type @Redundant[(after any implicit dereference)]},
+the following attribute is defined:
address@hidden(description)
address@hidden, Kind=[Revised], ChginAnnex=[T],
+  Leading=[F], Prefix=<A>, AttrName=<Constrained>, ARef=[AI05-0214-1],
+  InitialVersion=[0],
+  Text=[Yields the value True if A denotes a constant, a value,
+  @Chg{Version=[3],New=[a tagged object, ],Old=[]}or a constrained variable,
+  and False otherwise.]}
address@hidden(ImplNote)
address@hidden,Kind=[Revised],ARef=[AI05-0214-1]}
+ This attribute is primarily used on parameters, to determine whether
+ the discriminants can be changed as part of an assignment.
+ The Constrained attribute is statically True for @key(in) parameters.
+ For @key(in out) and @key(out) parameters of a discriminated type,
+ the value of this attribute needs to be passed as an implicit
+ parameter, in general. However, if the type @Chg{Version=[3],New=[is
+ tagged or ],Old=[]}does not have
+ defaults for its discriminants, the attribute is statically True,
+ so no implicit parameter is needed.
+ Parameters of a limited @Chg{Version=[3],New=[untagged ],Old=[]}type
+ with defaulted discriminants need this implicit parameter,
+ unless there are no nonlimited views,
+ because they might be passed to a subprogram whose body has
+ visibility on a nonlimited view of the type, and hence might be
+ able to assign to the object and change its discriminants.
address@hidden(ImplNote)
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0214-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0005-1]}
address@hidden,Text=[All tagged objects are known to be constrained (as
+ nonlimited tagged types cannot have discriminant defaults, and limited tagged
+ objects are immutably limited), and are always considered constrained by this
+ attribute to avoid distributed overhead for parameters of limited
+ @Chg{Version=[4],New=[class-wide],Old=[classwide]}
+ types, as limited tagged objects may technically be unconstrained if they use
+ defaulted discriminants. Such objects still cannot have their discriminants
+ changed, as assignment is not supported for them, so there is no use for this
+ attribute that would justify the overhead of passing it with all
+ @Chg{Version=[4],New=[class-wide],Old=[classwide]} parameters.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1],ARef=[AI05-0214-1]}
address@hidden,Text=[If the type of A is a type derived from an untagged
+ partial view of a tagged type such that it is not a tagged type, then A is not
+ considered a tagged object, and A'Constrained can return either True or
+ False depending on the nature of the object.]}
address@hidden
address@hidden(description)
address@hidden
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)}
+The execution of a construct is erroneous if the construct
+has a constituent that is a @nt<name> denoting
+a subcomponent that depends on discriminants, and the
+value of any of these discriminants is changed by this execution
+between evaluating the @nt<name> and the last use (within this
+execution) of the subcomponent denoted by the @nt<name>.
address@hidden
+  This rule applies to @nt<assignment_statement>s,
+  calls (except when the discriminant-dependent subcomponent is
+  an @key(in) parameter passed by copy),
+  @nt<indexed_component>s, and @nt<slice>s.
+  Ada 83 only covered the first two cases. AI83-00585 pointed out
+  the situation with the last two cases.
+  The cases of @nt<object_renaming_declaration>s and
+  generic formal @key(in out) objects are handled differently,
+  by disallowing the situation at compile time.
address@hidden
address@hidden
+
address@hidden
address@hidden,address@hidden be consistent with 8652/0006}
address@hidden to Ada 83}
+For consistency with other attributes, we are allowing
+the @address@hidden,Old=[prefix]} of Constrained to be a value as well
+as an object of a discriminated type, and also an implicit
+dereference. These extensions are
+not important capabilities, but there seems no
+reason to make this attribute different from
+other similar attributes. We are curious what most
+Ada 83 compilers do with F(1).X'Constrained.
+
+We now handle in a general way
+the cases of erroneousness identified by AI83-00585, where
+the @nt<prefix> of an @nt<indexed_component> or @nt<slice>
+is discriminant-dependent, and the evaluation of the index or
+discrete range changes the value of a discriminant.
address@hidden
+
address@hidden
+We have moved all discussion of erroneous use of @nt<name>s
+that denote discriminant-dependent
+subcomponents to this subclause. In Ada 83, it used to
+appear separately under @nt{assignment_statement}s and
+subprogram calls.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0214-1]}
+  @ChgAdded{Version=[3],Text=[A'Constrained is now defined to return
+  True for any A that is a tagged object. This doesn't change the result
+  for any A allowed by previous versions of Ada; the change is necessary to
+  avoid unnecessary overhead for limited tagged parameters.]}
address@hidden
+
+
address@hidden Types}
+
address@hidden
address@hidden
address@hidden type}
+A record object is a composite object consisting of named components.
+The value of a record object is a composite value consisting of the
+values of the components.
address@hidden,See=(record type)}
address@hidden
+
address@hidden
address@hidden<record_type_definition>,rhs="address@hidden @key{tagged}] 
address@hidden @Syn2{record_definition}"}
address@hidden<record_definition>,rhs="
+    @key{record}
+       @Syn2{component_list}
+    @key{end} @key{record}
+  | @key{null record}"}
+
+
address@hidden<component_list>,rhs="
+      @Syn2{component_item} address@hidden
+   | address@hidden @Syn2{variant_part}
+   |  @key{null};"}
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden<component_item>,rhs="@Syn2{component_declaration} | 
@address@hidden,address@hidden"}
+
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<component_declaration>,rhs="
+   @Syn2{defining_identifier_list} : @Syn2{component_definition} [:= 
@address@hidden,New=<
+        address@hidden>,Old=[]};"}
address@hidden
+
address@hidden
address@hidden type], Sec=(component_declaration default_expression)}
+The expected type for the @nt<default_expression>, if any, in
+a @nt<component_declaration> is the type of the
+component.
address@hidden
+
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00287-01]}
address@hidden,Text=[A @nt<default_expression> is not permitted if
+the component is of a limited type.]}
+
address@hidden,Kind=[Revised],address@hidden is not THE definition of component}
address@hidden, Sec=(of a record type)}
+Each @nt<component_declaration> declares a
address@hidden,New=[component],address@hidden(component)]} of the record type.
+Besides components declared by @nt<component_declaration>s, the components of a
+record type include any components declared by @nt<discriminant_specification>s
+of the record type declaration. @Redundant[The identifiers of all components of
+a record type shall be distinct.]
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+  The identifiers of all
+  components of a record type have to
+  be distinct because they are all declared immediately
+  within the same declarative region. See 
@Chg{Version=[3],New=[Clause],Old=[Section]}
+  @RefSecNum{Visibility Rules}.
address@hidden
+
+
+Within a @nt{type_declaration},
+a @nt{name} that denotes a component, protected subprogram,
+or entry of the type is allowed only in the following cases:
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0004-1],ARef=[AI05-0295-1]}
+A @nt{name} that denotes any component, protected subprogram,
+or entry is allowed within @Chg{Version=[3],New=[an @nt{aspect_specification},
+an operational item, or ],Old=[]}a
+representation item that occurs within the declaration of the composite type.
+
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
+A @nt{name} that denotes a noninherited discriminant
+is allowed within the declaration of the type,
+but not within the @nt{discriminant_part}.
+If the discriminant is used to define the constraint of
+a component, the bounds of an entry family, or
+the constraint of the parent subtype in a
address@hidden<derived_type_definition>@Chg{Version=[3],New=[,],Old=[]}
+then its name shall appear alone as a @nt<direct_name> (not as
+part of a larger expression or expanded name).
+A discriminant shall not be used to define the constraint of
+a scalar address@hidden,Sec=[use in a record address@hidden index entry}
address@hidden
+The penultimate restriction simplifies implementation,
+  and allows the outer discriminant and the inner discriminant
+  or bound to possibly share storage.
address@hidden
address@hidden
+  Other rules prevent such a discriminant from being an inherited one.
address@hidden
address@hidden
+The last restriction is inherited from Ada 83.
+The restriction is not really necessary from a language design point of
+view, but we did not remove it,
+in order to avoid unnecessary changes to existing compilers.
address@hidden
address@hidden
+  Note that a discriminant can be used to define the constraint
+  for a component that is of an access-to-composite type.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00373-01]}
+  The above rules, and a similar one in @RefSecNum{Subprogram Declarations}
+  for formal parameters, are intended to allow initializations of
+  components or parameters to occur in @Chg{Version=[2],
+  New=[a (nearly)],Old=[an]} arbitrary order @em whatever
+  order is most address@hidden,New=[ (subject to the restrictions
+  of @RefSecNum{Object Declarations})],Old=[]},
+  since one @nt{default_expression} cannot depend on the value of
+  another one.
+  @Chg{Version=[2],New=[They],Old=[It]} also prevent circularities.
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0295-1]}
+  Inherited discriminants are not allowed to be denoted,
+  except within @Chg{Version=[3],address@hidden
+  and ],Old=[]}representation items.
+  However, the @address@hidden of
+  the parent @nt{subtype_indication} is allowed to denote
+  a discriminant of the parent.
address@hidden
address@hidden
+
+If the name of the current instance of a type
+(see @RefSecNum{The Context of Overload Resolution})
+is used to define the constraint of a component,
+then it shall appear as a @nt{direct_name}
+that is the @nt<prefix> of an @nt{attribute_reference}
+whose result is of an access type,
+and the @nt{attribute_reference} shall appear alone.
address@hidden
+  This rule allows T'Access
+  or T'Unchecked_Access, but disallows, for example,
+  a range constraint (1..T'Size).
+  Allowing things like (1..T'Size) would mean that a per-object
+  constraint could affect the size of the object,
+  which would be bad.
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00318-02]}
address@hidden,Kind=[Added],ARef=[AI05-0004-1]}
address@hidden,address@hidden limited record}
address@hidden,Sec=(explicitly limited)}
+If a @Chg{Version=[3],address@hidden,address@hidden
+includes the reserved word @key{limited}, the type is called an
address@hidden<explicitly limited record> type.]}
+
address@hidden subtype], Sec=(of a record component)}
+The @nt{component_definition} of a @nt<component_declaration>
+defines the (nominal) subtype of the component.
+If the reserved word @key(aliased) appears in the @nt{component_definition},
+then the component is aliased (see @RefSecNum{Access Types}).
address@hidden(Ramification)
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00363-01]}
+  @ChgDeleted{Version=[2],Text=[In this case, the nominal subtype cannot be
+  an unconstrained discriminated subtype.
+  See @RefSecNum{Array Types}.]}
address@hidden(Ramification)
+
address@hidden record}
+If the @nt<component_list> of a record type is defined by the reserved
+word @key(null) and there are no discriminants, then the record type has
+no components and all records of the type are @i(null records).
+A @nt<record_definition> of @key{null record} is equivalent to
address@hidden null; end record}.
address@hidden
+
+  This short-hand is available both for declaring a record type
+  and a record extension @em see @RefSecNum(Type Extensions).
address@hidden
+
address@hidden
+
address@hidden
address@hidden, Sec=(record_type_definition)}
+The elaboration of a @nt{record_type_definition} creates
+the record type and its first subtype,
+and consists of the elaboration of the @nt<record_definition>.
address@hidden, Sec=(record_definition)}
+The elaboration of a @nt<record_definition> consists of the
+elaboration of its @nt{component_list}, if any.
+
address@hidden, Sec=(component_list)}
+The elaboration of a @nt{component_list} consists of the elaboration
+of the @nt{component_item}s and
address@hidden, if any, in the order in which they appear.
address@hidden, Sec=(component_declaration)}
+The elaboration of a @nt{component_declaration} consists of the
+elaboration of the @nt{component_definition}.
address@hidden(Discussion)
+  If the @nt<defining_identifier_list> has more than one
+  @nt<defining_identifier>, we presume here that the transformation
+  explained in @RefSecNum(Object Declarations) has already
+  taken place. Alternatively, we could say that
+  the @nt<component_definition> is elaborated once for
+  each @nt<defining_identifier> in the list.
address@hidden(Discussion)
+
address@hidden,Kind=[Revised],Ref=[8652/0002],ARef=[AI95-00171-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00230-01]}
address@hidden expression}
address@hidden constraint}
address@hidden index subtype}
+Within the definition of a composite type,
+if a @nt<component_definition> or @nt<discrete_subtype_definition>
+(see @RefSecNum{Entries and Accept Statements})
+includes a @nt<name> that denotes a discriminant of the type, or
+that is an @nt<attribute_reference> whose @nt<prefix> denotes the current
+instance of the type,
+the expression containing the @nt<name> is called a @i(per-object expression),
+and the @address@hidden or @nt{range}],Old=[constraint]} being defined
+is called a @i(per-object constraint).
address@hidden, Sec=(component_definition)}
+For the elaboration of a @nt{component_definition} of
+a @nt<component_declaration>@Chg{New=[ or the @address@hidden@!definition}
+of an @address@hidden for an entry family (see
address@hidden and Accept Statements})],Old=[]},@Chg{Version=[2],
+New=[ if the component subtype is defined by an @nt{access_definition} or],
+Old=[]} if the @nt{constraint}
address@hidden @nt{range}],Old=[]} of the @nt{subtype_indication}
address@hidden @address@hidden@!definition}],Old=[]} is not a per-object
+constraint, then address@hidden,New=[ @nt{access_definition},],Old=[]}
address@hidden@Chg{Version=[2],New=[,],Old=[]}
address@hidden @address@hidden@!definition}],Old=[]}
+is elaborated. On the other hand, if the @nt{constraint}
address@hidden @nt{range}],Old=[]} is a per-object constraint,
+then the elaboration consists of the evaluation of any included
+expression that is not part of a per-object expression.
address@hidden such expression is evaluated once unless it is part of a named
+association in a discriminant constraint, in which case it is evaluated once
+for each associated discriminant.],Old=[]}
+
address@hidden,Kind=[Added],Ref=[8652/0002],ARef=[AI95-00171-01]}
address@hidden@PDefn2{Term=[Elaboration],Sec=(per-object constraint)}When a
+per-object constraint is elaborated @Redundant[(as part of creating an
+object)], each per-object expression of the constraint is evaluated. For other
+expressions, the values determined during the elaboration of the
address@hidden@!definition} or @address@hidden are used. Any checks
+associated with the enclosing @nt{subtype_indication} or
address@hidden are address@hidden, including the subtype
+compatibility check (see @RefSecNum{Subtype Declarations}),] and the associated
+subtype is created.],
+Old=[]}
address@hidden(Discussion)
+  The evaluation of other expressions that appear in
+  @nt<component_definition>s and @nt<discrete_subtype_definition>s
+  is performed when the type definition is elaborated.
+  The evaluation of expressions that appear as
+  @nt<default_expression>s is postponed until an object is created.
+  Expressions in representation items
+  that appear within a composite type definition are evaluated
+  according to the rules of the particular representation item.
address@hidden(Discussion)
address@hidden
+
address@hidden
+A @nt<component_declaration> with several identifiers is equivalent
+to a sequence of single @nt<component_declaration>s, as explained
+in @RefSecNum{Object Declarations}.
+
+The @nt<default_expression> of a record component is only
+evaluated upon the creation of
+a default-initialized object of the record type (presuming
+the object has the component, if it is in a @nt<variant_part> @em
+see @RefSecNum{Object Declarations}).
+
+The subtype defined by a @nt<component_definition> (see @RefSecNum(Array 
Types))
+has to be a definite subtype.
+
+If a record type does not have a @nt<variant_part>, then the same components
+are present in all values of the type.
+
+A record type is limited if it has the reserved word @key[limited]
+in its definition, or if any of its components are
+limited (see @RefSecNum{Limited Types}).
+
address@hidden operations],Sec=(of a record type)}
+The predefined operations of a record type include membership
+tests, qualification, and explicit conversion. If the
+record type is nonlimited, they also include
+assignment and the predefined equality operators.
+
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
+A component of a record can be named with a @nt<selected_component>.
+A value of a record can be specified with a 
@nt<record_aggregate>@Chg{Version=[2],
+New=[],Old=[, unless the record type is limited]}.
+
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of record type declarations: )
address@hidden(Example)
address@hidden(type) Date @key(is)
+   @key(record)
+      Day   : Integer @key(range) 1 .. 31;
+      Month : Month_Name;
+      Year  : Integer @key(range) 0 .. 4000;
+   @key(end) @key(record);
+
address@hidden(type) Complex @key(is)
+   @key(record)
+      Re : Real := 0.0;
+      Im : Real := 0.0;
+   @key(end) @key(record);
address@hidden(Example)
+
address@hidden
address@hidden@address@hidden(Examples of record variables: )
address@hidden
address@hidden(Example)
+Tomorrow, Yesterday : Date;
+A, B, C : Complex;
+
address@hidden both components of A, B, and C are implicitly initialized to 
zero ]
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax rule for @nt<component_declaration> is modified
+to use @nt<component_definition> (instead of
address@hidden<component_subtype_definition>). The effect of this change
+is to allow the reserved word @key(aliased) before the
address@hidden<component_subtype_definition>.
+
+A short-hand is provided for defining a null record type
+(and a null record extension), as these will be more common
+for abstract root types (and derived types without additional components).
+
+The syntax rule for @nt{record_type_definition} is modified to allow
+the reserved words @key{tagged} and @key{limited}.
+Tagging is new.
+Limitedness is now orthogonal to privateness.
+In Ada 83 the syntax implied that limited private was sort of more
+private than private.
+However, limitedness really has nothing to do with privateness;
+limitedness simply indicates the lack of assignment capabilities,
+and makes perfect sense for nonprivate types such as record types.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+The syntax rules now allow @address@hidden,
address@hidden to appear in a @nt{record_definition}.
+This is not a language extension, because @LegalityName@;s prevent all
+language-defined representation clauses from appearing there.
+However, an implementation-defined @nt{attribute_definition_clause}
+could appear there.
+The reason for this change is to allow the rules for
address@hidden@nt{aspect_clause}s],address@hidden and
+representation pragmas to be as similar as possible.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Record components can have an anonymous access type.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Limited components can be initialized, so long as the expression is
+  one that allows building the object in place (such as an @nt{aggregate} or
+  @nt{function_call}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0002],ARef=[AI95-00171-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Improved the description 
of the
+  elaboration of per-object constraints.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0009],ARef=[AI95-00137-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Changed representation 
clauses to
+  aspect clauses to reflect that they are used for more than just
+  representation.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],Text=[Defined @i{explicitly limited record} type to
+  use in other rules.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a 
@nt{component_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
+
address@hidden Parts and Discrete Choices}
+
address@hidden
+A record type with a @nt<variant_part> specifies alternative
+lists of components. Each @nt<variant> defines the components
+for the value or values of the discriminant
+covered by its @nt<discrete_choice_list>.
address@hidden
address@hidden a value}
address@hidden and @nt{discrete_choice}s are
+said to @i(cover) values as defined below; which
address@hidden covers a value determines
+which of various alternatives is chosen. These are used
+in @nt{variant_part}s, @nt{array_aggregate}s, and
address@hidden
address@hidden
address@hidden
+
address@hidden
+The definition of @lquotes@;address@hidden@; in this subclause
+and the rules about discrete choices
+are designed so that they
+are also appropriate for array aggregates and case statements.
+
+The rules of this subclause intentionally
+parallel those for case statements.
address@hidden
+
address@hidden
address@hidden<variant_part>,rhs="
+   @key{case} @address@hidden @key{is}
+       @Syn2{variant}
+      address@hidden
+   @key{end} @key{case};"}
+
+
address@hidden<variant>,rhs="
+   @key{when} @Syn2{discrete_choice_list} =>
+      @Syn2{component_list}"}
+
+
address@hidden<discrete_choice_list>,rhs="@Syn2{discrete_choice} {| 
@Syn2{discrete_choice}}"}
+
address@hidden,Kind=[Revised],ARef=[AI05-0153-3],ARef=[AI05-0158-1]}
address@hidden<discrete_choice>,rhs="@Chg{Version=[3],address@hidden,address@hidden
 | @Chg{Version=[3],address@hidden@Syn2{subtype_indication} | 
@Syn2{range}],address@hidden | @key{others}"}
address@hidden
+
address@hidden
address@hidden, Sec=(of a @nt<variant_part>)}
+The @i(discriminant_)@nt{direct_name} shall resolve to denote
+a discriminant (called
+the @i(discriminant of the @nt<variant_part>)) specified in
+the @nt{known_discriminant_part} of the @nt{full_type_declaration}
+that contains the @nt{variant_part}.
address@hidden type], Sec=(variant_part discrete_choice)}
+The expected type for each @nt{discrete_choice} in a @nt<variant> is the type
+of the discriminant of the @nt{variant_part}.
address@hidden
+  A @nt<full_type_declaration> with a @nt<variant_part>
+  has to have a (new) @nt<known_discriminant_part>;
+  the discriminant of the @nt<variant_part> cannot be an
+  inherited discriminant.
address@hidden
address@hidden
+
address@hidden
+The discriminant of the @nt{variant_part} shall
+be of a discrete type.
+  @begin{Ramification}
+It shall not be of an access type,
+  named or address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0153-3]}
+The @Chg{Version=[3],address@hidden, @nt{subtype_indication}s,
+and @nt{range}s],address@hidden and @nt{discrete_range}s]} given as
address@hidden in a @nt{variant_part} shall be static.
+The @nt{discrete_choice} @key(others) shall appear alone
+in a @nt{discrete_choice_list}, and such a @nt{discrete_choice_list},
+if it appears, shall be the last one in the enclosing construct.
+
address@hidden@PDefn2{Term=[cover a value], Sec=(by a @nt{discrete_choice})}
+A @nt<discrete_choice> is defined to @i(cover a value) in the
+following cases:
address@hidden(itemize)
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
+  A @nt{discrete_choice} that is
+  @Chg{Version=[3],New=[a @nt{choice_expression}],Old=[an @nt{expression}]}
+  covers a value if
+  the value equals the value of
+  the @Chg{Version=[3],address@hidden,address@hidden
+  converted to the expected type.
+
address@hidden,Kind=[Added],ARef=[AI05-0153-3],ARef=[AI05-0262-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0071-1]}
+  @ChgAdded{Version=[3],Text=[A @nt{discrete_choice} that is a
+  @nt{subtype_indication} covers all values (possibly none) that belong to the
+  subtype and that satisfy the static @Chg{Version=[4],New=[predicates],
+  Old=[predicate]} of the subtype (see @RefSecnum{Subtype Predicates}).]}
+
+  @begin{Ramification}
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0262-1]}
+    @ChgAdded{Version=[3],Text=[A dynamic predicate is never allowed in this 
case
+    (for @nt{variant}s, @nt{case_statement}s, and @nt{case_expression}s,
+    a subtype with a dynamic
+    predicate isn't static and thus isn't allowed in a @nt{discrete_choice},
+    and for a choice in an @nt{array_aggregate}, a dynamic predicate
+    is explicitly disallowed @em see @RefSecnum{Subtype Predicates}).]}
+  @end{Ramification}
+
address@hidden,Kind=[Revised],ARef=[AI05-0153-3]}
+  A @nt{discrete_choice} that is a
+  @Chg{Version=[3],address@hidden,address@hidden covers all values
+  (possibly none) that belong to the range.
+
+  The @nt{discrete_choice} @key{others} covers all values of its
+  expected type that are not covered by
+  previous @nt{discrete_choice_list}s of the same construct.
+  @begin(Ramification)
+    For @nt{case_statement}s,
+    this includes values outside the range of the static subtype (if any)
+    to be covered by the choices.
+    It even includes values outside the base
+    range of the case expression's type,
+    since values of numeric types (and undefined values of any scalar type?)
+    can be outside their base range.
+  @end(Ramification)
address@hidden(itemize)
+
address@hidden a value], Sec=(by a @nt{discrete_choice_list})}
+A @nt{discrete_choice_list} covers a value if one of
+its @nt{discrete_choice}s covers the value.
+
address@hidden@keepnext@;The possible values of the discriminant of a 
@nt{variant_part}
+shall be covered as follows:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0153-3],ARef=[AI05-0188-1],ARef=[AI05-0262-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0071-1]}
+  If the discriminant is of a static constrained scalar
+  address@hidden,New=[],Old=[,]}
+  address@hidden,New=[, except within an instance of a generic
+  unit,],Old=[]} each address@hidden @address@hidden shall cover
+  only values in that address@hidden,New=[ that satisfy its
+  @Chg{Version=[4],New=[predicates],Old=[predicate]}],Old=[]}, and each value
+  of that subtype @Chg{Version=[3],New=[that satisfies its
+  @Chg{Version=[4],New=[predicates],Old=[predicate]} ],Old=[]}shall be covered
+  by some @address@hidden @Redundant[(either explicitly or
+  by @key<others>)];
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0188-1]}
address@hidden,Type=[Leading],Text=[The exemption for a discriminated type 
declared in an instance
+  allows the following example:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key[type] T @key[is new] Integer;
address@hidden G @key[is]
+   @key[type] Rec (Discrim : T) @key[is record]
+      @key[case] Discrim @key[is]
+         @key[when] -10 .. -1 =>
+            Foo : Float;
+         @key[when others] =>
+            @key[null];
+      @key[end case];
+   @key[end record];
address@hidden G;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden I @key{is new} G (Natural); -- @Examcom{Legal}]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+  If the type of the discriminant is a
+  descendant of a generic formal scalar address@hidden,New=[,],Old=[]}
+  then the @nt{variant_part} shall have an @key{others}
+  @nt{discrete_choice};
address@hidden
+  The base range is not known statically in this case.
address@hidden
+
+  Otherwise,
+  each value of the base range of the type of the discriminant shall
+  be covered @Redundant[(either explicitly or by @key<others>)].
address@hidden
+
+Two distinct @nt{discrete_choice}s of a @nt{variant_part} shall not cover
+the same value.
+
address@hidden
+
address@hidden
+If the @nt{component_list} of a @nt{variant} is specified by @key(null),
+the variant has no components.
+
address@hidden a @nt{variant_part}}
address@hidden a @nt{variant}}
+The discriminant of a @nt<variant_part> is said to @i(govern) the
address@hidden<variant_part> and its @nt<variant>s. In addition,
+the discriminant of a derived
+type governs a @nt<variant_part> and its @nt<variant>s if it
+corresponds (see @RefSecNum(Discriminants)) to the
+discriminant of the @nt<variant_part>.
+
address@hidden
+
address@hidden
+A record value contains the values of the components of a particular
address@hidden only if the
+value of the discriminant governing the @nt<variant> is covered
+by the @nt{discrete_choice_list} of the @nt{variant}.
+This rule applies in turn to any further @nt{variant} that is, itself,
+included in the @nt{component_list} of the given @nt{variant}.
+
address@hidden,Kind=[Added],ARef=[AI05-0290-1]}
address@hidden,Text=[When an object of a discriminated type @i<T> is
+initialized by default, Constraint_Error is raised if no
address@hidden of any @nt{variant} of a @nt{variant_part} of @i<T>
+covers the value of the discriminant that governs the @nt{variant_part}. When a
address@hidden appears in the @nt{component_list} of another @nt{variant}
address@hidden<V>, this test is only applied if the value of the discriminant 
governing
address@hidden<V> is covered by the @nt{discrete_choice_list} of @i<V>.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is not a @ldquote@;address@hidden; it cannot
+  be suppressed. However, in most cases it is not necessary to generate any 
code
+  to raise this exception. A test is needed (and can fail) in the case where 
the
+  discriminant subtype has a Static_Predicate specified, it also has predicate
+  checking disabled, and the discriminant governs a @nt{variant_part} which
+  lacks a @key[when others] choice.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The test also could fail for a static 
discriminant
+  subtype with range checking suppressed and the discriminant governs a
+  @nt{variant_part} which lacks a @key[when others] choice. But execution is 
erroneous if a range
+  check that would have failed is suppressed (see @RefSecNum{Suppressing 
Checks}),
+  so an implementation does not have to generate code to check this case. (An
+  unchecked failed predicate does not cause erroneous execution, so the test is
+  required in that case.)]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Like the checks associated with a per-object
+  constraint, this test is not made during the elaboration of a
+  @nt{subtype_indication}.]}
address@hidden
+
address@hidden, Sec=(variant_part)}
+The elaboration of a @nt{variant_part} consists
+of the elaboration of the @nt{component_list} of each
address@hidden in the order in which they appear.
address@hidden
+
address@hidden
address@hidden@address@hidden(Example of record type with a variant part: )
address@hidden(Example)
address@hidden(type) Device @key(is) (Printer, Disk, Drum);
address@hidden(type) State  @key(is) (Open, Closed);
+
address@hidden(type) Peripheral(Unit : Device := Disk) @key(is)
+   @key(record)
+      Status : State;
+      @key(case) Unit @key(is)
+         @key(when) Printer =>
+            Line_Count : Integer @key(range) 1 .. Page_Size;
+         @key(when) @key(others) =>
+            Cylinder   : Cylinder_Index;
+            Track      : Track_Number;
+         @key(end) @key(case);
+      @key(end) @key(record);
address@hidden(Example)
+
address@hidden
address@hidden@address@hidden(Examples of record subtypes:)
address@hidden
address@hidden(Example)
address@hidden(subtype) Drum_Unit @key(is) Peripheral(Drum);
address@hidden(subtype) Disk_Unit @key(is) Peripheral(Disk);
address@hidden(Example)
+
address@hidden
address@hidden@address@hidden(Examples of constrained record variables:)
address@hidden
address@hidden(Example)
+Writer   : Peripheral(Unit  => Printer);
+Archive  : Disk_Unit;
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden to Ada 83}
+In Ada 83, the discriminant of a @nt{variant_part} is not allowed to
+be of a generic formal type.
+This restriction is removed in Ada 95; an @key{others} @nt{discrete_choice}
+is required in this case.
address@hidden
+
address@hidden
+The syntactic category @ntf{choice} is removed.
+The syntax rules for @nt{variant}, @nt{array_aggregate}, and
address@hidden now use @nt{discrete_choice_list}
+or @nt{discrete_choice} instead.
+The syntax rule for @nt{record_aggregate} now defines its own syntax
+for named associations.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+We have added the term Discrete Choice to the title
+since this is where they are talked about.
+This is analogous to the name of the subclause
+"Index Constraints and Discrete Ranges" in
+the @Chg{Version=[3],New=[subclause],Old=[clause]} on Array Types.
+
+The rule requiring that the discriminant denote
+a discriminant of the type being defined seems to have been
+left implicit in RM83.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0158-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  Membership tests are no longer allowed as a @nt{discrete_choice}, in
+  order that those tests can be expanded to allow multiple tests in a
+  single expression without ambiguity. Since a membership test has a
+  boolean type, they are very unlikely to be used as a @nt{discrete_choice}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0153-3]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Subtypes with static predicates can be used in @nt{discrete_choice}s,
+  and the coverage rules are modified to respect the predicates.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0188-1]}
+  @ChgAdded{Version=[3],Text=[Variants in generic specifications are no
+  longer rejected if the subtype
+  of the actual type does not include all of the case choices. This probably
+  isn't useful, but it is consistent with the treatment of 
@nt{case_expression}s.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0290-1]}
+  @ChgAdded{Version=[3],Text=[Added a test that some @nt{variant} covers the
+  value of a discriminant that governs a @nt{variant_part}. This is similar
+  to the test that some case limb covers the value of the
+  @address@hidden of a @nt{case_statement}. This test cannot
+  change the behavior of any nonerroneous Ada 2005 program, so it is not
+  an inconsistency.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0071-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Updated wording of the
+  coverage rules to use the new term "satisfies the predicates"
+  (see @RefSecNum{Subtype Predicates}).]}
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/03c.mss 
b/packages/ada-ref-man/source_2012/03c.mss
new file mode 100755
index 0000000..b7bf735
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/03c.mss
@@ -0,0 +1,6595 @@
address@hidden(03, Root="ada.mss")
+
address@hidden: 2016/02/09 04:55:40 $}
+
address@hidden: e:\\cvsroot/ARM/Source/03c.mss,v $}
address@hidden: 1.136 $}
+
address@hidden Types and Type Extensions}
+
address@hidden
address@hidden@PDefn{dispatching operation}
address@hidden
address@hidden binding],See=(dispatching operation)}
address@hidden unit],See=(dispatching operation)}
address@hidden,See=(tagged type)}
+Tagged types and type extensions support
+object-oriented programming, based on
+inheritance with extension and run-time polymorphism via
address@hidden(dispatching operations).
address@hidden programming (OOP)],See=[tagged types and type extensions]}
address@hidden (object-oriented programming)],See=[tagged types and type 
extensions]}
address@hidden,See=[tagged types and type extension]}]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00251-01]}
+The intended implementation model is for @Chg{Version=[2],New=[the static
+portion of ],Old=[]}a tag to be represented as a
+pointer to a statically allocated and link-time initialized type
+descriptor. The type descriptor contains the address of the code for
+each primitive operation of the type. It probably also contains
+other information, such as might make membership tests convenient and
address@hidden,New=[ Tags for nested type extensions must also have
+a dynamic part that identifies the particular elaboration of the type.],Old=[]}
+
+The primitive operations of a tagged type are known at its first
+freezing point; the type descriptor is laid out at that point.
+It contains linker symbols for each primitive operation; the linker
+fills in the actual addresses.
+
address@hidden,Kind=[Added],ARef=[AI95-00251-01]}
address@hidden,Text=[Primitive operations of type extensions that are
+declared at a level deeper than the level of the ultimate ancestor from which
+they are derived can
+be represented by wrappers that use the dynamic part of the tag to call the
+actual primitive operation. The dynamic part would generally be some way to
+represent the static link or display necessary for making a nested call. One
+implementation strategy would be to store that information in the extension
+part of such nested type extensions, and use the dynamic part of the tag to
+point at it. (That way, the @lquotes@;address@hidden@; part of the tag could
+be static, at the cost of indirect access.)]}
+
address@hidden,Kind=[Added],ARef=[AI95-00251-01]}
address@hidden,Text=[If the tagged type is descended from any interface
+types, it also will need to include @lquotes@;address@hidden@; (one for
+each interface) that describe the mapping of the primitive operations of the
+interface to the primitives of the type. These subtags could directly reference
+the primitive operations (for faster performance), or simply provide the tag
address@hidden@;address@hidden@; numbers for the primitive operations (for 
easier
+derivation). In either case, the subtags would be used for calls that dispatch
+through a class-wide type of the interface.]}
+
+Other implementation models are possible.
+
+The rules ensure that @lquotes@;dangling address@hidden@; is impossible;
+that is, when a dispatching call is made, there is always a body to
+execute. This is different from some other object-oriented
+languages, such as Smalltalk, where it is possible to get a run-time
+error from a missing method.
+
address@hidden,Kind=[Revised],ARef=[AI95-00251-01]}
+Dispatching calls should be efficient, and should have a bounded
+worst-case execution time. This is important in a language intended
+for real-time applications. In the intended implementation model, a
+dispatching call involves calling indirect through the appropriate
+slot in the dispatch table. No complicated "method lookup" is
address@hidden,New=[ although a call which is dispatching on
+an interface may require a lookup of the appropriate interface subtag],Old=[]}.
+
+The programmer should have the choice at each call site of a
+dispatching operation whether to do a dispatching call or a
+statically determined call (i.e. whether the body executed should be
+determined at run time or at compile time).
+
+The same body should be executed for a call where the tag is
+statically determined to be T'Tag as for a dispatching call where the
+tag is found at run time to be T'Tag. This allows one to test a
+given tagged type with statically determined calls, with some
+confidence that run-time dispatching will produce the same behavior.
+
+All views of a type should share the same type descriptor and the
+same tag.
+
+The visibility rules determine what is legal at compile time; they
+have nothing to do with what bodies can be executed at run time.
+Thus, it is possible to dispatch to a subprogram whose declaration is
+not visible at the call site. In fact, this is one of the primary
+facts that gives object-oriented programming its power. The
+subprogram that ends up being dispatched to by a given call might
+even be designed long after the call site has been coded and
+compiled.
+
+Given that Ada has overloading, determining whether a given
+subprogram overrides another is based both on the names and the type
+profiles of the operations.
+
address@hidden,Kind=[Revised],ARef=[AI95-00401-01]}
+When a type extension is declared, if there is any place within its
+immediate scope where a certain subprogram of the parent
address@hidden,New=[or progenitor ],Old=[]}is visible,
+then a matching subprogram should override. If there is no such
+place, then a matching subprogram should be totally unrelated, and
+occupy a different slot in the type descriptor. This is important to
+preserve the privacy of private parts; when an operation declared in
+a private part is inherited, the inherited version can be overridden
+only in that private part, in the package body, and in any children
+of the package.
+
+If an implementation shares code for instances
+of generic bodies, it should be
+allowed to share type descriptors of tagged types
+declared in the generic body, so long as they are not extensions of types
+declared in the specification of the generic unit.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden type}
+A record type or private type that has the reserved word @key(tagged)
+in its declaration is called a @i(tagged) address@hidden,New=[ In
+addition, an interface type is a tagged type, as is a task or protected
+type derived from an interface (see @RefSecNum{Interface Types}).],Old=[]}
address@hidden deriving
+from a tagged type, @Chg{Version=[2],New=[as],Old=[additional components
+may be defined. As]} for any derived type,
+additional primitive subprograms may be defined,
+and inherited primitive subprograms may be overridden.]
address@hidden extension}
address@hidden, Sec=(of a type)}
+The derived type is called an @i(extension)
+of @Chg{Version=[2],New=[its],Old=[the]} ancestor
address@hidden,New=[types],Old=[type]}, or simply a @i(type
+extension)address@hidden,New=[],Old=[ @Defn2{Term=[extension], Sec=(of a 
record type)}
address@hidden extension}
address@hidden, Sec=(of a private type)}
+Every type extension is also a tagged type, and
+is either a @i(record extension) or a @i(private extension) of
+some other tagged type.
+A record extension is defined by a @nt<derived_type_definition>
+with a @nt<record_extension_part>.
+A private extension, which is a partial view of a record extension,
+can be declared in the visible part of a package
+(see @RefSecNum(Private Types and Private Extensions))
+or in a generic formal part
+(see @RefSecNum(Formal Private and Derived Types)).]}
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01]}
address@hidden,address@hidden, Sec=(of a record type)}
address@hidden extension}
address@hidden, Sec=(of a private type)}
+Every type extension is also a tagged type, and
+is a @i(record extension) or a @i(private extension) of some other
+tagged type, or a noninterface synchronized tagged type (see
address@hidden Types}).
+A record extension is defined by a @nt<derived_type_definition>
+with a @nt<record_extension_part> (see @RefSecNum{Type Extensions})@Redundant[,
+which may include the definition of additional components].
+A private extension, which is a partial view of a record extension or
+of a synchronized tagged type,
+can be declared in the visible part of a package
+(see @RefSecNum(Private Types and Private Extensions))
+or in a generic formal part
+(see @RefSecNum(Formal Private and Derived Types)).]}
address@hidden<Tagged type>,
+  Text=<The objects of a tagged type have a run-time type tag,
+  which indicates the specific type with which the object was originally
+  created.
+  An operand of a class-wide tagged type
+  can be used in a dispatching call;
+  the tag indicates which subprogram body to invoke.
+  Nondispatching calls, in which the subprogram body to invoke
+  is determined at compile time, are also allowed.
+  Tagged types may be extended with additional components.>}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00218-03]}
+If a tagged type is declared other than in a @nt{package_specification},
+it is impossible to add new primitive subprograms for that type,
+although it can inherit primitive subprograms,
+and those can be overridden.
+If the user incorrectly thinks a certain subprogram is primitive when it
+is not, and tries to call it with a dispatching call, an error message
+will be given at the call address@hidden,New=[ Similarly, by using
+an @nt{overriding_indicator} (see @RefSecNum{Subprogram Declarations}),
+the user can declare that a subprogram is intended to be overriding, and
+get an error message when they made a mistake. The use of
address@hidden is highly recommended in new code that does not
+need to be compatible with Ada 95.],Old=[]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00344-01]}
address@hidden,Text=[Note that the accessibility rules imply that a
+tagged type declared in a library @nt{package_specification} cannot be
+extended in a nested subprogram or task body.]}
address@hidden
+
address@hidden of an object}
+An object of a tagged type has an associated (run-time)
address@hidden(tag) that identifies the specific tagged type used to create
+the object originally.
address@hidden
+The tag of an operand of a class-wide tagged type @i(T)'Class
+controls which subprogram body is to be executed when a
+primitive subprogram of type @i(T) is applied to
+the operand
+(see @RefSecNum(Dispatching Operations of Tagged Types));
address@hidden
+using a tag to control which body to execute is called @i(dispatching).]
address@hidden tag],See=[tag]}
address@hidden type],See=[tag]}
address@hidden,See=[tag]}
address@hidden,See=[tag]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00344-01]}
+The tag of a specific tagged type identifies
+the @nt<full_type_declaration> of the address@hidden,New=[, and
+for a type extension, is sufficient to uniquely identify the type among
+all descendants of the same ancestor],Old=[]}.
+If a declaration for a tagged type occurs within a
address@hidden,
+then the corresponding type declarations in distinct
+instances of the generic package are associated with distinct tags.
+For a tagged type that is local to a generic package address@hidden,
+New=[ and with all of its ancestors (if any) also local to the
+generic body],Old=[]},
+the language does not specify whether repeated instantiations
+of the generic body result in distinct address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Deleted],ARef=[AI95-00344-01]}
+  @ChgDeleted{Version=[2],Text=[This eases generic code sharing.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00344-01]}
+  @ChgAdded{Version=[2],Text=[In most cases, a tag need only identify a 
particular
+    tagged type declaration, and can therefore be a simple link-time-known
+    address. However, for tag checks
+    (see @RefSecNum{Dispatching Operations of Tagged Types}) it is essential
+    that each descendant (that currently exists) of a given type have
+    a unique tag. Hence, for types declared in shared generic bodies
+    where an ancestor comes from outside the generic, or for types
+    declared at a deeper level than an ancestor, the tag needs to be
+    augmented with some kind of dynamic descriptor (which may be a
+    static link, global display, instance descriptor pointer, or combination).
+    This implies that type Tag may need to be two words, the second of which
+    is normally null, but in these identified special cases needs to
+    include a static link or equivalent. Within an object of one of
+    these types with a two-word tag, the two parts of the tag would
+    typically be separated, one part as the first word of the object,
+    the second placed in the first extension part that corresponds to a
+    type declared more nested than its parent or declared in a shared
+    generic body when the parent is declared outside. Alternatively,
+    by using an extra level of indirection, the type Tag could remain
+    a single-word.]}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00344-01]}
+  @Chg{Version=[2],New=[For types that are not type extensions (even
+    for ones declared in nested scopes), we do not require that],
+    Old=[The language does not specify whether]}
+    repeated elaborations of the same @nt<full_type_declaration>
+    correspond to distinct tags. @Chg{Version=[2],New=[This was done so that
+    Ada 2005 implementations of tagged types could maintain representation
+    compatibility with Ada 95 implementations. Only type extensions that were
+    not allowed in Ada 95 require additional information with the tag.],
+    Old=[In most cases, we
+    expect that all elaborations will correspond to the same tag,
+    since the tag will frequently be the address (or index) of a statically
+    allocated type descriptor. However, with shared
+    generics, the type descriptor might have to be allocated on a per-instance
+    basis, which in some implementation models implies per-elaboration of the
+    instantiation.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00344-01]}
+  @ChgAdded{Version=[2],Text=[The wording @lquotes@;is sufficient to uniquely
+  identify the type among all descendants of the same address@hidden@; only
+  applies to types that currently exist. It is not necessary to distinguish
+  between descendants that currently exist, and descendants of the same type
+  that no longer exist.
+  For instance, the address of the stack frame of the subprogram that created
+  the tag is sufficient to meet the requirements of this rule, even though
+  it is possible, after the subprogram returns, that a later call of the
+  subprogram could have the same stack frame and thus have an identical tag.]}
address@hidden
+
address@hidden@keepnext@;The following language-defined library package exists:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00362-01]}
address@hidden,address@hidden Ada.Tags @key[is]
+    @Chg{Version=[2],address@hidden Preelaborate(Tags);
+    ],address@hidden @AdaTypeDefn{Tag} @key[is] 
@key[private];@Chg{Version=[2],New=[
+    @key[pragma] Preelaborable_Initialization(Tag);],Old=[]}
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,Text=[    @AdaObjDefn{No_Tag} : @key[constant] Tag;]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00400-01]}
+    @key[function] @AdaSubDefn{Expanded_Name}(T : Tag) @key[return] 
String;@Chg{Version=[2],New=[
+    @key[function] @AdaSubDefn{Wide_Expanded_Name}(T : Tag) @key[return] 
Wide_String;
+    @key[function] @AdaSubDefn{Wide_Wide_Expanded_Name}(T : Tag) @key[return] 
Wide_Wide_String;],Old=[]}
+    @key[function] @AdaSubDefn{External_Tag}(T : Tag) @key[return] String;
+    @key[function] @AdaSubDefn{Internal_Tag}(External : String) @key[return] 
Tag;
+
address@hidden,Kind=[Added],ARef=[AI95-00344-01]}
address@hidden,Text=[    @key[function] @AdaSubDefn{Descendant_Tag}(External : 
String; Ancestor : Tag) @key[return] Tag;
+    @key[function] @AdaSubDefn{Is_Descendant_At_Same_Level}(Descendant, 
Ancestor : Tag)
+        @key[return] Boolean;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,Text=[    @key[function] @AdaSubDefn{Parent_Tag} (T : Tag) 
@key[return] Tag;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00405-01]}
address@hidden,Text=[    @key[type] @AdaTypeDefn{Tag_Array} @key[is array] 
(Positive @key[range] <>) @key[of] Tag;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00405-01]}
address@hidden,Text=[    @key[function] @AdaSubDefn{Interface_Ancestor_Tags} (T 
: Tag) @key[return] Tag_Array;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0173-1]}
address@hidden,Text=[    @key[function] @AdaSubDefn{Is_Abstract} (T : Tag) 
@key[return] Boolean;]}
+
+    @AdaExcDefn{Tag_Error} : @key[exception];
+
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden Ada.Tags;
address@hidden
address@hidden
+Tag is a nonlimited, definite subtype,
+because it needs the equality operators,
+so that tag checking makes sense.
+Also, equality, assignment, and object declaration
+are all useful capabilities for this subtype.
+
+For an object X and a type T,
address@hidden@;X'Tag = T'address@hidden@; is not needed,
+because a membership test can be used.
+However, comparing the tags of two objects
+cannot be done via membership.
+This is one reason to allow equality for type Tag.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,Text=[No_Tag is the default initial value of type Tag.]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00260-02]}
address@hidden,Text=[This is similar to the requirement that all
+access values be initialized to @key[null].]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00400-01]}
+The function @Chg{Version=[2],address@hidden@address@hidden,
address@hidden returns the full expanded name of the
+first subtype of the specific type identified by the tag,
+in upper case, starting with a root library unit.
+The result is implementation defined if the type is declared within
+an unnamed @nt{block_statement}.
address@hidden
+  This name, as well as each @nt{prefix} of it,
+  does not denote a @nt{renaming_declaration}.
address@hidden
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[The result of @Chg{Version=[2],
address@hidden@address@hidden,address@hidden for types
+declared within an unnamed @nt{block_statement}.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00400-01]}
address@hidden,Text=[The function Expanded_Name (respectively,
+Wide_Expanded_Name) returns the same sequence of graphic characters as that
+defined for Wide_Wide_Expanded_Name, if all the graphic characters are defined
+in Character (respectively, Wide_Character); otherwise, the sequence of
+characters is implementation defined, but no shorter than that returned by
+Wide_Wide_Expanded_Name for the same value of the argument.]}
address@hidden,Kind=[AddedNormal],address@hidden,New=[
+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).],Old=[]}]}
+
+The function External_Tag returns a string to be used in an
+external representation for the given tag. The call External_Tag(S'Tag)
+is equivalent to the @nt<attribute_reference> S'External_Tag
+(see @RefSecNum{Operational and Representation Attributes}).
address@hidden
+It might seem redundant to provide both the function External_Tag and
+the attribute External_Tag.
+The function is needed because the attribute can't be applied to
+values of type Tag.
+The attribute is needed so that it can be @Chg{Version=[2],
+New=[specified],Old=[specifiable]}
+via an @nt{attribute_definition_clause}.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00417-01]}
address@hidden,Text=[The string returned by the functions Expanded_Name,
address@hidden@!Name, address@hidden@!Name, and External_Tag has lower bound
+1.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00279-01]}
+The function Internal_Tag returns @Chg{Version=[2],New=[a],Old=[the]} tag that
+corresponds to the given external tag, or raises Tag_Error if the given string
+is not the external tag for any specific
+type of the address@hidden,New=[ Tag_Error is also raised
+if the specific type identified is a library-level type whose tag
+has not yet been created (see @RefSecNum{Freezing Rules}).],Old=[]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00279-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[The check for uncreated library-level types
+  prevents a reference to the type before execution reaches the freezing point
+  of the type. This is important so that T'Class'Input or an instance of
+  Tags.Generic_Dispatching_Constructor do not try to create an object of a type
+  that hasn't been frozen (which @Chg{Version=[3],New=[might],Old=[may]}
+  not have yet elaborated its constraints).
+  We don't require this behavior for non-library-level types as the tag can
+  be created multiple times and possibly multiple copies can exist at the
+  same time, making the check complex.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00344-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0113-1]}
address@hidden,Text=[The function Descendant_Tag returns the (internal)
+tag for the type that corresponds to the given external tag and is both a
+descendant of the type identified by the Ancestor tag and has the same
+accessibility level as the identified ancestor. Tag_Error is raised if External
+is not the external tag for such a type. Tag_Error is also raised if the
+specific type identified is a library-level type whose tag has not yet been
address@hidden,New=[, or if the given external tag identifies more than
+one type that has the appropriate Ancestor and accessibility level],Old=[]}.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Descendant_Tag is used by T'Class'Input to
+    identify the type identified by an external tag. Because there can be
+    multiple elaborations of a given type declaration, Internal_Tag does not
+    have enough information to choose a unique such type. Descendant_Tag does
+    not return the tag for types declared at deeper accessibility levels than
+    the ancestor because there could be ambiguity in the presence of
+    recursion or multiple tasks. Descendant_Tag can
+    be used in constructing a user-defined replacement for T'Class'Input.]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0113-1]}
+  @ChgAdded{Version=[3],Text=[Rules for specifying external tags will usually
+  prevent an external tag from identifying more than one type. However, an
+  external tag can identify multiple types if a generic body contains a
+  derivation of a tagged type declared outside of the generic, and there are
+  multiple instances at the same accessibility level as the type. (The Standard
+  allows default external tags to not be unique in this case.)]}
+  @end{Reason}
+
address@hidden,Kind=[Added],ARef=[AI95-00344-01]}
address@hidden,Text=[The function Is_Descendant_At_Same_Level returns
+True if the Descendant tag identifies a type that is both a descendant of the
+type identified by Ancestor and at the same accessibility level. If not, it
+returns False.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Is_Descendant_At_Same_Level (or something similar
+    to it) is used by T'Class'Output to determine whether the item being
+    written is at the same accessibility level as T. It may be used to
+    determine prior to using T'Class'Output whether Tag_Error will be raised,
+    and also can be used in constructing a user-defined replacement
+    for T'Class'Output.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0115-1]}
address@hidden,Text=[For the purposes of the dynamic semantics of
+functions Descendant_Tag and Is_Descendant_At_Same_Level, a tagged type T2
+is a @i<descendant> of
+a type T1 if it is the same as T1, or if its parent type or one of its
+progenitor types is a descendant of type T1 by this address@hidden,
+even if at the point of the declaration of T2, one of the derivations
+in the chain is not address@hidden,Sec=[at run-time]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[In other contexts, @ldquote@;address@hidden
+  is dependent on visibility, and the particular view a derived type has of
+  its parent type. See @RefSecNum{Private Operations}.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,address@hidden number changed}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0056-1]}
address@hidden,Text=[The function Parent_Tag returns the tag of the
+parent type of the type whose tag is T. If the type does not have a parent type
+(that is, it was not @Chg{Version=[4],New=[defined],Old=[declared]} by a
address@hidden,address@hidden,Old=[derived_type_declaration]}),
+then No_Tag is returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0005-1]}
address@hidden,Text=[The parent type is always the parent of the full
+type; a private extension appears to define a parent type, but it does not
+(only the various forms of derivation do that). As this is a run-time
+operation, ignoring @Chg{Version=[4],New=[privacy],Old=[privateness]} is OK.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00405-01]}
address@hidden,address@hidden number changed}
address@hidden,Text=[The function Interface_Ancestor_Tags returns an
+array containing the tag of each interface ancestor type of the type whose tag
+is T, other than T itself. The lower bound of the returned array is 1, and the
+order of the returned tags is unspecified. Each tag appears in the result
+exactly address@hidden If the type whose tag is T has no interface ancestors,
+a null array is address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The result of Interface_Ancestor_Tags includes the
+tag of the parent type, if the parent is an interface.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Indirect interface ancestors are included in the
+result of Interface_Ancestor_Tags. That's because where an interface appears
+in the derivation tree has no effect on the semantics of the type; the only
+interesting property is whether the type has an interface as an ancestor.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0173-1]}
address@hidden,Text=[The function Is_Abstract returns True if the type
+whose tag is T is abstract, and False otherwise.]}
+
+For @PrefixType{every subtype S of a tagged type @i(T)
+(specific or class-wide)}, the following attributes are
+defined:
address@hidden(description)
address@hidden<S>, AttrName=<Class>,
+  Text=[S'Class
+  denotes a subtype of the class-wide type
+  (called @i(T)'Class in this International Standard) for the class
+  rooted at @i(T) (or if S already denotes a class-wide subtype,
+  then S'Class is the same as S).
+
+  @address@hidden, Sec=(subtype)}
+  @Defn2{Term=[constrained], Sec=(subtype)}
+  S'Class is unconstrained. However,
+  if S is constrained, then the values of S'Class are only those
+  that when converted to the type @i(T) belong to S.]}
+  @begin{Ramification}
+    This attribute is defined for both specific
+    and class-wide subtypes. The definition is such
+    that S'Class'Class is the same as S'Class.
+
+    Note that if S is constrained, S'Class is only partially constrained,
+    since there might be additional discriminants
+    added in descendants of @i(T) which are not constrained.
+  @end{Ramification}
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00326-01]}
+    The Class attribute is not defined for untagged subtypes
+    (except for incomplete types and private types
+    whose full view is tagged
+    @em see @Chg{Version=[2],address@hidden Class Attribute of Untagged 
Incomplete Types}],
+    address@hidden Type Declarations}]} and
+    @RefSecNum{Private Operations})
+    so as to preclude implicit conversion in the absence of run-time
+    type information. If it were defined for untagged subtypes, it would
+    correspond to the concept of universal types provided for the predefined
+    numeric classes.
+  @end{Reason}
+
address@hidden<S>, AttrName=<Tag>,
+  Text=[S'Tag denotes the tag of
+  the type @i(T) (or if @i(T) is class-wide, the tag of the root type of the
+  corresponding class).
+  The value of this attribute is of type Tag.]}
+  @begin{Reason}
+S'Class'Tag equals S'Tag, to avoid generic
+    contract model problems when S'Class is the actual
+    type associated with a generic formal derived address@hidden
address@hidden(description)
address@hidden
+
+Given @PrefixType{a @nt<prefix> X that is of a class-wide
+tagged type @Redundant[(after any implicit dereference)]},
+the following attribute is defined:
address@hidden(description)
address@hidden<X>, AttrName=<Tag>,
+  Text=[X'Tag denotes the tag of X.
+  The value of this attribute is of type Tag.]}
+  @begin(Reason)
+    X'Tag is not defined if X is of a specific type.
+    This is primarily to avoid confusion that might result
+    about whether the Tag attribute should reflect the tag of
+    the type of X, or the tag of X. No such
+    confusion is possible if X is of a class-wide type.
+  @end(Reason)
address@hidden(description)
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02],ARef=[AI95-00441-01]}
address@hidden,Type=[Leading],Text=[The following language-defined
+generic function exists:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0229-1]}
address@hidden,address@hidden,address@hidden@address@hidden
+    @key{type} T (<>) @key{is abstract tagged limited private};
+    @key{type} Parameters (<>) @key{is limited private};
+    @key{with function} Constructor (Params : @key{not null access} Parameters)
+        @key{return} T @key{is abstract};
address@hidden Ada.Tags.Generic_Dispatching_Constructor
+   (The_Tag : Tag;
+    Params  : @key{not null access} Parameters) @key{return} 
T'address@hidden,New=[
+   @key{with} Convention => Intrinsic],Old=[]};
address@hidden 
Preelaborate(Generic_Dispatching_Constructor);@Chg{Version=[3],New=[],Old=[
address@hidden Convention(Intrinsic, Generic_Dispatching_Constructor);]}]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,Text=[Tags.Generic_Dispatching_Constructor provides
+a mechanism to create an object of an appropriate type from just a tag value.
+The function Constructor is expected to create the object given a reference to
+an object of type Parameters.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This specification is designed to make it easy to
+create dispatching constructors for streams; in particular, this can be used to
+construct overridings for T'Class'Input.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0005-1]}
address@hidden,Text=[Note that @Chg{Version=[5],New=[almost ],Old=[]}any
+tagged type @Chg{Version=[5],New=[can be used in an instance of
+Generic_Dispatching_Constructor. Using a tagged incomplete view or a tagged
+partial view before the completion of the type in such an instance would be
+illegal; all other tagged types can be used in an instance of
+Generic_Dispatching_Constructor],Old=[will match T (see
address@hidden Private and Derived Types})]}.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden@keepnext@;The tag associated with an object of a tagged type is
+determined as follows:
address@hidden(Itemize)
address@hidden of an object], Sec=(stand-alone object, component, or 
@nt<aggregate>)}
+The tag of a stand-alone object, a component, or an
address@hidden<aggregate> of a specific tagged type @i(T)
+identifies @i(T).
address@hidden
+  The tag of a formal parameter of type @i(T)
+  is not necessarily the tag of @i(T), if, for example, the actual was a
+  type conversion.
address@hidden
+
address@hidden of an object], Sec=(object created by an @nt<allocator>)}
+The tag of an object created by an allocator for an
+access type with a specific designated tagged type @i(T),
+identifies @i(T).
address@hidden
+The tag of an object designated by a
+  value of such an access type might not be @i(T), if, for
+  example, the access value is the result of a type address@hidden
+
address@hidden of an object], Sec=(class-wide object)}
+The tag of an object of a class-wide tagged type
+is that of its initialization expression.
address@hidden
+  The tag of an object (even a class-wide one)
+  cannot be changed after it is initialized, since a @lquotes@;address@hidden@;
+  @nt{assignment_statement} raises Constraint_Error if the tags don't
+  match, and a @lquotes@;address@hidden@; @nt{assignment_statement} does not 
affect
+  the tag.
address@hidden
+
address@hidden of an object], Sec=(returned by a function)}
+The tag of the result returned by a function whose
+result type is a specific tagged type @i(T) identifies @i(T).
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00318-02]}
+  @Chg{Version=[2],New=[For a limited tagged type, the return object is
+  @lquotes@;built in address@hidden in the ultimate result object with the
+  appropriate tag.], Old=[This requires
+  a run-time check for limited tagged types, since they are
+  returned "by-reference."]}
+  For a nonlimited
+  type, a new anonymous object with the appropriate tag
+  is created as part of the function
+  address@hidden,New=[],Old=[, and then assigned the value of the
+  return expression]}.
+  See @RefSec{Return Statements}.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden of an object], Sec=(returned by a function)}
+The tag of the result returned by a
+function with a class-wide result
+type is that of the return @Chg{Version=[2],New=[object],Old=[expression]}.
address@hidden(Itemize)
+
address@hidden of an object], Sec=(preserved by type conversion and parameter 
passing)}
+The tag is preserved by type conversion and by parameter passing.
+The tag of a value is the tag of the associated object
+(see @RefSecNum{Formal Parameter Modes}).
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02],ARef=[AI95-00344-01],ARef=[AI95-00405-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0092-1],ARef=[AI05-0262-1]}
address@hidden,Text=[Tag_Error is raised by a call of Descendant_Tag,
+Expanded_Name, External_Tag, @Chg{Version=[3],address@hidden@!Tags],
+Old=[Interface_Ancestor_Tag]},@Chg{Version=[3],New=[
+Is_Abstract,],Old=[]}
address@hidden,
address@hidden,New=[],Old=[or address@hidden,New=[,
+Wide_Expanded_Name, or Wide_Wide_Expanded_Name],Old=[]} if any
+tag passed is No_Tag.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,Text=[An instance of Tags.Generic_Dispatching_Constructor
+raises Tag_Error if The_Tag does not represent a concrete descendant of T or
+if the innermost master (see @RefSecNum{Completion and Finalization}) of this
+descendant is not also a master of the instance.
+Otherwise, it dispatches to the primitive function denoted by the formal
+Constructor for the type identified by The_Tag, passing Params, and
+returns the result. Any exception raised by the function is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The tag check checks both that The_Tag is in
+T'Class, and that it is not abstract. These checks are similar to the ones
+required by streams for T'Class'Input
+(see @RefSecNum{Stream-Oriented Attributes}). In addition, there is a
+check that the tag identifies a type declared on the current dynamic
+call chain, and not a more nested type or a type declared by another
+task. This check is not necessary for streams, because the stream attributes
+are declared at the same dynamic level as the type used.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,address@hidden(erroneous execution),Sec=(cause)}
+If an internal tag provided to an instance of
+Tags.Generic_Dispatching_Constructor or to any subprogram declared in
+package Tags identifies either a type that is not
+library-level and whose tag has not been created
+(see @RefSecNum{Freezing Rules}), or a type that does not exist in the
+partition at the time of the call, then execution is erroneous.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[One reason that a type might not exist in
+the partition is that the tag refers to a type whose declaration was
+elaborated as part of an execution of a @nt{subprogram_body} which has been
+left (see @RefSecNum{Completion and Finalization}).]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[We exclude tags of library-level types from
+the current execution of the partition, because misuse of such tags
+should always be detected. T'Tag freezes the type (and thus creates the tag),
+and Internal_Tag and Descendant_Tag
+cannot return the tag of a library-level type that has not been created.
+All ancestors of a tagged type must be frozen no later than the (full)
+declaration of a type that uses them, so Parent_Tag and Interface_Ancestor_Tags
+cannot return a tag that has not been created.
+Finally, library-level types never cease to exist while the partition is
+executing. Thus, if the tag comes from
+a library-level type, there cannot be erroneous execution (the use of
+Descendant_Tag rather than Internal_Tag can help ensure that the tag is
+of a library-level type). This is also similar to the rules for T'Class'Input
+(see @RefSecNum{Stream-Oriented Attributes}).]}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00344-01]}
address@hidden,Text=[Ada 95 allowed Tag_Error in this case, or expected
+the functions to work. This worked because most implementations used tags
+constructed at link-time, and each elaboration of the same 
@nt{type_declaration}
+produced the same tag. However, Ada 2005 requires at least part of the tags
+to be dynamically constructed for a type derived from a type at a shallower
+level. For dynamically constructed tags, detecting the error can be expensive
+and unreliable. To see
+this, consider a program containing two tasks. Task A creates a nested tagged
+type, passes the tag to task B (which saves it), and then terminates. The
+nested tag (if dynamic) probably will need to refer in some way to the stack
+frame for task A.
+If task B later tries to use the tag created by task A, the tag's reference to
+the stack frame of A probably is a dangling pointer. Avoiding this would
+require some sort of protected tag manager, which would be a bottleneck in a
+program's performance. Moreover, we'd still have a race condition; if task A
+terminated after the tag check, but before the tag was used, we'd still have
+a problem. That means that all of these operations would have to be serialized.
+That could be a significant performance drain, whether or not nested tagged
+types are ever used. Therefore, we allow execution to become erroneous
+as we do for other dangling pointers. If the implementation can detect the
+error, we recommend that Tag_Error be raised.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00260-02],ARef=[AI95-00279-01]}
+The implementation of @Chg{Version=[2],New=[Internal_Tag and Descendant_Tag],
+Old=[the functions in Ada.Tags]}
+may raise Tag_Error if no specific type corresponding to the
address@hidden,New=[string External],Old=[tag]} passed
+as a parameter exists in the partition at the time the function is
address@hidden,New=[, or if there is no such type whose innermost
+master is a master of the point of the function call],Old=[]}.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00260-02],ARef=[AI95-00279-01],ARef=[AI95-00344-01]}
address@hidden,New=[Locking would be required to ensure that the mapping of
+strings to tags never returned tags of types which no longer exist, because
+types can cease to exist (because they belong to another task, as described
+above) during the execution of these operations. Moreover, even if these
+functions did use locking, that would not prevent the type from ceasing to
+exist at the instant that the function returned. Thus, we do not require the
+overhead of locking;],Old=[In most implementations,
+repeated elaborations of the same
address@hidden will all produce the same tag.
+In such an implementation, Tag_Error will be raised in cases where the
+internal or external tag was passed from a different partition.
+However, some implementations might create a new tag value at run time
+for each elaboration of a @nt{type_declaration}.
+In that case, Tag_Error could also be raised if the created type
+no longer exists because the subprogram
+containing it has returned, for example.
+We don't require the latter behavior;]} hence the word
address@hidden@;address@hidden@; in this rule.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0113-1]}
address@hidden,Text=[Internal_Tag should return the tag of
+a address@hidden,New=[, if one exists,],Old=[]} whose
+innermost master is @Chg{Version=[3],New=[a],Old=[the]} master of the point of 
the function call.]}
address@hidden,Kind=[Revised],InitialVersion=[2],
address@hidden,
+New=[Tags.Internal_Tag should return the tag of
+a address@hidden,New=[, if one exists,],Old=[]} whose innermost master
+is @Chg{Version=[3],New=[a],Old=[the]} master of the point of the function 
call.],Old=[]}.]}
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00260-02],ARef=[AI95-00344-01]}
+  @ChgAdded{Version=[2],Text=[It's not helpful if Internal_Tag returns the tag 
of
+  some type in another task when one is available in the task that made the 
call.
+  We don't require this behavior (because it requires the same implementation
+  techniques we decided not to insist on previously), but encourage it.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0113-1]}
+  @ChgAdded{Version=[3],Text=[There is no Advice for the result of Internal_Tag
+  if no such type exists. In most cases, the @ImplPermName can be
+  used to raise Tag_Error, but some other tag can be returned as well.]}
address@hidden
address@hidden
+
address@hidden
+A type declared with the reserved word @key[tagged]
+should normally be declared in a @nt{package_specification},
+so that new primitive subprograms can be declared for it.
+
+Once an object has been created,
+its tag never changes.
+
+Class-wide types are defined to have unknown discriminants
+(see @RefSecNum(Discriminants)). This means that objects of a class-wide
+type have to be explicitly initialized (whether created by
+an @nt<object_declaration> or an @nt<allocator>),
+and that @nt<aggregate>s have to be explicitly qualified with a specific
+type when their expected type is class-wide.
+
address@hidden,Kind=[Revised],ARef=[AI95-00260-02],ARef=[AI95-00326-01]}
address@hidden,New=[The capability provided by
+Tags.Generic_Dispatching_Constructor is sometimes known as a
address@hidden<factory>address@hidden@Defn{class factory}],Old=[If S denotes an
+untagged private type whose full type is tagged,
+then S'Class is also allowed before the full type definition,
+but only in the private part of the package in which the type is
+declared
+(see @RefSecNum(Private Operations)).
+Similarly, the Class attribute is defined
+for incomplete types whose full type is tagged, but only within
+the library unit in which the incomplete type is declared
+(see @RefSecNum(Incomplete Type Declarations)).]}
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of tagged record types:)
address@hidden(Example)
address@hidden(type) Point @key(is tagged)
+  @key(record)
+    X, Y : Real := 0.0;
+  @key(end record);
+
address@hidden(type) Expression @key(is tagged null record);
+  address@hidden Components will be added by each extension]
address@hidden(Example)
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Tagged types are a new concept.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00279-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] Added wording specifying that Internal_Tag
+  must raise Tag_Error if the tag of a library-level type has not yet been
+  created. Ada 95 gave an Implementation Permission to do this; we require
+  it to avoid erroneous execution when streaming in an object of a
+  library-level type that has not yet been elaborated. This is technically
+  inconsistent; a program that used Internal_Tag outside of streaming and
+  used a compiler that didn't take advantage of the Implementation Permission
+  would not have raised Tag_Error, and may have returned a useful tag. (If
+  the tag was used in streaming, the program would have been erroneous.)
+  Since such a program would not have been portable to a compiler that did
+  take advantage of the Implementation Permission, this is not a significant
+  inconsistency.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00417-01]}
+  @ChgAdded{Version=[2],Text=<We now define the lower bound of the string
+  returned from [[Wide_]Wide_]Expanded_Name and External_Name. This makes
+  working with the returned string easier, and is consistent with many other
+  string-returning functions in Ada. This is technically an inconsistency; if a
+  program depended on some other lower bound for the string returned from one
+  of these functions, it could fail when compiled with Ada 2005. Such code is
+  not portable even between Ada 95 implementations, so it should be very
+  rare.>}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00260-02],ARef=[AI95-00344-01],ARef=[AI95-00400-01],ARef=[AI95-00405-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  Constant No_Tag, and functions Parent_Tag, Interface_Ancestor_Tags,
+  Descendant_Tag, Is_Descendant_At_Same_Level, Wide_Expanded_Name,
+  and Wide_Wide_Expanded_Name are @Chg{Version=[3],New=[],Old=[newly ]}added
+  to Ada.Tags.
+  If Ada.Tags is referenced in a @nt{use_clause}, and an entity @i<E> with the
+  same @nt{defining_identifier} as a new entity in Ada.Tags is defined in a
+  package that is also referenced in a @nt{use_clause}, the entity @i<E> may no
+  longer be use-visible, resulting in errors. This should be rare and is easily
+  fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00362-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Ada.Tags is now defined to be preelaborated.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00260-02]}
+  @ChgAdded{Version=[2],Text=[Generic function
+    Tags.Generic_Dispatching_Constructor is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],Text=[We talk about return objects rather than
+  return expressions, as functions can return using an
+  @nt{extended_return_statement}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00344-01]}
+  @ChgAdded{Version=[2],Text=[Added wording to define that tags for all
+  descendants of a tagged type must be distinct. This is needed to ensure
+  that more nested type extensions will work properly. The wording does not
+  require implementation changes for types that were allowed in Ada 95.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0113-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  @b[Correction:] Added wording specifying that Dependent_Tag
+  must raise Tag_Error if there is more than one type which matches the
+  requirements. If an implementation had returned a random tag of the matching
+  types, a program may have worked properly. However, such a program would
+  not be portable (another implementation may return a different tag) and the
+  conditions that would cause the problem are unlikely (most likely, a tagged
+  type extension declared in a generic body with multiple instances in the
+  same scope).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0173-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  Function Is_Abstract is added to Ada.Tags.
+  If Ada.Tags is referenced in a @nt{use_clause}, and an entity @i<E> with the
+  @nt{defining_identifier} Is_Abstract is defined in a
+  package that is also referenced in a @nt{use_clause}, the entity @i<E> may no
+  longer be use-visible, resulting in errors. This should be rare and is easily
+  fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0115-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> We explicitly define the 
meaning
+  of "descendant" at runtime, so that it does not depend on visibility
+  as does the usual meaning.]}
address@hidden
+
+
address@hidden Extensions}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden@Defn{type extension}
address@hidden, Sec=(of a type)}
address@hidden extension}
address@hidden, Sec=(of a record type)}
address@hidden extension}
address@hidden, Sec=(of a private type)}
+Every type extension is a tagged type, and
+is @Chg{Version=[2],New=[],Old=[either ]}a @i(record extension) or a
address@hidden(private extension) of
+some other tagged address@hidden,New=[, or a noninterface
+synchronized tagged type],Old=[]}.]
address@hidden
+
address@hidden
+
+We want to make sure that we can extend a generic formal
+tagged type, without knowing its discriminants.
+
+We don't want to allow components in an extension aggregate
+to depend on discriminants inherited from the parent value,
+since such dependence requires staticness in aggregates, at least for
+variants.
address@hidden
+
address@hidden
address@hidden<record_extension_part>,rhs="@key(with) @Syn2{record_definition}"}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00344-01],ARef=[AI95-00345-01],ARef=[AI95-00419-01]}
+The parent type of a record extension shall not be
+a class-wide address@hidden,New=[ nor shall it be a synchronized
+tagged type (see @RefSecNum{Interface Types})],Old=[]}.
+If the parent address@hidden,New=[ or any progenitor],Old=[]} is
+nonlimited, then each of the
+components of the @nt{record_extension_part} shall be
address@hidden,New=[],Old=[
address@hidden rule],Sec=(record extension)}
+The accessibility level
+(see @RefSecNum(Operations of Access Types))
+of a record extension shall not be statically deeper than that of its
+parent type.]}
address@hidden contract issue}
+In addition to the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}),
+these rules apply also in the private part of an
+instance of a generic unit.
address@hidden
+If the parent is a limited formal type,
+then the actual might be nonlimited.
+
address@hidden,Kind=[Revised],ARef=[AI95-00344-01]}
address@hidden,New=[Ada 95 required the record extensions to be the
+same level as the parent type. Now we use accessibility checks on class-wide
address@hidden and return statements to prevent objects from living
+longer than their type.],
+Old=[A similar accessibility rule is not needed for
+private extensions, because in a package, the rule will apply to the
address@hidden,
+and for a generic formal private extension,
+the actual is all that matters.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00345-01]}
address@hidden,Text=[Synchronized tagged types cannot be extended. We
+have this limitation so that all of the data of a task or protected type is
+defined within the type. Data defined outside of the type wouldn't be
+subject to the mutual exclusion properties of a protected type, and couldn't
+be used by a task, and thus doesn't seem to be worth the potential impact
+on implementations.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00344-01]}
address@hidden,New=[Within the body of a generic unit, or the body of any of
+its descendant library units, a tagged type],Old=[A type extension]}
+shall not be declared
address@hidden,New=[as a descendant of a formal type
+declared within the formal part of the generic unit],
+Old=[in a generic body if the parent type is declared outside that body]}.
+
address@hidden
+This paragraph ensures that a dispatching call will never
+attempt to execute an inaccessible subprogram body.
+
address@hidden,Kind=[Added],ARef=[AI95-00344-01]}
address@hidden,Text=[The convoluted wording (@ldquote@;formal type declared
+within the formal address@hidden@;) is necessary to include tagged types that
+are formal parameters of formal packages of the generic unit, as well as
+formal tagged and tagged formal derived types of the generic unit.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00344-01]}
address@hidden rule is only about generic bodies (and always was only
+about generic bodies. So we drop the extra text.}
address@hidden,New=[This rule],Old=[The part about generic bodies]} is
+necessary in order to preserve the contract model.
+
address@hidden@;@ChgRef{Version=[2],Kind=[Revised],ARef=[AI05-0005-1]}
address@hidden,Kind=[Revised],ARef=[AI95-00344-01]}
address@hidden,New=[If an ancestor],Old=[Since a generic unit can be 
instantiated at a
+deeper accessibility level than the generic unit, it is necessary to prevent
+type extensions whose parent is declared outside the generic unit.
+The same is true if the parent]} is a formal of the generic unit
address@hidden,New=[, we have a problem],Old=[.
+If the parent is declared in the @nt{generic_declaration}
+(but is not a formal), we don't run afoul of the accessibility rules,
+because we know that the instance declaration and body will be at the
+same accessibility level.
+However, we still have a problem in that case,]} because
+it might have an unknown number address@hidden,New=[],Old=[ abstract]}
address@hidden,New=[ that require overriding],Old=[]},
+as in the following example:
address@hidden
address@hidden,Kind=[Revised]}
address@hidden P @key[is]
+    @key[type] T @key[is] @key[tagged] @key[null] @key[record];
+    @key[function] F @key[return] T; address@hidden Inherited versions will 
@Chg{Version=[2],New=[require overriding],Old=[be abstract]}.}
address@hidden P;
+
address@hidden
+    @key[type] TT @key[is] @key[tagged] @key[private];
address@hidden Gp @key[is]
+    @key[type] NT @key[is] @key[abstract new] TT @key[with] @key[null] 
@key[record];
+    @key[procedure] Q(X : @key[in] NT) @key[is abstract];
address@hidden Gp;
+
address@hidden,Kind=[Revised]}
address@hidden @key[body] Gp @key[is]
+    @key[type] NT2 @key[is] @key[new] NT @key[with] @key[null] @key[record]; 
address@hidden Illegal!}
+    @key[procedure] Q(X : @key[in] NT2) @key[is] @key[begin] @key[null]; 
@key[end] Q;
+    address@hidden Is this legal or not? Can't decide because}
+    address@hidden we don't know whether TT had any functions that 
@Chg{Version=[2],New=[require],Old=[go abstract]}}
+    address@hidden @Chg{Version=[2],New=[overriding ],Old=[]}on extension.}
address@hidden Gp;
+
address@hidden I @key[is] @key[new] Gp(TT => P.T);
address@hidden
+
address@hidden,Kind=[Revised]}
+I.NT is an abstract type with two abstract subprograms:
+F (inherited as abstract) and Q (explicitly declared as abstract).
+But the generic body doesn't know about F,
+so we don't know that it needs to be overridden to make a nonabstract
+extension of address@hidden,New=[],Old=[
+Furthermore, a formal tagged limited private type can be extended with
+limited components,
+but the actual might not be limited,
+which would allow assignment of limited types,
+which is bad.]} Hence, we have to disallow this
address@hidden,New=[],Old=[ as well]}.
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Similarly, since the actual type for a
+formal tagged limited private type can be a nonlimited type, we would have
+a problem if a type extension of a limited private formal type could be
+declared in a generic body. Such an
+extension could have a task component, for example, and an object of that
+type could be passed to a dispatching operation of a nonlimited ancestor
+type. That operation could try to copy the object with the task component.
+That would be bad. So we disallow this as well.]}
+
+If TT were declared as abstract, then we could have the same
+problem with abstract procedures.
+
+We considered disallowing all tagged types in a generic body,
+for simplicity.
+We decided not to go that far,
+in order to avoid unnecessary restrictions.
+
address@hidden rule],Sec=(not part of generic contract)}
+We also considered trying make the accessibility level part of the
+contract; i.e. invent some way of saying (in the
address@hidden) @lquotes@;all instances of this generic unit will
+have the same accessibility level as the
address@hidden@rquotes@;
+Unfortunately, that doesn't solve the part of the problem having to do
+with abstract types.
+
address@hidden,Kind=[Deleted]}
address@hidden,Text=[Children of
+generic units obviate the need for extension in the body somewhat.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00344]}
address@hidden,Text=[This rule applies to types with ancestors (directly
+or indirectly) of formal interface types
+(see @RefSecNum{Formal Interface Types}), formal tagged private types
+(see @RefSecNum{Formal Private and Derived Types}), and
+formal derived private types whose ancestor type is tagged
+(see @RefSecNum{Formal Private and Derived Types}).]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00391-01]}
address@hidden,address@hidden extension}
+A record extension is a @i{null extension} if its declaration
+has no @nt{known_discriminant_part} and its @nt{record_extension_part}
+includes no @nt{component_declaration}s.]}
address@hidden
+
address@hidden
address@hidden, Sec=(record_extension_part)}
+The elaboration of a @nt{record_extension_part} consists
+of the elaboration of the @nt{record_definition}.
address@hidden
+
address@hidden
+The term @lquotes@;type address@hidden@; refers to a type as a whole.
+The term @lquotes@;extension address@hidden@; refers to the piece
+of text that defines the additional components (if any) the
+type extension has relative to its specified ancestor type.
address@hidden(Discussion)
+  We considered other terminology, such as @lquotes@;extended address@hidden@;
+  However, the terms @lquotes@;private extended address@hidden@; and 
@lquotes@;record extended address@hidden@;
+  did not convey the proper meaning. Hence, we have chosen
+  to uniformly use the term @lquotes@;address@hidden@; as the type resulting
+  from extending a type, with @lquotes@;private address@hidden@; being one
+  produced by privately extending the type, and @lquotes@;record 
address@hidden@;
+  being one produced by extending the type with an additional record-like set
+  of components.
+  Note also that the term @lquotes@;type address@hidden@; refers to the result
+  of extending a type in the language Oberon as well (though there
+  the term @lquotes@;extended address@hidden@; is also used, interchangeably, 
perhaps because
+  Oberon doesn't have the concept of a @lquotes@;private address@hidden@;).
address@hidden(Discussion)
+
address@hidden,Kind=[Revised],ARef=[AI95-00344-01]}
address@hidden,New=[],Old=[The accessibility rules imply that a tagged type
+declared in a library @nt{package_specification} can be extended only
+at library level or as a generic formal. ]}When
address@hidden,New=[an],Old=[the]} extension is declared immediately within
+a @Chg{Version=[2],New=[body],address@hidden,
+primitive subprograms are inherited and are overridable,
+but new primitive subprograms cannot be added.
+
+A @nt<name> that denotes a component (including a discriminant) of
+the parent type is not allowed within the
address@hidden
+Similarly, a @nt<name> that denotes a component defined within the
address@hidden is not allowed within
+the @nt{record_extension_part}.
+It is permissible to use a @nt<name>
+that denotes a discriminant of the record extension, providing there is
+a new @nt{known_discriminant_part} in the enclosing type declaration.
+(The full rule is given in @RefSecNum(Record Types).)
address@hidden(Reason)
+  The restriction against depending on
+  discriminants of the parent is to simplify the definition of extension
+  aggregates. The restriction against using parent components in other
+  ways is methodological; it presumably simplifies implementation as
+  well.
address@hidden(Reason)
+
+Each visible component of a record extension has to have a
+unique name, whether the component is (visibly) inherited
+from the parent type or declared in the
address@hidden<record_extension_part> (see @RefSecNum{Visibility}).
address@hidden
+
address@hidden
address@hidden@address@hidden of record extensions (of types defined above in 
@RefSecNum(Tagged Types and Type Extensions)):}
address@hidden(Example)
address@hidden(type) Painted_Point @key(is new) Point @key(with)
+  @key(record)
+    Paint : Color := White;
+  @key(end record);
+    address@hidden Components X and Y are inherited]
+
+Origin : @key(constant) Painted_Point := (X | Y => 0.0, Paint => Black);
+
address@hidden(type) Literal @key(is new) Expression @key(with)
+  @key(record)                 address@hidden a leaf in an Expression tree]
+    Value : Real;
+  @key(end record);
+
address@hidden(type) Expr_Ptr @key(is access all) Expression'Class;
+                               address@hidden see @RefSecNum(Access Types)]
+
address@hidden(type) Binary_Operation @key(is new) Expression @key(with)
+  @key(record)                 address@hidden an internal node in an 
Expression tree]
+    Left, Right : Expr_Ptr;
+  @key(end record);
+
address@hidden(type) Addition @key(is new) Binary_Operation @key(with null 
record);
address@hidden(type) Subtraction @key(is new) Binary_Operation @key(with null 
record);
+  address@hidden No additional components needed for these extensions]
+
+Tree : Expr_Ptr :=         address@hidden A tree representation of 
@lquotes@;5.0 + (address@hidden@;7.0)@rquotes@;]
+   @key(new) Addition'(
+      Left  => @key(new) Literal'(Value => 5.0),
+      Right => @key(new) Subtraction'(
+         Left  => @key(new) Literal'(Value => 13.0),
+         Right => @key(new) Literal'(Value => 7.0)));
address@hidden(Example)
+
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Type extension is a new concept.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00344-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Type extensions now can be
+  declared in more nested scopes than their parent types. Additional
+  accessibility checks on @nt{allocator}s and return statements prevent
+  objects from outliving their type.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00345-01]}
+  @ChgAdded{Version=[2],Text=[Added wording to prevent extending synchronized
+  tagged types.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00391-01]}
+  @ChgAdded{Version=[2],Text=[Defined null extension for use elsewhere.]}
address@hidden
+
+
address@hidden Operations of Tagged Types}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00260-02],ARef=[AI95-00335-01]}
address@hidden operation}
address@hidden call], Sec=(on a dispatching operation)}
address@hidden call], Sec=(on a dispatching operation)}
address@hidden determined tag}
address@hidden determined tag}
address@hidden
address@hidden polymorphism}
address@hidden tag], Sec=(for a call on a dispatching operation)}
+The primitive subprograms of a tagged address@hidden,New=[, the
+subprograms declared by @address@hidden@address@hidden,
+and the stream attributes of a specific tagged type that are available (see
address@hidden Attributes}) at the end of the declaration list
+where the type is declared],Old=[]}
+are called @i(dispatching operations).
address@hidden dispatching operation can be called using a statically
+determined @i{controlling} tag, in which case the body to be
+executed is determined at compile time.
+Alternatively, the controlling tag can be dynamically determined,
+in which case the call @i{dispatches} to a
+body that is determined at run time;]
+such a call is termed a @i{dispatching call}.
address@hidden explained below, the properties of the operands
+and the context of a particular call on a dispatching operation
+determine how the controlling tag is determined,
+and hence whether or not the call is a dispatching call.
+Run-time polymorphism is achieved when a dispatching operation is called
+by a dispatching call.]
address@hidden programming (OOP)],See=[dispatching operations of tagged types]}
address@hidden (object-oriented programming)],See=[dispatching operations of 
tagged types]}
address@hidden,See=[dispatching call]}
address@hidden,See=[dispatching subprogram]}
address@hidden function],See=[dispatching subprogram]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00335-01]}
address@hidden,Text=[For the stream attributes of a type
+declared immediately within a @nt{package_specification} that has a
+partial view, the declaration list to consider is the visible part of the
+package. Stream attributes that are not available in the same declaration
+list are not dispatching as there is no guarantee that descendants of the
+type have available attributes (there is such a guarantee for visibly
+available attributes). If we allowed dispatching for any available
+attribute, then for attributes defined in the private part we could end up
+executing a nonexistent body.]}
address@hidden
+
address@hidden
+
address@hidden
+The controlling tag determination rules are analogous to the
+overload resolution rules, except they deal with run-time
+type identification (tags) rather than compile-time type
+resolution. As with overload resolution, controlling tag determination
+may depend on operands or result context.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00260-02],ARef=[AI95-00416-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0076-1]}
address@hidden on a dispatching operation}
address@hidden operation}
+A @i{call on a dispatching operation} is a call whose @nt<name> or
address@hidden<prefix> denotes the declaration address@hidden,New=[],
+Old=[ a primitive subprogram of a tagged type, that is,]} a dispatching
+operation.
address@hidden operand}
+A @i{controlling operand} in a call on a dispatching operation of a tagged
+type @i(T) is one whose corresponding formal parameter is of type @i(T)
+or is of an anonymous access type with designated type @i(T);
address@hidden formal parameter}
+the corresponding formal parameter is called a
address@hidden(controlling formal parameter).
+If the controlling formal parameter is an access parameter, the
+controlling operand is the object designated by the actual parameter,
+rather than the actual parameter itself.
address@hidden address@hidden,address@hidden,Sec=[with a controlling 
result]}],Old=[]}
+If the call is to a (primitive) function with result type
address@hidden(T)@Chg{Version=[3],New=[ (a @i{function with a controlling 
result})],Old=[]},
+then the call has a @i(controlling result) @em
+the context of the call can control the address@hidden,
+New=[ Similarly, if the call is to a function with
address@hidden,New=[an ],Old=[]}access result type designating
address@hidden(T)@Chg{Version=[3],New=[ (a @i{function with a controlling 
access result})],Old=[]},
+then the call has a @i(controlling access result), and
+the context can similarly control dispatching.],address@hidden,address@hidden 
access address@hidden,Sec=[with a controlling access result]}],Old=[]}
address@hidden
+  This definition implies that a call through the dereference of an
+  access-to-subprogram value is never considered a call on
+  a dispatching operation.
+  Note also that if the @nt{prefix} denotes a @nt{renaming_declaration},
+  the place where the renaming occurs determines whether it is
+  primitive; the thing being renamed is irrelevant.
address@hidden
+
address@hidden@;A @nt<name> or expression of a tagged type
+is either @i(statically) tagged,
address@hidden(dynamically) tagged, or @i(tag indeterminate), according
+to whether, when used as a controlling operand, the tag
+that controls dispatching is determined statically by the operand's
+(specific) type,
+dynamically by its tag at run time,
+or from context.
+A @nt<qualified_expression> or parenthesized expression is
+statically, dynamically, or indeterminately tagged according
+to its operand. For other kinds of @nt<name>s and expressions, this
+is determined as follows:
address@hidden(Itemize)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00416-01]}
+  @Defn{statically tagged}
+  The @nt<name> or expression is @i(statically
+  tagged) if it is of a specific tagged type and,
+  if it is a call with a controlling address@hidden,New=[ or
+  controlling access result],Old=[]}, it has at least
+  one statically tagged controlling operand;
+  @begin{Discussion}
+    It is illegal to have both statically tagged and
+    dynamically tagged controlling operands in the same call -- see below.
+  @end{discussion}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00416-01]}
+  @Defn{dynamically tagged}
+  The @nt<name> or expression is @i(dynamically tagged)
+  if it is of a class-wide type, or it is a call with
+  a controlling address@hidden,New=[ or
+  controlling access result],Old=[]} and at least one dynamically
+  tagged controlling operand;
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00416-01]}
+  @Defn{tag indeterminate}
+  The @nt<name> or expression is @i(tag indeterminate)
+  if it is a call with a controlling address@hidden,New=[ or
+  controlling access result],Old=[]}, all of whose
+  controlling operands (if any) are tag indeterminate.
address@hidden(itemize)
+
address@hidden,Kind=[Revised],Ref=[8652/0010],ARef=[AI95-00127-01]}
address@hidden @nt<type_conversion> is statically or dynamically
+tagged according to whether the type determined by the @nt<subtype_mark>
+is specific or class-wide, respectively.]
address@hidden an object that is designated by an expression whose expected type
+is an anonymous access-to-specific tagged type, the object is dynamically
+tagged if the expression, ignoring enclosing parentheses, is of the form
+X'Access, where X is of a class-wide type, or is of the form
address@hidden(new) T'(...), where T denotes a class-wide subtype. Otherwise, 
the object],
+Old=[For a controlling operand that is designated by an actual parameter,
+the controlling operand]} is statically or dynamically tagged according to
+whether the designated type @Chg{New=[of the type of the expression],
+Old=[of the actual parameter]} is specific or class-wide, respectively.
address@hidden
+  A @nt<type_conversion> is never tag indeterminate, even if its
+  operand is. A designated object is never tag indeterminate.
+
+  @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0010],ARef=[AI95-00127-01]}
+  @ChgAdded{Version=[1],Text=[Allocators and access attributes of class-wide 
types can be used as
+  the controlling parameters of dispatching calls.]}
address@hidden
address@hidden
+
address@hidden
+A call on a dispatching operation shall not
+have both dynamically tagged and statically tagged controlling operands.
address@hidden
+  This restriction is intended to minimize
+  confusion between whether the dynamically tagged operands
+  are implicitly converted to, or tag checked against the
+  specific type of the statically tagged operand(s).
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0010],ARef=[AI95-00127-01]}
+If the expected type for an expression or @nt<name>
+is some specific tagged type, then the expression or @nt<name>
+shall not be dynamically tagged unless it is a controlling operand in a call
+on a dispatching operation.
+Similarly, if the expected type for an expression
+is an anonymous access-to-specific
+tagged type, then the @Chg{New=[object designated by the expression
+shall not be dynamically tagged unless it is],Old=[expression shall not be
+of an access-to-class-wide type unless it designates]} a controlling
+operand in a call on a dispatching operation.
address@hidden(Reason)
+  This prevents implicit "truncation"
+  of a dynamically-tagged value to the specific type of the
+  target object/formal. An explicit conversion is required to request
+  this truncation.
address@hidden(Reason)
address@hidden(Ramification)
+  @ChgRef{Version=[2],Kind=[Revised],address@hidden info about prefix calls}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0039-1]}
+  This rule applies to all expressions
+  or @nt<name>s with a specific expected type, not just those that
+  are actual parameters to a dispatching call. This rule does not apply to
+  a membership test whose
+  
@Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden<expression>]}
+  is class-wide, since any type that covers the tested type is explicitly 
allowed.
+  See @RefSecNum(Relational Operators and Membership Tests)address@hidden,
+  New=[ This rule also doesn't apply to a @nt{selected_component} whose
+  @nt{selector_name} is a subprogram, since the rules explicitly say that
+  the prefix may be class-wide (see @RefSecNum{Selected Components}).],Old=[]}
address@hidden(Ramification)
+
address@hidden,Kind=[Revised],Ref=[8652/0011],ARef=[AI95-00117-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00430-01]}
+In the declaration of a dispatching operation of a tagged type,
+everywhere a subtype of the tagged type appears as a
+subtype of the profile (see @RefSecNum(Subprogram Declarations)),
+it shall statically match the first subtype of the tagged type.
address@hidden matching],Sec=(required)}
+If the dispatching operation overrides an inherited subprogram,
+it shall be subtype conformant with the inherited subprogram.
address@hidden conformance],Sec=(required)}
address@hidden convention of an inherited @Chg{Version=[2],New=[],
+Old=[or overriding ]}dispatching operation is
+the convention of the corresponding primitive operation of the parent
address@hidden,New=[or progenitor ],Old=[]}type. @Chg{Version=[2],New=[The
+default convention of a dispatching operation that overrides an inherited
+primitive operation is the convention of the inherited operation; if the
+operation overrides multiple inherited operations, then they shall all
+have the same convention. ],Old=[]}An
+explicitly declared],Old=[A]} dispatching operation shall not be of convention
address@hidden,Old=[ If a dispatching operation overrides the predefined
+equals operator, then it shall be of convention Ada @Redundant[(either
+explicitly or by default @em see @RefSecNum{Conformance Rules})].]}
address@hidden
+  These rules ensure that constraint checks can be performed by the
+  caller in a dispatching call, and parameter passing conventions
+  match up properly. A special rule on aggregates
+  prevents values of a tagged type from being created that
+  are outside of its first subtype.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00416-01]}
+The @nt<default_expression> for a controlling formal parameter
+of a dispatching operation shall be tag address@hidden@Chg{Version=[2],
+New=[],Old=[ A controlling formal parameter that is an access parameter
+shall not have a @nt<default_expression>.]}
address@hidden(Reason)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00416-01]}
+  @Chg{Version=[2],New=[This rule],Old=[The first part]} ensures
+  that the @nt{default_expression} always produces the "correct"
+  tag when called with or without dispatching,
+  or when inherited by a descendant. If
+  it were statically tagged, the default would be useless for
+  a dispatching call; if it were dynamically tagged, the default
+  would be useless for a nondispatching call.
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00416-01]}
+  @ChgDeleted{Version=[2],Text=[The second part is consistent with the
+  first part, since designated objects are never tag-indeterminate.]}
address@hidden(Reason)
+
address@hidden,Kind=[Added],ARef=[AI95-00404-01]}
address@hidden,Text=[If a dispatching operation is defined by a
address@hidden or the instantiation of a generic
+subprogram, any access parameter of the renamed subprogram or the generic
+subprogram that corresponds to a controlling access parameter of the
+dispatching operation, shall have a subtype that excludes null.]}
+
+A given subprogram shall not be a dispatching operation of two
+or more distinct tagged types.
address@hidden
+  This restriction minimizes
+  confusion since multiple dispatching is not provided. The normal
+  solution is to replace all but one of the tagged types with their
+  class-wide types.
address@hidden
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0098],ARef=[AI95-00183-01]}
+  @ChgAdded{Version=[1],Text=[This restriction applies even if the partial 
view (see
+  @RefSecNum{Private Types and Private Extensions}) of one or both
+  of the types is untagged. This follows from the definition of dispatching
+  operation: the operation is a dispatching operation anywhere the full
+  views of the (tagged) types are visible.]}
address@hidden
+
+The explicit declaration of a primitive subprogram of a
+tagged type shall occur before the type is frozen
+(see @RefSecNum{Freezing Rules}).
address@hidden example, new dispatching operations cannot be added after
+objects or values of the type exist,
+nor after deriving a record extension from it,
+nor after a body.]
+
address@hidden following is a "fix" to keep consistent with v. 5.95;
+appearently 6.0 is different.
address@hidden
+    @ChgRef{Version=[1],Kind=[Deleted]}
+    @ChgDeleted{Version=[1],Text=[Old @b{Change}.]}
address@hidden
address@hidden
address@hidden,Kind=[Revised],address@hidden now have two parts, logically}
+This rule is needed
+because (1) we don't want people dispatching to things that haven't
+been declared yet, and (2) we want to allow @Chg{Version=[2],New=[the static
+part of ],Old=[]}tagged type descriptors
+to be static (allocated statically, and initialized to link-time-known
+symbols). Suppose T2 inherits primitive P from T1, and then
+overrides P. Suppose P is called @i{before} the declaration of the
+overriding P. What should it dispatch to? If the answer is the new
+P, we've violated the first principle above. If the answer is the
+old P, we've violated the second principle. (A call
+to the new one necessarily raises Program_Error, but that's
+beside the point.)
+
+Note that a call upon a dispatching operation of type @i(T) will freeze @i(T).
+
+We considered applying this rule to all derived types,
+for uniformity.
+However, that would be upward incompatible,
+so we rejected the idea.
+As in Ada 83, for an untagged type, the above call upon P will call the
+old P (which is arguably confusing).
address@hidden
address@hidden
address@hidden,Kind=[Revised],address@hidden have tagged incomplete types now, 
and they don't freeze}
+Because of this rule,
+the type descriptor can be created (presumably containing linker
+symbols pointing at the not-yet-compiled bodies) at the first
+freezing point of the type.
+It also prevents, for a @Chg{Version=[2],New=[(nonincomplete) ],Old=[]}tagged
+type declared in a
address@hidden, overriding in the body or by a child subprogram.
address@hidden
address@hidden
address@hidden,Kind=[Revised],address@hidden cause this too}
+A consequence is that for a @Chg{Version=[2],New=[tagged type declaration],
address@hidden in a
address@hidden, only the @Chg{Version=[2],New=[last (overriding)],Old=[first]}
+primitive subprogram can be
+declared by a @address@hidden,New=[ (Other overridings
+must be provided by @nt{subprogram_declaration}s.)],Old=[]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0222-1]}
+  @ChgAdded{Version=[3],Text=[This rule applies only to "original" declarations
+  and not to the completion of a primitive subprogram, even though a completion
+  is technically an explicit declaration, and it may declare a primitive
+  subprogram.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden@PDefn2{Term=[execution], Sec=(call on a dispatching operation)}
address@hidden tag value}
+For the execution of a call on a dispatching operation of a type @i(T),
+the @i(controlling tag value) determines
+which subprogram body is executed.
+The controlling tag value is defined as follows:
address@hidden(itemize)
+  @PDefn{statically determined tag}
+  If one or more controlling operands are statically tagged, then
+  the controlling tag value is @i(statically determined) to be the tag
+  of @i(T).
+
+  If one or more controlling operands are dynamically tagged, then
+  the controlling tag value is not statically determined, but is
+  rather determined by
+  the tags of the controlling operands.
+  @IndexCheck{Tag_Check}
+  If there is more than one dynamically tagged controlling operand,
+  a check is made that they all have the same tag.
+  @Defn2{Term=(Constraint_Error),Sec=(raised by failure of run-time check)}
+  If this check fails, Constraint_Error is raised
+  unless the call is a @nt<function_call> whose @nt<name> denotes
+  the declaration of an equality operator (predefined or user defined) that
+  returns Boolean,
+  in which case the result of the call is defined to indicate
+  inequality, and no @nt<subprogram_body> is executed.
+  This check is performed prior to evaluating any tag-indeterminate
+  controlling operands.
+  @begin(Reason)
+    Tag mismatch is considered an error (except for "=" and "/=")
+    since the corresponding primitive
+    subprograms in each specific type expect all controlling
+    operands to be of the same type.
+    For tag mismatch with an equality operator, rather than raising
+    an exception, "=" returns False and "/=" returns True.
+    No equality operator is actually invoked, since there
+    is no common tag value to control the dispatch.
+    Equality is a special case to be consistent with the existing
+    Ada 83 principle that equality comparisons, even
+    between objects with different constraints, never raise Constraint_Error.
+  @end(Reason)
+
address@hidden@keepnext@;@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00196-01]}
+If all of the controlling operands @Chg{Version=[2],New=[(if any) ],Old=[]}are
+tag-indeterminate, then:
+  @begin(inneritemize)
+    
@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00239-01],ARef=[AI95-00416-01]}
+    If the call has a controlling address@hidden,New=[ or controlling
+    access result],Old=[]} and is address@hidden,New=[, or designates,],Old=[]}
+    a (possibly parenthesized or qualified)
+    controlling operand of an enclosing call on a dispatching operation
+    of @Chg{Version=[2],New=[a descendant of ],Old=[]}type @i(T),
+    then its controlling tag value is determined by the controlling tag
+    value of this enclosing call;
+
+    @begin{Discussion}
+      @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00239-01]}
+      @ChgAdded{Version=[2],Text=[For code that a user can write explicitly,
+      the only contexts that can control dispatching of a function with a
+      controlling result of type T are those that involve controlling operands
+      of the same type T: if the two types differ there is an illegality and
+      the dynamic semantics are irrelevant.]}
+
+      @ChgRef{Version=[2],Kind=[AddedNormal]}
+      @ChgAdded{Version=[2],Text=[In the case of an inherited subprogram
+      however, if a default expression is a function call, it may be of type T
+      while the parameter is of a type derived from T. To cover this case, we
+      talk about "a descendant of T" above. This is safe, because if the type
+      of the parameter is descended from the type of the function result, it is
+      guaranteed to inherit or override the function, and this ensures that
+      there will be an appropriate body to dispatch to. Note that abstract
+      functions are not an issue here because the call to the function is a
+      dispatching call, so it is guaranteed to always land on a concrete
+      body.]}
+    @end{Discussion}
+
+    @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00196-01],ARef=[AI95-00416-01]}
+    @ChgAdded{Version=[2],Text=[If the call has a controlling result or
+    controlling access result and (possibly parenthesized, qualified, or
+    dereferenced) is the expression of an @nt{assignment_statement} whose
+    target is of a class-wide type, then its controlling tag value is
+    determined by the target;]}
+
+    @PDefn{statically determined tag}
+    Otherwise, the controlling tag value is statically determined to be
+    the tag of type @i(T).
+      @begin{Ramification}
+        This includes the cases of
+        a tag-indeterminate procedure call, and
+        a tag-indeterminate @nt{function_call} that is
+        used to initialize a class-wide formal parameter or class-wide
+        object.
+      @end{Ramification}
+  @end(inneritemize)
address@hidden(itemize)
+
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0126-1]}
address@hidden,Type=[Leading],address@hidden add to allow conditional "leading"}
+For the execution of a call on a dispatching operation,
+the @Chg{Version=[2],New=[action performed is determined by the properties
+of the corresponding dispatching operation],Old=[body executed is the one for
+the corresponding primitive subprogram]} of the specific type
+identified by the controlling tag address@hidden,New=[:],Old=[.
address@hidden,New=[If the corresponding operation is],Old=[The body
+for an]} explicitly declared
address@hidden,New=[for this type, @Redundant[even if the declaration occurs
+in a private part], then the action comprises an invocation of the],
+Old=[dispatching operation is the corresponding]}
+explicit body for the
address@hidden,New=[operation. If the corresponding operation is
+implicitly declared for this type:],Old=[subprogram.
+The body for an implicitly
+declared dispatching operation that is overridden is the body for the
+overriding subprogram, @Redundant[even if the overriding occurs in a private
+part.] The body for an inherited dispatching operation that is not overridden
+is the body of the corresponding subprogram of the parent or ancestor type.]}]}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0126-1]}
address@hidden,Text=[if the corresponding operation is explicitly
+declared for this type, @Redundant[even if the declaration occurs in a private
+part], then the action comprises an invocation of the explicit body for the
+operation;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0126-1]}
address@hidden,Text=[if the
address@hidden,New=[corresponding ],Old=[]}operation is
address@hidden,New=[implicitly
+declared for this type and is ],Old=[]}implemented by an entry or
+protected subprogram (see @RefSecNum{Task Units and Task Objects} and
address@hidden Units and Protected Objects}), then the action comprises a
+call on this entry or protected subprogram, with the target object being given
+by the first actual parameter of the call, and the actual parameters of the
+entry or protected subprogram being given by the remaining actual parameters of
+the call, if any;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0197-1]}
address@hidden,Text=[if the corresponding operation is a predefined
+operator then the action comprises an invocation of that operator;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0126-1],ARef=[AI05-0197-1],ARef=[AI05-0250-1],ARef=[AI05-0254-1]}
address@hidden,Text=[otherwise, the action is the same as the action for
+the corresponding operation of the parent address@hidden,New=[ or
+progenitor type from which the operation was inherited except that additional
+invariant checks (see @RefSecnum{Type Invariants}) and class-wide postcondition
+checks (see @RefSecNum{Preconditions and Postconditions}) may apply. If there 
is
+more than one such corresponding operation, the action is that for the 
operation
+that is not a null procedure, if any; otherwise, the action is that of an
+arbitrary one of the operations],Old=[]}.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI05-0126-1]}
address@hidden,Text=[In the unusual case in which a
+dispatching subprogram is explicitly declared (overridden) by a body (with no
+preceding @nt{subprogram_declaration}), the body for that dispatching 
subprogram
+is that body; that is, the @lquotes@;corresponding explicit address@hidden@; in
+the above rule is the body itself.]}
address@hidden
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0005-1],ARef=[AI05-0126-1]}
address@hidden,address@hidden@;Corresponding dispatching address@hidden
+refers to the inheritance relationship between subprograms. Primitive
+operations are always inherited for a type T, but they might not be declared if
+the primitive operation is never visible within the immediate scope of the type
+T. If no corresponding operation is declared, the last bullet is used and the
+corresponding operation of the parent type is executed (an explicit body that
+happens to have the same name and profile is not called in that case).]}
+
address@hidden,Kind=[Added],ARef=[AI05-0005-1],ARef=[AI05-0126-1]}
address@hidden,Text=[We have to talk about progenitors in the last
+bullet in case the corresponding operation is a null procedure inherited
+from an interface. In that case, the parent type might not even have the
+operation in question.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0197-1]}
address@hidden,Text=[For the last bullet, if there are multiple
+corresponding operations for the parent and progenitors, all but one of them
+have to be a null procedure. (If the progenitors declared abstract routines,
+there would have to be an explicit overriding of the operation, and then the
+first bullet would apply.) We call the nonnull routine if one exists.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0126-1]}
address@hidden,Text=[Any explicit declaration for an inherited
+corresponding operation has to be an overriding routine.
+These rules mean that a dispatching call executes the
+overriding routine (if any) for the specific type.]}
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
address@hidden@;The wording of the above 
@Chg{Version=[3],New=[rules],Old=[rule]}
+is intended to ensure that the same body is executed for a given tag,
+whether that tag is determined statically or dynamically.
+For a type declared in a package,
+it doesn't matter whether a given subprogram is
+overridden in the visible part or the private part,
+and it doesn't matter whether the call is inside or outside the package.
+For example:
address@hidden
address@hidden P1 @key[is]
+    @key[type] T1 @key[is] @key[tagged] @key[null] @key[record];
+    @key[procedure] Op_A(Arg : @key[in] T1);
+    @key[procedure] Op_B(Arg : @key[in] T1);
address@hidden P1;
+
address@hidden P1; @key[use] P1;
address@hidden P2 @key[is]
+    @key[type] T2 @key[is] @key[new] T1 @key[with] @key[null] @key[record];
+    @key[procedure] Op_A(Param : @key[in] T2);
address@hidden
+    @key[procedure] Op_B(Param : @key[in] T2);
address@hidden P2;
+
address@hidden,address@hidden AI-00009 & AI-00114}
address@hidden P1; @key[with] P2;
address@hidden Main @key[is]
+    X : @Chg{New=[P2.],Old=[]}T2;
+    Y : @Chg{New=[P1.],Old=[]}T1'Class := X;
address@hidden
+    P2.Op_A(Param => X); address@hidden Nondispatching address@hidden to a 
dispatching operation],Old=[]}.}
+    P1.Op_A(Arg => Y); address@hidden Dispatching call.}
+    P2.Op_B(Arg => X); address@hidden Nondispatching address@hidden to a 
dispatching operation],Old=[]}.}
+    P1.Op_B(Arg => Y); address@hidden Dispatching call.}
address@hidden Main;
address@hidden
+
+The two calls to Op_A both execute the body of Op_A that has to occur in
+the body of package P2.
+Similarly,
+the two calls to Op_B both execute the body of Op_B that has to occur in
+the body of package P2,
+even though Op_B is overridden in the private part of P2.
+Note, however, that the formal parameter names are different for P2.Op_A
+versus P2.Op_B.
+The overriding declaration for P2.Op_B is not visible in Main,
+so the name in the call actually denotes the implicit declaration
+of Op_B inherited from T1.
+
+
+If a call occurs in the program text before an overriding,
+which can happen only if the call is part of a default expression,
+the overriding will still take effect for that call.
+
address@hidden
+
address@hidden
+Even when a tag is not @i(statically determined), a compiler
+  might still be able to figure it out and thereby avoid
+  the overhead of run-time dispatching.
address@hidden
+
address@hidden
+
address@hidden
+
+The body to be executed for a call on a dispatching operation is
+determined by the tag;
+it does not matter whether that tag is determined statically or
+dynamically,
+and it does not matter whether the subprogram's declaration is visible at
+the place of the call.
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00260-02]}
+This subclause covers calls on @Chg{Version=[2],New=[dispatching],
+Old=[primitive]} subprograms of a tagged type.
+Rules for tagged type membership tests are described
+in @RefSecNum(Relational Operators and Membership Tests).
+Controlling tag determination for an
address@hidden
+is described in @RefSecNum(Assignment Statements).
+
+A dispatching call can dispatch to a body whose declaration is
+not visible at the place of the call.
+
+A call through an access-to-subprogram value is never
+a dispatching call, even if the
+access value designates a dispatching operation. Similarly
+a call whose @nt<prefix> denotes a @nt<subprogram_renaming_declaration>
+cannot be a dispatching call unless the renaming itself is the
+declaration of a primitive subprogram.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The concept of dispatching operations is new.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00404-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  If a dispatching operation is defined by a
+  @nt{subprogram_renaming_declaration}, and it has a controlling access
+  parameter, Ada 2005 requires the subtype of the parameter to exclude null.
+  The same applies to instantiations. This is required so that all
+  calls to the subprogram operate the same way (controlling access parameters
+  have to exclude null so that dispatching calls will work).
+  Since Ada 95 didn't have the notion of access subtypes
+  that exclude null, and all access parameters excluded null, it had no such
+  rules. These rules will require the
+  addition of an explicit @key{not null} on nondispatching operations that are
+  later renamed to be dispatching, or on a generic that is used to define a
+  dispatching operation.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Functions that have an access result type can be dispatching in
+  the same way as a function that returns a tagged object directly.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0010],ARef=[AI95-00127-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:>@ChgNote{This is 
documented as an extension in
+  the two @Chg{Version=[3],New=[clauses],Old=[sections]} referenced below.}
+  Allocators and access attributes of objects of class-wide types
+  can be used as the controlling parameter in a dispatching calls. This
+  was an oversight in the definition of Ada 95. (See @RefSecNum{Operations of 
Access Types} and
+  @RefSecNum{Allocators}).]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0011],ARef=[AI95-00117-01],ARef=[AI95-00430-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the conventions 
of
+  dispatching operations. This is extended in Ada 2005 to cover operations
+  inherited from progenitors, and to ensure that the conventions of all
+  inherited operations are the same.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00196-01]}
+  @ChgAdded{Version=[2],Text=[Clarified the wording to ensure that functions 
with
+  no controlling operands are tag-indeterminate, and to describe that the
+  controlling tag can come from the target of an @nt{assignment_statement}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00239-01]}
+  @ChgAdded{Version=[2],Text=[Fixed the wording to cover default expressions
+  inherited by derived subprograms. A literal reading of the old wording
+  would have implied that operations would be called with objects of the
+  wrong type.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00260-02]}
+  @ChgAdded{Version=[2],Text=[An abstract formal subprogram is a dispatching
+  operation, even though it is not a primitive operation. See
+  @RefSec{Formal Subprograms}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00345-01]}
+  @ChgAdded{Version=[2],Text=[Dispatching calls include operations
+  implemented by entries and protected operations, so we have to update the
+  wording to reflect that.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00335-01]}
+  @ChgAdded{Version=[2],Text=[A stream attribute of a tagged type is
+  usually a dispatching operation, even though it is not a primitive
+  operation. If they weren't dispatching, T'Class'Input and T'Class'Output
+  wouldn't work.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0076-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Defined
+  @ldquote@;function with a controlling address@hidden, as it is used
+  in @RefSecNum{Abstract Types and Subprograms}.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0126-1],ARef=[AI05-0197-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected holes in the
+  definition of dynamic dispatching: the behavior for operations that are
+  never declared and/or inherited from a progenitor were not specified.]}
address@hidden
+
+
address@hidden Types and Subprograms}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden@Defn{abstract type}
address@hidden data type (ADT)],See=(abstract type)}
address@hidden (abstract data type)],See=(abstract type)}
address@hidden type],See=(nonabstract type)}
+An @i(abstract type) is a tagged type intended
+for use as @Chg{Version=[2],New=[an ancestor of other types],Old=[a parent
+type for type extensions]}, but which is not allowed to have objects of its 
own.
address@hidden subprogram}
address@hidden subprogram],See=(nonabstract subprogram)}
+An @i(abstract subprogram) is a subprogram that has no body,
+but is intended to be overridden at some point when inherited.
+Because objects of an abstract type cannot be created,
+a dispatching call to an abstract subprogram always
+dispatches to some overriding body.]
address@hidden,Kind=[Added],Term=<Abstract type>,
+  Text=<@ChgAdded{Version=[2],Text=[An abstract type is a tagged type
+  intended for use as an ancestor of other types, but which is not allowed to
+  have objects of its own.]}>}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+An abstract subprogram has no body, so the
+rules in this @Chg{Version=[3],New=[subclause],Old=[clause]} are
+designed to ensure (at compile time)
+that the body will never be invoked.
+We do so primarily by disallowing the creation of
+values of the abstract type.
+Therefore, since type conversion and parameter passing
+don't change the tag, we know we will
+never get a class-wide value with a tag identifying an abstract type.
+This means that we only have to disallow nondispatching calls
+on abstract subprograms (dispatching calls will never reach them).
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00218-03],ARef=[AI95-00348-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0183-1]}
address@hidden,lhs=<@Chg{Version=[2],New=<abstract_subprogram_declaration>,Old=<>}>,
+rhs="@Chg{Version=[2],New=<
+    address@hidden
+    @Syn2{subprogram_specification} @key{is} @address@hidden,New=<
+        address@hidden>,Old=[]};>,Old=<>}"}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00345-01]}
address@hidden,address@hidden type}
address@hidden, Sec=(abstract)}Interface types
+(see @RefSecNum{Interface Types}) are
+abstract types. In addition, a tagged type that has the reserved word
address@hidden in its declaration is an abstract type. The class-wide type
+(see @RefSecNum{Derivation Classes}) rooted at an abstract type is not itself
+an abstract type.],Old=[]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden,New=[Only a tagged type shall have],address@hidden type}
address@hidden, Sec=(abstract)}
+An @i{abstract type} is a specific type
+that has]} the reserved word @key{abstract} in its
address@hidden,New=[],Old=[Only a tagged type is allowed to be
+declared abstract.]}
address@hidden@ChgNote{These AARM notes really belong on the
+Static Semantics paragraph, but I won't move them, as it's not worth the time.}
+  Untagged types are never abstract,
+  even though they can have primitive abstract subprograms.
+  Such subprograms cannot be called,
+  unless they also happen to be dispatching operations of
+  some tagged type, and then only via a dispatching call.
+
+  Class-wide types are never abstract.
+  If T is abstract, then it is illegal to declare a stand-alone
+  object of type T,
+  but it is OK to declare a stand-alone object of type T'Class;
+  the latter will get a tag from its initial value,
+  and this tag will necessarily be different from T'Tag.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00260-02],ARef=[AI95-00348-01]}
address@hidden subprogram}
address@hidden, Sec=(abstract)}
+A subprogram declared by an @address@hidden@!declaration}
address@hidden,New=[or a
address@hidden@address@hidden@!declaration} (see @RefSecNum{Formal 
Subprograms})],
+Old=[(see @RefSecNum{Subprogram Declarations})]}
+is an @i{abstract subprogram}.
+If it is a primitive subprogram of a tagged type,
+then the tagged type shall be abstract.
address@hidden
address@hidden@keepnext@;Note that for a private type, this applies to both 
views.
+  The following is illegal:
address@hidden
address@hidden P @key[is]
+    @key[type] T @key[is] @key[abstract] @key[tagged] @key[private];
+    @key[function] Foo (X : T) @key[return] Boolean @key[is] @key[abstract]; 
address@hidden Illegal!}
address@hidden
+    @key[type] T @key[is] @key[tagged] @key[null] @key[record]; address@hidden 
Illegal!}
+    X : T;
+    Y : Boolean := Foo (T'Class (X));
address@hidden P;
address@hidden
+
+The full view of T is not abstract,
+but has an abstract operation Foo,
+which is illegal.
+The two lines marked "address@hidden Illegal!}" are illegal when taken 
together.
address@hidden
address@hidden
address@hidden@;@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00310-01]}
+  We considered disallowing untagged types from having abstract
+  primitive subprograms.
+  However, we rejected that plan, because it introduced some silly
+  anomalies, and because such subprograms are address@hidden,
+  New=[],Old=[ (if not terribly useful)]}.
+  For example:
address@hidden
address@hidden,address@hidden AI-00010}
address@hidden P @key[is]
+   @key[type] Field_Size @key[is] @key[range] 0..100;
+   @key[type] T @key[is] @key[abstract tagged] @key[null] @key[record];
+   @key[procedure] Print(X : @key[in] T; F : @key[in] Field_Size := 0) 
@key[is] @address@hidden,Old=[abstract]};
+  . . .
address@hidden Q @key[is]
+   @key[type] My_Field_Size @key[is] @key[new] Field_Size;
+   address@hidden implicit declaration of Print(X : T; F : My_Field_Size := 0) 
@address@hidden abstract]],Old=[is abstract]};}
address@hidden Q;
address@hidden
+
+It seemed silly to make the derivative of My_Field_Size illegal,
+just because there was an implicitly declared abstract subprogram
+that was not primitive on some tagged type.
+Other rules could be formulated to solve this problem,
+but the current ones seem like the simplest.
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00310-01]}
address@hidden,Text=[In Ada 2005, abstract primitive subprograms of
+an untagged type may be used to @lquotes@;address@hidden@; an operation.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00260-02]}
address@hidden,Text=[Note that the second sentence does not apply to
+abstract formal subprograms, as they are never primitive operations of
+a type.]}
address@hidden
+
address@hidden@;@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00251-01],ARef=[AI95-00334-01],ARef=[AI95-00391-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0097-1],ARef=[AI05-0198-1]}
address@hidden,New=[If a type has an implicitly declared primitive subprogram
+that is inherited or is @Chg{Version=[3],New=[a],Old=[the]} predefined
address@hidden,New=[],Old=[equality ]}operator, and the corresponding
+primitive subprogram of],Old=[For a derived type, if]}
+the parent or ancestor type
address@hidden,New=[is abstract or is a function with a controlling access
+result, or if a type other than a
address@hidden,New=[nonabstract ],Old=[]}null extension inherits a],
+Old=[has an abstract primitive subprogram, or a primitive]}
+function with a controlling result, then:
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0068-1]}
+  @ChgAdded{Version=[3],Text=[These rules apply to each view of the type
+  individually. That is necessary to preserve privacy. For instance, in the
+  following example:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden P @key[is]
+   @key[type] I @key[is interface];
+   @key[procedure] Op (X : I) @key[is abstract];
address@hidden P;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden P;
address@hidden Q @key[is]
+   @key[type] T @key[is abstract new] P.I @key[with private];
+   -- @RI[Op inherited here.]
address@hidden
+   @key[type] T @key[is abstract new] P.I @key[with null record];
+   @key[procedure] Op (X : T) @key[is null];
address@hidden Q;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Q;
address@hidden R @key[is]
+   @key[type] T2 @key[is new] Q.T @key[with null record];
+   -- @RI[Illegal. Op inherited here, but requires overriding.]
address@hidden R;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If this did not depend on the view,
+this would be legal. But in that case, the fact that Op is overridden
+in the private part would be visible; package R would have to be
+illegal if no overriding was in the private part.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Note that this means that whether an inherited
+subprogram is abstract or concrete depends on where it inherited.
+In the case of Q, Q.Op in the visible part is abstract,
+while Q.Op in the private part is concrete. That is, R is illegal since
+it is an unrelated unit (and thus it cannot see the private part), but if
+R had been a private child of Q, it would have been legal.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00251-01],ARef=[AI95-00334-01]}
+  If the @Chg{Version=[2],New=[],Old=[derived ]}type is abstract or untagged,
+  the @Chg{Version=[2],New=[implicitly declared],Old=[inherited]} subprogram is
+  @i{abstract}.
+  @begin{Ramification}
+    Note that it is possible to override a concrete subprogram
+    with an abstract one.
+  @end{Ramification}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00391-01]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0080-1]}
+  Otherwise, the subprogram shall be overridden with a nonabstract
+  address@hidden,New=[ or, in the case of a private extension
+  inheriting a @Chg{Version=[4],New=[nonabstract ],Old=[]}function with a
+  controlling result, have a full type that is a null
+  extension],address@hidden; for a type declared in the visible part of
+  a package, the overriding may be either in the visible or the private part].
+  @Chg{Version=[2],New=[Such a subprogram is said to
+  @i{require address@hidden overriding} ],Old=[]}However,
+  if the type is a generic formal type,
+  the subprogram need not be overridden for the formal type itself;
+  @Redundant[a nonabstract version will necessarily be provided by the
+  actual type.]
+  @begin{Reason}
+    
@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00228-01],ARef=[AI95-00391-01]}
+    A function that returns the parent type @Chg{Version=[2],New=[requires
+    overriding],Old=[becomes address@hidden't leave this ancient and broken 
terminology around here!!}
+    for @Chg{Version=[2],New=[a],Old=[an abstract]} type
+    extension @Chg{Version=[2],New=[(or becomes abstract for an abstract 
type)],
+    Old=[(if not overridden)]} because conversion
+    from a parent type to a type extension is
+    not defined, and function return semantics is defined in terms
+    of address@hidden,New=[ (other than for a null extension;
+    see below)],Old=[]}. (Note that parameters of mode @key{in out} or
+    @key{out} do not have this problem, because the tag of the actual
+    is not changed.)
+
+    @address@hidden@;Note that the overriding required above can be in the
+    private part, which allows the following:
+    @begin{Example}
address@hidden Pack1 @key[is]
+    @key[type] Ancestor @key[is] @key[abstract] ...;
+    @key[procedure] Do_Something(X : @key[in] Ancestor) @key[is] 
@key[abstract];
address@hidden Pack1;
+
address@hidden Pack1; @key[use] Pack1;
address@hidden Pack2 @key[is]
+    @key[type] T1 @key[is] @key[new] Ancestor @key[with] @key[record] ...;
+        address@hidden A concrete type.}
+    @key[procedure] Do_Something(X : @key[in] T1); address@hidden Have to 
override.}
address@hidden Pack2;
+
address@hidden Pack1; @key[use] Pack1;
address@hidden Pack2; @key[use] Pack2;
address@hidden Pack3 @key[is]
+    @key[type] T2 @key[is] @key[new] Ancestor @key[with] @key[private];
+        address@hidden A concrete type.}
address@hidden
+    @key[type] T2 @key[is] @key[new] T1 @key[with] address@hidden Parent 
different from ancestor.}
+      @key[record] ... @key[end] @key[record];
+    address@hidden Here, we inherit Pack2.Do_Something.}
address@hidden Pack3;
+    @end{Example}
+
+    @ChgRef{Version=[1],address@hidden AI-00011}
+    @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00228-01]}
+    T2 inherits an abstract Do_Something, but @Chg{New=[T2],Old=[T]} is not
+    abstract, so Do_Something has to be overridden.
+    However, it is OK to override it in the private part.
+    In this case, we override it by inheriting a concrete version
+    from a different type.
+    Nondispatching calls to Pack3.Do_Something are allowed
+    both inside and outside package address@hidden,New=[, as the
+    client @lquotes@;address@hidden@; that the subprogram was necessarily
+    overridden somewhere],Old=[]}.
+
+    @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00391-01]}
+    @ChgAdded{Version=[2],Text=[For a null extension, the result of a function
+    with a controlling result is defined in terms of an 
@nt{extension_aggregate}
+    with a @key{null record} extension part
+    (see @RefSecNum{Derived Types and Classes}). This means that these
+    restrictions on functions with a controlling result do not have to apply to
+    null extensions.]}
+
+    @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00391-01]}
+    @ChgAdded{Version=[2],Text=[However, functions with controlling access
+    results still require overriding. Changing the tag in place might clobber
+    a preexisting object, and allocating new memory would possibly change the
+    pool of the object, leading to storage leaks. Moreover, copying the object
+    isn't possible for limited types. We don't need to restrict functions
+    that have an access return type of an untagged type, as derived types
+    with primitive subprograms have to have the same representation as their
+    parent type.]}
+  @end{Reason}
address@hidden
+
+A call on an abstract subprogram shall be a dispatching call;
address@hidden calls to an abstract subprogram are not
+allowed.]
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00310-01]}
+  If an abstract subprogram is not a dispatching operation of
+  some tagged type, then it cannot be called at
+  address@hidden,New=[ In Ada 2005, such subprograms are not
+  even considered by name resolution (see @RefSecNum{Subprogram 
Calls}).],Old=[]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0073-1],ARef=[AI05-0203-1]}
+The type of an @nt{aggregate}, or of an object created by an
address@hidden or an @nt{allocator},
+or a generic formal object of mode @key[in],
+shall not be abstract.
+The type of the target of an assignment
+operation (see @RefSecNum{Assignment Statements}) shall not
+be abstract.
+The type of a component shall not be abstract.
+If the result type of a function is abstract,
+then the function shall be address@hidden,New=[
+If a function has an access result type
+designating an abstract type, then the function shall be abstract.
+The type denoted by a @nt{return_subtype_indication} (see
address@hidden Statements}) shall not be abstract. A generic function
+shall not have an abstract result type or an access result type designating an
+abstract type.],Old=[]}
address@hidden
+  This ensures that values of an abstract type cannot be created,
+  which ensures that a dispatching call to an abstract subprogram
+  will not try to execute the nonexistent body.
+
+  Generic formal objects of mode @key[in] are like constants;
+  therefore they should be forbidden for abstract types. Generic formal
+  objects of mode @key[in out] are like renamings; therefore, abstract
+  types are OK for them, though probably not terribly useful.
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0073-1]}
+  @ChgAdded{Version=[3],Text=[Generic functions returning a formal
+  abstract type are illegal because any instance would have to be
+  instantiated with a nonabstract type in order to avoid violating
+  the function rule (generic functions cannot be declared abstract).
+  But that would be an implied contract; it would be better for the
+  contract to be explicit by the formal type not being declared
+  abstract. Moreover, the implied contract does not add any capability.]}
address@hidden
+
+If a partial view is not abstract, the corresponding
+full view shall not be abstract.
+If a generic formal type is abstract,
+then for each primitive subprogram of the formal that is not abstract,
+the corresponding primitive subprogram of the actual shall
+not be abstract.
address@hidden
+  By contrast, we allow the actual type to be nonabstract
+  even if the formal type is declared abstract.
+  Hence, the most general formal tagged type possible is "@key(type)
+  T(<>) @key(is abstract tagged limited private);".
+
+  For an abstract private extension declared in the visible
+  part of a package, it is only possible for the
+  full type to be nonabstract if the private extension has
+  no abstract dispatching operations.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00294-01]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[In the sentence about primitive
+  subprograms above, there is some ambiguity as to what is meant by
+  @lquotes@;address@hidden@; in the
+  case where an inherited operation is overridden.  This is best explained by
+  an example, where the implicit declarations are shown as comments:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden P1 @key{is}
+   @key{type} T1 @key{is abstract tagged null record};
+   @key{procedure} P (X : T1); -- @RI[(1)]
address@hidden P1;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden P2 @key{is}
+   @key{type} T2 @key{is abstract new} P1.T1 @key{with null record};
+   -- @address@hidden P (X : T2); -- (2)]
+   @key{procedure} P (X : T2) @key{is abstract}; -- (3)
+end P2;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key{type} D @key{is abstract new} P1.T1 @key{with private};
+   -- @address@hidden P (X : D); -- (4)]
address@hidden G (X : D);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden I @key{is new} G (P2.T2); -- @RI[Illegal.]]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,New=[Type T2 inherits a nonabstract procedure P (2) from the
+primitive procedure P (1) of T1. P (2) is overridden by the explicitly declared
+abstract procedure P (3). Type D inherits a nonabstract procedure P (4) from P
+(1). In instantiation I, the operation corresponding to P (4) is the one which
+is not overridden, that is, P (3): the overridden operation P (2) does not
address@hidden@;address@hidden@;. Therefore, the instantiation is 
illegal.],Old=[]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0073-1]}
+For an abstract type declared in a visible part,
+an abstract primitive subprogram
+shall not be declared in the private part,
+unless it is overriding an abstract subprogram
+implicitly declared in the visible part.
+For a tagged type declared in a visible part,
+a primitive function with a controlling address@hidden,New=[
+or a controlling access result],Old=[]} shall not be declared
+in the private part, unless it is overriding a function
+implicitly declared in the visible part.
address@hidden
address@hidden@;The @lquotes@;visible address@hidden@; could be that of a 
package
+or a generic package. This rule is needed because a nonabstract type extension
+declared outside the package would not know about any abstract primitive
+subprograms or primitive functions with controlling results
+declared in the private part, and wouldn't know that they
+need to be overridden with nonabstract subprograms.
+The rule applies to a tagged record type or record extension declared
+in a visible part,
+just as to a tagged private type or private extension.
+The rule applies to explicitly and implicitly declared abstract
+subprograms:
address@hidden
address@hidden Pack @key[is]
+    @key[type] T @key[is] @key[abstract] @key[new] T1 @key[with] @key[private];
address@hidden
+    @key[type] T @key[is] @key[abstract] @key[new] T2 @key[with] @key[record] 
... @key[end] @key[record];
+    ...
address@hidden Pack;
address@hidden
+
+The above example would be illegal if T1 has a nonabstract primitive
+procedure P, but T2 overrides P with an abstract one;
+the private part should override P with a nonabstract version.
+On the other hand, if the P were abstract for both T1 and T2,
+the example would be legal as is.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00260-02]}
+A generic actual subprogram shall not be an abstract
+subprogram @Chg{Version=[2],New=[unless the generic formal subprogram is
+declared by a @nt{formal_abstract_subprogram_declaration}],Old=[]}.
+The @nt{prefix} of an @nt{attribute_reference} for the Access,
+Unchecked_Access, or Address attributes shall not denote an abstract 
subprogram.
address@hidden
+An @nt{abstract_subprogram_declaration} is not syntactically a
address@hidden
+Nonetheless, an abstract subprogram is a subprogram,
+and an @nt{abstract_subprogram_declaration} is a declaration of a subprogram.
+
address@hidden,Kind=[Revised],ARef=[AI95-00260-02]}
+The part about generic actual subprograms includes those given by
address@hidden,New=[ Of course, an abstract formal subprogram's
+actual subprogram can be abstract.],Old=[]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00348-01]}
address@hidden,address@hidden, Sec=(abstract_subprogram_declaration)}
+The elaboration of an @nt{abstract_subprogram_declaration} has no effect.]}
address@hidden
+
address@hidden
+Abstractness is not inherited; to declare an abstract type,
+the reserved word @key[abstract] has to be used
+in the declaration of the type extension.
address@hidden
+A derived type can be abstract even if its parent is not.
+Similarly, an inherited concrete subprogram can be overridden with an
+abstract subprogram.
address@hidden
+
+A class-wide type is never abstract. Even if a class
+is rooted at an abstract type, the class-wide type for the
+class is not abstract, and an object of the class-wide type
+can be created; the tag of such an object will identify
+some nonabstract type in the class.
address@hidden
+
address@hidden
address@hidden@address@hidden(Example of an abstract type representing a set of 
natural numbers:)
address@hidden
address@hidden(package) Sets @key(is)
+    @key(subtype) Element_Type @key(is) Natural;
+    @key(type) Set @key(is abstract tagged null record);
+    @key(function) Empty @key(return) Set @key(is abstract);
+    @key(function) Union(Left, Right : Set) @key(return) Set @key(is abstract);
+    @key(function) Intersection(Left, Right : Set) @key(return) Set @key(is 
abstract);
+    @key(function) Unit_Set(Element : Element_Type) @key(return) Set @key(is 
abstract);
+    @key(procedure) Take(Element : @key(out) Element_Type;
+                   From : @key(in out) Set) @key(is abstract);
address@hidden(end) Sets;
address@hidden
address@hidden
+
address@hidden
address@hidden(Notes on the example:)
+Given the above abstract type, one could then derive
+various (nonabstract) extensions of the type, representing
+alternative implementations of a set. One might use a bit
+vector, but impose an upper bound on the largest element representable,
+while another might use a hash table, trading off space for flexibility.
address@hidden
+One way to export a type from a package with some components visible
+and some components private is as follows:
address@hidden
address@hidden P @key[is]
+    @key[type] Public_Part @key[is] @key[abstract] @key[tagged]
+        @key[record]
+            ...
+        @key[end] @key[record];
+    @key[type] T @key[is] @key[new] Public_Part @key[with] @key[private];
+    ...
address@hidden
+    @key[type] T @key[is] @key[new] Public_Part @key[with]
+        @key[record]
+            ...
+        @key[end] @key[record];
address@hidden P;
address@hidden
+
+The fact that Public_Part is abstract tells clients they have to
+create objects of type T instead of Public_Part.
+Note that the public part has to come first;
+it would be illegal to declare a private type Private_Part,
+and then a record extension T of it,
+unless T were in the private part after the full declaration of Private_Part,
+but then clients of the package would not have visibility to T.
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00391-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  It is not necessary to override functions with a controlling result
+  for a null extension. This makes it easier to derive a tagged type
+  to complete a private type.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01],ARef=[AI95-00345-01]}
+  @ChgAdded{Version=[2],Text=[Updated the wording to reflect the addition of
+  interface types (see @RefSecNum{Interface Types}).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00260-02]}
+  @ChgAdded{Version=[2],Text=[Updated the wording to reflect the addition of
+  abstract formal subprograms (see @RefSecNum{Formal Subprograms}).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00334-01]}
+  @ChgAdded{Version=[2],Text=[The wording of shall-be-overridden was clarified
+  so that it clearly applies to abstract predefined equality.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00348-01]}
+  @ChgAdded{Version=[2],Text=[Moved the syntax and elaboration rule for
+  @nt{abstract_subprogram_declaration} here, so the syntax and most of the
+  semantics are together (which is consistent with null procedures).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00391-01]}
+  @ChgAdded{Version=[2],Text=[We define the term @i<require overriding>
+  to make other wording easier to understand.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0073-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Added rules to eliminate holes with controlling access results and generic
+  functions that return abstract types. While these changes are technically
+  incompatible, it is unlikely that they could be used in a program without
+  violating some other rule of the use of abstract types.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0097-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected a minor
+  glitch having to do with abstract null extensions. The Ada 2005
+  rule allowed such extensions to inherit concrete operations in some
+  rare cases. It is unlikely that these cases exist in user code.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in an
+  @nt{abstract_subprogram_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0198-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified that the 
predefined
+  operator corresponding to an inherited abstract operator is also abstract. 
The
+  Ada 2005 rules caused the predefined operator and the inherited operator to
+  override each other, which is weird. But the effect is the same either way
+  (the operator is not considered for resolution).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0203-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added wording to
+  disallow abstract return objects. These were illegal in Ada 2005 by other
+  rules; the extension to support class-wide type better opened a hole which
+  has now been plugged.]}
address@hidden
+
+
address@hidden,Name=[Interface Types]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01],ARef=[AI95-00345-01]}
address@hidden,address@hidden interface type is an abstract tagged
+type that provides a restricted form of multiple inheritance. A tagged type,
+task type, or protected type may have one or more interface types as
+ancestors.]]}
address@hidden,Kind=[AddedNormal],Term=<Interface type>,
+  Text=<@ChgAdded{Version=[2],Text=[An interface type is a form of abstract
+  tagged type which has no components or concrete operations
+  except possibly null procedures. Interface types are used for
+  composing other interfaces and tagged types and thereby
+  provide multiple inheritance. Only an interface type can be used as a
+  progenitor of another type.]}>}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01],ARef=[AI95-00345-01]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[The rules are designed so that an
+  interface can be used as either a parent type or a progenitor type without
+  changing the meaning. That's important so that the order that interfaces are
+  specified in a @nt{derived_type_definition} is not significant. In 
particular,
+  we want:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Con1 @key{is new} Int1 @key{and} Int2 @key{with 
null record};
address@hidden Con2 @key{is new} Int2 @key{and} Int1 @key{with null record};]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Trailing],Text=[to mean exactly the same thing.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01],ARef=[AI95-00345-01]}
address@hidden,lhs=<@Chg{Version=[2],New=<interface_type_definition>,Old=<>}>,
+rhs="@Chg{Version=[2],New=<
+    address@hidden | @key{task} | @key{protected} | @key{synchronized}] 
@key{interface} address@hidden @Syn2{interface_list}]>,Old=<>}"}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01],ARef=[AI95-00419-01]}
address@hidden<@Chg{Version=[2],New=<interface_list>,Old=<>}>,
+rhs="@Chg{Version=[2],New=<@address@hidden address@hidden 
@address@hidden>,Old=<>}"}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01]}
address@hidden,New=[An interface type (also called an @i{interface})
address@hidden@PDefn2{Term=[interface],Sec=[type]}
+a specific abstract tagged type that is defined by
+an @nt{interface_type_definition}.],Old=[]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00345-01]}
address@hidden,Text=[An interface with the reserved word @key{limited},
address@hidden, @key{protected},
+or @key{synchronized} in its definition is termed, respectively, a @i{limited
+interface}, a @i{task interface}, a @i{protected interface}, or a
address@hidden interface}.
+In addition,@PDefn2{Term=[interface],Sec=[synchronized]}
address@hidden,Sec=[protected]}
address@hidden,Sec=[task]}
address@hidden,Sec=[limited]}
address@hidden,Sec=[nonlimited]}
address@hidden interface}
address@hidden interface}
address@hidden interface}
address@hidden interface}
address@hidden interface}
+all task and protected interfaces
+are synchronized interfaces, and all synchronized interfaces are limited
+interfaces.]}
address@hidden,Kind=[AddedNormal],Term=<Synchronized>,
+  Text=<@ChgAdded{Version=[2],Text=[A synchronized entity is one
+  that will work safely with multiple tasks at one time. A synchronized
+  interface can be an ancestor of a task or a protected type. Such a
+  task or protected type is called a synchronized tagged type.]}>}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00345-01],ARef=[AI95-00443-01]}
address@hidden,address@hidden tagged type}
address@hidden,Sec=[synchronized tagged]}
address@hidden type],Sec=[synchronized]}
address@hidden type],Sec=[task]}
address@hidden type],Sec=[protected]}
address@hidden tagged type}
address@hidden tagged type}
address@hidden task or protected type derived from an interface is a tagged 
type.]
+Such a tagged type is called a @i<synchronized> tagged
+type, as are synchronized interfaces and private extensions whose declaration
+includes the reserved word @b{synchronized}.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The full definition of tagged types given in
address@hidden Types and Type Extensions} includes task and protected types
+derived from interfaces.]}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The class-wide type associated with a tagged task
+type (including a task interface type) is a task type, because
address@hidden@;address@hidden is one of the language-defined classes of types 
(see
address@hidden and Subtypes}). However, the class-wide type associated with an
+interface is @i<not> an interface type, as @lquotes@;address@hidden is
address@hidden<not> one of the language-defined classes (as it is not closed 
under
+derivation). In this sense, @lquotes@;address@hidden is similar to
address@hidden@;address@hidden The class-wide type associated with an interface 
is
+a concrete (nonabstract) indefinite tagged composite type.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden@;Private address@hidden@; includes
+generic formal private extensions, as explained in
address@hidden Private and Derived Types}.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00345-01]}
address@hidden,Text=[A task interface is an @Redundant[abstract] task
+type. A protected interface is an @Redundant[abstract] protected type.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The @lquotes@;address@hidden follows
+  from the definition of an interface type.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This ensures that task operations (like abort and
+  the Terminated attribute) can be applied to a task interface type and the
+  associated class-wide type. While there are no protected type operations,
+  we apply the same rule to protected interfaces for consistency.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01]}
address@hidden,address@hidden interface type has no components.]],Old=[]}
address@hidden
address@hidden,Kind=[AddedNormal]}
+   @ChgAdded{Version=[2],Text=[This follows from the syntax and the fact that
+   discriminants are not allowed for interface types.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00419-01]}
address@hidden,address@hidden address@hidden type}
+An @Syni(interface_)@nt{subtype_mark} in an @nt{interface_list} names a
address@hidden(progenitor subtype); its type is the @i(progenitor type).
+An interface type inherits user-defined primitive subprograms from each
+progenitor type in the same way that a derived type inherits user-defined
+primitive subprograms from its progenitor types
+(see @RefSecNum{Derived Types and Classes}).]}
address@hidden,Kind=[Added],Term=<Progenitor>,
+  Text=<@ChgAdded{Version=[2],Text=[A progenitor of a derived type is
+  one of the types given in the definition of the derived type other
+  than the first. A progenitor is always an interface type.
+  Interfaces, tasks, and protected types may also have progenitors.]}>}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01]}
address@hidden,New=[All user-defined primitive subprograms of an interface
+type shall be abstract subprograms or null procedures.],Old=[]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01]}
address@hidden,New=[The type of a subtype named in an @nt{interface_list}
+shall be an interface type.],Old=[]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01],ARef=[AI95-00345-01]}
address@hidden,Text=[A type derived from a nonlimited interface shall be
+nonlimited.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00345-01]}
address@hidden,Text=[An interface derived from a task interface shall
+include the reserved word @key{task} in its
+definition; any other type derived from a task interface shall be a private
+extension or a task type declared by a task declaration (see
address@hidden Units and Task Objects}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00345-01]}
address@hidden,Text=[An interface derived from a
+protected interface shall include
+the reserved word @key{protected} in its definition; any other type derived
+from a protected interface shall be a private extension or a protected type
+declared by a protected declaration (see
address@hidden Units and Protected Objects}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00345-01]}
address@hidden,Text=[An interface derived from
+a synchronized interface shall include one of the reserved words @key{task},
address@hidden, or @key{synchronized} in its definition; any other type
+derived from a synchronized interface shall be a private extension, a task
+type declared by a task declaration, or a protected type declared by a 
protected
+declaration.]}
+
address@hidden
+   @ChgRef{Version=[2],Kind=[AddedNormal]}
+   @ChgAdded{Version=[2],Text=[We require that an interface descendant of a
+   task, protected, or synchronized interface repeat the explicit kind of
+   interface it will be, rather than simply inheriting it, so that a reader is
+   always aware of whether the interface provides synchronization and whether
+   it may be implemented only by a task or protected type. The only place where
+   inheritance of the kind of interface might be useful would be in a generic
+   if you didn't know the kind of the actual interface. However, the value of
+   that is low because you cannot implement an interface properly if you don't
+   know whether it is a task, protected, or synchronized interface. Hence, we
+   require the kind of the actual interface to match the kind of the formal
+   interface (see @RefSecNum{Formal Interface Types}).]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00345-01]}
address@hidden,Text=[No type shall be derived from both a task interface
+and a protected interface.]}
+
address@hidden
+   @ChgAdded{Version=[2],Text=[This prevents a single private
+   extension from inheriting from both a task and a protected interface. For a
+   private type, there can be no legal completion. For a generic formal derived
+   type, there can be no possible matching type (so no instantiation could be
+   legal). This rule provides early detection of the errors.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01]}
address@hidden,Text=[In addition to the places where @LegalityTitle
+normally apply (see @RefSecNum{Generic Instantiation}), these rules apply also
+in the private part of an instance of a generic
address@hidden contract issue}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[This paragraph is intended to apply to all of the
+  @LegalityTitle@; in this @Chg{Version=[3],New=[subclause],Old=[clause]}. We
+  cannot allow interface types which do not
+  obey these rules, anywhere. Luckily, deriving from a formal type (which might
+  be an interface) is not allowed for any tagged types in a generic body. So
+  checking in the private part of a generic covers all of the cases.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0070-1]}
address@hidden,Text=[The elaboration of an
address@hidden @Chg{Version=[3],New=[creates
+the interface type and its first subtype],Old=[has no effect]}.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised]}
+  @ChgAdded{Version=[2],address@hidden,New=[There is no other
+  effect. ],Old=[]}An @nt{interface_list} is made up of
+  @nt{subtype_mark}s, which do not need to be elaborated, so the
+  @nt{interface_list} does not either. This is consistent with the
+  handling of @nt{discriminant_part}s.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00411-01]}
address@hidden,Text=[Nonlimited interface types have predefined
+nonabstract equality operators. These may be overridden with user-defined
+abstract equality operators. Such operators will then require
+an explicit overriding for any nonabstract descendant of the interface.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,Type=[Leading],address@hidden of a limited
+interface and a synchronized interface extending it:}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Queue @key{is limited interface};
address@hidden Append(Q : @key{in out} Queue; Person : @key{in} Person_Name) 
@key{is abstract};
address@hidden Remove_First(Q      : @key{in out} Queue;
+                       Person : @key{out} Person_Name) @key{is abstract};
address@hidden Cur_Count(Q : @key{in} Queue) @key{return} Natural @key{is 
abstract};
address@hidden Max_Count(Q : @key{in} Queue) @key{return} Natural @key{is 
abstract};
+-- @RI[See @RefSecNum{Incomplete Type Declarations} for Person_Name.]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[AddedNormal],ARef=[AI05-0004-1]}
address@hidden,Text=[Queue_Error : @key{exception};
address@hidden Append raises Queue_Error if 
@Chg{Version=[3],New=[Cur_Count],Old=[Count]}(Q) = Max_Count(Q)]
address@hidden Remove_First raises Queue_Error if 
@Chg{Version=[3],New=[Cur_Count],Old=[Count]}(Q) = 0]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Synchronized_Queue @key{is synchronized interface 
and} Queue; address@hidden see @RefSecNum{Example of Tasking and 
Synchronization}]
address@hidden Append_Wait(Q      : @key{in out} Synchronized_Queue;
+                      Person : @key{in} Person_Name) @key{is abstract};
address@hidden Remove_First_Wait(Q      : @key{in out} Synchronized_Queue;
+                            Person : @key{out} Person_Name) @key{is 
abstract};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[...]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Transfer(From   : @key{in out} Queue'Class;
+                   To     : @key{in out} Queue'Class;
+                   Number : @key{in}     Natural := 1) @key{is}
+   Person : Person_Name;
address@hidden
+   @key{for} I @key{in} 1..Number @key{loop}
+      Remove_First(From, Person);
+      Append(To, Person);
+   @key{end loop};
address@hidden Transfer;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This defines a Queue interface defining a queue of
+people. (A similar design could be created to define any kind of queue simply
+by replacing Person_Name by an appropriate type.) The Queue interface has four
+dispatching operations, Append, Remove_First, Cur_Count, and Max_Count. The
+body of a class-wide operation, Transfer is also shown. Every nonabstract
+extension of Queue must provide implementations for at least its four
+dispatching operations, as they are abstract. Any object of a type derived from
+Queue may be passed to Transfer as either the From or the To operand. The two
+operands need not be of the same type in any given call.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The Synchronized_Queue interface inherits the four
+dispatching operations from Queue and adds two additional dispatching
+operations, which wait if necessary rather than raising the Queue_Error
+exception. This synchronized interface may only be implemented by a task or
+protected type, and as such ensures safe concurrent access.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,Type=[Leading],address@hidden use of the interface:}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0004-1]}
address@hidden,address@hidden Fast_Food_Queue @key{is new} Queue @key{with 
record} ...;
address@hidden Append(Q : @key{in out} Fast_Food_Queue; Person : @key{in} 
Person_Name);
address@hidden Remove_First(Q : @key{in out} Fast_Food_Queue; Person : 
@Chg{Version=[3],address@hidden,address@hidden Person_Name);
address@hidden Cur_Count(Q : @key{in} Fast_Food_Queue) @key{return} Natural;
address@hidden Max_Count(Q : @key{in} Fast_Food_Queue) @key{return} Natural;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[...]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Cashier, Counter : Fast_Food_Queue;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[...
+-- @RI[Add George (see @RefSecNum{Incomplete Type Declarations}) to the 
cashier's queue:]
+Append (Cashier, George);
+-- @RI[After payment, move George to the sandwich counter queue:]
+Transfer (Cashier, Counter);
+...]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[An interface such as Queue can be used directly as
+the parent of a new type (as shown here), or can be used as a progenitor when a
+type is derived. In either case, the primitive operations of the
+interface are inherited. For Queue, the implementation of the four inherited
+routines must be provided. Inside the call of Transfer, calls will dispatch to
+the implementations of Append and Remove_First for type Fast_Food_Queue.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,Type=[Leading],address@hidden of a task interface:}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Serial_Device @key{is task interface};  
address@hidden see @RefSecNum{Task Units and Task Objects}]
address@hidden Read (Dev : @key{in} Serial_Device; C : @key{out} Character) 
@key{is abstract};
address@hidden Write(Dev : @key{in} Serial_Device; C : @key{in}  Character) 
@key{is abstract};]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The Serial_Device interface has two dispatching
+operations which are intended to be implemented by task entries (see 9.1).]}
+
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01],ARef=[AI95-00345-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}Interface types
+  are new. They provide multiple inheritance of interfaces, similar to the
+  facility provided in Java and other recent language designs.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0070-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the definition
+  of elaboration for an @nt{interface_type_definition} to match that
+  of other type definitions.]}
address@hidden
+
+
address@hidden Types}
+
address@hidden
address@hidden type}
address@hidden value}
address@hidden
+A value of an access type (an @i(access value))
+provides indirect access to the object or subprogram
+it @i(designates). Depending on its type, an access value
+can designate either subprograms, objects created by allocators
+(see @RefSecNum(Allocators)), or more generally @i(aliased) objects of
+an appropriate type.
address@hidden,See=(access value)}
address@hidden type],See=(access type)}
address@hidden(Discussion)
+  A @nt<name> @i(denotes) an entity; an access value @i(designates) an
+  entity. The @lquotes@;address@hidden@; of an access value X, written
+  @lquotes@;address@hidden@rquotes@;, is a @nt<name> that denotes the entity 
designated by X.
address@hidden(Discussion)
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Access values should always be well defined
+(barring uses of certain unchecked features of 
@Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden Issues}).
+In particular, uninitialized access variables should be prevented
+by compile-time rules.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00231-01]}
address@hidden<access_type_definition>,rhs="
+    @Chg{Version=[2],New=<address@hidden >,Old=<>address@hidden
+  | @Chg{Version=[2],New=<address@hidden >,Old=<>address@hidden"}
+
address@hidden<access_to_object_definition>,rhs="
+    @key{access} address@hidden @Syn2{subtype_indication}"}
address@hidden<general_access_modifier>,rhs="@key{all} | @key{constant}"}
+
address@hidden<access_to_subprogram_definition>,rhs="
+    @key{access} address@hidden @key{procedure} @Syn2{parameter_profile}
+  | @key{access} address@hidden @key{function}  
@Syn2{parameter_and_result_profile}"}
+
address@hidden,Kind=[Added],ARef=[AI95-00231-01]}
address@hidden,lhs=<@Chg{Version=[2],New=[null_exclusion],Old=[]}>,
+rhs="@Chg{Version=[2],address@hidden @key{null}],Old=[]}"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01],ARef=[AI95-00254-01],ARef=[AI95-00404-01]}
address@hidden<access_definition>,rhs="@Chg{Version=[2],New=<
+    address@hidden @key{access} address@hidden @Syn2{subtype_mark}
+  | address@hidden @key{access} address@hidden @key{procedure} 
@Syn2{parameter_profile}
+  | address@hidden @key{access} address@hidden @key{function} 
@Syn2{parameter_and_result_profile}>,
address@hidden @Syn2{subtype_mark}]}"}
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0012],ARef=[AI95-00062-01]}
address@hidden type}
address@hidden type}
address@hidden access type}
address@hidden access type}
+There are two kinds of access types, @i{access-to-object} types, whose
+values designate objects, and @i(access-to-subprogram) types, whose
+values designate subprograms.
address@hidden pool}
+Associated with an access-to-object type is a @i(storage pool);
+several access types may share the same storage pool.
address@hidden descendants of an access type share the same storage 
pool.],Old=[]}
address@hidden element}
+A storage pool is an area of storage used to hold dynamically
+allocated objects (called @i(pool elements)) created
+by address@hidden; storage pools
+are described further in @RefSec(Storage Management)].
+
address@hidden access type}
address@hidden access type}
+Access-to-object types are further subdivided into
address@hidden(pool-specific) access types, whose values can designate only
+the elements of their associated storage pool,
+and @i(general) access types, whose
+values can designate the elements of any storage pool,
+as well as aliased objects created by declarations
+rather than allocators,
+and aliased subcomponents of other objects.
address@hidden(ImplNote)
+  The value of an access type will typically be a machine address.
+  However, a value of a pool-specific access type can be
+  represented as an offset (or index) relative to its storage pool,
+  since it can point only to the elements of that pool.
address@hidden(ImplNote)
+
address@hidden,Kind=[Revised],ARef=[AI95-00225-01],ARef=[AI95-00363-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0053-1],ARef=[AI05-0142-4],ARef=[AI05-0277-1]}
address@hidden
+A view of an object is defined to be @i(aliased) if
+it is defined by an @nt<address@hidden>@Chg{Version=[3],New=[,],Old=[ or]}
address@hidden<address@hidden>@Chg{Version=[3],New=[,
address@hidden@!specification}, or
address@hidden,Old=[]}
+with the reserved word @key(aliased), or by a renaming of an aliased view.
+In addition, the dereference of an access-to-object
+value denotes an aliased view, as does a view conversion
+(see @RefSecNum{Type Conversions}) of an aliased view.
address@hidden,New=[The],Old=[Finally, the]} current instance of
address@hidden,New=[an immutably limited type (see @RefSecNum{Limited Types})
+is],Old=[a address@hidden,New=[ tagged],Old=[]} type,
address@hidden,New=[a protected type, a task type, or a type that has the
+reserved word @key{limited} in its full definition is also],Old=[]}]}
address@hidden,New=[defined to be aliased. Finally,],Old=[and]}
+a formal parameter or generic formal object of a
+tagged type @Chg{Version=[2],New=[is],Old=[are]} defined to be aliased.
address@hidden views are the ones that can be designated by an
+access value.]
address@hidden,New=[],address@hidden, Sec=(object)}
address@hidden, Sec=(object)}
address@hidden by its initial value}
+If the view defined by an @address@hidden is aliased,
+and the type of the object has discriminants,
+then the object is constrained;
+if its nominal subtype is unconstrained,
+then the object is constrained by its initial value.
address@hidden, if the object created by an @nt<allocator>
+has discriminants, the object is constrained,
+either by the designated subtype, or by its initial value.]]}
address@hidden<Aliased>,
+  Text=<An aliased view of an object is one that can be designated by an
+  access value.
+  Objects allocated by allocators are aliased.
+  Objects can also be explicitly declared as aliased with
+  the reserved word @key(aliased).
+  The Access attribute can be used to create an access value
+  designating an aliased object.>}
address@hidden(Ramification)
+  The current instance of a nonlimited type is not aliased.
+
+  The object created by an allocator is aliased, but not its
+  subcomponents, except of course for those that themselves have @key(aliased)
+  in their @nt<component_definition>.
+
+  The renaming of an aliased object is aliased.
+
+  Slices are never aliased.
+  See @RefSecNum{Slices} for more discussion.
address@hidden(Ramification)
address@hidden(Reason)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00225-01]}
+  The current instance of a limited type is defined to be aliased
+  so that an access discriminant of a component can be initialized
+  with T'Access inside the definition of address@hidden,New=[ Note that
+  we don't want this to apply to a type that could become nonlimited later
+  within its immediate scope, so we require the full definition to be 
limited.],Old=[]}
+
+  A formal parameter of a tagged type is defined to be aliased
+  so that a (tagged) parameter X may be passed to an access parameter P
+  by using P => X'Access. Access parameters are most important
+  for tagged types because of dispatching-on-access-parameters
+  (see @RefSecNum(Dispatching Operations of Tagged Types)).
+  By restricting this to formal parameters, we minimize problems
+  associated with allowing components that are not declared aliased
+  to be pointed-to from within the same record.
+
address@hidden@;A view conversion of an aliased view is aliased so that
+  the type of an access parameter can be changed without
+  first converting to a named access type. For example:
address@hidden
address@hidden(type) T1 @key(is tagged) ...;
address@hidden(procedure) P(X : @key(access) T1);
+
address@hidden(type) T2 @key(is new) T1 @key(with) ...;
address@hidden(procedure) P(X : @key(access) T2) @key(is)
address@hidden(begin)
+    P(T1(address@hidden(all))'Access);  address@hidden hand off to T1's P]
+    . . .     address@hidden now do extra T2-specific processing]
address@hidden(end) P;
address@hidden
+
+  @ChgRef{Version=[2],Kind=[Deleted],ARef=[AI95-00363-01]}
+  @ChgDeleted{Version=[2],Text=[The rule about objects with discriminants is
+  necessary because values of a constrained access subtype
+  can designate an object whose nominal subtype is unconstrained;
+  without this rule, a check on every use of such values would
+  be required to ensure that the discriminants of the object had not
+  changed.
+  With this rule (among others), we ensure that if there might
+  exist aliased views of a discriminated object, then the object is
+  necessarily constrained.
+  Note that this rule is necessary only for untagged types,
+  since a discriminant of a tagged type can't have a default,
+  so all tagged discriminated objects are always constrained
+  anyway.]}
+  @ChgNote{This rule was a disaster, so it thankfully has been repealed.
+  We instead make general access constrained subtypes illegal if the type
+  allows unconstrained instances, see Discriminant Constraints.}
+
+  @ChgRef{Version=[2],address@hidden reported double word}
+  We considered making more kinds of objects aliased by default.
+  In particular, any object of a by-reference type will pretty
+  much have to be allocated at an addressable location,
+  so it can be passed by reference without using bit-field
+  pointers. Therefore, one might wish to allow the Access and
+  @Chg{Version=[2],New=[],Old=[and ]}Unchecked_Access attributes for such
+  objects. However, private parts are transparent to the definition of
+  @lquotes@;by-reference address@hidden@;, so if we made all objects of a 
by-reference
+  type aliased, we would be violating the privacy of private parts.
+  Instead, we would have to define a concept of @lquotes@;visibly 
address@hidden@;
+  and base the rule on that.
+  This seemed to complicate the rules more than it was worth,
+  especially since there is no way to declare an untagged limited
+  private type to be by-reference, since the full type might by
+  nonlimited.
address@hidden(Reason)
address@hidden
+  Note that we do not use the term @lquotes@;address@hidden@; to refer to 
formal
+  parameters that are referenced through multiple access paths
+  (see @RefSecNum{Formal Parameter Modes}).
address@hidden
+
+An @nt{access_to_object_definition} defines
+an access-to-object type and its first subtype;
address@hidden subtype], Sec=(of a named access type)}
address@hidden type], Sec=(of a named access type)}
+the @nt<address@hidden> defines the @i(designated subtype)
+of the access type.
+If a @nt<address@hidden@!modifier> appears, then the access type
+is a general access type.
address@hidden type}
+If the modifier is the reserved word @key(constant), then the type is an
address@hidden(access-to-constant type)@Redundant[; a designated object cannot 
be updated
+through a value of such a type].
address@hidden type}
+If the modifier is the reserved word @key(all),
+then the type is an @i(access-to-variable type)@Redundant[; a designated object
+can be both read and updated through a value of such a type].
+If no @nt<address@hidden@!modifier> appears in the
address@hidden<address@hidden@!definition>, the access type is a
+pool-specific access-to-variable type.
address@hidden
+  The type of the designated subtype is called the
+  @i{designated type}.
address@hidden
address@hidden(Reason)
+  The modifier @key(all) was picked to suggest that
+  values of a general access type could point into @lquotes@;address@hidden@; 
storage pools,
+  as well as to objects declared aliased, and that @lquotes@;address@hidden@; 
access
+  (both read and update) to the designated object was provided.
+  We couldn't think of any use for pool-specific
+  access-to-constant types, so any access type defined with
+  the modifier @key(constant) is considered a general access type,
+  and can point into any storage pool or at other (appropriate)
+  aliased objects.
address@hidden(Reason)
address@hidden(ImplNote)
+  The predefined generic Unchecked_Deallocation can be
+  instantiated for any named access-to-variable type. There
+  is no (language-defined) support for deallocating objects
+  designated by a value of an access-to-constant type. Because of this,
+  an allocator for an access-to-constant type can allocate
+  out of a storage pool with no support for deallocation.
+  Frequently, the allocation can be done at link-time,
+  if the size and initial value are known then.
address@hidden(ImplNote)
address@hidden(Discussion)
+  For the purpose of generic formal type matching, the relevant
+  subclasses of access types are access-to-subprogram
+  types, access-to-constant types, and (named) access-to-variable types,
+  with its subclass (named) general access-to-variable types.
+  Pool-specific access-to-variable types are not a separately matchable
+  subclass of types, since they don't have any @lquotes@;address@hidden@; 
operations
+  relative to all (named) access-to-variable types.
address@hidden(Discussion)
+
address@hidden type}
+An @nt{access_to_subprogram_definition} defines
+an access-to-subprogram type and its first subtype;
address@hidden profile], Sec=(of an access-to-subprogram type)}
+the @nt<parameter_profile> or @nt<parameter_and_result_profile>
+defines the @i(designated profile) of the access type.
address@hidden convention], Sec=(associated with a designated profile)}
+There is a @i(calling convention) associated with the designated
address@hidden; only subprograms with this
+calling convention can be designated by
+values of the access type.]
+By default, the calling convention is @address@hidden(protected)@rquotes@; if 
the reserved
+word @key(protected) appears, and @lquotes@;address@hidden@; otherwise.
address@hidden @RefSecNum{Interface to Other Languages}
+for how to override this default.]
address@hidden(Ramification)
+  The calling convention @i(protected) is
+  in italics to emphasize that it cannot be specified explicitly
+  by the user. This is a consequence of it being a reserved word.
address@hidden(Ramification)
address@hidden(ImplNote)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00254-01]}
+  For @Chg{Version=[2],New=[a named],Old=[an]} access-to-subprogram type, the
+  representation of an access value might include
+  implementation-defined information needed to support
+  up-level references @em for example, a static link.
+  The accessibility rules (see @RefSecNum(Operations of Access Types)) ensure
+  that in a "global-display-based" implementation model (as opposed to
+  a static-link-based model), @Chg{Version=[2],New=[a named],Old=[an]}
+  access-to-(unprotected)-subprogram value need consist only of the
+  address of the subprogram. The global display is guaranteed
+  to be properly set up any time the designated subprogram is called.
+  Even in a static-link-based model, the only time a static link
+  is definitely required is for an access-to-subprogram type declared
+  in a scope nested at least two levels deep within subprogram or
+  task bodies, since values of such a type might designate subprograms
+  nested a smaller number of levels. For the normal case of
+  @Chg{Version=[2],New=[a named],Old=[an]} access-to-subprogram type
+  declared at the outermost (library) level,
+  a code address by itself should be sufficient to represent the
+  access value in many implementations.
+
+  For access-to-protected-subprogram, the access values will necessarily
+  include both an address (or other identification) of the code of the
+  subprogram, as well as the address of the associated protected object.
+  This could be thought of as a static link, but it will be needed even
+  for global-display-based implementation models. It corresponds
+  to the value of the @lquotes@;implicit address@hidden@; that is passed into
+  every call of a protected operation, to identify the current instance
+  of the protected type on which they are to operate.
+
+  Any Elaboration_Check is performed when a call
+  is made through an access value, rather than when the
+  access value is first "created" via a 'Access.
+  For implementation models that normally put that check at the
+  call-site, an access value will have to point to a separate
+  entry point that does the check. Alternatively, the
+  access value could point to a "subprogram descriptor" that
+  consisted of two words (or perhaps more), the first being
+  the address of the code, the second being the elaboration bit.
+  Or perhaps more efficiently, just the address of the code,
+  but using the trick that the descriptor is initialized to
+  point to a Raise-Program-Error routine initially, and then
+  set to point to the "real" code when the body is elaborated.
+
+  For implementations that share code between generic instantiations,
+  the extra level of indirection suggested above to support
+  Elaboration_Checks could also be used to provide a pointer to the
+  per-instance data area normally required when calling shared code.
+  The trick would be to put a pointer to the per-instance data
+  area into the subprogram descriptor, and then make sure that
+  the address of the subprogram descriptor is loaded into a
+  "known" register whenever an indirect call is performed.
+  Once inside the shared code, the address of the per-instance
+  data area can be retrieved out of the subprogram descriptor,
+  by indexing off the "known" register.
+
+  @ChgRef{Version=[2],Kind=[Deleted],ARef=[AI95-00344-01]}
+  @ChgNote{This is not remotely true with nested extensions and with
+  interfaces. I don't much feel like trying to explain this properly.}
+  @ChgDeleted{Version=[2],Text=[Essentially the same implementation issues
+  arise for calls on dispatching operations of tagged types, except that
+  the static link is always known "statically."]}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00254-01]}
+  Note that access parameters of an
+  anonymous access-to-subprogram type are @Chg{Version=[2],New=[],Old=[not 
]}permitted.
+  @Chg{Version=[2],New=[Such],Old=[If there were such]} address@hidden,
+  New=[ represent],Old=[,]} full @lquotes@;address@hidden@;
+  address@hidden,New=[],Old=[would be required]}, meaning that
+  in an implementation that uses a per-task (global) display,
+  the display @Chg{Version=[2],New=[will],Old=[would]} have to be passed
+  as a hidden parameter,
+  and reconstructed at the point of address@hidden,New=[],
+  Old=[ This was felt to be an undue implementation burden,
+  given that an equivalent (actually, more general) capability
+  is available via formal subprogram parameters to a generic.]}
address@hidden(ImplNote)
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00231-01],ARef=[AI95-00254-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden access type}
address@hidden subtype], Sec=(of an anonymous access type)}
address@hidden type], Sec=(of an anonymous access type)}
+An @nt{access_definition} defines an anonymous
+general @Chg{Version=[2],New=[access type or an
+anonymous access-to-subprogram type. For a general access type,],
+Old=[access-to-variable type;]} the @nt<subtype_mark> denotes
+its @i(designated subtype)@Chg{Version=[2],New=[; if the
address@hidden@address@hidden @key{constant} appears, the type is an
+access-to-constant type; address@hidden,New=[,],Old=[]} it is
+an access-to-variable type. For an access-to-subprogram type, the
address@hidden@!profile} or @address@hidden@address@hidden denotes its
address@hidden address@hidden profile], Sec=(of an anonymous access type)}],
+Old=[. @Redundant[An @nt<access_definition> is used in the
+specification of an access discriminant
+(see @RefSecNum(Discriminants)) or an access
+parameter (see @RefSecNum(Subprogram Declarations)).]]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00231-01]}
address@hidden value], Sec=(of an access type)}
+For each @Chg{Version=[2],New=[],Old=[(named) ]}access type, there is
address@hidden,New=[],Old=[a literal @key(null) which has ]}a null
+access value designating no entity at address@hidden,New=[, which can be
+obtained by (implicitly) converting the literal @key{null} to the access
+type],Old=[]}.
address@hidden null value of @Chg{Version=[2],New=[an],Old=[a named]} access
+type is the default initial value of the type.]
address@hidden,New=[Nonnull],Old=[Other]} values of an
address@hidden,New=[-to-object],Old=[]} type are
+obtained by evaluating @Chg{Version=[2],New=[],Old=[an
address@hidden<attribute_reference> for the Access or Unchecked_Access
+attribute of an aliased view of an object or nonintrinsic
+subprogram, or, in the case of a named access-to-object type,]}
+an @nt<allocator>@Redundant[, which
+returns an access value designating a newly created object
+(see @RefSecNum(Operations of Access Types))address@hidden,New=[, or in the
+case of a general access-to-object type, evaluating an
address@hidden for the Access or Unchecked_Access
+attribute of an aliased view of an object. Nonnull values of an
+access-to-subprogram type are obtained by evaluating an
address@hidden for the Access attribute of a
+nonintrinsic subprogram],Old=[]}.
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Deleted],ARef=[AI95-00231-01]}
+  @ChgDeleted{Version=[2],Text=[A value of an anonymous access type
+  (that is, the value of an access parameter or access discriminant)
+  cannot be null.]}
address@hidden
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00231-01]}
address@hidden,Text=[Access parameters allow dispatching on the
+tag of the object designated
+by the actual parameter (which gets converted to the anonymous access
+type as part of the call).
+In order for dispatching to work properly,
+there had better be such an object.
+Hence, the type conversion will raise Constraint_Error if the value of
+the actual parameter is null.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00231-01]}
address@hidden,address@hidden null],Sec=[subtype]}
+A @nt{null_exclusion} in a construct specifies
+that the null value does not belong to the access subtype defined by the
+construct, that is, the access subtype @i{excludes null}. In addition, the
+anonymous access subtype defined by the @nt{access_definition} for a 
controlling
+access parameter (see @RefSecNum{Dispatching Operations of Tagged Types})
+excludes null. Finally, for a @nt{subtype_indication} without a
address@hidden, the subtype denoted by the @nt{subtype_indication}
+excludes null if and only if the subtype denoted by the @nt{subtype_mark} in
+the @nt{subtype_indication} excludes null.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],Text=[An @nt{access_definition} used in a controlling
+  parameter excludes null because it is necessary to read the tag to
+  dispatch, and null has no tag. We would have preferred to
+  require @key{not null} to be specified for such
+  parameters, but that would have been too incompatible with Ada 95 code
+  to require.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[Note that we considered imposing a similar
+  implicit null exclusion for controlling access results, but chose not to do
+  that, because there is no Ada 95 compatibility issue, and there is no
+  automatic null check inherent in the use of a controlling access result. If a
+  null check is necessary, it is because there is a dereference of the result,
+  or because the value is passed to a parameter whose subtype excludes null.
+  If there is no dereference of the result, a null return value is perfectly
+  acceptable, and can be a useful indication of a particular status of the
+  call.]}
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0013],ARef=[AI95-00012-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Sec=(subtype)}
address@hidden,Sec=(subtype)}
address@hidden subtypes of an access-to-subprogram type
+are constrained.] The first subtype of a type defined by
+an 
@address@hidden<access_definition>],address@hidden<access_type_definition>]} or 
an
address@hidden<access_to_object_definition> is unconstrained if the designated 
subtype
+is an unconstrained array or discriminated @Chg{New=[subtype],Old=[type]};
address@hidden,New=[,],Old=[]} it is constrained.
address@hidden(TheProof)
+  The @LegalityTitle on @nt<range_constraint>s (see @RefSecNum(Scalar Types))
+  do not permit the @nt<subtype_mark> of the @nt<subtype_indication> to denote
+  an access-to-scalar type, only a scalar type.
+  The @LegalityTitle on @nt<index_constraint>s
+  (see @RefSecNum(Index Constraints and Discrete Ranges)) and
+  @nt<discriminant_constraint>s (see @RefSecNum(Discriminant Constraints))
+  both permit access-to-composite types in a @nt<subtype_indication>
+  with such address@hidden<constraint>s. Note that an 
access-to-access-to-composite
+  is never permitted in a @nt<subtype_indication> with a @nt<constraint>.
address@hidden(TheProof)
address@hidden(Reason)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00363-01]}
+  Only @nt<composite_constraint>s are permitted
+  for an access type, and only
+  on access-to-composite types.
+  A constraint on an access-to-scalar or access-to-access type
+  might be violated due to assignments
+  via other access paths that were not so constrained. By contrast,
+  if the designated subtype is an array or discriminated
+  address@hidden,New=[ without defaults],Old=[]},
+  the constraint could not be violated by unconstrained assignments,
+  since array objects are always constrained, and
+  @Chg{Version=[2],New=[],Old=[aliased]} discriminated objects are
+  also constrained @Chg{Version=[2],New=[when the type does not have defaults
+  for its discriminants. Constraints are not allowed on general 
access-to-unconstrained
+  discriminated types if the type has defaults for its discriminants;
+  constraints on pool-specific access types are usually allowed because
+  allocated objects are usually constrained by their initial value.],
+  Old=[(by fiat, see @StaticSemTitle).]}
address@hidden(Reason)
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00231-01]}
address@hidden,Text=[If a
address@hidden@!indication}, @address@hidden,
address@hidden@!specification}, @address@hidden@address@hidden,
address@hidden@address@hidden, or @address@hidden@!declaration}
+has a @address@hidden, the @address@hidden in that construct
+shall denote an access subtype that does not exclude null.]}
address@hidden(Honest)
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],Text=[This means @lquotes@;directly allowed 
address@hidden;
+  we are not talking about a @nt{null_exclusion} that occurs in an
+  @nt{access_definition} in one of these constructs (for an
+  @nt{access_definition}, the @nt{subtype_mark} in such an
+  @nt{access_definition} is not restricted).]}
address@hidden(Honest)
address@hidden(Reason)
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],Text=[This is similar to doubly constraining a
+  composite subtype, which we also don't allow.]}
address@hidden(Reason)
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00231-01]}
address@hidden,
+  Sec=(composite_constraint with an access subtype)}
+A @nt<composite_constraint> is @i(compatible) with an unconstrained
+access subtype if it is compatible with the designated
address@hidden,New=[ A @nt{null_exclusion} is compatible with any
+access subtype that does not exclude null.],Old=[]}
address@hidden, Sec=(for an access value)}
+An access value @i(satisfies) a @nt<composite_constraint> of an access
+subtype if it equals the null value of its type
+or if it designates an object whose value satisfies the
address@hidden,New=[ An access value satisfies an exclusion
+of the null value if it does not equal the
+null value of its type.],Old=[]}
+
address@hidden, Sec=(access_type_definition)}
+The elaboration of an @nt{access_type_definition}
+creates the access type and its first subtype.
+For an access-to-object type,
+this elaboration includes the elaboration of the @nt{subtype_indication},
+which creates the designated subtype.
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00254-01]}
address@hidden, Sec=(access_definition)}
+The elaboration of an @nt{access_definition} creates
+an address@hidden,New=[],Old=[ general]} address@hidden,
+New=[],Old=[-to-variable]} address@hidden,New=[],
+Old=[ @Redundant[(this happens as part of the initialization of
+an access parameter or access discriminant)]]}.
address@hidden
+
address@hidden
+Access values are called @lquotes@;address@hidden@; or 
@lquotes@;address@hidden@; in
+some other languages.
+
+Each access-to-object type has an associated storage pool;
+several access types can share the same pool.
+An object can be created in the storage pool of an
+access type by an @nt{allocator} (see @RefSecNum{Allocators})
+for the access type.
+A storage pool (roughly) corresponds to what some other languages
+call a @lquotes@;address@hidden@;
+See @RefSecNum{Storage Management} for a discussion of pools.
+
+Only @nt<index_constraint>s and @nt<discriminant_constraint>s
+can be applied to access types
+(see @RefSecNum{Index Constraints and Discrete Ranges} and
address@hidden Constraints}).
address@hidden
+
address@hidden
address@hidden@address@hidden of access-to-object types:}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden,Kind=[Revised],ARef=[AI12-0056-1]}
address@hidden,address@hidden Frame @key<is access> Matrix;    address@hidden  
see @RefSecNum{Array Types}]
+],address@hidden Peripheral_Ref @key<is @Chg{Version=[2],New=[not null 
],Old=[]}access> Peripheral;  address@hidden  see @RefSecNum{Variant Parts and 
Discrete Choices}]
address@hidden Binop_Ptr @key[is access all] Binary_Operation'Class;
+                                           address@hidden general 
access-to-class-wide, see @RefSecNum{Type Extensions}]
address@hidden
+
address@hidden
address@hidden@address@hidden of an access subtype:}
address@hidden
address@hidden
address@hidden Drum_Ref @key[is] Peripheral_Ref(Drum);  address@hidden  see 
@RefSecNum{Variant Parts and Discrete Choices}]
address@hidden
+
address@hidden
address@hidden@address@hidden of an access-to-subprogram type:}
address@hidden
address@hidden
address@hidden Message_Procedure @key[is] @key[access] @key[procedure] (M : 
@key[in] String := "Error!");
address@hidden Default_Message_Procedure(M : @key[in] String);
+Give_Message : Message_Procedure := Default_Message_Procedure'Access;
+...
address@hidden Other_Procedure(M : @key[in] String);
+...
+Give_Message := Other_Procedure'Access;
+...
+Give_Message("File not found.");  address@hidden call with parameter 
(address@hidden is optional)}
address@hidden;                 address@hidden call with no parameters}
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax for @nt{access_type_definition} is
+changed to support general access
+types (including access-to-constants) and access-to-subprograms.
+The syntax rules for @nt{general_access_modifier} and
address@hidden are new.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0190-1]}
+  We use the term "storage pool" to talk about the data area from which
+  allocation takes place. The term "collection" is @Chg{Version=[3],New=[only
+  used for finalization],Old=[no longer used]}. ("Collection" and "storage 
pool"
+  are not the same thing because multiple unrelated access types can share the
+  same storage pool; see @RefSecNum(Storage Management) for more discussion.)
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  Access discriminants and noncontrolling access parameters no longer
+  exclude null. A program which passed @key{null} to such an access
+  discriminant or access parameter and expected it to raise Constraint_Error
+  may fail @ChgNote{but not if the parameter is dereferenced in the subprogram 
or
+  record }when compiled with Ada 2005. One hopes that there no such programs
+  outside of the ACATS. (Of course, a program which actually wants to pass
+  @key{null} will work, which is far more likely.)]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00363-01]}
+  @ChgAdded{Version=[2],Text=[Most unconstrained aliased objects
+  with defaulted discriminants are no longer
+  constrained by their initial values. This means that a program that
+  raised Constraint_Error from an attempt to change the discriminants
+  will no longer do so. The change only affects programs that depended
+  on the raising of Constraint_Error in this case, so the inconsistency
+  is unlikely to occur outside of the ACATS. This change may however cause
+  compilers to implement these objects differently, possibly taking additional
+  memory or time. This is unlikely to be worse than the differences caused by
+  any major compiler upgrade.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00225-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @B[Amendment Correction:] The rule defining when a current instance of a
+  limited type is considered to be aliased has been tightened to apply only to
+  types that cannot become nonlimited. A program that attempts to take 'Access
+  of the current instance of a limited type that can become nonlimited will be
+  illegal in Ada 2005. While original Ada 95 allowed the current instance of
+  any limited type to be treated as aliased, this was inconsistently
+  implemented in compilers, and was likely to not work as expected for types
+  that are ultimately nonlimited.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00231-01]}
address@hidden,address@hidden to Ada 95}The @nt{null_exclusion} is
+new. It can be used in both anonymous and named access type definitions.
+It is most useful to declare that parameters cannot be @key{null},
+thus eliminating the need for checks on use.],Old=[]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00231-01],ARef=[AI95-00254-01],ARef=[AI95-00404-01]}
address@hidden,New=[The kinds of anonymous
+access types allowed were increased by adding anonymous access-to-constant
+and anonymous access-to-subprogram types. Anonymous access-to-subprogram
+types used as parameters allow passing of subprograms at any level.],Old=[]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0012],ARef=[AI95-00062-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added accidentally-omitted
+  wording that says that a derived access type shares its storage pool with its
+  parent type. This was clearly intended, both because of a note in
+  @RefSecNum{Derived Types and Classes}, and because anything else would
+  have been incompatible with Ada 83.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0013],ARef=[AI95-00012-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Fixed typographical 
errors in
+  the description of when access types are constrained.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01]}
+  @ChgAdded{Version=[2],Text=[The wording was fixed to allow @nt{allocator}s 
and
+  the literal @key{null} for anonymous access types. The former was clearly
+  intended by Ada 95; see the @ImplAdviceTitle in @RefSecNum{Storage 
Management}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00363-01]}
+  @ChgAdded{Version=[2],Text=[The rules about aliased objects being 
constrained by
+  their initial values now apply only to allocated objects, and thus have
+  been moved to @RefSec{Allocators}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0053-1],ARef=[AI05-0277-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> The rule about a current 
instance
+  being aliased now is worded in terms of immutably limited types.
+  Wording was also added to make extended return object declarations that have 
the
+  keyword @key[aliased] be considered aliased. This latter was a significant
+  oversight in Ada 2005 @em technically, the keyword @key[aliased] had no
+  effect. But of course implementations followed the intent, not the letter of
+  the Standard.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0142-4]}
+  @ChgAdded{Version=[3],Text=[Explicitly aliased parameters (see
+  @RefSecNum{Subprogram Declarations}) are defined to be aliased.]}
address@hidden
+
+
address@hidden Type Declarations}
+
address@hidden
+There are no particular limitations on the designated type of an
+access type. In particular, the type of a component of the
+designated type can be another access type, or even the same access
+type. This permits mutually dependent and recursive access types.
+An @nt<incomplete_type_declaration> can be used to introduce a type
+to be used as a designated type, while deferring its full definition
+to a subsequent @nt<full_type_declaration>.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00326-01]}
address@hidden<incomplete_type_declaration>,
+rhs="@key{type} @Syn2{defining_identifier} 
address@hidden@Chg{Version=[2],New=< address@hidden tagged}]>,Old=<>};"}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00326-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0137-1]}
address@hidden,address@hidden address@hidden view}
+An @nt{incomplete_type_declaration} declares
+an @i{incomplete view} of a
+type and its first subtype; the first subtype is unconstrained if
+a @nt<discriminant_part> appears. If the
address@hidden@address@hidden includes the reserved word @key{tagged}, it
+declares a @i{tagged incomplete address@hidden view],address@hidden incomplete 
view}
address@hidden,New=[If @i{T} denotes a tagged incomplete view, then
address@hidden'Class denotes a tagged incomplete view. ],address@hidden 
incomplete
+view of a type is a limited view of the type (see @RefSecNum{Limited 
Types}).]]}
+
address@hidden,Kind=[Added],ARef=[AI95-00326-01]}
address@hidden,Type=[Leading],Text=[Given an access type @i{A} whose
+designated type @i{T} is
+an incomplete view, a dereference of a value of type @i{A} also
+has this incomplete view except when:]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0208-1]}
+  @ChgAdded{Version=[3],Text=[Whether the designated type is an incomplete view
+  (and thus whether this set of rules applies) is determined by the view of the
+  type at the declaration of the access type; it does not change during the 
life
+  of the type.]}
address@hidden
address@hidden
address@hidden,Kind=[Added]}
address@hidden,New=[it occurs within the immediate scope of the completion
+of @i{T}, or],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0208-1]}
address@hidden,Text=[it occurs within the scope of a @nt{nonlimited_with_clause}
+that mentions a library package in whose visible part the completion of @i{T}
+is address@hidden,New=[, or],Old=[.]}]}
+
address@hidden,Kind=[Added],ARef=[AI05-0208-1]}
address@hidden,Text=[it occurs within the scope of the completion
+of @i{T} and @i{T} is an incomplete view declared by an
address@hidden
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0162-1]}
address@hidden,Text=[In these cases, the dereference has the
address@hidden,New=[],Old=[full ]}view
+of @address@hidden,New=[
+visible at the point of the dereference],Old=[]}.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[We need the @lquotes@;in
+  whose visible address@hidden@; rule so that the second rule doesn't trigger
+  in the body of a package with a @key{with} of a child unit:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden P @Key{is}
address@hidden
+   @Key{type} T;
+   @Key{type} PtrT @Key{is access} T;
address@hidden P;],Old=[]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden package} P.C @Key{is}
+   Ptr : PtrT;
address@hidden P.C;],Old=[]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,address@hidden P.C;
address@hidden body} P @Key{is}
+    -- @RI{Ptr.all'Size is not legal here, but @Chg{Version=[3],New=[we are 
within],Old=[it is in]} the scope}
+    -- @RI{of a @nt{nonlimited_with_clause} @RI{for P.}}
address@hidden T @Key{is} ...
+    --  @RI{Ptr.all'Size is legal here.}
address@hidden P;],Old=[]}
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00412-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0162-1],ARef=[AI05-0208-1]}
address@hidden,Text=[Similarly, if a @nt{subtype_mark} denotes a
address@hidden defining a subtype of an incomplete view @i<T>, the
address@hidden denotes an incomplete view except under the
+same @Chg{Version=[3],New=[three],Old=[two]}
+circumstances given above, in which case it denotes the
address@hidden,New=[],Old=[full ]}view of @i<T>@Chg{Version=[3],New=[ visible 
at the
+point of the @nt{subtype_mark}],Old=[]}.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0162-1]}
address@hidden a completion], Sec=(@nt<incomplete_type_declaration>)}
+An @address@hidden@!declaration} requires a completion, which shall
+be a @Chg{Version=[3],address@hidden@!declaration} other than an
address@hidden@address@hidden,address@hidden@address@hidden
address@hidden the @address@hidden@!declaration} occurs immediately
+within either the visible part of a
address@hidden@!specification} or a @nt<address@hidden>,
+then the @Chg{Version=[3],address@hidden@!declaration}],
address@hidden@address@hidden shall occur later and immediately within this
+visible part or @nt<address@hidden>.
+If the @address@hidden@!declaration} occurs
+immediately within the private part of a
+given @nt<address@hidden>, then the
address@hidden,address@hidden@!declaration}],
address@hidden@address@hidden shall occur later and immediately
+within either the private part itself, or the @address@hidden
+of the corresponding @address@hidden
address@hidden
+This is implied by the next AARM-only rule,
+plus the rules in @RefSec{Completions of Declarations}
+which require a completion to appear later and immediately within
+the same declarative region.
address@hidden
address@hidden
+If the @nt{incomplete_type_declaration} occurs immediately within
+the visible part of a @nt{package_specification},
+then the @Chg{Version=[3],New=[completing @address@hidden,
address@hidden@address@hidden
+shall occur immediately within this visible part.
address@hidden
address@hidden(Honest)
+  If the implementation supports it, an
+  @nt{incomplete_type_declaration} can be @Chg{Version=[3],New=[imported
+  (using aspect Import, see @RefSecNum{Interfacing Aspects}), in which
+  case no explicit completion is allowed],Old=[completed by a @nt{pragma}
+  Import]}.
address@hidden(Honest)
+
address@hidden,Kind=[Revised],ARef=[AI95-00326-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0162-1]}
address@hidden,New=[If an @address@hidden@!declaration} includes the
+reserved word @key{tagged}, then a 
@Chg{Version=[3],address@hidden@!declaration}],
address@hidden@address@hidden that completes
+it shall declare a tagged type. ],Old=[]}If an @address@hidden@!declaration}
+has a @address@hidden@!part},
+then a @Chg{Version=[3],address@hidden@!declaration}],
address@hidden@address@hidden that completes it shall have a fully
+conforming (explicit) @address@hidden@!part}
+(see @RefSecNum(Conformance Rules)).
address@hidden conformance],Sec=(required)}
address@hidden an @address@hidden@!declaration} has no @nt<discriminant_part>
+(or an @nt<address@hidden@!part>),
+then a corresponding @Chg{Version=[3],address@hidden@!declaration}],
address@hidden@address@hidden is nevertheless allowed
+to have discriminants, either explicitly, or inherited via derivation.]
+
+
address@hidden@keepnext@;@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00326-01]}
address@hidden,New=[A],Old=[The only allowed uses of a]} @nt{name} that
+denotes an @Chg{Version=[2],New=[incomplete view of a type may be used],
address@hidden are]} as follows:
address@hidden(Discussion)
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00326-01]}
+  @ChgDeleted{Version=[2],Text=[No need to say "prior to the end of the
+  @nt{full_type_declaration}" since the name would not denote the
+  @nt{incomplete_type_declaration} after the end of the
+  @nt{full_type_declaration}. Also, with child library units, it would not be
+  well defined whether they come before or after the @nt<full_type_declaration>
+  for deferred incomplete types.]}
address@hidden(Discussion)
address@hidden(itemize)
address@hidden,Kind=[Revised],ARef=[AI05-0098-1]}
+  as the @nt{subtype_mark} in the @nt{subtype_indication}
+  of an @address@hidden@!definition};
+  @Redundant[the only form of @nt{constraint} allowed in this
+  @nt{subtype_indication} is a @address@hidden,New=[
+  @Redundant[(a @nt{null_exclusion} is not allowed)]],Old=[]};]
+  @begin(ImplNote)
+    We now allow @nt<discriminant_constraint>s even if the
+    full type is deferred to the package body. However, there
+    is no particular implementation burden because we have
+    dropped the concept of the dependent compatibility check.
+    In other words, we have effectively repealed AI83-00007.
+  @end(ImplNote)
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00326-01],address@hidden old 
rule is moved}
+  as the @nt{subtype_mark} @Chg{Version=[2],New=[in the @nt{subtype_indication}
+  of a @nt{subtype_declaration}; the @address@hidden shall not have a
+  @address@hidden or a @nt{constraint};],Old=[defining the subtype
+  of a parameter or result of an @address@hidden@!definition};]}
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],address@hidden moved}
+    @ChgDeleted{Version=[2],Text=[This allows, for example, a record to have a
+    component designating a subprogram that takes that same record
+    type as a parameter.]}
+  @end{Reason}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00326-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0151-1]}
+  as the @nt<subtype_mark> in an
+  @nt<access_definition>@Chg{Version=[2],address@hidden,New=[ for
+  an access-to-object type;],Old=[.]}],Old=[;]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This does not mean any random @nt{subtype_mark}
+  in a construct that makes up an @nt<access_definition>, such as
+  a @nt<formal_part>, just the one given directly in the syntax of
+  @nt<access_definition>.]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0151-1]}
+  @ChgAdded{Version=[3],Text=[as the @nt{subtype_mark} defining the subtype
+  of a parameter or result in a profile occurring within a
+  @nt{basic_declaration};]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[But not in the profile for a body or entry.]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0213-1]}
+  @ChgAdded{Version=[3],Text=[as a generic actual parameter whose corresponding
+  generic formal parameter is a formal incomplete type (see
+  @RefSecNum{Formal Private and Derived Types}).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00326-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[If such a @nt{name}
+denotes a tagged incomplete view, it may also be used:]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00326-01]}
+  @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0151-1]}
+  @ChgAdded{Version=[2],Text=[as the @nt{subtype_mark} defining the subtype of 
a
+  parameter in @Chg{Version=[3],New=[the profile for a @nt{subprogram_body},
+  @nt{entry_body}, or @nt{accept_statement}],Old=[a @nt{formal_part}]};]}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00326-01]}
+  as the @nt{prefix} of an @nt{attribute_reference}
+  whose @address@hidden
+  is Class; such an @address@hidden
+  is @Chg{Version=[2],New=[],Old=[similarly ]}restricted to the uses
+  allowed here;
+  @Chg{Version=[2],New=[it denotes a tagged incomplete view],
+  Old=[when used in this way,
+  the corresponding @address@hidden shall
+  declare a tagged type, and the @nt<address@hidden>
+  shall occur in the same library unit as
+  the @nt<address@hidden@!declaration>]}.
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[Deleted],ARef=[AI95-00326-01]}
+    @ChgDeleted{Version=[2],Text=[This is to prevent
+    children from imposing requirements on their ancestor library
+    units for deferred incomplete types.]}
+  @end{reason}
address@hidden(itemize)
+
address@hidden,Kind=[Added],ARef=[AI95-00326-01]}
address@hidden,Kind=[DeletedAdded],ARef=[AI05-0151-1]}
address@hidden,Type=[Leading],address@hidden,New=[],Old=[If
+such a @nt{name} occurs within
+the declaration list containing the completion of the
+incomplete view, it may also be used:]}]}
+
address@hidden
address@hidden,Kind=[Added],address@hidden moved}
address@hidden,Kind=[DeletedAdded],ARef=[AI05-0098-1],address@hidden part of 
the next paragraph}
address@hidden,address@hidden,New=[],Old=[as the @nt{subtype_mark} defining the 
subtype of a
+parameter or result of an @address@hidden@!definition}.]}]}
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgRef{Version=[3],Kind=[Deleted]}
+    @ChgAdded{Version=[2],address@hidden,New=[],Old=[This allows,
+    for example, a record to have a
+    component designating a subprogram that takes that same record
+    type as a parameter.]}]}
+  @end{Reason}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00326-01]}
address@hidden,Text=[If any of the above uses occurs as part of the
+declaration of a primitive subprogram of the incomplete view,
+and the declaration occurs immediately within the private part of a package, 
then
+the completion of the incomplete view shall also
+occur immediately within the private part; it shall not be deferred to the
+package body.]}
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[This fixes a hole in Ada 95 where a dispatching
+    operation with an access parameter could be declared in a private part
+    and a dispatching call on it could occur in a child even though there is
+    no visibility on the full type, requiring access to the controlling tag
+    without access to the representation of the type.]}
+  @end{Reason}
+
address@hidden,Kind=[Added],ARef=[AI95-00326-01]}
address@hidden,Text=[No other uses of a @nt{name} that denotes an
+incomplete view of a type are allowed.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00326-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0151-1]}
address@hidden,New=[A @nt{prefix} that denotes an object],
+Old=[A dereference (whether implicit or explicit @em see @RefSecNum(Names))]}
+shall not be of an incomplete @Chg{Version=[2],New=[view],address@hidden,New=[
+An actual parameter in a call shall not be of an untagged incomplete
+view. The result object of a function call shall not be of an
+incomplete view. A @nt{prefix} shall not denote a subprogram
+having a formal parameter of an untagged incomplete view,
+nor a return type that is an incomplete view.],Old=[]}
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[We used to disallow all dereferences of an 
incomplete
+    type. Now we only disallow such dereferences when used as a @nt{prefix}.
+    Dereferences used in other contexts do not pose a problem since normal type
+    matching will preclude their use except when the full type is 
@lquotes@;address@hidden@;
+    as context (for example, as the expected type).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[This also disallows @nt{prefix}es that are
+    directly of an incomplete view. For instance, a parameter @i{P} can be
+    declared of a tagged incomplete type, but we don't want to allow 
@i{P}'Size,
+    @i{P}'Alignment, or the like, as representation values aren't known for an
+    incomplete view.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[We say @lquotes@;denotes an address@hidden
+    so that prefixes that directly name an incomplete view are not covered;
+    the previous rules cover such cases, and we certainly don't want to ban
+    Incomp'Class.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0151-1]}
+    @ChgAdded{Version=[3],Text=[As subprogram profiles now may include any
+    kind of incomplete type, we also disallow passing objects of untagged
+    incomplete types in subprogram calls (as the parameter passing method
+    is not known as it is for tagged types) and disallow returning any
+    sort of incomplete objects (since we don't know how big they are).]}
+  @end{Reason}
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00326-01]}
address@hidden,address@hidden type}
+An @nt{incomplete_type_declaration} declares an incomplete
+type and its first subtype; the first subtype is unconstrained if
+a @nt<known_discriminant_part> appears.]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[If an @nt<unknown_discriminant_part> or
+no @nt{discriminant_part}
+appears, then the constrainedness of the first subtype doesn't matter
+for any other rules or semantics, so we don't bother defining it.
+The case with a @nt<known_discriminant_part> is the only case in which
+a constraint could later be given in a @nt{subtype_indication} naming
+the incomplete type.]}
address@hidden
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraph 11 was
+deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered.}
address@hidden
+
address@hidden
address@hidden, Sec=(incomplete_type_declaration)}
+The elaboration of an @nt{incomplete_type_declaration} has no effect.
address@hidden(Reason)
+  An incomplete type has no real existence, so it doesn't need to be
+  "created" in the usual sense we do for other types.
+  It is roughly equivalent to a "forward;" declaration in Pascal.
+  Private types are different, because they have a different
+  set of characteristics from their full type.
address@hidden(Reason)
address@hidden
+
address@hidden
address@hidden legality}
+Within a @nt<declarative_part>, an @nt<incomplete_type_declaration>
+and a corresponding @nt<full_type_declaration> cannot be separated
+by an intervening body.
+This is because a type has to
+be completely defined before it is frozen, and a body freezes
+all types declared prior to it in the same @nt<declarative_part>
+(see @RefSecNum{Freezing Rules}).
+
address@hidden,Kind=[Added],ARef=[AI05-0151-1],ARef=[AI05-0269-1]}
address@hidden,Text=[A @nt{name} that denotes an object of an
+incomplete view is defined to be of a limited type. Hence, the target of
+an assignment statement cannot be of an incomplete view.]}
+
address@hidden
+
address@hidden
address@hidden@address@hidden(Example of a recursive type:)
address@hidden(Example)
address@hidden(type) Cell;  address@hidden  incomplete type declaration]
address@hidden(type) Link @key(is) @key(access) Cell;
+
address@hidden(type) Cell @key(is)
+   @key(record)
+      Value  : Integer;
+      Succ   : Link;
+      Pred   : Link;
+   @key(end) @key(record);
+
+Head   : Link  := @key(new) Cell'(0, @key(null), @key(null));
+Next   : Link  := Head.Succ;
address@hidden(Example)
+
address@hidden(Examples of mutually dependent access types:)
address@hidden(Example)
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden(type) Person(<>);    address@hidden incomplete type declaration]
address@hidden(type) address@hidden,New=[ @key{is tagged};],Old=[;          ]} 
address@hidden incomplete type declaration]
+
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden(type) Person_Name @key(is) @key(access) Person;
address@hidden(type) Car_Name    @key(is) @key(access) @key(all) 
address@hidden,New=['Class],Old=[]};
+
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden(type) Car @key(is)@Chg{Version=[2],New=[ @key(tagged)],Old=[]}
+   @key(record)
+      Number  : Integer;
+      Owner   : Person_Name;
+   @key(end) @key(record);
+
+
address@hidden(type) Person(Sex : Gender) @key(is)
+   @key(record)
+      Name     : String(1 .. 20);
+      Birth    : Date;
+      Age      : Integer @key(range) 0 .. 130;
+      Vehicle  : Car_Name;
+      @key(case) Sex @key(is)
+         @key(when) M => Wife           : Person_Name(Sex => F);
+         @key(when) F => Husband        : Person_Name(Sex => M);
+      @key(end) @key(case);
+   @key(end) @key(record);
+
+My_Car, Your_Car, Next_Car : Car_Name := @key[new] Car;  address@hidden see 
@RefSecNum{Allocators}]
+George : Person_Name := @key[new] Person(M);
+   ...
+George.Vehicle := Your_Car;
address@hidden(Example)
+
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The @nt{full_type_declaration} that completes an
address@hidden may have a
address@hidden even if the
address@hidden does not.
+
address@hidden,address@hidden AI-00013}
+A @nt<discriminant_constraint> may be applied
+to an incomplete type, even if @Chg{New=[],Old=[it ]}its completion is
+deferred to the package body, because there is no
address@hidden@;dependent compatibility address@hidden@; required any more.
+Of course, the constraint can be specified only if
+a @nt<known_discriminant_part> was given in the
address@hidden<incomplete_type_declaration>. As mentioned in the previous
+paragraph, that is no longer required even when the full type
+has discriminants.
address@hidden
+
address@hidden
address@hidden@;Dereferences producing incomplete types
+were not explicitly disallowed in RM83, though
+AI83-00039 indicated that it was not strictly necessary since
+troublesome cases would result in Constraint_Error at run time,
+since the access value would necessarily be null.
+However, this introduces an undesirable implementation burden,
+as illustrated by Example 4 of AI83-00039:
address@hidden
address@hidden Pack @key[is]
+    @key[type] Pri @key[is] @key[private];
address@hidden
+    @key[type] Sep;
+    @key[type] Pri @key[is] @key[access] Sep;
+    X : Pri;
address@hidden Pack;
+
address@hidden @key[body] Pack @key[is] address@hidden Could be separately 
compiled!}
+    @key[type] Sep @key[is] ...;
+    X := @key[new] Sep;
address@hidden Pack;
+
address@hidden Elaborate(Pack);
address@hidden @key[package] Pack.Child @key[is]
+    I : Integer := address@hidden'Size; address@hidden Legal, by AI-00039.}
address@hidden Pack.Child;
address@hidden
+
+Generating code for the above example could be a serious implementation
+burden, since it would require all aliased objects to store size dope,
+and for that dope to be in the same format for all kinds of types
+(or some other equivalently inefficient implementation).
+On the contrary, most implementations allocate dope differently (or
+not at all) for different designated subtypes.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00326-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  It is now illegal to use an incomplete view (type) as the parameter or result
+  of an access-to-subprogram type unless the incomplete view is completed in
+  the same declaration list as the use. This was allowed in Ada 95 for
+  incomplete types where the completion was deferred to the body. By
+  disallowing this rare use of incomplete views, we can allow the use of
+  incomplete views in many more places, which is especially valuable for
+  limited views.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00326-01]}
+  @ChgAdded{Version=[2],Text=[It is now illegal to use an incomplete view
+  (type) in a primitive subprogram of the type unless the incomplete view is
+  completed in the package specification. This was allowed in Ada 95 for
+  incomplete types where the completion was deferred to the body (the use would
+  have to be in an access parameter). This incompatibility was caused by the
+  fix for the hole noted in @LegalityTitle above.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00326-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}Tagged incomplete types
+  are new. They are allowed in parameter declarations as well as the usual
+  places, as tagged types are always by-reference types (and thus there can
+  be no code generation issue).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00412-01]}
+  @ChgAdded{Version=[2],Text=[A @nt{subtype_declaration} can be used to
+  give a new name to an incomplete view of a type. This is valuable to
+  give shorter names to entities imported with a @nt{limited_with_clause}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00326-01]}
+  @ChgAdded{Version=[2],Text=[The description of incomplete types as
+  @i{incomplete views} is new. Ada 95 defined these as separate types, but
+  neglected to give any rules for matching them with other types. Luckily,
+  implementers did the right thing anyway. This change also makes it easier to
+  describe the meaning of a limited view.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0098-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada address@hidden<Correction:>
+  Fixed the definition so that an anonymous access-to-subprogram type can use 
an
+  incomplete view in the same way that a named access-to-subprogram type can.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0151-1]}
+  @ChgAdded{Version=[3],Text=[Incomplete types now can be used
+  in subprogram declarations. The type has to be complete before any calls
+  or the body is declared. This reduces the places where access types are
+  required for types imported from limited views of packages.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0162-1]}
+  @ChgAdded{Version=[3],Text=[Incomplete types now can be
+  completed by private types and private extensions. Since this can already
+  happen for limited views, there is no remaining reason to disallow it for
+  explicitly declared incomplete types.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0208-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Changed the
+  rules of uses of dereferences of incomplete views such that it does not
+  introduce an unintentional incompatibility with Ada 83 and Ada 95.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0213-1]}
+  @ChgAdded{Version=[3],Text=[Incomplete types now can be used as actuals to
+  formal incomplete types (see @RefSecNum{Formal Private and Derived Types}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0137-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigndum:> Changed the wording to 
clarify
+  that the class-wide type associated with a specific tagged type that has
+  an incomplete view is also an incomplete view.
+  While this was previously undefined, an interpretation where it is not
+  an incomplete view is leads to semantic nonsense, and thus we don't consider
+  this a potential incompatibility, as compilers most likely are doing the
+  right thing.]}
address@hidden
+
+
address@hidden of Access Types}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden attribute Access is used to create access values
+designating aliased objects and nonintrinsic subprograms.
+The @lquotes@;address@hidden@; rules prevent dangling references
+(in the absence of uses of certain unchecked features
address@hidden see @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden Issues}).]
address@hidden
+
address@hidden
+It should be possible for an access value to designate an object
+declared by an object declaration, or a subcomponent thereof.
+In implementation terms, this means pointing at stack-allocated and
+statically allocated data structures.
+However, dangling references should be prevented, primarily via
+compile-time rules, so long as features like Unchecked_Access and
+Unchecked_Deallocation are not used.
+
+In order to create such access values, we require that the access type be a
+general access type, that the designated object be aliased,
+and that the accessibility rules be obeyed.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00235-01]}
address@hidden type], Sec=(access attribute_reference)}
+For an @nt<attribute_reference> with @nt<attribute_designator>
+Access (or Unchecked_Access @em see @RefSecNum(Unchecked Access Value 
Creation)),
+the expected type shall be a single
+access address@hidden,New=[ @i<A> such that:],address@hidden; the
address@hidden<prefix> of such an @nt<attribute_reference>
+is never interpreted as an @nt<implicit_dereference>].
address@hidden profile],
+  Sec=(Access @nt<attribute_reference> @nt<prefix>)}
+If the expected type is an access-to-subprogram type,
+then the expected profile of the @nt<prefix> is the
+designated profile of the access type.]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00235-01]}
address@hidden,address@hidden is an access-to-object type with designated type
address@hidden and the type of the @nt{prefix} is @i{D}'Class or is covered by 
@i{D}, or],Old=[]}
+
address@hidden,Kind=[Added],ARef=[AI95-00235-01]}
address@hidden,address@hidden is an access-to-subprogram type whose designated
+profile is type conformant with that of the prefix.],Old=[]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00235-01]}
address@hidden,address@hidden @nt{prefix} of such an
address@hidden is never interpreted as an @nt{implicit_dereference}
+or a parameterless @nt{function_call} (see @RefSecNum{Attributes}).]
address@hidden profile],
+  Sec=(Access @nt<attribute_reference> @nt<prefix>)}
address@hidden type],
+  Sec=(Access @nt<attribute_reference> @nt<prefix>)}
+The designated type or profile of the expected type of the 
@nt{attribute_reference}
+is the expected type or profile for the @nt{prefix}.],Old=[]}
address@hidden(Discussion)
+  Saying that the expected type shall be a "single access type"
+  is our "new" way of saying that the type has to be determinable from
+  context using only the fact that it is an access type.
+  See @RefSecNum{Literals} and @RefSecNum{The Context of Overload Resolution}.
+  Specifying the expected profile only implies type conformance.
+  The more stringent subtype conformance is required by a Legality
+  Rule. This is the only Resolution Rule that applies to the
+  @nt<name> in a @nt{prefix} of an @nt{attribute_reference}.
+  In all other cases, the @nt{name} has to be resolved without
+  using context. See @RefSecNum{Attributes}.
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00235-01]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[Saying @lquotes@;single access
+  address@hidden@; is a bit of a fudge. Both the context and the @nt{prefix} 
may
+  provide both multiple types; @lquotes@;address@hidden@; only means that a
+  single, specific interpretation must remain after resolution. We say
+  @lquotes@;address@hidden@; here to trigger the @LegalityTitle of
+  @RefSecNum{The Context of Overload Resolution}. The resolution of an access
+  attribute is similar to that of an @nt{assignment_statement}. For example:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Int_Ptr @key{is access all} Integer;
address@hidden Char_Ptr @key{is access all} Character;
address@hidden Float_Ptr @key{is access all} Float;],Old=[]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Zap (Val : Int_Ptr) @key{return} Float;   -- 
@RI[(1)]
address@hidden Zap (Val : Float_Ptr) @key{return} Float; -- @RI[(2)]
address@hidden Zop @key{return} Int_Ptr;  -- @RI[(3)]
address@hidden Zop @key{return} Char_Ptr; -- @RI[(4)]],Old=[]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,New=[Result : Float := Zap (address@hidden'Access); -- 
@RI[Resolves to Zap (1) and Zop (3).]],Old=[]}
address@hidden
address@hidden(Discussion)
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00162-01]}
address@hidden level}
address@hidden,Sec=(accessibility)}
address@hidden,Sec=(accessibility level)}
address@hidden,Sec=(accessibility level)}
address@hidden references],Sec=(prevention via accessibility rules)}
address@hidden
address@hidden accessibility rules,
+which prevent dangling references,
+are written in terms of @i{accessibility levels},
+which reflect the run-time nesting of @i{masters}. As explained in
address@hidden and Finalization},
+a master is the execution of a
address@hidden,New=[certain construct, such as],Old=[,@nt{task_body}, a 
@nt{block_statement},]}
+a @address@hidden,New=[],Old=[, an @nt{entry_body}, or an 
@nt{accept_statement}]}.
+An accessibility level is @i{deeper than} another if it is more
+deeply nested at run time.
+For example, an object declared local to a called subprogram has a deeper
+accessibility level than an object declared local to the calling
+subprogram.
+The accessibility rules for access types require that the
+accessibility level of an object designated by an access value be no
+deeper than that of the access type.
+This ensures that the object will live at least as long as the access
+type, which in turn ensures that the access value cannot later
+designate an object that no longer exists.
+The Unchecked_Access attribute may be used to circumvent the
+accessibility rules.]
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,Text=[The Unchecked_Access attribute acts as if the
+object was declared at library-level; this applies even when it is used as the
+value of anonymous access type.
+See @RefSecNum{Unchecked Access Value Creation}.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Subclause @RefSecNum{Operations of Access Types},
+home of the accessibility rules, is informally known
+as the @ldquote@;Heart of address@hidden amongst the maintainers of Ada.
+Woe unto all who enter here (well, at least unto anyone that needs to 
understand
+any of these rules).
address@hidden of address@hidden rules],See=[Heart of Darkness]}]}
address@hidden
+
address@hidden deeper}
address@hidden,Sec=(statically)}
address@hidden given accessibility level is said to be @i{statically
+deeper} than another if the given level is known at compile time (as
+defined below) to be deeper than the other for all possible executions.
+In most cases, accessibility is enforced at compile time by
address@hidden
+Run-time accessibility checks are also used,
+since the @LegalityTitle do not cover
+certain cases involving access parameters and generic packages.]
+
address@hidden@keepnext@;Each master, and each entity and view created by it,
+has an accessibility level:
address@hidden
+The accessibility level of a given master is deeper than
+that of each dynamically enclosing master,
+and deeper than that of each master upon which the task executing the
+given master directly depends
+(see @RefSecNum{Task Dependence - Termination of Tasks}).
+
address@hidden,Kind=[Revised],ARef=[AI95-00162-01],ARef=[AI95-00416-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0235-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0067-1],ARef=[AI12-0089-1]}
+An entity or view @Chg{Version=[2],New=[defined],Old=[created]} by a
address@hidden,New=[ and created as part of its elaboration],Old=[]}
+has the same accessibility level
+as the innermost @Chg{Version=[2],New=[],Old=[enclosing ]}master
address@hidden,New=[of the declaration ],Old=[]}except in the
+cases of renaming and derived access types described below.
address@hidden,New=[Other than for an explicitly aliased
address@hidden,New=[ of a function or generic function],Old=[]}, a
+formal],Old=[A]} parameter of a
address@hidden,New=[callable entity],Old=[master]} has the same
+accessibility level as the address@hidden,New=[ representing the
+invocation of the entity],Old=[]}.
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[This rule defines the @lquotes@;address@hidden
+  accessibility of entities. In the absence of special rules below, we intend
+  for this rule to apply.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[2],Text=[This rule defines the accessibility of all
+  named access types, as well as the accessibility level of
+  @Chg{Version=[4],New=[],Old=[all ]}anonymous
+  access types @Chg{Version=[4],New=[in a @nt{component_definition}],Old=[other
+  than those for access parameters and access discriminants.]} Special rules
+  exist for the accessibility level of @Chg{Version=[4],New=[other],Old=[such]}
+  anonymous types. address@hidden,New=[],Old=[,
+  stand-alone objects, and function results]} whose
+  (anonymous) type is defined by an @nt{access_definition} have
+  accessibility levels corresponding to named access types defined at
+  the same point.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01]}
+  @ChgAdded{Version=[2],Text=[Because accessibility level is determined
+  by where the @nt{access_definition} is elaborated, for a type extension,
+  the anonymous access types of components (other than access discriminants)
+  inherited from the parent have the same accessibility as they did in the
+  parent; those in the extension part have the accessibility
+  determined by the scope where the type extension is declared.
+  Similarly, the types of the nondiscriminant access components
+  of a derived untagged type have the same accessibility as they
+  did in the parent.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0235-1]}
+  @ChgAdded{Version=[3],Text=[We use "invocation of" in the parameter case
+  as a master is formally an execution of something. But we mean this to be
+  interpreted statically (for instance, as the body of the subprogram) for the
+  purposes of computing "statically deeper than" (see below).]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0235-1]}
+  @ChgAdded{Version=[3],Text=[Note that accessibility can differ depending on
+  the view of an object (for both static and dynamic accessibility). For
+  instance, the accessibility level of a formal parameter may be different than
+  the accessibility level of the corresponding actual parameter. This occurs
+  in other cases as well.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0235-1]}
+  @ChgAdded{Version=[3],Text=[We define the (dynamic) accessibility of formal
+  parameters in order that it does not depend on the parameter passing model
+  (by-reference or by-copy) as that is implementation defined. Otherwise, there
+  would be a portability issue.]}
address@hidden
+
+The accessibility level of
+a view of an object or subprogram defined by a @nt{renaming_declaration}
+is the same as that of
+the renamed view.
+
address@hidden,Kind=[Revised],ARef=[AI95-00416-01]}
+The accessibility level of
+a view address@hidden,New=[, @nt{qualified_expression}, or
+parenthesized expression,],Old=[]}
+is the same as that of
+the operand.
+
address@hidden,Kind=[Added],ARef=[AI05-0188-1]}
address@hidden,Text=[The accessibility level of a
address@hidden is the accessibility level of the evaluated
address@hidden@nt{expression}.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02],ARef=[AI95-00416-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0234-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0027-1]}
address@hidden,New=[The],Old=[For a function whose result type is a
+return-by-reference type,
+the accessibility level of the result object is the same as
+that of the master that elaborated the function body. For
+any other function, the]} accessibility level of @Chg{Version=[2],New=[an
address@hidden @Chg{Version=[3],New=[],Old=[or the result of a function call 
@Redundant[(or equivalent use
+of an operator)] ]}that is
+used (in its entirety) to directly initialize part of an],Old=[the result]}
+object is that of the
address@hidden,New=[object being initialized. In other contexts, the
+accessibility level of an @nt{aggregate} @Chg{Version=[3],New=[],Old=[or the
+result of a function call ]}is that of the innermost
+master that evaluates the @address@hidden,New=[],Old=[ or
+function call]}],Old=[execution of the called
address@hidden,New=[ Corresponding rules apply to a value conversion
+(see @RefSecNum{Type Conversions}).],Old=[]}
+
address@hidden,Kind=[Added],ARef=[AI05-0234-1]}
address@hidden,Type=[Leading],Text=[The accessibility level of the result
+of a function call is that of the @i<master of the function call>, which is
+determined by the point of call as follows:@Defn{master of a 
address@hidden,Sec=[master address@hidden call],Sec=[master of]}]}
+
address@hidden
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[If the result is used (in its entirety) to
+  directly initialize part of an object, the master is that of the object being
+  initialized. In the case where the initialized object is a coextension
+  (see below) that becomes a coextension of another object, the master is that
+  of the eventual object to which the coextension will be transferred.]}
+
+  @begin{Honest}
+    @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+    @ChgAdded{Version=[2],Text=[The first sentence is talking about a static
+    use of the entire return object @em a slice that happens to be the entire
+    return object doesn't count. On the other hand, this is intended to allow
+    parentheses and @nt{qualified_expression}s.]}
+  @end{Honest}
+  @begin{Ramification}
+    @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+    @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0234-1]}
+    @ChgAdded{Version=[2],Text=[If the function is used as a @nt{prefix},
+    @Chg{Version=[3],New=[this bullet does not apply],Old=[the second sentence
+    applies]}. Similarly, an @nt{assignment_statement} is not an initialization
+    of an object, so @Chg{Version=[3],New=[this bullet does not 
apply],Old=[the second sentence
+    applies]}.]}
+  @end{Ramification}
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[If the result is of an anonymous access type and
+  is the operand of an explicit conversion, the master is that of the target
+  type of the conversion;]}
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[If the result is of an anonymous access type and
+  defines an access discriminant, the master is the same as that for an object
+  created by an anonymous @nt{allocator} that defines an access discriminant
+  (even if the access result is of an access-to-subprogram type).]}
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[If the call itself defines the result of a
+  function to which one of the above rules applies, these rules are applied
+  recursively;]}
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[In other cases, the master of the call is that of
+  the innermost master that evaluates the function call.]}
+
+  @begin{Ramification}
+    
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02],ARef=[AI95-00416-01]}
+    @ChgAdded{Version=[2],Text=[The @lquotes@;innermost master which evaluated
+    the function address@hidden@; does not include the function call itself 
(which
+    might be a master).]}
+
+    
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02],ARef=[AI95-00416-01]}
+    @ChgAdded{Version=[2],Text=[We really mean the innermost master here,
+    which could be a very short lifetime. Consider a function call used as
+    a parameter of a procedure call. In this case the innermost master which
+    evaluated the function call is the procedure call.]}
+  @end{Ramification}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0234-1]}
+  @ChgAdded{Version=[3],Text=[These rules do not mention whether the result
+  object is built-in-place (see @RefSecNum{Assignment and Finalization}). In
+  particular, in the case where building in place is optional, the choice
+  whether or not to build-in-place has no effect on masters, lifetimes, or
+  accessibility.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0234-1]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[There are several cases where the
+  implementation may have to pass in the accessibility level of the result
+  object on a call, to support later rules where the accessibility level comes
+  from the master of the call:]}
+
+  @begin{Itemize}
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[when the function result may have a part with
+    access discriminants;]}
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[when the function result type is an anonymous
+    access type;]}
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[when the function result is built-in-place;]}
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[when the function has an explicitly
+    aliased parameter.]}
+  @end{Itemize}
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[In particular, this implies passing a level
+  parameter when the result type is class-wide, since descendants may add 
access
+  discriminants. For most implementations this will mean that functions with
+  controlling results will also need a level parameter.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0284-1]}
address@hidden,NoPrefix=[T],Text=[In the case of a call to a function
+whose result type is an anonymous access type, the accessibility level of the
+type of the result of the function call is also determined by the point of call
+as described above.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00416-01]}
address@hidden,address@hidden because the paragraph number is changed}
address@hidden,Text=[Within a return statement, the accessibility level
+of the return object is that of the execution of the return statement. If the
+return statement completes normally by returning from the
+function, then prior to leaving the function, the accessibility level
+of the return object changes to be a level determined by the point
+of call, as does the level of any coextensions (see below) of the
+return object.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We define the accessibility level of the return
+  object during the return statement to be that of the return statement itself
+  so that the object may be designated by objects local to the return
+  statement, but not by objects outside the return statement. In addition, the
+  intent is that the return object gets finalized if the return statement ends
+  without actually returning (for example, due to propagating an exception, or
+  a goto). For a normal return, of course, no finalization is done before
+  returning.]}
address@hidden
+
+The accessibility level of
+a derived access type
+is the same as that of
+its ultimate ancestor.
+
address@hidden,Kind=[Added],ARef=[AI95-00230-01]}
address@hidden,Text=[The accessibility level of the anonymous access
+type defined by an @nt{access_definition} of an
address@hidden is the same as that of the renamed view.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00416-01]}
address@hidden ChgAdded below to get conditional Leading}
address@hidden,Type=[Leading],Text=[]}The accessibility level
+of the anonymous access type of an access discriminant
address@hidden,New=[in the @nt{subtype_indication} or
address@hidden of an @nt{allocator}, or in the @nt{expression} or
address@hidden@address@hidden of a return statement is determined as
+follows:],Old=[is the same as that of the containing object or associated
+constrained subtype.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[If the value of the access discriminant is
+determined by a @nt{discriminant_association} in a @nt{subtype_indication},
+the accessibility level of the object or subprogram designated by
+the associated value (or library level if the value is null);]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[This deals with the following 
cases,
+    when they occur in the context of an @nt{allocator} or return statement:]}
+  @begin{InnerItemize}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[An @nt{extension_aggregate} where the
+    @nt{ancestor_part} is a @nt{subtype_mark} denoting a constrained subtype;]}
+
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[An uninitialized @nt{allocator} where the
+    @nt{subtype_indication} defines a constrained subtype;]}
+
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[A discriminant of an object with a constrained
+    nominal subtype, including constrained components, the result of calling
+    a function with a constrained result subtype, the dereference of an
+    access-to-constrained subtype, etc.]}
+  @end{InnerItemize}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0281-1]}
+  @ChgAdded{Version=[3],Text=[The @nt{subtype_indication} mentioned in this
+  bullet is not necessarily the one given in the @nt{allocator} or
+  return statement that is determining the accessibility level; the constrained
+  subtype might have been defined in an earlier declaration (as a named
+  subtype).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[3],Text=[If the value for this rule and the next one is
+  derived from an Unchecked_Access attribute, the accessibility is 
library-level
+  no matter what the accessibility level of the object is (see
+  @RefSecNum{Unchecked Access Value Creation}).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0234-1]}
address@hidden,Text=[If the value of the access discriminant is
+determined by a @nt{default_expression} in the declaration of the discriminant,
+the level of the object or subprogram designated by the associated value (or
+library level if null);]}
address@hidden
address@hidden,Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[This covers the case of an unconstrained
+  subcomponent of a limited type with defaulted access discriminants.]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0004-1]}
address@hidden,Text=[If the value of the access discriminant is
+determined by a @Chg{Version=[3],address@hidden,
address@hidden in an @nt{aggregate}, the
+accessibility level of the object or subprogram designated by the associated
+value (or library level if the value is null);]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[In this bullet, the @nt{aggregate} has to occur
+  in the context of an @nt{allocator} or return statement, while the
+  @nt{subtype_indication} of the previous bullet can occur anywhere
+  (it doesn't have to be directly given in the @nt{allocator} or
+  return statement).]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden because the paragraph number is changed}
address@hidden,Text=[In other cases, where the value of the access
+discriminant is determined by an object
+with an unconstrained nominal subtype, the accessibility level of the object.]}
+
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[In other words, if you know the value of the
+  discriminant for an @nt{allocator} or return statement from a discriminant
+  constraint or an @nt{aggregate} component
+  association, then that determines the accessibility level; if you don't know
+  it, then it is based on the object itself.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00416-01]}
address@hidden,address@hidden because the paragraph number is changed}
address@hidden,Text=[The accessibility level of the anonymous access
+type of an access discriminant in any other context is that of the
+enclosing object.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00162-01],ARef=[AI95-00254-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0270-1]}
+The accessibility level of
+the anonymous access type of an access
address@hidden,New=[ specifying an access-to-object type],Old=[]}
+is the same as that of
+the view designated by the address@hidden,New=[ (or library-level
+if the actual is null)],address@hidden,New=[],Old=[ If the
+actual is an @nt{allocator},
+this is the accessibility level of the execution of the called
+subprogram.]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,Text=[If the value of the actual is derived from an
+Unchecked_Access attribute, the accessibility is always library-level (see
address@hidden Access Value Creation}).]}
address@hidden
+
+
address@hidden,Kind=[Added],ARef=[AI95-00254-01]}
address@hidden,Text=[The accessibility level of the anonymous access type
+of an access parameter specifying an access-to-subprogram type is
+deeper than that of any master; all such
+anonymous access types have this same level.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden closure}
address@hidden,Sec=(downward)}
+These represent @lquotes@;downward address@hidden@; and
+thus require passing of static links or global display information (along
+with generic sharing information if the implementation does sharing) along
+with the address of the subprogram. We must prevent conversions of these to
+types with @lquotes@;address@hidden@; accessibility, as those typically don't
+include the extra information needed to make a call.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0070-1]}
address@hidden,Text=[The accessibility level of the anonymous access
+subtype defined by a @nt{return_subtype_indication} that is
+an @nt{access_definition} (see @RefSecNum{Return Statements})
+is that of the result subtype of the enclosing function.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0148-1],ARef=[AI05-0240-1]}
address@hidden,Kind=[RevisedAdded],address@hidden to reflect the paragraph 
number change}
address@hidden,Text=[The accessibility level of the type of a stand-alone
+object of an anonymous access-to-object type is the same as the accessibility
+level of the type of the access value most recently assigned to the
address@hidden; accessibility checks ensure that this
+is never deeper than that of the declaration of the stand-alone object].]}
+
address@hidden,Kind=[Added],ARef=[AI05-0142-4],ARef=[AI05-0240-1]}
address@hidden,Kind=[RevisedAdded],address@hidden to reflect the paragraph 
number change}
address@hidden,Text=[The accessibility level of an explicitly aliased
+(see @RefSecNum{Subprogram Declarations}) formal parameter in a function body 
is
+determined by the point of call; it is the same level that the return object
+ultimately will have.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00416-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0051-1],ARef=[AI05-0253-1]}
address@hidden ChgAdded below to get conditional Leading}
address@hidden,Type=[Leading],Text=[]}
+The accessibility level of an object created by an @nt{allocator}
+is the same as that of
+the access address@hidden,New=[, except for an @nt{allocator} of an
+anonymous access type @Chg{Version=[3],New=[(an @i<anonymous allocator>) in
address@hidden allocator}certain contexts, as follows: For an anonymous
+allocator that defines the result of a function with an access result, the
+accessibility level is determined as though the @nt{allocator} were in place
+of the call of the function; in the special case of a call that is the operand 
of a
+type conversion, the level is that of the target access type of the
+conversion],Old=[that defines the value of an access parameter or an access
+discriminant]}. For an @Chg{Version=[3],New=[anonymous
+allocator],address@hidden defining the value of an access parameter, the
+accessibility level is that of the innermost master of the call.
address@hidden,New=[For an anonymous allocator whose type is that of a
+stand-alone object of an anonymous access-to-object type, the accessibility
+level is that of the declaration of the stand-alone object. ],Old=[]}For one
+defining an access discriminant, the accessibility level is determined as
+follows:],Old=[.]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00416-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0024-1]}
address@hidden,Text=[for an @nt{allocator} used to define the
address@hidden,New=[discriminant of an object,
+the level of the object],Old=[constraint in a
address@hidden, the level of the @nt{subtype_declaration}]};]}
+
address@hidden,Kind=[Added],ARef=[AI95-00416-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0024-1]}
address@hidden,Text=[for an @nt{allocator} used to define the constraint
+in a @Chg{Version=[3],address@hidden in any other context, the
+level of the master that elaborates the
address@hidden,address@hidden, the level of the
+enclosing type;]}]}
+
address@hidden,Kind=[Added],ARef=[AI95-00416-01]}
address@hidden,Kind=[DeletedAdded],ARef=[AI05-0024-1]}
address@hidden,address@hidden,New=[],Old=[for an @nt{allocator}
+used to define the discriminant of an object, the level of the object.]}]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00416-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0024-1],ARef=[AI05-0066-1]}
address@hidden,NoPrefix=[T],address@hidden,Sec=(of an object)}
+In @Chg{Version=[3],New=[the first],Old=[this last]} case, the allocated object
+is said to be a @i{coextension} of the object whose discriminant designates it,
+as well as of any object of which the discriminated object is itself a
+coextension or address@hidden,New=[ If the allocated object is
+a coextension of an
+anonymous object representing the result of an aggregate or function
+call that is used (in its entirety) to directly initialize a part of
+an object, after the result is assigned, the coextension becomes a
+coextension of the object being initialized and is no longer
+considered a coextension of the anonymous object.],Old=[]}
+All coextensions of an object @Chg{Version=[3],address@hidden(which have not
+thus been transfered by such an initialization)] ],Old=[]}are finalized when
+the object is finalized (see @RefSecNum{Completion and Finalization}).]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[The rules of access discriminants are such that
+  when the space for an object with a coextension is reclaimed, the space for
+  the coextensions can be reclaimed. Hence, there is implementation advice (see
+  13.11) that an object and its coextensions all be allocated from the same
+  storage pool (or stack frame, in the case of a declared object).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0051-1]}
address@hidden,Text=[Within a return statement, the accessibility level
+of the anonymous access type of an access result is that of the master of the
+call.]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0014-1]}
+The accessibility level of a view of an object or subprogram
address@hidden,New=[designated by],Old=[denoted by a dereference of]} an
+access value is the same as that of the access type.
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1],ARef=[AI05-0014-1]}
address@hidden,Text=[This rule applies even when no dereference exists,
+for example when an access value is passed as an access parameter.
+This rule ensures that implementations are not required to include dynamic
+accessibility values with all access values.]}
address@hidden
+
+The accessibility level of
+a component, protected subprogram, or entry
+of (a view of) a composite object
+is the same as that of
+(the view of) the composite object.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00416-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0262-1]}
address@hidden,Text=[In the above rules, the operand of a view
+conversion, parenthesized
+expression or @nt{qualified_expression} is considered to be used in a context
+if the view conversion, parenthesized expression or @nt{qualified_expression}
+itself is used in that address@hidden,New=[
+Similarly, a @address@hidden of a @nt{conditional_expression}
+is considered to be used in a context if the @nt{conditional_expression} itself
+is used in that context.],Old=[]}]}
+
address@hidden
address@hidden@Defn{statically deeper}
address@hidden,Sec=(statically)}
+One accessibility level is defined to be
address@hidden deeper} than another in the following cases:
address@hidden
address@hidden
+For a master that is statically nested within another master,
+the accessibility level of the inner master is statically deeper than
+that of the outer master.
address@hidden
+Strictly speaking, this should talk about the @i{constructs}
+(such as @ntf{subprogram_bodies})
+being statically nested within one another;
+the masters are really the @i{executions} of those constructs.
address@hidden
address@hidden
+If a given accessibility level is statically deeper than another,
+then each level defined to be the same as the given
+level is statically deeper than each level defined to be the same as
+the other level.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00254-01]}
address@hidden,Text=[The accessibility level of the anonymous access type
+of an access parameter specifying an access-to-subprogram type is
+statically deeper than that of any master; all such
+anonymous access types have this same level.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This rule means that it is illegal to convert an
+access parameter specifying an access to subprogram to a
+named access to subprogram type, but it is allowed to pass such an access
+parameter to another access parameter (the implicit conversion's accessibility
+will succeed).]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00254-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0082-1]}
+The statically deeper relationship does not apply to the accessibility
+level of the anonymous type of an access address@hidden,
+New=[ specifying an access-to-object type],address@hidden,
+New=[ nor does it apply to a descendant of a generic formal type],Old=[]};
+that is, such an accessibility level is not considered to be statically
+deeper, nor statically shallower, than any other.
+
address@hidden,Kind=[Added],ARef=[AI05-0148-1]}
address@hidden,Text=[The statically deeper relationship does not apply to
+the accessibility level of the type of a stand-alone object of an anonymous
+access-to-object type; that is, such an accessibility level is not considered 
to
+be statically deeper, nor statically shallower, than any other.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[In these cases, we use dynamic accessibility
+checks.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0142-4],ARef=[AI05-0235-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0089-1],ARef=[AI12-0157-1]}
address@hidden,Text=[Inside a return statement that applies to a function
address@hidden,New=[or generic function ],address@hidden<F>,
address@hidden,New=[or the return expression of an expression function
address@hidden<F>, ],Old=[]}when determining
+whether the accessibility level of an explicitly aliased
+parameter of @i<F> is statically deeper than the level of the return object of
address@hidden<F>, the level of the return object is considered to be the same 
as that of
+the level of the explicitly aliased parameter; for statically comparing with 
the
+level of other entities, an explicitly aliased parameter of @i<F> is 
considered to
+have the accessibility level of the body of @i<F>.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0051-1],ARef=[AI05-0234-1],ARef=[AI05-0235-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0089-1],ARef=[AI12-0157-1]}
address@hidden,Text=[For determining whether a level is statically deeper
+than the level of the anonymous access type of an access result of a
address@hidden,New=[ or generic function @i<F>],Old=[]},
+when within a return statement that applies to
address@hidden,address@hidden<F> or the return expression of expression
+function @i<F>],Old=[the function]}, the level
+of the master of the call is presumed to be the same as that of the level
+of the master that elaborated address@hidden,New=[],Old=[ function]}
address@hidden,New=[ of @i<F>],Old=[]}.]}
+
address@hidden,New=[ or generic function @i<F>],address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0235-1]}
+  @ChgAdded{Version=[3],Text=[This rule has no effect if the previous bullet
+  also applies (that is, the @ldquote@;a address@hidden is of
+  an explicitly aliased parameter).]}
address@hidden
+
+
+
address@hidden determining whether one level is statically deeper than another
+when within a generic package body, the generic package is presumed to be
+instantiated at the same level as where it was declared;
+run-time checks are needed in the case of more deeply nested instantiations.]
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0082-1]}
+  @ChgAdded{Version=[3],Text=[A generic package does not introduce a new 
master,
+  so it has the static level of its declaration; the rest follows from the
+  other @ldquote@;statically address@hidden rules.]}
address@hidden
+
+For determining whether one level is statically deeper than another when
+within the declarative region of a @nt{type_declaration},
+the current instance of the type is presumed to be an object created at
+a deeper level than that of the type.
address@hidden
+  In other words, the rules are checked at compile time of the
+  @nt{type_declaration}, in an assume-the-worst manner.
address@hidden
address@hidden
+
address@hidden level}
address@hidden,Sec=(library)}
+The accessibility level of all library units is called the
address@hidden level};
+a library-level declaration or entity is one whose accessibility level
+is the library level.
address@hidden
+  @nt{Library_unit_declaration}s are library level.
+  Nested declarations are library level if they are nested only within
+  packages (possibly more than one),
+  and not within subprograms, tasks, etc.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised]}
+  @Leading@;The definition of the accessibility level of the anonymous type
+  of an access address@hidden,New=[ specifying an access-to-object
+  type],Old=[]} cheats a bit, since it refers to the view designated
+  by the actual, but access values designate objects, not views of objects.
+  What we really mean is the view that @lquotes@;would address@hidden@; 
denoted by an
+  expression @lquotes@;address@hidden@rquotes@;, where X is the actual, even 
though such
+  an expression is a figment of our imagination.
+  The definition is intended to be equivalent to the
+  following more verbose version:
+  The accessibility level of the anonymous type of an access parameter is
+  as follows:
+  @begin{Itemize}
+  if the actual is
+  an expression of a named access type @em
+  the accessibility level of that type;
+
+  if the actual is
+  an @nt{allocator} @em
+  the accessibility level of the execution of the called
+  subprogram;
+
address@hidden,address@hidden be consistent with 8652/0006}
+  if the actual is
+  a reference to the Access attribute @em
+  the accessibility level of the view denoted by the 
@address@hidden,Old=[prefix]};
+
+  if the actual is
+  a reference to the Unchecked_Access attribute @em
+  library accessibility level;
+
+  if the actual is
+  an access parameter @em
+  the accessibility level of its type.
+  @end{Itemize}
+
+  Note that the @nt{allocator} case is explicitly mentioned in the RM95,
+  because otherwise the definition would be circular:
+  the level of the anonymous type is that of the view designated by the
+  actual, which is that of the access type.
address@hidden
address@hidden
+  A deeper accessibility level implies a shorter maximum lifetime.
+  Hence, when a rule requires X to have a level that is
+  @lquotes@;not deeper address@hidden@; Y's level,
+  this requires that X has a lifetime at least as long as Y.
+  (We say @lquotes@;maximum address@hidden@; here, because the accessibility
+  level really represents an upper bound on the lifetime;
+  an object created by an @nt{allocator} can have its lifetime
+  prematurely ended by an instance of Unchecked_Deallocation.)
+
+  Package elaborations are not masters, and are therefore
+  invisible to the accessibility rules:
+  an object declared immediately within a package has the
+  same accessibility level as an object declared immediately within the
+  declarative region containing the package.
+  This is true even in the body of a package;
+  it jibes with the fact that objects declared in a
+  @nt{package_body} live as long as objects declared
+  outside the package,
+  even though the body objects are not visible outside the package.
+
+  Note that the level of the @i{view} denoted by address@hidden
+  can be different from the level of the @i{object} denoted by address@hidden
+  The former is determined by the type of X;
+  the latter is determined either by the type of the @nt{allocator},
+  or by the master in which the object was declared.
+  The former is used in several @LegalityTitle and run-time checks;
+  the latter is used to define when address@hidden gets finalized.
+  The level of a view reflects what we can conservatively 
@lquotes@;address@hidden@;
+  about the object of that view;
+  for example, due to @nt{type_conversion}s,
+  an access value might designate an object that was allocated by an
+  @nt{allocator} for a different access type.
+
+  Similarly, the level of the view denoted by address@hidden
+  can be different from the level of the object denoted by address@hidden
+
+  If Y is statically deeper than X,
+  this implies that Y will be (dynamically) deeper than X in all
+  possible executions.
+
+  @Leading@;Most accessibility checking is done at compile time;
+  the rules are stated in terms of @lquotes@;statically deeper 
address@hidden@;.
+  The exceptions are:
+  @begin{Itemize}
+  @ChgRef{Version=[2],Kind=[Revised]}
+  Checks involving access address@hidden,New=[ of an
+  access-to-object type],Old=[]}. The fact that @lquotes@;statically deeper
+  address@hidden@; is not defined for the anonymous access type of an access
+  parameter implies that any rule saying @lquotes@;shall not be statically
+  deeper address@hidden@; does not apply to such a type, nor to anything 
defined
+  to have @lquotes@;the address@hidden@; level as such a type.
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0082-1]}
+  @ChgAdded{Version=[3],Text=[Checks involving generic formal types
+  and their descendants. This is because the actual type can be more
+  or less deeply nested than the generic unit. Note that this only
+  applies to the generic unit itself, and not to the instance. Any
+  static checks needed in the instance will be performed. Any other
+  checks (such as those in the generic body) will require a run-time
+  check of some sort (although implementations that macro-expand
+  generics can determine the result of the check when the generic
+  is expanded).]}
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0082-1]}
+  Checks involving @Chg{Version=[3],New=[other ],Old=[]}entities and
+  views within generic packages. This is because an instantiation can
+  be at a level that is more deeply nested than the generic package itself.
+  In implementations that use a macro-expansion model of generics,
+  these violations can be detected at macro-expansion time.
+  For implementations that share generics,
+  run-time code is needed to detect the error.
+
+  
@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00318-02],ARef=[AI95-00344-01],ARef=[AI95-00416-01]}
+  Checks during function address@hidden,New=[ and @nt{allocator}s,
+  for nested type extensions and access discriminants],Old=[]}.
+  @end{Itemize}
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  Note that run-time checks are not required
+  for access address@hidden,New=[ (except during
+  function returns and @nt{allocator}s)],Old=[]}, because their accessibility 
is
+  determined statically by the accessibility level of the enclosing object.
+
+  @ChgRef{Version=[2],Kind=[Revised]}
+  @Chg{Version=[2],New=[],Old=[This ]}The accessibility level of the result
+  object of a function reflects
+  the time when that object will be finalized;
+  we don't allow pointers to the object to survive beyond that time.
+
+  We sometimes use the terms @lquotes@;address@hidden@;
+  and @lquotes@;address@hidden@; to mean that something has an
+  accessibility level that is not deeper, or deeper,
+  respectively, than something else.
address@hidden
address@hidden(ImplNote)
+  
@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00318-02],ARef=[AI95-00344-01],ARef=[AI95-00416-01]}
+  If an accessibility @LegalityName is satisfied,
+  then the corresponding run-time check (if any)
+  cannot fail (and a reasonable implementation will not
+  generate any checking code)
+  unless @Chg{Version=[2],New=[one of the cases requiring run-time checks 
mentioned
+  previously is],Old=[access parameters or shared generic bodies are]} 
involved.
+
+  Accessibility levels are defined in terms of the relations
+  @lquotes@;the same address@hidden@; and @lquotes@;deeper address@hidden@;.
+  To make the discussion more concrete,
+  we can assign actual numbers to each level.
+  Here, we assume that library-level accessibility is level 0,
+  and each level defined as @lquotes@;deeper address@hidden@; is one level 
deeper.
+  Thus, a subprogram directly called from the environment task
+  (such as the main subprogram) would be at level 1,
+  and so on.
+
+  @ChgRef{Version=[2],Kind=[Revised]}
+  Accessibility is not enforced at compile time for access
+  address@hidden,New=[ of an access-to-object type],Old=[]}.
+  The @lquotes@;address@hidden@; implementation of the run-time checks would be
+  inefficient, and would involve distributed overhead;
+  therefore, an efficient method is given below.
+  The @lquotes@;address@hidden@; implementation would be to pass
+  the level of the caller at each subprogram call,
+  task creation, etc.
+  This level would be incremented by 1 for each
+  dynamically nested master.
+  An Accessibility_Check would be implemented as a simple
+  comparison @em checking that X is not deeper than Y
+  would involve checking that X <= Y.
+
+  A more efficient method is based on passing @i{static}
+  nesting levels
+  (within constructs that correspond at run time to
+  masters @em packages don't count).
+  Whenever an access parameter is passed,
+  an implicit extra parameter is passed with it.
+  The extra parameter represents (in an indirect way)
+  the accessibility level of the anonymous access type,
+  and, therefore, the level of the view denoted
+  by a dereference of the access parameter.
+  This is analogous to the implicit @lquotes@;address@hidden@; bit associated
+  with certain formal parameters of an unconstrained but definite
+  composite subtype.
+  In this method, we avoid distributed overhead:
+  it is not necessary to pass any extra information
+  to subprograms that have no access parameters.
+  For anything other than an access parameter and its anonymous type,
+  the static nesting level is known at compile time,
+  and is defined analogously to the RM95 definition
+  of accessibility level (e.g. derived access types
+  get their nesting level from their parent).
+  Checking @lquotes@;not deeper address@hidden@; is a "<=" test on the levels.
+
+  @ChgRef{Version=[2],Kind=[Revised]}
+  @address@hidden@;For each access address@hidden,New=[ of
+  an access-to-object type],Old=[]}, the static depth passed depends on the
+  actual, as follows:
+  @begin{Itemize}
+  If the actual is
+  an expression of a named access type,
+  pass the static nesting level of that type.
+
+  If the actual is
+  an @nt{allocator},
+  pass the static nesting level of the caller,
+  plus one.
+
address@hidden,address@hidden be consistent with 8652/0006}
+  If the actual is
+  a reference to the Access attribute,
+  pass the level of the view denoted by the @address@hidden,Old=[prefix]}.
+
+  If the actual is
+  a reference to the Unchecked_Access attribute,
+  pass 0 (the library accessibility level).
+
+  @ChgRef{Version=[2],Kind=[Revised]}
+  If the actual is an access address@hidden,New=[ of
+  an access-to-object type],Old=[]},
+  usually just pass along the level passed in.
+  However, if the
+  static nesting level of the formal (access) parameter is greater than
+  the static nesting level of the actual (access) parameter,
+  the level to
+  be passed is the minimum of the static nesting level
+  of the access parameter
+  and the actual level passed in.
+  @end{Itemize}
+
+  @ChgRef{Version=[2],Kind=[Revised]}
+  For the Accessibility_Check associated with a @nt{type_conversion}
+  of an access address@hidden,New=[ of
+  an access-to-object type],Old=[]} of a given subprogram to a
+  named access type,
+  if the target type is statically nested within the subprogram,
+  do nothing; the check can't fail in this case.
+  Otherwise, check that the value passed in is <= the static
+  nesting depth of the target type.
+  The other Accessibility_Checks are handled in a similar manner.
+
+  This method, using statically known values most of the time,
+  is efficient, and, more importantly, avoids distributed overhead.
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0148-1]}
+  @ChgAdded{Version=[3],Text=[The implementation of accessibility checks for
+  stand-alone objects of anonymous access-to-object types can be similar to
+  that for anonymous access-to-object parameters. A static level suffices; it
+  can be calculated using rules similar to those previously described for 
access
+  parameters.]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0148-1]}
+  @ChgAdded{Version=[3],Text=[One important difference between the stand-alone
+  access variables and access parameters is that one can assign a local access
+  parameter to a more global stand-alone access variable. Similarly, one can
+  assign a more global access parameter to a more local stand-alone access
+  variable.]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0148-1]}
+  @ChgAdded{Version=[3],Text=[For these cases, it is important to note that the
+  @ldquote@;address@hidden static accessibility level for an access parameter
+  assigned to a stand-alone access object is the minimum of the passed in
+  level and the static accessibility level of the stand-alone object itself.
+  This is true since the static accessibility level passed in might be deeper
+  than that of the stand-alone object, but the dynamic accessibility of the
+  passed in object clearly must be shallower than the stand-alone object
+  (whatever is passed in must live at least as long as the subprogram call). We
+  do not need to keep a more local static level as accesses to objects
+  statically deeper than the stand-alone object cannot be stored into the
+  stand-alone object.]}
address@hidden(ImplNote)
address@hidden
address@hidden@keepnext@;Examples of accessibility:
address@hidden
address@hidden,Kind=[Revised],address@hidden is access-to-variable, X better be 
a variable}
address@hidden @key[body] Lib_Unit @key[is]
+    @key[type] T @key[is] @key[tagged] ...;
+    @key[type] A0 @key[is] @key[access] @key[all] T;
+    Global: A0 := ...;
+    @key[procedure] P(X: @Chg{Version=[3],address@hidden out] ],Old=[]}T) 
@key[is]
+        Y: @key[aliased] T;
+        @key[type] A1 @key[is] @key[access] @key[all] T;
+        Ptr0: A0 := Global; address@hidden OK.}
+        Ptr1: A1 := X'Access; address@hidden OK.}
+    @key[begin]
+        Ptr1 := Y'Access; address@hidden OK;}
+        Ptr0 := A0(Ptr1); address@hidden Illegal type conversion!}
+        Ptr0 := X'Access; address@hidden Illegal reference to Access 
attribute!}
+        Ptr0 := Y'Access; address@hidden Illegal reference to Access 
attribute!}
+        Global := Ptr0; address@hidden OK.}
+    @key[end] P;
address@hidden Lib_Unit;
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+The above illegal statements are illegal because the accessibility
address@hidden,New=[levels],Old=[level]} of X and Y are statically deeper
+than the accessibility level of A0.
+In every possible execution of any program including this library
+unit, if P is called, the accessibility level of X will be
+(dynamically) deeper than that of A0.
+Note that the accessibility levels of X and Y are the same.
+
address@hidden,Kind=[Revised]}
address@hidden@keepnext@;Here's an example involving access
address@hidden,New=[ of an access-to-object type],Old=[]}:
address@hidden
address@hidden Main @key[is]
+    @key[type] Level_1_Type @key[is] @key[access] @key[all] Integer;
+
+    @key[procedure] P(X: @key[access] Integer) @key[is]
+        @key[type] Nested_Type @key[is] @key[access] @key[all] Integer;
+    @key[begin]
+        ... Nested_Type(X) ... address@hidden (1)}
+        ... Level_1_Type(X) ... address@hidden (2)}
+    @key[end] P;
+
+    @key[procedure] Q(X: @key[access] Integer) @key[is]
+        @key[procedure] Nested(X: @key[access] Integer) @key[is]
+        @key[begin]
+            P(X);
+        @key[end] Nested;
+    @key[begin]
+        Nested(X);
+    @key[end] Q;
+
+    @key[procedure] R @key[is]
+        Level_2: @key[aliased] Integer;
+    @key[begin]
+        Q(Level_2'Access); address@hidden (3)}
+    @key[end] R;
+
+    Level_1: @key[aliased] Integer;
address@hidden
+    Q(Level_1'Access); address@hidden (4)}
+    R;
address@hidden Main;
address@hidden
+
+The run-time Accessibility_Check at (1) can never fail,
+and no code should be generated to check it.
+The check at (2) will fail when called from (3),
+but not when called from (4).
+
address@hidden@;Within a @nt{type_declaration}, the rules are checked in an
+assume-the-worst manner.
+For example:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0298-1]}
address@hidden P @key[is]
+    @key[type] Int_Ptr @key[is] @key[access] @key[all] Integer;
+    @key[type] Rec(D: @key[access] Integer) @key[is] @key[limited] 
@key[private];
address@hidden
+    @key[type] Rec_Ptr @key[is] @key[access] @key[all] Rec;
+    @key[function] F(X: Rec_Ptr) @key[return] Boolean;
+    @key[function] G(X: @key[access] Rec) @key[return] Boolean;
+    @key[type] Rec(D: @key[access] Integer) @key[is]
+        @Chg{Version=[3],address@hidden ],address@hidden
+            C1: Int_Ptr := Int_Ptr(D); address@hidden Illegal!}
+            C2: Rec_Ptr := Rec'Access; address@hidden Illegal!}
+            C3: Boolean := F(Rec'Access); address@hidden Illegal!}
+            C4: Boolean := G(Rec'Access);
+        @key[end] @key[record];
address@hidden P;
address@hidden
+
+C1, C2, and C3 are all illegal, because one might declare an object of
+type Rec at a more deeply nested place than the declaration of the type.
+C4 is legal, but the accessibility level of the object will be passed to
+function G, and constraint checks within G will prevent it from
+doing any evil deeds.
+
+Note that we cannot defer the checks on C1, C2, and C3 until
+compile-time of the object creation, because that would cause violation
+of the privacy of private parts.
+Furthermore, the problems might occur within a task or protected body,
+which the compiler can't see while compiling an object creation.
address@hidden
+
address@hidden
address@hidden@;The following attribute is defined for @PrefixType{a 
@nt{prefix} X that
+denotes an aliased view of an object}:
address@hidden
address@hidden(description)
address@hidden, Kind=[Revised], ChginAnnex=[F], Leading=[F],
+  Prefix=<X>, AttrName=<Access>, Ref=[8652/0010], ARef=[AI95-00127-01],
+  Text=<X'Access yields an access value that designates the object
+  denoted by X. The type of X'Access is an access-to-object type,
+  as determined by the expected type.
+  The expected type shall be a general access type.>}
address@hidden attribute],See=(Access attribute)}
address@hidden
+  X shall denote an aliased view of an address@hidden, including possibly the
+  current instance (see @RefSecNum{The Context of Overload Resolution})
+  of a limited type within its definition, or a formal parameter
+  or generic formal object of a tagged type].
+  The view denoted by the @nt<prefix> X
+  shall satisfy the following additional requirements, presuming the
+  expected type for X'Access is the general access type
+  @i(A)@Chg{New=[ with designated type @i(D)],Old=[]}:
address@hidden(itemize)
+  If @i(A) is an access-to-variable type, then the view shall be a
+  variable; @Redundant[on the other hand, if @i(A) is an
+  access-to-constant type, the view may be either a constant
+  or a variable.]
+  @begin{Discussion}
+    The current instance of a limited type
+    is considered a variable.
+  @end{discussion}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00363-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0008-1],ARef=[AI05-0041-1]}
+  The view shall not be a subcomponent that
+  depends on discriminants of @Chg{Version=[3],New=[an object unless
+  the object is known to be constrained],Old=[a
+  variable whose nominal subtype is unconstrained,
+  unless this subtype is indefinite,
+  or the variable is @Chg{Version=[2],New=[constrained by its initial value],
+  Old=[aliased]}]}.
+
+  @begin(Discussion)
+    @comment{The following is a "fix" to keep consistent with v. 5.95;
+    appearently 6.0 is different.
+    @ChgRef{Version=[1],Kind=[Deleted]}
+    @ChgDeleted{Version=[1],Text=[Old @b{Change}.]}}
+
+     This restriction is intended to be similar to the restriction
+     on renaming discriminant-dependent subcomponents.
+  @end{Discussion}
+  @begin{Reason}
+    This prevents references to subcomponents that might
+    disappear or move or change constraints after creating the reference.
+  @end{Reason}
+  @begin{ImplNote}
+     @Leading@;There was some thought to making this restriction
+     more stringent, roughly:
+     "X shall not denote a subcomponent of a variable
+     with discriminant-dependent subcomponents, if the nominal
+     subtype of the variable is an unconstrained definite subtype."
+     This was because in some implementations, it is not
+     just the discriminant-dependent subcomponents that might
+     move as the result of an assignment that changed the discriminants
+     of the enclosing object. However, it was decided not to make
+     this change because a reasonable implementation strategy was identified
+     to avoid such problems, as follows:
+     @begin(Itemize)
+       Place non-discriminant-dependent components with any aliased parts
+       at offsets preceding any discriminant-dependent components
+       in a discriminated record type with defaulted discriminants.
+
+       Preallocate the maximum space for unconstrained discriminated
+       variables with aliased subcomponents, rather than allocating
+       the initial size and moving them to a larger (heap-resident)
+       place if they grow as the result of an assignment.
+     @end(Itemize)
+
+     Note that for objects of a by-reference type, it is not an error
+     for a programmer to take advantage of the fact that such objects
+     are passed by reference. Therefore, the above approach is also
+     necessary for discriminated record types with components of
+     a by-reference type.
+
+     To make the above strategy work, it is important that
+     a component of a derived type is defined to be
+     discriminant-dependent if it is inherited and the parent subtype
+     constraint is defined in terms of a discriminant of the derived type
+     (see @RefSecNum(Discriminants)).
+  @end{ImplNote}
+
+  @ChgRef{Version=[1],Kind=[Revised],Ref=[8652/0010],ARef=[AI95-00127-01]}
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00363-01]}
+  If @address@hidden(A) is a named access type and @i(D) is a tagged type],
+  Old=[the designated type of @i(A) is tagged]}, then the type of the view
+  shall be covered by @address@hidden(D)],Old=[the designated type]};
+  @Chg{New=[if @i(A) is anonymous and @i(D) is tagged, then the type of the
+  view shall be either @i(D)'Class or a type covered by
+  @Chg{Version=[2],address@hidden<D>],Old=[D]};],Old=[]}
+  if @address@hidden(D) is untagged],address@hidden(A)'s designated type is 
not tagged]},
+  then the type of the view shall be
+  @address@hidden(D)],Old=[the same]},
+  and @Chg{Version=[2],New=[either:],address@hidden,Old=[either 
address@hidden(A)'s
+  designated subtype shall @Chg{New=[either ],Old=[]}
+  statically match the nominal subtype of the address@hidden or be],
+  Old=[, or the designated subtype shall be]} discriminated
+  and unconstrained;
+  @PDefn2{Term=[statically matching],Sec=(required)}]}
+  @begin{InnerItemize}
+    @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00363-01]}
+    @ChgAdded{Version=[2],Text=[the designated subtype of @i{A} shall 
statically
+    match the nominal subtype of the view;
+    address@hidden matching],Sec=(required)}]}
+
+    @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00363-01]}
+    @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0041-1]}
+    @ChgRef{Version=[4],Kind=[RevisedAdded],ARef=[AI12-0095-1]}
+    @ChgAdded{Version=[2],address@hidden shall be discriminated in its full 
view
+    and unconstrained in any partial view, and the designated subtype of
+    @i{A} shall be address@hidden,address@hidden,New=[],
+    Old=[ For the purposes
+    of determining within a generic body whether @i{D} is unconstrained
+    in any partial view, a discriminated subtype is
+    considered to have a constrained partial view if it is a descendant
+    of an untagged generic formal private or derived type.]}],Old=[]}]}
+  @end{InnerItemize}
+  @begin{ImplNote}
+    This ensures
+    that the dope for an aliased array object can always be stored contiguous
+    with it, but need not be if its nominal subtype is constrained.
+  @end{implnote}
+  @begin{Ramification}
+  @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0010],ARef=[AI95-00127-01]}
+  @Chg{New=[An access attribute can be used as the controlling operand in a
+  dispatching call; see @RefSecNum{Dispatching Operations of Tagged Types}.],
+  Old=[]}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00363-01]}
+  @Chg{Version=[2],New=[This does not require that types have a partial view
+  in order to allow an access attribute of an unconstrained discriminated
+  object, only that any partial view that does exist is unconstrained.],Old=[]}
+  @end{Ramification}
+
+  @begin{Discussion}
+    @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0095-1]}
+    @ChgAdded{Version=[4],Text=[We assume the worst in a generic body whether
+    or not a formal subtype has a constrained partial view; specifically, in a
+    generic body a discriminated subtype is considered to have a constrained
+    partial view if it is a descendant of an untagged generic formal private
+    or derived type (see @RefSecNum{Formal Private and Derived Types} for the
+    formal definition of this rule).]}
+  @end{Discussion}
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0041-1]}
+  The accessibility level of the view shall not be statically deeper
+  than that of the access type @address@hidden,New=[],Old=[
+  In addition to the places where @LegalityTitle normally apply
+  (see @RefSecNum{Generic Instantiation}),
+  this rule applies also in the private part of an
+  instance of a generic address@hidden contract issue}]}
address@hidden rule],Sec=(Access attribute)}
+  @begin(Ramification)
+    In an instance body, a run-time check applies.
+
+    @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00230-01]}
+    If @i(A) is an address@hidden,New=[ access-to-object type of
+    an access parameter],Old=[access type]}, then the view can never have a
+    deeper accessibility level than @i(A)@Chg{Version=[2],New=[. The same is
+    true for an anonymous access-to-object type of an access
+    discriminant],Old=[]}, except when X'Access is used to initialize
+    an access discriminant of an object created by an @nt<allocator>.
+    The latter case is illegal if the accessibility level of X
+    is statically deeper than that of the access type of the
+    @nt<allocator>; a run-time check is needed in the case where the
+    initial value comes from an access address@hidden,New=[ Other
+    anonymous access-to-object types have "normal" accessibility 
checks.],Old=[]}
+  @end(Ramification)
address@hidden(itemize)
+
address@hidden,Kind=[Added],ARef=[AI05-0041-1]}
address@hidden,NoPrefix=[T],Text=[In addition to the places where
+  @LegalityTitle normally apply
+  (see @RefSecNum{Generic Instantiation}), these requirements apply
+  also in the private part of an instance of a generic
+  address@hidden contract issue}]}
+
+  @address@hidden
+  @Defn2{Term=[Program_Error],Sec=(raised by failure of run-time check)}
+  A check is made that the accessibility level of X is not
+  deeper than that of the access type @i(A).
+  If this check fails, Program_Error is raised.
+  @begin{Ramification}
+    @ChgRef{Version=[2],Kind=[Revised]}
+    The check is needed for access parameters @Chg{Version=[2],New=[ of
+    an access-to-object type],Old=[]} and in instance bodies.
+
+    @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0024-1]}
+    @ChgAdded{Version=[3],Text=[Because there are no access parameters 
permitted for task
+    entries, the accessibility levels are always comparable. We would have to
+    switch to the terminology used in @RefSecNum{Allocators} and
+    @RefSecNum{Return Statements} based on inclusion within
+    masters if we relax this restriction. That might introduce unacceptable
+    distributed overhead.]}
+  @end{Ramification}
+  @begin(ImplNote)
+    @ChgRef{Version=[2],Kind=[Revised]}
+    @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0148-1]}
+    This check requires that some indication of lifetime is
+    passed as an implicit parameter along with access address@hidden,
+    New=[ of an access-to-object type],address@hidden,New=[ A similar
+    indication is required for stand-alone objects of anonymous 
access-to-object
+    types.],Old=[]}No such requirement applies to @Chg{Version=[2],New=[other
+    anonymous access types],Old=[access discriminants]}, since
+    the checks associated with them are all compile-time checks.
+  @end(ImplNote)
+
+  @address@hidden subtype conversion],Sec=(Access attribute)}
+  If the nominal subtype of X does not statically match the designated
+  subtype of @i(A), a view conversion of X to the designated subtype
+  is evaluated (which might raise Constraint_Error @em
+  see @RefSecNum(Type Conversions))
+  and the value of X'Access designates that view.
address@hidden(description)
+
+The following attribute is defined for @PrefixType{a @nt{prefix} P that
+denotes a subprogram}:
address@hidden(description)
address@hidden,Kind=[Revised],ChginAnnex=[F], Leading=[F],
+  Prefix=<P>, AttrName=<Access>,ARef=[AI95-00229-01], 
ARef=[AI95-00254-01],ARef=[AI05-0239-1],
+  Text=<P'Access yields an access value that designates the subprogram
+  denoted by P.
+  The type of P'Access is an access-to-subprogram type (@i(S)),
+  as determined by the expected type.>}
address@hidden
address@hidden rule],Sec=(Access attribute)}
+  The accessibility level of P shall not be statically deeper than
+  that of @i{S}.
+  @PDefn{generic contract issue}
+  In addition to the places where @LegalityTitle normally apply
+  (see @RefSecNum{Generic Instantiation}),
+  this rule applies also in the private part of an
+  instance of a generic unit.
+  The profile of P
+  shall be @Chg{Version=[3],New=[subtype conformant],Old=[subtype-conformant]}
+  with the designated profile of @i(S),
+  and shall not be Intrinsic.
address@hidden conformance],Sec=(required)}
+  If the subprogram denoted by P is declared within a
+  generic @Chg{Version=[2],New=[unit, and the expression P'Access occurs within
+  the body of that generic unit or within the body of a generic unit declared
+  within the declarative region of the generic unit, then the ultimate ancestor
+  of @i{S} shall be either a nonformal type declared within the generic unit
+  or an anonymous access type of an access parameter.],
+  Old=[body, @i{S} shall be declared within the generic body.]}
+
+  @begin(Discussion)
+    @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00229-01]}
+    The part about generic bodies is worded in terms of the denoted
+    subprogram, not the denoted view; this implies that renaming is
+    invisible to this part of the
+    address@hidden,New=[ @lquotes@;Declared within the declarative region of
+    the address@hidden@; is referring to child and nested generic
+    units.],Old=[]} This rule is partly to prevent contract model problems
+    with respect to the accessibility rules,
+    and partly to ease shared-generic-body implementations,
+    in which a subprogram declared in an instance needs to have a
+    different calling convention from other subprograms with the same
+    profile.
+
+    @Comment{The change is from AI05-0239-1, just punctuation}
+    Overload resolution ensures only that the profile
+    is @Chg{Version=[3],New=[type conformant],Old=[type-conformant]}.
+    This rule specifies that subtype conformance is required (which also
+    requires matching calling conventions).
+    P cannot denote an entry because access-to-subprogram types
+    never have the @i(entry) calling convention. P cannot denote
+    an enumeration literal or an attribute function because
+    these have intrinsic calling conventions.
+  @end(Discussion)
address@hidden(description)
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0188-1]}
address@hidden,Type=[Leading],Text=[An @nt{expression} is said to have
address@hidden accessibility} if it
address@hidden address@hidden,Sec=[distributed]}]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[a @nt{conditional_expression} (see
address@hidden Expressions}); or]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[a view conversion, @nt{qualified_expression},
+or parenthesized expression whose operand has distributed accessibility.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0188-1]}
address@hidden,Text=[The statically deeper relationship does not apply to
+the accessibility level of an @nt{expression} having distributed accessibility;
+that is, such an accessibility level is not considered to be statically deeper,
+nor statically shallower, than any other.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0188-1]}
address@hidden,Text=[Any static accessibility requirement that is imposed
+on an @nt{expression} that has distributed accessibility (or on its type) is
+instead imposed on the @address@hidden of the underlying
address@hidden This rule is applied recursively if a
address@hidden@nt{expression} also has distributed accessibility.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This means that any @LegalityName requiring that
+  the accessibility level of an @nt{expression} (or that of the type of an
+  @nt{expression}) shall or shall not be statically deeper than some other 
level
+  also applies, in the case where the @nt{expression} has distributed
+  accessibility, to each @address@hidden of the underlying
+  @nt{conditional_expression}.]}
address@hidden
+
address@hidden
+
address@hidden
+The Unchecked_Access attribute yields the same result as the Access
+attribute for objects, but has fewer restrictions
+(see @RefSecNum{Unchecked Access Value Creation}).
+There are other predefined operations that yield access values:
+an @nt<allocator> can be used to create an object, and return an
+access value that designates it (see @RefSecNum(Allocators));
+evaluating the literal @key(null) yields a null access value that designates
+no entity at all (see @RefSecNum(Literals)).
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01]}
address@hidden operations],Sec=(of an access type)}
+The predefined operations of an access type also include
+the assignment operation, qualification, and membership tests.
+Explicit conversion is allowed between general access types with
+matching designated subtypes; explicit conversion is allowed
+between access-to-subprogram types with subtype conformant profiles
+(see @RefSecNum{Type Conversions}).
address@hidden conformance}
+Named access types have predefined equality operators;
+anonymous access types do address@hidden,New=[, but they can use the
+predefined equality operators for @i<universal_access> ],Old=[]}(see
address@hidden Operators and Membership Tests}).
address@hidden(Reason)
address@hidden,Kind=[Revised],ARef=[AI95-00230-01]}
address@hidden,New=[Anonymous access types can use the universal access
+equality operators declared in Standard, while named access types cannot
+for compatibility reasons. ],Old=[]}By not
+having equality operators for anonymous access types,
+we eliminate the need to specify exactly where the
+predefined operators for anonymous access types would be defined, as
+well as the need for an implementer to insert an implicit
+declaration for "=", etc. at the appropriate place in their symbol table.
+Note that @Chg{Version=[2],New=[":=", ],Old=[]}'address@hidden,New=[,],Old=[]} 
and
+"address@hidden" are address@hidden,New=[],Old=[, and ":=" is defined
+though useless since all instances are constant. The literal
address@hidden(null) is also defined for the
+purposes of overload resolution, but is disallowed by a @LegalityTitle
+of this subclause]}.
address@hidden(Reason)
+
+The object or subprogram designated by an access value can be named
+with a dereference, either an @nt<address@hidden> or an
address@hidden<implicit_dereference>. See @RefSecNum{Names}.
+
+A call through the dereference of an access-to-subprogram
+value is never a dispatching call.
address@hidden
+See @RefSecNum{Dispatching Operations of Tagged Types}.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00254-01]}
address@hidden closure}
address@hidden,Sec=(downward)}
address@hidden,New=[The],Old=[The accessibility rules imply that it
+is not possible to use the]} Access
address@hidden,New=[ for subprograms and parameters of an
+anonymous access-to-subprogram type may together be used],Old=[]}
+to implement @lquotes@;downward address@hidden@; @em that is,
+to pass a more-nested subprogram as a parameter to a
+less-nested subprogram, as might be @Chg{Version=[2],
+New=[appropriate],Old=[desired for example]} for an
+iterator address@hidden,New=[ or numerical integration.
+Downward],Old=[. Instead, downward]}
+closures can @Chg{Version=[2],New=[also ],Old=[]}be implemented using
+generic formal subprograms (see @RefSecNum{Formal Subprograms}).
+Note that Unchecked_Access is not allowed for subprograms.
+
+Note that using
+an access-to-class-wide tagged type with a dispatching operation
+is a potentially more structured alternative to using an
+access-to-subprogram type.
+
+An implementation may consider
+two access-to-subprogram values to be unequal,
+even though they designate the same subprogram. This might
+be because one points directly to the subprogram,
+while the other points to a special prologue that
+performs an Elaboration_Check and then jumps to the subprogram.
+See @RefSecNum(Relational Operators and Membership Tests).
address@hidden
+
+If equality of
+access-to-subprogram values is important to the logic
+of a program, a reference to the Access attribute of a subprogram
+should be evaluated only once
+and stored in a global constant for subsequent use and equality
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of use of the Access attribute:}
address@hidden
+Martha : Person_Name := @key[new] Person(F);       address@hidden see 
@RefSecNum{Incomplete Type Declarations}]
+Cars   : @key[array] (1..2) @key[of] @key[aliased] Car;
+   ...
+Martha.Vehicle := Cars(1)'Access;
+George.Vehicle := Cars(2)'Access;
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+We no longer make things like 'Last and ".component"
+(basic) operations of an access type that need to be "declared"
+somewhere. Instead, implicit dereference
+in a @nt{prefix} takes care of them all. This means that
+there should never be a case when address@hidden'Last is legal
+while X'Last is not. See AI83-00154.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00363-01]}
address@hidden,address@hidden@;@Defn{incompatibilities with Ada 95} Aliased
+variables are not necessarily constrained in Ada 2005 (see
address@hidden Types}). Therefore, a subcomponent of an aliased variable
+may disappear or change shape, and taking 'Access of such a subcomponent
+thus is illegal, while the same operation would have been legal in Ada 95.
+Note that most allocated objects are
+still constrained by their initial value (see @RefSecNum{Allocators}), and thus
+legality of 'Access didn't change for them. For example:],Old=[]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden T1 (D1 : Boolean := False) @key{is}
+   @key{record}
+      @key{case} D1 @key{is}
+         @key{when} False =>
+            C1 : @key{aliased} Integer;
+         @key{when} True =>
+            @key{null};
+      @key{end} @key{case};
+   @key{end} @key{record};
address@hidden Acc_Int @key{is access all} Integer;],Old=[]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,New=[A_T : @key{aliased} T1;
+Ptr : Acc_Int := A_T.C1'Access; -- @RI[Illegal in Ada 2005, legal in Ada 95]
+A_T := (D1 => True);            -- @RI[Raised Constraint_Error in Ada 95, but 
does not]
+                                -- @RI[in Ada 2005, so Ptr would become 
invalid when this]
+                                -- @RI[is assigned (thus Ptr is 
illegal).]],Old=[]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00363-01]}
address@hidden,New=[If a discriminated full type has a partial view (private
+type) that is constrained, we do not allow 'Access on objects to create a value
+of an object of an
+access-to-unconstrained type. Ada 95 allowed this attribute and various
+access subtypes, requiring that the heap object be constrained and thus making
+details of the implementation of the private type visible to the client of
+the private type. See @RefSecNum{Allocators} for more on this topic.],Old=[]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00229-01],ARef=[AI95-00254-01]}
address@hidden,address@hidden Correction:] Taking 'Access of a subprogram
+declared in a generic unit in the body of that generic is no longer allowed.
+Such references can easily be used to create dangling pointers, as
address@hidden are not rechecked in instance bodies. At the same time, the
+rules were loosened a bit where that is harmless, and also to allow any routine
+to be passed to an access parameter of an access-to-subprogram type. The now
+illegal uses of 'Access can almost always be moved to the private part of the
+generic unit, where they are still legal (and rechecked upon instantiation for
+possibly dangling pointers).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],Ref=[8652/0010],ARef=[AI95-00127-01]}
address@hidden,address@hidden<Corrigendum:> @Defn{extensions to Ada 95}
+Access attributes of objects of class-wide types
+can be used as the controlling parameter in a dispatching calls (see
address@hidden Operations of Tagged Types}). This was an oversight in
+Ada 95.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00235-01]}
address@hidden,address@hidden Correction:] The type of the prefix
+can now be used in resolving Access attributes. This allows more uses of the
+Access attribute to resolve. For example:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Int_Ptr @key{is access all} Integer;
address@hidden Float_Ptr @key{is access all} Float;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Zap (Val : Int_Ptr) @key{return} Float;
address@hidden Zap (Val : Float_Ptr) @key{return} Float;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Value : @key{aliased} Integer := 10;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Result1 : Float := Zap (Value'access); -- @RI[Ambiguous in 
Ada 95; resolves in Ada 2005.]
+Result2 : Float := Zap (Int_Ptr'(Value'access)); -- @RI[Resolves in Ada 95 and 
Ada 2005.]]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This change is upward compatible; any expression
+that does not resolve by the new rules would have failed a Legality Rule.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00162-01]}
address@hidden,Text=[Adjusted the wording to reflect the fact that
+expressions and function calls are masters.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00230-01],ARef=[AI95-00254-01],ARef=[AI95-00318-02],ARef=[AI95-00385-01],ARef=[AI95-00416-01]}
address@hidden,Text=[Defined the accessibility of the various new kinds and
+uses of anonymous access types.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0008-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Simplified the description of when a discriminant-dependent component is
+  allowed as the prefix of 'Access to when the object is known to be
+  constrained. This fixes a confusion as to whether a subcomponent of an object
+  that is not certain to be constrained can be used as a prefix of 'Access. The
+  fix introduces an incompatibility, as the rule did not apply in Ada 95 if the
+  prefix was a constant; but it now applies no matter what kind of object is
+  involved. The incompatibility is not too bad, since most kinds of constants
+  are known to be constrained.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0041-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the checks for 
the
+  constrainedness of the prefix of the Access attribute so that 
assume-the-worst
+  is used in generic bodies. This may make some programs illegal, but those
+  programs were at risk having objects disappear while valid access values 
still
+  pointed at them.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0082-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada address@hidden<Correction:>
+  Eliminated the static accessibility definition for generic formal types, as
+  the actual can be more or less nested than the generic itself. This allows
+  programs that were illegal for Ada 95 and for Ada 2005.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0148-1],ARef=[AI05-0253-1]}
+  @ChgAdded{Version=[3],Text=[Eliminate the static
+  accessibility definition for stand-alone objects of anonymous 
access-to-object
+  types. This allows such objects to be used as temporaries without causing
+  accessibility problems.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0014-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the rules so 
that the
+  accessibility of the object designated by an access object is that of the
+  access type, even when no dereference is given. The accessibility was not
+  specified in the past. This correction applies to both Ada 95 and Ada 2005.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0024-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected accessibility 
rules for
+  access discriminants so that no cases are omitted.]}
+
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0051-1],ARef=[AI05-0234-1],ARef=[AI05-0235-1],ARef=[AI05-0284-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected accessibility 
rules for
+  anonymous access return types and access discriminants in return 
statements.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0066-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Changed coextension rules 
so that
+  coextensions that belong to an anonymous object are transfered to the 
ultimate
+  object.]}
+
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0142-4],ARef=[AI05-0188-1],ARef=[AI05-0235-1]}
+  @ChgAdded{Version=[3],Text=[Defined the accessibility of explicitly
+  aliased parameters (see @RefSecNum{Subprogram Declarations}) and
+  @nt{conditional_expression}s (see @RefSecNum{Conditional Expressions}).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0234-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Defined the term 
@ldquote@;master
+  of the address@hidden to simplify other wording, especially that for the
+  accessibility checks associated with return statements and explicitly aliased
+  parameters.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0270-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Defined the (omitted)
+  accessibility level of null values when those are passed as the actual of an
+  access-to-object parameter.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0027-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Defined the accessibility of a value conversion, so that it is treated like
+  an @nt{aggregate} built at the point of the conversion. This was
+  previously unspecified, so this change might be
+  incompatible if an Ada implementation treated the accessibility of such
+  conversions as that of the operand type; in that case, previous legal
+  conversions probably will become illegal as the lifetime of the conversion
+  is very short. However, code that could tell this difference is fairly rare
+  (taking 'Access of a component of a result of a type conversion), code
+  depending on this accessibility was not portable, and such code could have
+  created an immediately dangling pointer if the conversion actually made
+  a copy (which is necessary in some instances).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0067-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Corrected so that it is 
clear
+  that explicitly aliased parameters in procedures have the same accessibility
+  as other parameters. Only explicitly aliased parameters in functions are
+  special.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0070-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> The accessibility of
+  an anonymous access type of an @nt{extended_return_statement} is defined
+  here rather than in @RefSecNum{Return Statements} so that all accessibility
+  rules are here.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0089-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Corrected a number of 
rules so
+  that they clearly apply to generic functions as well as functions. (Remember,
+  a generic function is not a function.)]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0095-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Moved the assume the 
worst rule
+  about constrainedness of the prefix of attribute Access to
+  @RefSecNum{Formal Private and Derived Types}, as a number of places in the
+  Standard need this rule.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0157-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Ensured that the 
statically
+  deeper relationship applies within the return expression of an expression
+  function. (Dynamic properties apply by equivalence, but static properties
+  are handled separately.)]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Parts}
+
address@hidden
address@hidden @nt<declarative_part> contains @nt<declarative_item>s
+(possibly none).]
address@hidden
+
address@hidden
address@hidden<declarative_part>,rhs="address@hidden"}
+
+
address@hidden<declarative_item>,rhs="
+    @Syn2{basic_declarative_item} | @Syn2{body}"}
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden<basic_declarative_item>,rhs="
+    @Syn2{basic_declaration} | @address@hidden,address@hidden | 
@Syn2{use_clause}"}
+
address@hidden<body>,rhs="@Syn2{proper_body} | @Syn2{body_stub}"}
+
address@hidden<proper_body>,rhs="
+    @Syn2{subprogram_body} | @Syn2{package_body} | @Syn2{task_body} | 
@Syn2{protected_body}"}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00420-01]}
address@hidden,Text=[The list of @nt{declarative_item}s of a
address@hidden is called the @i{declaration list} of the
address@hidden@PDefn2{Term=[declaration list],Sec=[declarative_part]}]}
address@hidden
+
address@hidden
address@hidden, Sec=(declarative_part)}
+The elaboration of a @nt{declarative_part} consists of the elaboration of
+the @nt{declarative_item}s, if any, in the order in which they are given
+in the @nt{declarative_part}.
+
address@hidden
+An elaborable construct is in the @i(elaborated) state after the
+normal completion of its elaboration.
+Prior to that, it is @i(not yet elaborated).
address@hidden
+  The elaborated state is only important for bodies;
+  certain uses of a body raise an exception if the body is not yet
+  elaborated.
+
+  Note that "prior" implies before the start of elaboration,
+  as well as during elaboration.
+
+  The use of the term "normal completion" implies that
+  if the elaboration propagates an exception or is aborted, the
+  declaration is not elaborated.
+  RM83 missed the aborted case.
address@hidden
+
address@hidden
+For a construct that attempts to use a body,
+a check (Elaboration_Check) is performed, as follows:
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0014],ARef=[AI95-00064-01]}
+For a call to a (non-protected) subprogram that has
+an explicit body, a check is made that the
address@hidden,address@hidden is already elaborated.
+This check and the evaluations of any actual parameters of the call
+are done in an arbitrary address@hidden order],Sec=[allowed]}
address@hidden
+  AI83-00180 specifies that there is no elaboration check for
+  a subprogram defined by a @nt{pragma} Interface (or equivalently,
+  @nt{pragma} Import). AI83-00430 specifies that there is no elaboration check
+  for an enumeration literal. AI83-00406 specifies that the evaluation
+  of parameters and the elaboration check occur in an arbitrary order.
+  AI83-00406 applies to generic instantiation as well (see below).
+
+  @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0014],ARef=[AI95-00064-01]}
+  @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0177-1]}
+  @ChgAdded{Version=[1],Text=[A subprogram can be completed by a
+  address@hidden,New=[, a @nt{null_procedure_declaration}, or
+  an @nt{expression_function_declaration}],Old=[]}, and we need
+  to make an elaboration check on such a body, so we use
+  @lquotes@;address@hidden@; rather than @nt{subprogram_body} above.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+For a call to a protected operation of a protected type
+(that has a body @em no check is performed if @Chg{Version=[3],New=[],Old=[a
address@hidden Import applies to]} the protected address@hidden,New=[ is
+imported @em see @RefSecNum{Interfacing Aspects}],Old=[]}),
+a check is made that the @nt<protected_body> is already elaborated.
+This check and the evaluations of any actual parameters of the call
+are done in an arbitrary address@hidden order],Sec=[allowed]}
address@hidden
+  A protected type has only one elaboration @lquotes@;bit,@rquotes@; rather 
than
+  one for each operation, because one call may result in evaluating
+  the barriers of other entries, and because there are no elaborable
+  declarations between the bodies of the operations. In fact,
+  the elaboration of a @nt<protected_body> does not elaborate
+  the enclosed bodies, since they are not considered independently
+  elaborable.
+
+  Note that there is no elaboration check when calling a task entry.
+  Task entry calls are permitted even before the associated @nt<task_body>
+  has been seen. Such calls are simply queued until the task is
+  activated and reaches a corresponding @nt<accept_statement>.
+  We considered a similar rule for protected entries @em simply
+  queuing all calls until the @nt<protected_body> was seen, but felt
+  it was not worth the possible implementation overhead, particularly
+  given that there might be multiple instances of the protected type.
address@hidden
+
+For the activation of a task, a check is made by the
+activator that the @nt{task_body} is already elaborated.
+If two or more tasks are being activated together
+(see @RefSecNum{Task Execution - Task Activation}),
+as the result of the elaboration of
+a @nt{declarative_part} or the initialization
+for the object created by an allocator,
+this check is done for all of them before activating any
+of them.
address@hidden
+  As specified by AI83-00149, the check is done by the
+  activator, rather than by the task itself. If it were
+  done by the task itself, it would be turned into a Tasking_Error
+  in the activator, and the other tasks would still be activated.
address@hidden
+
+For the instantiation of a generic unit that has a body, a check is
+made that this body is already elaborated.
+This check and the evaluation of any @nt{explicit_generic_actual_parameter}s
+of the instantiation are done in an arbitrary address@hidden 
order],Sec=[allowed]}
address@hidden
+
address@hidden,Sec=(raised by failure of run-time check)}
+The exception Program_Error is raised if any of these checks fails.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
address@hidden to Ada 83}
+The syntax for @nt{declarative_part} is modified to remove the ordering
+restrictions of Ada 83; that is, the distinction between
address@hidden and @ntf{later_declarative_item}s
+within @nt{declarative_part}s is removed.
+This means that things like @nt{use_clause}s and
address@hidden,address@hidden,address@hidden
+can be freely intermixed with things like bodies.
+
+The syntax rule for @nt{proper_body} now allows a @nt{protected_body},
+and the rules for elaboration checks now cover calls on
+protected operations.
address@hidden
+
address@hidden
+The syntax rule for @ntf{later_declarative_item} is removed;
+the syntax rule for @nt{declarative_item} is new.
+
+RM83 defines @lquotes@;address@hidden@; and @lquotes@;not yet address@hidden@; 
for
address@hidden here, and for other things in @RefSec{Declarations}.
+That's no longer necessary, since these terms are fully defined in
address@hidden
+
+In RM83, all uses of @nt{declarative_part} are optional
+(except for the one in @nt{block_statement} with a @key(declare))
+which is sort of strange, since a @nt{declarative_part} can be empty,
+according to the syntax.
+That is, @nt{declarative_part}s are sort of @lquotes@;doubly address@hidden@;.
+In Ada 95, these @nt{declarative_part}s are always required
+(but can still be empty).
+To simplify description, we go further and say
+(see @RefSec(Block Statements)) that a
address@hidden<block_statement> without an explicit @nt<declarative_part>
+is equivalent to one with an empty one.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],Ref=[8652/0009],ARef=[AI95-00137-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Changed representation 
clauses
+  to aspect clauses to reflect that they are used for more than just
+  representation.]}
+
address@hidden,Kind=[AddedNormal],Ref=[8652/0014],ARef=[AI95-00064-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that the 
elaboration
+  check applies to all kinds of subprogram bodies.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00420-01]}
+  @ChgAdded{Version=[2],Text=[Defined @lquotes@;declaration address@hidden to
+  avoid confusion for various rules. Other kinds of declaration list are
+  defined elsewhere.]}
address@hidden
+
+
address@hidden of Declarations}
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0014],ARef=[AI95-00064-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0177-1]}
+Declarations sometimes come in two parts.
address@hidden a completion}
+A declaration that requires a second part is said to @i(require completion).
address@hidden, Sec=(compile-time concept)}
+The second part is called the @i(completion) of the declaration (and of
+the entity declared),
+and is either another declaration, a body, or a @nt<pragma>.
address@hidden @defn<body>@i<body> is a @nt<body>,
+an @nt<entry_body>,@Chg{Version=[3],New=[ a @nt{null_procedure_declaration} or 
an
address@hidden that completes another declaration,],Old=[]} or
+a renaming-as-body
+(see @RefSecNum<Subprogram Renaming Declarations>).],Old=[]}
address@hidden
address@hidden@keepnext@;Throughout the RM95, there are rules about completions 
that
+define the following:
address@hidden
+Which declarations require a corresponding completion.
+
+Which constructs can only serve as the completion
+of a declaration.
+
+Where the completion of a declaration is allowed to be.
+
+What kinds of completions are allowed to correspond to each kind of
+declaration that allows one.
address@hidden
+
+Don't confuse this compile-time concept with
+the run-time concept of completion
+defined in @RefSecNum{Completion and Finalization}.
+
+Note that the declaration of a private type (if limited) can be
+completed with the declaration of a task type, which is then completed
+with a body.
+Thus, a declaration can actually come in @i{three} parts.
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00217-06]}
address@hidden,Kind=[Revised],ARef=[AI05-0162-1]}
address@hidden,address@hidden,New=[An incomplete type (whether declared
+in the limited view of a package or not) may be completed by a private type
+declaration],Old=[In Ada 2005 the limited view of the package contains an
+incomplete view of the private type]}, so we can
address@hidden,New=[in fact ],Old=[]}have @i{four}
address@hidden,New=[],Old=[ now]}.],Old=[]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[In Ada 2012, there are no language-defined pragmas
+that act as completions. Pragma Import (which is obsolescent) has the effect of
+setting aspect Import to True; such an aspect makes giving a completion 
illegal.
+The wording that allows pragmas as completions was left as it is harmless and
+appears in many places in this Standard.]}
address@hidden
address@hidden
+
address@hidden
address@hidden@keepnext@;A construct that can be a completion
+is interpreted as the completion of a prior
+declaration only if:
address@hidden(itemize)
+The declaration and the completion occur immediately within
+the same declarative region;
+
+The defining name or @nt{defining_program_unit_name}
+in the completion is the same as in the declaration,
+or in the case of a @nt{pragma}, the @nt{pragma} applies to
+the declaration;
+
+If the declaration is overloadable, then the completion
+either has a type-conformant profile,
+or is a @nt{pragma}.
address@hidden conformance],Sec=(required)}
address@hidden(itemize)
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+An implicit declaration shall not have a completion.
address@hidden a completion}
+For any explicit declaration that is specified
+to @i(require completion), there shall be a corresponding explicit
address@hidden,New=[, unless the declared
+entity is imported (see @RefSecNum{Interfacing Aspects})],Old=[]}.
address@hidden(Honest)
address@hidden,Kind=[Added],ARef=[AI95-00217-06]}
address@hidden,Text=[The implicit declarations occurring in a
+limited view do have a completion (the explicit declaration occurring in the
+full view) but that's a special case, since the implicit declarations are
+actually built from the explicit ones. So they do not @i{require} a
+completion, they have one by @i{fiat}.]}
address@hidden
+
address@hidden(Discussion)
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  The implicit declarations of predefined operators are not allowed to
+  have a completion.
+  Enumeration literals, although they are subprograms, are not allowed to have 
a
+  corresponding @nt{subprogram_body}.
+  That's because the completion rules are described in terms of constructs
+  (@nt{subprogram_declaration}s) and not entities (subprograms).
+  When a completion is required, it has to be explicit;
+  the implicit null @nt{package_body} that 
@Chg{Version=[3],New=[Clause],Old=[Section]}
+  @RefSecNum{Packages}
+  talks about cannot serve as the completion of a
+  @nt{package_declaration} if a completion is required.
address@hidden(Discussion)
+
+At most one completion is allowed for a given declaration.
+Additional requirements on completions appear where each kind
+of completion is defined.
address@hidden
+A subunit is not a completion;
+the stub is.
+
+If the completion of a declaration is also a declaration,
+then @i{that} declaration might have a completion, too.
+For example, a limited private type can be completed with a task type,
+which can then be completed with a task body.
+This is not a violation of the @lquotes@;at most one address@hidden@; rule.
address@hidden
+
address@hidden defined}
+A type is @i(completely defined) at a place that is after its
+full type definition (if it has one) and after all of its
+subcomponent types are completely defined.
+A type shall be completely defined before it is frozen
+(see @RefSecNum{Freezing Rules} and
address@hidden Types and Private Extensions}).
address@hidden(Reason)
+  @comment{The following is a "fix" to keep consistent with v. 5.95;
+  appearently 6.0 is different.
+  @ChgRef{Version=[1],Kind=[Deleted]}
+  @ChgDeleted{Version=[1],Text=[Old @b{Change}.]}}
+
+  Index types are always completely defined @em no need to mention them.
+  There is no way for a completely defined type to depend on the value of
+  a (still) deferred constant.
address@hidden(Reason)
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+Completions are in principle allowed for any kind of explicit declaration.
+However, for some kinds of declaration,
+the only allowed completion is @Chg{Version=[3],New=[an implementation-defined
+pragma], Old=[a @nt{pragma} Import]},
+and implementations are not required to @Chg{Version=[3],New=[have any
+such pragmas],Old=[support @nt{pragma} Import for
+every kind of entity]}.
address@hidden(Discussion)
+  @ChgRef{Version=[3],Kind=[Deleted],ARef=[AI05-0229-1]}
+  @ChgDeleted{Version=[3],Text=[In fact, we expect that implementations
+  will @i{not} support pragma
+  Import of things like types @em it's hard to even define the
+  semantics of what it would mean.
+  Therefore, in practice, @i{not} every explicit declaration
+  can have a completion.
+  In any case, if an implementation chooses to support pragma Import for,
+  say, types, it can place whatever restrictions on the feature it wants
+  to. For example, it might want the @nt{pragma} to be a freezing point for
+  the type.]}
address@hidden(Discussion)
+
+There are rules that prevent premature uses of declarations that have a
+corresponding completion.
+The Elaboration_Checks of @RefSecNum{Declarative Parts} prevent such
+uses at run time for subprograms, protected operations, tasks, and
+generic units.
+The rules of @RefSec{Freezing Rules}
+prevent, at compile time, premature uses of other entities
+such as private types and deferred constants.
address@hidden
+
address@hidden
+This subclause is new. It is intended to cover all
+kinds of completions of declarations, be they a body for a spec,
+a full type for an incomplete or private type, a full constant
+declaration for a deferred constant declaration, or a @nt{pragma} Import
+for any kind of entity.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0014],ARef=[AI95-00064-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added a definition of 
@i{body},
+  which is different than @nt{body} or @key{body}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI95-0177-1]}
+  @ChgAdded{Version=[3],Text=[Added null procedures and expression functions
+  that are completions to the definition of @i<body>.]}
address@hidden
diff --git a/packages/ada-ref-man/source_2012/04a.mss 
b/packages/ada-ref-man/source_2012/04a.mss
new file mode 100755
index 0000000..b528037
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/04a.mss
@@ -0,0 +1,5748 @@
address@hidden(04, Root="ada.mss")
+
address@hidden: 2016/02/09 04:55:40 $}
address@hidden and Expressions}
+
address@hidden: e:\\cvsroot/ARM/Source/04a.mss,v $}
address@hidden: 1.140 $}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden rules applicable to the different forms of @nt<name> and
+expression, and to their evaluation, are given in this
address@hidden,New=[clause],Old=[section]}.]
address@hidden
+
address@hidden
+
address@hidden
address@hidden@nt<Name>s can denote declared entities, whether declared 
explicitly
+or implicitly (see @RefSecNum(Declarations)). @nt<Name>s can also
+denote objects or subprograms designated by access values; the
+results of @nt<type_conversion>s or @nt<function_call>s; subcomponents
+and slices of objects and values; protected subprograms,
+single entries, entry families,
+and entries in families of entries.
+Finally, @nt<name>s can denote attributes of any of the foregoing.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0003-1],ARef=[AI05-0139-2]}
address@hidden, lhs=<name>,rhs="
+     @address@hidden| @Syn2{explicit_dereference}
+   | @address@hidden| @Syn2{slice}
+   | @address@hidden| @Syn2{attribute_reference}
+   | @address@hidden| @Syn2{function_call}
+   | @address@hidden,address@hidden| @Syn2{qualified_expression}
+   | @address@hidden| @Syn2{generalized_indexing}],Old=[]}"}
+
+
address@hidden<direct_name>,
+rhs="@Syn2{identifier} | @Syn2{operator_symbol}"}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+  @nt<character_literal> is no longer a @nt<direct_name>.
+  @nt<character_literal>s are usable even when the corresponding
+  @Chg{Version=[2],New=[enumeration type
+  declaration],address@hidden<enumeration_type_declaration>]} is not visible. 
See
+  @RefSecNum(Literals).
address@hidden
+
address@hidden<prefix>,rhs="@Syn2{name} | @Syn2{implicit_dereference}"}
+
address@hidden<explicit_dereference>,rhs="@address@hidden"}
+
address@hidden<implicit_dereference>,rhs="@Syn2{name}"}
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0004-1]}
address@hidden forms of @nt<name> (@nt<indexed_component>s,
address@hidden<selected_component>s, @nt<slice>s, and
address@hidden,address@hidden<attribute_reference>s],address@hidden<attribute>s]})
+include a @nt<prefix> that is either itself a @nt<name> that denotes
+some related entity, or an @nt<implicit_dereference> of an access
+value that designates some related entity.]
address@hidden
+
address@hidden
address@hidden
address@hidden type],
+  Sec=(dereference @nt{name})}
+The @nt{name} in a @i(dereference) (either an
address@hidden<implicit_dereference> or an @nt<explicit_dereference>)
+is expected to be of any access type.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0008-1]}
address@hidden subtype], Sec=(associated with a dereference)}
+If the type of the @nt{name} in a dereference is some access-to-object
+type @i(T), then the dereference denotes a view of an object, the
address@hidden(nominal subtype) of the view being the designated subtype
+of @i(T)address@hidden,New=[ If the designated subtype has
+unconstrained discriminants, the (actual) subtype of the view is constrained
+by the values of the discriminants of the designated object, except when
+there is a partial view of the type of the designated subtype that does not
+have discriminants, in which case the dereference is not constrained by its
+discriminant values.],Old=[]}
address@hidden
+  If the
+  value of the @nt<name> is the result of an access type conversion, the
+  dereference denotes a view created as part of the conversion.
+  The nominal subtype of the view is not necessarily
+  the same as that used to create the designated object.
+  See @RefSecNum{Type Conversions}.
address@hidden
address@hidden
+  @PDefn2{Term=[nominal subtype], Sec=(of a @nt<name>)}
+  We sometimes refer to the nominal subtype of a particular kind
+  of @nt<name> rather than the nominal subtype of the view denoted by
+  the @nt<name> (presuming the @nt<name> denotes a view of an object).
+  These two uses of nominal subtype are intended to mean the same
+  thing.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0008-1]}
+  @ChgAdded{Version=[3],Text=[The last sentence was not present in Ada 95;
+    it is necessary in Ada 2005 because general access types can designate
+    unconstrained objects, which was not possible in Ada 95. Thus, the rules
+    that had this effect in Ada 95 (the object being constrained by its initial
+    value) don't work in Ada 2005 and we have to say this explicitly.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0008-1]}
+  @ChgAdded{Version=[3],Text=[The @ldquote@;address@hidden@; part of the
+   last sentence prevents privacy
+    @ldquote@;address@hidden@;, so that
+    if a private type has discriminants only in the full view, they don't
+    interfere with freely interassigning values between objects of the type,
+    even when the objects live in the heap.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0008-1]}
+  @ChgAdded{Version=[3],Text=[Since we don't depend on whether the designated
+  object is constrained, it is not necessary to include a constrained
+  bit in every object that could be designated by a general access type.]}
address@hidden
+
address@hidden, Sec=(associated with a dereference)}
+If the type of the @nt<name> in a dereference is some access-to-subprogram
+type @i(S), then the dereference denotes a view of a subprogram,
+the @i(profile) of the view being the designated profile of @i(S).
address@hidden
+This means
+  that the formal parameter names and default expressions to be used
+  in a call whose @nt<name> or @nt<prefix> is a dereference
+  are those of the designated profile, which need not be the same as those
+  of the subprogram designated by the access value, since 'Access
+  requires only subtype conformance, not full conformance.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00415-01]}
address@hidden, Sec=(name)}
+The evaluation of a @nt<name> determines the entity denoted by the
address@hidden,address@hidden<name>],Old=[name]}. This evaluation has no other
+effect for a @nt<name> that
+is a @nt<direct_name> or a @nt<character_literal>.
+
address@hidden, Sec=(name that has a prefix)}
address@hidden evaluation of a @nt<name> that has a @nt<prefix> includes
+the evaluation of the @nt<prefix>.]
address@hidden, Sec=(prefix)}
+The evaluation of a @nt{prefix} consists of the evaluation of
+the @nt{name} or the @nt{implicit_dereference}.
+The @nt{prefix} denotes the entity denoted by the @nt{name} or the
address@hidden
+
address@hidden, Sec=(dereference)}
+The evaluation of a dereference
+consists of the evaluation of the @nt{name}
+and the determination of the object or subprogram that is designated
+by the value of the @nt{name}.
address@hidden
+A check is made that the value of the @nt{name} is not the null access
+value.
address@hidden,Sec=(raised by failure of run-time check)}
+Constraint_Error is raised if this check fails.
+The dereference
+denotes the object or subprogram designated by the value of the @nt{name}.
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of direct names:)
address@hidden(Example)
address@hidden()@tabset(P9, P47)
+Pi @address@hidden(-- the direct name of a number) @\(see @RefSecNum(Number 
Declarations))
+Limit @address@hidden(-- the direct name of a constant) @\(see 
@RefSecNum(Object Declarations))
+Count @address@hidden(-- the direct name of a scalar variable) @\(see 
@RefSecNum(Object Declarations))
+Board @address@hidden(-- the direct name of an array variable) @\(see 
@RefSecNum(Index Constraints and Discrete Ranges))
+Matrix @address@hidden(-- the direct name of a type) @\(see @RefSecNum(Array 
Types))
+Random @address@hidden(-- the direct name of a function) @\(see 
@RefSecNum(Subprogram Declarations))
+Error @address@hidden(-- the direct name of an exception) @\(see 
@RefSecNum(Exception Declarations))
address@hidden(Example)
+
address@hidden
address@hidden@address@hidden of dereferences:}
address@hidden
address@hidden@tabclear()@tabset(P19)
address@hidden@address@hidden  explicit dereference denoting the object 
designated by]
+               @address@hidden  the access variable Next_Car (see 
@RefSecNum{Incomplete Type Declarations})]
+Next_Car.Owner @address@hidden  selected component with implicit dereference;]
+               @address@hidden  same as address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Type conversions and function calls are now considered names
+that denote the result of the operation.
+In the case of a type conversion used as an actual
+parameter or that is of a tagged type, the type conversion is considered
+a variable if the operand is a variable.
+This simplifies the description of "parameters of the
+form of a type conversion" as well as better supporting an
+important OOP paradigm that requires the combination of a
+conversion from a class-wide type to some specific
+type followed immediately by component selection.
+Function calls are considered names so that a type conversion
+of a function call and the function call itself are treated
+equivalently in the grammar.
+A function call is considered the name of a constant,
+and can be used anywhere such a name is permitted.
+See @RefSecNum(Return Statements).
+
address@hidden,address@hidden be consistent with 8652/0006}
+Type conversions of a tagged type are permitted anywhere
+their operand is permitted. That is, if the operand
+is a variable, then the type conversion can appear on the
+left-hand side of an @nt{assignment_statement}.
+If the operand is an object,
+then the type conversion can appear in an object renaming
+or as a @address@hidden,Old=[prefix]}.
+See @RefSecNum(Type Conversions).
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+Everything of the general syntactic form @nt{name}(...) is
+now syntactically a @nt{name}. In any realistic parser,
+this would be a necessity since distinguishing among the various
address@hidden(...) constructs inevitably requires name resolution.
+In cases where the construct yields a value rather than an object,
+the name denotes @Chg{Version=[2],New=[a],Old=[the]} value rather than an
+object. Names already denote values in Ada 83 with named numbers, components of
+the result of a function call, etc. This is partly just a wording change, and
+partly an extension of functionality (see Extensions heading above).
+
+The syntax rule for @nt{direct_name} is new. It is used in places where
+direct visibility is required.
+It's kind of like Ada 83's @ntf{simple_name}, but @ntf{simple_name} applied
+to both direct visibility and visibility by selection,
+and furthermore, it didn't work right for @nt{operator_symbol}s.
+The syntax rule for @ntf{simple_name} is removed,
+since its use is covered by a combination of @nt{direct_name} and
address@hidden
+The syntactic categories @nt{direct_name} and @nt{selector_name} are similar;
+it's mainly the visibility rules that distinguish the two.
+The introduction of @nt{direct_name} requires the insertion of one new
+explicit textual rule: to forbid @nt<statement_identifier>s from being
address@hidden<operator_symbol>s.
+This is the only case where the explicit rule is needed,
+because this is the only case where the declaration of the entity is
+implicit.
+For example, there is no need to syntactically forbid (say) @lquotes@;X: 
"Rem";@rquotes@;,
+because it is impossible to declare a type whose name is an
address@hidden in the first place.
+
+The syntax rules for @nt{explicit_dereference}
+and @nt{implicit_dereference} are new;
+this makes other rules simpler, since dereferencing an access value has
+substantially different semantics from @nt{selected_component}s.
+We also use @nt{name} instead of @nt{prefix} in the
address@hidden rule
+since that seems clearer. Note that these rules rely on the
+fact that function calls are now names, so we don't need to
+use prefix to allow functions calls in front of address@hidden
address@hidden
+Actually, it would be reasonable to allow any @nt{primary} in front
+of address@hidden, since only the value is needed, but that would be a bit
+radical.
address@hidden
+
+We no longer use the term @i(appropriate for a type)
+since we now describe the semantics of a prefix in terms
+of implicit dereference.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0003-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}A
+  @nt{qualified_expression} is now a @nt{name} denoting a constant view;
+  this allows them to be used as a prefix and to be renamed as an object.
+  They are often used to remove ambiguity from function calls, and there
+  may be no other way to do that. Interestingly, a @nt{type_conversion} of
+  a @nt{qualified_expression} is already legal in these contexts, so this
+  change mainly reduces clutter by eliminating an otherwise unneeded
+  @nt{type_conversion} from some expressions.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0008-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a missing rule so
+  that most dereferences are assumed constrained (without determining whether
+  the designated object is). This is just confirming the Ada 95 rules;
+  Ada 2005 failed to ensure that this property was unchanged.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[Added @nt{generalized_reference} and
+  @nt{generalized_indexing} as types of @nt{name}; these are documented
+  as extensions in the appropriate subclauses.]}
address@hidden
+
+
address@hidden Components}
+
address@hidden
address@hidden @nt<indexed_component> denotes either
+a component of an array or an entry
+in a family of entries.
address@hidden indexing],See=(indexed_component)}]
address@hidden
+
address@hidden
address@hidden<indexed_component>,rhs="@Syn2{prefix}(@Syn2{expression} {, 
@Syn2{expression}})"}
address@hidden
+
address@hidden
+The @nt{prefix} of an @nt{indexed_component} with a given
+number of @nt<expression>s
+shall resolve to denote an array (after any implicit dereference)
+with the corresponding number of index positions,
+or shall resolve to denote an entry family of a task or protected object
+(in which case there shall be only one @nt<expression>).
+
address@hidden type], Sec=(indexed_component expression)}
+The expected type for each @nt{expression} is the corresponding index type.
+
address@hidden
+
address@hidden
+When the @nt<prefix> denotes an array,
+the @nt<indexed_component> denotes the component of the
+array with the specified index value(s).
address@hidden subtype],
+  Sec=(associated with an @nt<indexed_component>)}
+The nominal subtype of the @nt<indexed_component> is the
+component subtype of the array type.
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00363-01]}
address@hidden,Text=[In the case of an array whose components are
+aliased, and
+of an unconstrained discriminated subtype, the components
+are constrained even though their nominal subtype is unconstrained.
+(This is because all aliased discriminated objects are constrained.
+See @RefSecNum(Operations of Access Types).)
+In all other cases, an array component is constrained if and only
+if its nominal subtype is constrained.]}
address@hidden
+
+When the @nt<prefix> denotes an entry family,
+the @nt<indexed_component> denotes
+the individual entry of the entry family with the specified index value.
+
address@hidden
+
address@hidden
address@hidden, Sec=(indexed_component)}
+For the evaluation of an @nt<indexed_component>, the @nt{prefix} and the
address@hidden are evaluated in an arbitrary address@hidden 
order],Sec=[allowed]}
+The value of
+each @nt<expression> is converted to the corresponding index type.
address@hidden subtype conversion],Sec=(array index)}
address@hidden
+A check is made that each index value
+belongs to the corresponding index range of the array or entry family
+denoted by the @nt<prefix>.
address@hidden,Sec=(raised by failure of run-time check)}
+Constraint_Error is raised if this check fails.
+
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of indexed components:)
address@hidden
address@hidden()@tabset(P64)
+ My_Schedule(Sat)     address@hidden  a component of a one-dimensional array 
@\(see @RefSecNum{Index Constraints and Discrete Ranges})]
+ Page(10)             address@hidden  a component of a one-dimensional array 
@\(see @RefSecNum{Array Types})]
+ Board(M, J + 1)      address@hidden  a component of a two-dimensional array 
@\(see @RefSecNum{Index Constraints and Discrete Ranges})]
+ Page(10)(20)         address@hidden  a component of a component @\(see 
@RefSecNum{Array Types})]
+ Request(Medium)      address@hidden  an entry in a family of entries @\(see 
@RefSecNum{Task Units and Task Objects})]
+ Next_Frame(L)(M, N)  address@hidden  a component of a function call @\(see 
@RefSecNum{Subprogram Declarations})]
address@hidden
address@hidden
+
address@hidden
address@hidden(Notes on the examples:)
+Distinct notations are used for components of multidimensional arrays (such
+as Board) and arrays of arrays (such as Page). The components of an array
+of arrays are arrays and can therefore be indexed. Thus Page(10)(20)
+denotes the 20th component of Page(10). In the last example Next_Frame(L)
+is a function call returning an access value that designates a
+two-dimensional array.
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden@Defn{array slice}
+A @nt<slice> denotes a one-dimensional array formed by a sequence of
+consecutive components of a one-dimensional array. A @nt<slice> of
+a variable is a variable; a @nt<slice> of a constant is a constant;]
+a @nt<slice> of a value is a value.
address@hidden
+
address@hidden
address@hidden<slice>,rhs="@Syn2{prefix}(@Syn2{discrete_range})"}
address@hidden
+
address@hidden
+The @nt{prefix} of a @nt{slice}
+shall resolve to denote a one-dimensional array
+(after any implicit dereference).
+
address@hidden type], Sec=(slice discrete_range)}
+The expected type for the @nt{discrete_range} of a @nt<slice>
+is the index type of the array type.
address@hidden
+
address@hidden
+A @nt<slice> denotes a one-dimensional array formed by the sequence of
+consecutive components of the array denoted by the @nt<prefix>,
+corresponding to the range of values
+of the index given by the @nt<discrete_range>.
+
+The type of the @nt<slice> is that of the @nt<prefix>.
+Its bounds are those defined by the @nt{discrete_range}.
+
address@hidden
+
address@hidden
address@hidden, Sec=(slice)}
+For the evaluation of a @nt{slice},
+the @nt{prefix} and the @nt{discrete_range}
+are evaluated in an arbitrary address@hidden order],Sec=[allowed]}
address@hidden
address@hidden slice}
+If the @nt{slice} is not a @i(null slice)
+(a @nt<slice> where the @nt<discrete_range> is a null range),
+then a check is made that the bounds of the @nt{discrete_range}
+belong to the index range of the array denoted by the @nt{prefix}.
address@hidden,Sec=(raised by failure of run-time check)}
+Constraint_Error is raised if this check fails.
+
address@hidden
+
address@hidden
+A @nt<slice> is not permitted as the @nt<prefix> of an
+Access @nt<attribute_reference>,
+even if the components or the array as a whole are aliased.
+See @RefSecNum(Operations of Access Types).
address@hidden
+  Slices are not aliased, by @RefSec{Access Types}.
address@hidden
address@hidden(Reason)
+  This is to ease implementation of general-access-to-array.
+  If slices were aliased, implementations would need to store
+  array dope with the access values, which is not always desirable
+  given access-to-incomplete types completed in a package body.
address@hidden(Reason)
+
+For a one-dimensional array A, the @nt<slice> A(N .. N) denotes
+an array that has only one component;
+its type is the type of A. On the other hand, A(N) denotes a
+component of the array A and has the corresponding component type.
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of slices:)
address@hidden
address@hidden()@tabset(P58)
+  Stars(1 .. 15)        address@hidden  a slice of 15 characters @\(see 
@RefSecNum{String Types})]
+  Page(10 .. 10 + Size) address@hidden  a slice of 1 + Size components @\(see 
@RefSecNum{Array Types})]
+  Page(L)(A .. B)       address@hidden  a slice of the array Page(L) @\(see 
@RefSecNum{Array Types})]
+  Stars(1 .. 0)         address@hidden  a null slice @\(see @RefSecNum{String 
Types})]
+  My_Schedule(Weekday)  address@hidden  bounds given by subtype @\(see 
@RefSecNum{Index Constraints and Discrete Ranges} and @RefSecNum{Enumeration 
Types})]
+  Stars(5 .. 15)(K)     address@hidden  same as Stars(K) @\(see 
@RefSecNum{String Types})]
+                        address@hidden  provided that K is in 5 .. 15]
address@hidden
address@hidden
+
address@hidden Components}
+
address@hidden
address@hidden@nt{Selected_component}s are used to denote components (including
+discriminants),
+entries, entry families, and protected subprograms; they are
+also used as expanded names as described below.
address@hidden selection],See=(selected_component)}]
address@hidden
+
address@hidden
address@hidden<selected_component>,rhs="@Syn2{prefix} . @Syn2{selector_name}"}
+
+
address@hidden<selector_name>,rhs="@Syn2{identifier} | @Syn2{character_literal} 
| @Syn2{operator_symbol}"}
address@hidden
+
address@hidden
address@hidden name}
+A @nt<selected_component> is called an @i(expanded name)
+if, according to the visibility rules, at least one possible
+interpretation of its @nt<prefix> denotes
+a package or an enclosing named construct (directly, not through
+a @nt<subprogram_renaming_declaration>
+or @nt<generic_renaming_declaration>).
address@hidden
+See AI83-00187.
address@hidden
+
address@hidden@;A @nt{selected_component} that is not an expanded name
+shall resolve to denote one of the following:
address@hidden(Ramification)
+  If the @nt<prefix> of a @nt<selected_component> denotes
+  an enclosing named construct, then the @nt<selected_component> is interpreted
+  only as an expanded name, even if the named construct
+  is a function that could be called without parameters.
address@hidden(Ramification)
address@hidden
+A component @Redundant[(including a discriminant)]:
+
address@hidden@;The @nt{prefix} shall resolve to denote an object or value of 
some
+non-array composite type
+(after any implicit dereference).
+The @nt{selector_name} shall resolve to denote a
address@hidden of the type, or, unless the type is
+a protected type, a @nt<component_declaration>
+of the type. The @nt{selected_component} denotes the
+corresponding component of the object or value.
address@hidden
+  @ChgRef{Version=[1],address@hidden AI-00015}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  The components of a protected object cannot be named except
+  by an expanded name, even from within the corresponding protected body.
+  The protected body @Chg{Version=[3],New=[cannot],Old=[may not]} reference
+  @Chg{New=[],Old=[the ]}the private
+  components of some arbitrary object of the protected
+  type; the protected body may reference components of the current
+  instance only (by an expanded name or a @nt<direct_name>).
address@hidden
address@hidden
+  Only the discriminants and components visible at the place of the
+  @nt<selected_component> can be selected, since a @nt<selector_name>
+  can only denote declarations that are visible (see @RefSecNum{Visibility}).
address@hidden
+
+A single entry, an entry family, or a protected subprogram:
+
address@hidden@;The @nt{prefix} shall resolve to denote an object or value of 
some
+task or protected type (after any implicit dereference).
+The @nt{selector_name} shall resolve to denote an @nt{entry_declaration}
+or @nt{subprogram_declaration} occurring (implicitly or explicitly)
+within the visible part of that type.
+The @nt{selected_component} denotes the
+corresponding entry, entry family, or protected subprogram.
address@hidden
+  This explicitly says @lquotes@;visible address@hidden@; because even though 
the body
+  has visibility on the private part, it cannot call the
+  private operations of some arbitrary object of the task or protected
+  type, only those of the current instance (and expanded name notation
+  has to be used for that).
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00252-01],ARef=[AI95-00407-01]}
address@hidden,Text=[A view of a subprogram whose first formal parameter is of
+a tagged type or is an access parameter whose designated type is tagged:]}
+
address@hidden,Kind=[Added],ARef=[AI95-00252-01],ARef=[AI95-00407-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0090-1]}
address@hidden,NoPrefix=[T],Text=[The @nt<prefix> (after any implicit
+dereference) shall resolve to denote an object or value of a specific tagged
+type @i<T> or class-wide type @i<T>'Class. The @nt<selector_name> shall resolve
+to denote a view of a subprogram declared immediately within the declarative
+region in which an ancestor of the type @i<T> is declared. The first formal
+parameter of the subprogram shall be of type @i<T>, or a class-wide type that
+covers @i<T>, or an access parameter designating one of these types. The
+designator of the subprogram shall not be the same as that of a component of
+the tagged type visible at the point of the @nt<selected_component>.
address@hidden,New=[The subprogram shall not
+be an implicitly declared primitive operation of type @i<T> that overrides
+an inherited subprogram implemented by an entry or protected subprogram
+visible at the point of the @nt{selected_component}. ],Old=[]}The
address@hidden<selected_component> denotes a view of this subprogram that omits 
the first
+formal parameter. This view is called a @i{prefixed view} of the subprogram,
+and the @nt{prefix} of the @nt<selected_component> (after any implicit
+dereference) is called the @i<prefix> of the prefixed view.
address@hidden address@hidden,Sec=[of a prefixed view]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0090-1]}
+  @ChgAdded{Version=[3],Text=[The part of the rule that excludes a primitive
+  overriding subprogram as a selector applies only to the wrapper subprogram
+  that is implicitly declared to override a subprogram inherited from a
+  synchronized interface that is implemented by an operation of a task or
+  protected type (see @RefSecNum{Task Units and Task Objects} and
+  @RefSecNum{Protected Units and Protected Objects}). We don't want
+  calls that use a prefixed view to be ambiguous between the wrapper
+  subprogram and the implementing entry or protected operation. Note that
+  it is illegal to declare an explicit primitive that has a prefixed view
+  that is homographic with one of the type's operations, so
+  in normal cases it isn't possible to have an ambiguity in a prefix call.
+  However, a class-wide operation of an ancestor type that is declared in the
+  same declaration list with the ancestor type is also considered, and that
+  can still make a call ambiguous.]}
address@hidden
address@hidden
+
address@hidden@;An expanded name shall resolve to denote a declaration that
+occurs immediately within a named declarative region, as follows:
address@hidden(itemize)
+The @nt<prefix> shall resolve to denote either a package @Redundant[(including
+the current instance of a generic package, or a rename of a package)], or
+an enclosing named construct.
+
+The @nt{selector_name}
+shall resolve to denote a declaration that occurs
+immediately within the declarative region of the
+package or enclosing construct @Redundant[(the declaration shall be visible
+at the place of the expanded name @em see @RefSecNum(Visibility))].
+The expanded name denotes that declaration.
address@hidden
+  Hence, a library unit or subunit can use an expanded
+  name to refer to the declarations within the private part of its
+  parent unit, as well as to other children that have been mentioned in
+  @nt<with_clause>s.
address@hidden
+
+If the @nt<prefix> does not denote a package, then it
+shall be a @nt<direct_name> or an expanded name,
+and it shall resolve to denote a program unit (other than a package),
+the current instance of a type, a @nt{block_statement}, a @nt{loop_statement},
+or an @address@hidden
+(in the case of an @nt<address@hidden> or @nt<address@hidden>,
+no family index is allowed);
+the expanded name shall occur within the
+declarative region of this construct.
+Further, if this construct is a callable construct
+and the @nt<prefix> denotes more than one such enclosing callable construct,
+then the expanded name is ambiguous, independently of the @nt<selector_name>.
+
address@hidden(itemize)
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00252-01],ARef=[AI95-00407-01]}
address@hidden,Text=[For a subprogram whose first parameter is an
+access parameter, the prefix of any prefixed view shall denote an aliased
+view of an object.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00407-01]}
address@hidden,Text=[For a subprogram whose first parameter is of mode
address@hidden<in out> or @b<out>, or of an anonymous access-to-variable type, 
the prefix
+of any prefixed view shall denote a variable.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[We want calls through a prefixed view and through
+a normal view to have the same legality. Thus, the implicit 'Access in
+this new notation needs the same legality check that an explicit 'Access
+would have. Similarly, we need to prohibit the object from being constant
+if the first parameter of the subprogram is @key{in out}, because that is
+(obviously) prohibited for passing a normal parameter.]}
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(selected_component)}
+The evaluation of a @nt{selected_component} includes the
+evaluation of the @nt{prefix}.
+
address@hidden
+For a @nt{selected_component} that denotes a component of a @nt{variant},
+a check is made that the values of the discriminants are such that
+the value or object denoted by the @nt<prefix> has this component.
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,Sec=(raised by failure of run-time check)}
+The exception Constraint_Error is raised if this check fails.
+
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of selected components:)
address@hidden
address@hidden()@tabset(P60)
address@hidden,Kind=[Revised],ARef=[AI95-00252-01],ARef=[AI95-00407-01]}
+  Tomorrow.Month     address@hidden  a record component @\(see 
@RefSecNum{Record Types})]
+  Next_Car.Owner     address@hidden  a record component @\(see 
@RefSecNum{Incomplete Type Declarations})]
+  Next_Car.Owner.Age address@hidden  a record component @\(see 
@RefSecNum{Incomplete Type Declarations})]
+                     address@hidden  the previous two lines involve implicit 
dereferences]
+  Writer.Unit        address@hidden  a record component (a discriminant) 
@\(see @RefSecNum{Variant Parts and Discrete Choices})]
+  Min_Cell(H).Value  address@hidden  a record component of the result @\(see 
@RefSecNum{Subprogram Declarations})]
+                     address@hidden  of the function call Min_Cell(H)]
address@hidden,New=<  Cashier.Append     address@hidden  a prefixed view of a 
procedure @\(see @RefSecNum{Interface Types})]
+>,Old=<>}  Control.Seize      address@hidden  an entry of a protected object 
@\(see @RefSecNum{Protected Units and Protected Objects})]
+  Pool(K).Write      address@hidden  an entry of the task Pool(K) @\(see 
@RefSecNum{Protected Units and Protected Objects})]
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of expanded names:)
address@hidden
address@hidden
address@hidden()@tabset(P67)
+  Key_Manager."<"      address@hidden  an operator of the visible part of a 
package @\(see @RefSecNum{Private Operations})]
+  Dot_Product.Sum      address@hidden  a variable declared in a function body 
@\(see @RefSecNum{Subprogram Declarations})]
+  Buffer.Pool          address@hidden  a variable declared in a protected unit 
@\(see @RefSecNum{Example of Tasking and Synchronization})]
+  Buffer.Read          address@hidden  an entry of a protected unit @\(see 
@RefSecNum{Example of Tasking and Synchronization})]
+  Swap.Temp            address@hidden  a variable declared in a block 
statement @\(see @RefSecNum{Block Statements})]
+  Standard.Boolean     address@hidden  the name of a predefined type @\(see 
@RefSecNum{The Package Standard})]
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+We now allow an expanded name to use a prefix
+that denotes a rename of a package, even if the
+selector is for an entity local to the body or private
+part of the package, so long as the entity is visible
+at the place of the reference. This eliminates
+a preexisting anomaly where references in a package
+body may refer to declarations of its visible part
+but not those of its private part or body when the
+prefix is a rename of the package.
address@hidden
+
address@hidden
+The syntax rule for @nt{selector_name} is new. It is used in places where
+visibility, but not necessarily direct visibility, is required.
+See @RefSec{Names} for more information.
+
+The description of dereferencing an access type has been moved
+to @RefSec{Names}; @nt<name>address@hidden(all) is no longer considered
+a @nt<selected_component>.
+
+The rules have been restated to be consistent with our
+new terminology, to accommodate class-wide types, etc.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00252-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}The prefixed view notation
+  for tagged objects is new. This provides a similar notation to that used in 
other
+  popular languages, and also reduces the need for @nt{use_clause}s. This
+  is sometimes known as @lquotes@;distinguished receiver address@hidden@;.
+  @Defn{distinguished receiver notation}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[Given the following
+definitions for a tagged type T:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Do_Something (Obj : @key{in out} T; Count : 
@key{in} Natural);
address@hidden Do_Something_Else (Obj : @key{access} T; Flag : @key{in} 
Boolean);
+My_Object : @key{aliased} T;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[the following calls are equivalent:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Do_Something (My_Object, Count => 10);
+My_Object.Do_Something (Count => 10);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[as are the following calls:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Do_Something_Else (My_Object'Access, Flag => True);
+My_Object.Do_Something_Else (Flag => True);]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0090-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the definition of
+  a prefixed view to ignore the implicit subprograms declared for
+  @ldquote@;implemented address@hidden entries and protected subprograms.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden
+
address@hidden
address@hidden
address@hidden @i(attribute) is a characteristic of an entity that can be
+queried via an @address@hidden
+or a @nt<address@hidden@!reference>.]
address@hidden
+
address@hidden
address@hidden<attribute_reference>,
+  rhs="@address@hidden@Syn2{attribute_designator}"}
+
address@hidden,Kind=[Revised],ARef=[AI05-0004-1]}
address@hidden<attribute_designator>,rhs="
+    @Syn2{identifier}[(@address@hidden)]
+  | Access | Delta | address@hidden,New=[ | Mod],Old=[]}"}
+
+
address@hidden<range_attribute_reference>,
+  rhs="@address@hidden@Syn2{range_attribute_designator}"}
+
address@hidden<range_attribute_designator>,
+  rhs="Range[(@address@hidden)]"}
address@hidden
+
address@hidden
+In an @nt<attribute_reference>,
+if the @nt<attribute_designator> is for an attribute defined
+for (at least some) objects of an access type, then the @nt<prefix> is never
+interpreted as an @nt<implicit_dereference>;
+otherwise (and for all @nt<range_attribute_reference>s),
+if the type of the @nt<name> within the @nt<prefix>
+is of an access type, the @nt<prefix> is interpreted as an
address@hidden<implicit_dereference>.
+Similarly, if the @nt{attribute_designator} is for an attribute defined for (at
+least some) functions, then the @nt<prefix> is never interpreted as a
+parameterless @nt{function_call}; otherwise
+(and for all @nt<range_attribute_reference>s), if the @nt<prefix>
+consists of a @nt<name> that denotes a function, it is interpreted
+as a parameterless @nt<function_call>.
address@hidden
+  The first part of this rule is essentially a "preference"
+  against implicit dereference, so that it is possible
+  to ask for, say, 'Size of an access object,
+  without automatically getting the size of the object designated
+  by the access object.
+  This rule applies to 'Access, 'Unchecked_Access, 'Size, and 'Address,
+  and any other attributes that are defined for at least some
+  access objects.
+
+  The second part of this rule implies that, for a parameterless function F,
+  F'Address is the address of F, whereas
+  F'Size is the size of the anonymous constant returned by F.
+
address@hidden,address@hidden be consistent with 8652/0006}
+  We normally talk in terms of expected type or profile for
+  name resolution rules, but we don't do this for attributes
+  because certain attributes are legal independent of the type
+  or the profile of the @address@hidden,Old=[prefix]}.
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00114-01]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[Other than the rules given above,
+  the @ResolutionName@;s for the @nt{prefix} of each attribute are defined as
+  @ResolutionTitle for that attribute. If no such rules are defined, then no
+  context at all should be used when resolving
+  the @nt{prefix}. In particular, any knowledge about the kind of entities
+  required must not be used for resolution unless that is required by
+  @ResolutionTitle. This matters in obscure cases;
+  for instance, given the following declarations:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[  @key[function] Get_It @key[return] Integer @key[is] ... 
-- @RI[(1)]
+  @key[function] Get_It @key[return] Some_Record_Type @key[is] ... -- 
@RI[(2)]]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[the following @nt{attribute_reference} 
cannot be
+resolved and is illegal:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[  @key[if] Get_It'Valid @key[then]]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[even though the Valid attribute is only defined
+  for objects of scalar types, and thus cannot be applied to the result of
+  function (2). That information cannot be used to resolve the @nt{prefix}.
+  The same would be true if (2) @Chg{Version=[3],New=[had],Old=[was]} been
+  a procedure; even though the procedure does not denote an object, the
+  @nt{attribute_reference} is still illegal.]}
address@hidden
+
address@hidden type],
+  Sec=(attribute_designator expression)}
address@hidden type],
+  Sec=(range_attribute_designator expression)}
+The @nt{expression}, if any, in an
address@hidden or @nt{range_attribute_designator}
+is expected to be of any integer type.
address@hidden
+
address@hidden
+The @nt{expression}, if any, in an @nt{attribute_designator}
+or @nt{range_attribute_designator} shall be static.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0006-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0032-1],ARef=[AI12-0159-1]}
+An @nt{attribute_reference} denotes a
+value, an object, a subprogram, or some
+other kind of program address@hidden,New=[
address@hidden,New=[Unless explicitly specified otherwise, for],Old=[For]}
+an @nt{attribute_reference} that denotes a value or an object, if
+its type is scalar, then its nominal subtype is the base subtype of
+the type; if its type is tagged, its nominal subtype is the first
+subtype of the type; otherwise, its nominal subtype is a subtype of the type
+without any address@hidden,New=[,],Old=[ or]}
address@hidden@Chg{Version=[4],New=[, or predicate],Old=[]}.
+Similarly, unless explicitly specified otherwise, for an
address@hidden that denotes a function, when its result
+type is scalar, its result subtype is the base subtype of the type,
+when its result type is tagged, the result subtype is the first
+subtype of the type, and when the result type is some other type,
+the result subtype is a subtype of the type without any
address@hidden,New=[,],Old=[ or]}
address@hidden@Chg{Version=[4],New=[, or predicate],Old=[]}.],Old=[]}
address@hidden
+  The attributes defined by the language are summarized in
+  @RefSecNum{Language-Defined Attributes}.
+  Implementations can define additional attributes.
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0006-1]}
+  @ChgAdded{Version=[3],Text=[The nominal subtype is primarily
+  a concern when an @nt{attribute_reference}, or
+  a call on an @nt{attribute_reference}, is used as the @nt{expression}
+  of a case statement, due to the full coverage requirement based on
+  the nominal subtype. For nondiscrete cases, we define the
+  nominal subtype mainly for completeness. Implementations may
+  specify otherwise for implementation-defined attribute functions.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The rule is written to match the meaning
+  of the italicized @i{T} in the definition of attributes such as Input;
+  see @RefSecNum{Logical Operators and Short-circuit Control Forms}.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0006-1]}
+  @ChgAdded{Version=[3],Text=[We don't worry about the fact that
+  @ldquote@;base address@hidden is not explicitly defined for the
+  universal types. Since it is
+  not possible to constrain a universal numeric type, all subtypes
+  are unconstrained, and hence can be considered base subtypes.
+  The wording above could be altered to bypass this issue, but it
+  doesn't seem necessary, since universal integer is handled
+  specially in the rules for case expression full coverage, and
+  we don't allow user-defined functions for attribute functions
+  whose result type is universal.]}
address@hidden
+
address@hidden @nt{range_attribute_reference}
+X'Range(N) is equivalent to the @nt<range> X'First(N) ..
+X'Last(N), except that the @nt{prefix} is only evaluated once.
+Similarly,
+X'Range is equivalent to X'First .. X'Last, except that the @nt{prefix}
+is only evaluated once.]
+
address@hidden
+
address@hidden
address@hidden, Sec=(attribute_reference)}
address@hidden, Sec=(range_attribute_reference)}
+The evaluation of an @nt{attribute_reference}
+(or @nt{range_attribute_reference}) consists
+of the evaluation of the @nt{prefix}.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0015],ARef=[AI95-00093-01]}
+An implementation may provide implementation-defined attributes;
+the @nt{identifier} for an implementation-defined
+attribute shall differ from those of the language-defined
address@hidden unless supplied for compatibility with a previous edition of
+this International Standard],Old=[]}.
address@hidden attributes.}
address@hidden
+They cannot be reserved words because reserved words are not legal
+identifiers.
+
+The semantics of implementation-defined attributes,
+and any associated rules, are, of course, implementation defined.
+For example, the implementation defines whether a given
+implementation-defined attribute can be used in a static expression.
+
address@hidden,Kind=[Added],Ref=[8652/0015],ARef=[AI95-00093-01]}
address@hidden are allowed to support the Small attribute for
+floating types, as this was defined in Ada 83, even though the name would
+conflict with a language-defined attribute.],Old=[]}
address@hidden
address@hidden
+
address@hidden
+Attributes are defined throughout this International Standard,
+and are summarized in
address@hidden Attributes}.
+
address@hidden,address@hidden be consistent with 8652/0006}
address@hidden,Kind=[Revised],ARef=[AI95-00235]}
+In general, the @nt<name> in a @nt<prefix> of an @nt<attribute_reference>
+(or a @nt<range_attribute_reference>) has to be resolved
+without using any context.
+However, in the case of the Access attribute,
+the expected type for the @Chg{Version=[2],address@hidden,
address@hidden@nt{prefix}],Old=[prefix]}]} has to be a
+single access type, address@hidden,New=[],Old=[ if it is an
+access-to-subprogram type (see @RefSecNum(Operations of Access Types)) then]}
+the resolution of the @nt<name> can use the fact that
address@hidden,New=[ type of the object or the],Old=[]} profile of the
+callable entity denoted by the @nt<prefix>
+has to @Chg{Version=[2],New=[match the designated type or ],Old=[]}be type
+conformant with the designated profile of the access type.
address@hidden conformance],Sec=(required)}
address@hidden(TheProof)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00235]}
+  In the general case, there is no @lquotes@;expected address@hidden@; for
+  the @nt<prefix> of an @nt<attribute_reference>.
+  In the special case of 'Access,
+  there is an @Chg{Version=[2],address@hidden@;expected address@hidden@; or ],
+  address@hidden@;expected address@hidden@; for the @nt<prefix>.
address@hidden(TheProof)
address@hidden(Reason)
+  'Access is a special case, because without it,
+  it would be very difficult to take 'Access of an overloaded
+  subprogram.
address@hidden(Reason)
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of attributes:)
address@hidden
address@hidden()@tabset(P64)
+Color'First        address@hidden minimum value of the enumeration type Color 
@\(see @RefSecNum{Enumeration Types})]
+Rainbow'Base'First address@hidden same as Color'First @\(see 
@RefSecNum{Enumeration Types})]
+Real'Digits        address@hidden precision of the type Real @\(see 
@RefSecNum{Floating Point Types})]
+Board'Last(2)      address@hidden upper bound of the second dimension of Board 
@\(see @RefSecNum{Index Constraints and Discrete Ranges})]
+Board'Range(1)     address@hidden index range of the first dimension of Board 
@\(see @RefSecNum{Index Constraints and Discrete Ranges})]
+Pool(K)'Terminated address@hidden True if task Pool(K) is terminated @\(see 
@RefSecNum{Task Units and Task Objects})]
+Date'Size          address@hidden number of bits for records of type Date 
@\(see @RefSecNum{Record Types})]
+Message'Address    address@hidden address of the record variable Message 
@\(see @RefSecNum{Discriminant Constraints})]
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+We now uniformly treat X'Range as X'First..X'Last,
+allowing its use with scalar subtypes.
+
+We allow any integer type in the @address@hidden
+of an attribute designator, not
+just a value of @i(universal_integer). The preference rules
+ensure upward compatibility.
address@hidden
+
address@hidden
+We use the syntactic category @nt{attribute_reference} rather
+than simply "attribute" to avoid confusing the name of something with
+the thing itself.
+
+The syntax rule for @nt{attribute_reference}
+now uses @nt{identifier} instead of
address@hidden, because attribute @nt{identifier}s are not required to
+follow the normal visibility rules.
+
+We now separate @nt{attribute_reference}
+from @nt{range_attribute_reference},
+and enumerate the reserved words that are legal attribute or range attribute
+designators.
+We do this because @nt{identifier} no longer includes reserved
+words.
+
+The Ada 95 name resolution rules are a bit more explicit than in Ada 83.
+The Ada 83 rule said that the
+  "meaning of the prefix of an attribute must be determinable
+  independently of the attribute designator and independently
+  of the fact that it is the prefix of an attribute."  That isn't
+  quite right since the meaning even in Ada 83 embodies whether or not
+  the prefix is interpreted as a parameterless function call,
+  and in Ada 95, it also embodies whether or not the prefix is interpreted
+  as an implicit_dereference. So the attribute designator does
+  make a difference @em just not much.
+
+  Note however that if the attribute designator is Access,
+  it makes a big difference in the interpretation of the
+  prefix (see @RefSecNum(Operations of Access Types)).
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],Ref=[8652/0015],ARef=[AI95-00093-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> The wording
+  was changed to allow implementations to continue to implement the Ada 83
+  Small attribute. This was always intended to be allowed.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00235-01]}
+  @ChgAdded{Version=[2],Text=[The note about resolving prefixes of attributes
+  was updated to reflect that the prefix of an Access attribute now has an
+  expected type (see @RefSecNum{Operations of Access Types}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0006-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Defined the nominal
+  subtype of an @nt{attribute_reference} to close a minor language hole.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0032-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Allowed overriding the
+  nominal subtype of an @nt{attribute_reference} for an object; that is used
+  elsewhere in this standard.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0159-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Added wording so it is 
clear that
+  predicates don't apply to the result of an attribute.]}
address@hidden
+
+
address@hidden,Name=[User-Defined References]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Type=[Leading],Text=[Given a discriminated type @i<T>,
+the following type-related operational aspect may be specified:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden aspect is specified by a
address@hidden that denotes an access discriminant declared for the
+type @i<T>address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Implicit_Dereference],
+    address@hidden,Text=[Mechanism for user-defined implicit address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Text=[A (view of a) type with a specified
+Implicit_Dereference aspect is a @i{reference address@hidden type}
+A @i{reference object} is an object of a reference address@hidden object}
+The discriminant named by the Implicit_Dereference aspect is the @i{reference
+discriminant} of the reference type or reference address@hidden discriminant}
address@hidden @nt{generalized_reference} is a @nt{name} that identifies a
+reference object, and denotes the object or subprogram designated by the
+reference discriminant of the reference object.]]}
+
address@hidden,Kind=[Added],Term=<Reference type>,
+Text=<@ChgAdded{Version=[3],Text=[A reference type is one that has user-defined
+behavior for @address@hidden@rdquote, defined by the
+Implicit_Dereference aspect.]}>}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,lhs=<@Chg{Version=[3],New=<generalized_reference>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<@address@hidden>,Old=<>}"}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0269-1]}
address@hidden,Text=[The expected type for the @address@hidden
+in a @nt{generalized_reference} is any reference address@hidden type],
+  Sec=(@address@hidden)}]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0138-1]}
address@hidden,Text=[The Implicit_Dereference aspect
+is nonoverridable (see @RefSecNum{Aspect Specifications}).]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This ensures that all descendants of a
+  reference type have the same reference discriminant. This prevents
+  generic contract problems with formal derived types.]}
address@hidden
+
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Text=[A @nt{generalized_reference} denotes a view
+equivalent to that of a dereference of the reference discriminant of the
+reference object.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Text=[Given a reference type @i<T>, the
+Implicit_Dereference aspect is inherited by descendants of type @i<T> if not
+overridden. If a descendant type constrains the value of the reference
+discriminant of @i<T> by a new discriminant, that new discriminant is the
+reference discriminant of the descendant. @Redundant[If the descendant type
+constrains the value of the reference discriminant of @i<T> by an
address@hidden other than the @nt{name} of a new discriminant, a
address@hidden that identifies an object of the descendant type
+denotes the object or subprogram designated by the value of this constraining
+expression.]]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,address@hidden, Sec=(generalized_reference)}
+The evaluation of a @nt{generalized_reference}
+consists of the evaluation of the @address@hidden and
+a determination of the object or subprogram designated by the
+reference discriminant of the named reference object.
address@hidden
+A check is made that the value of the reference
+discriminant is not the null access value.
address@hidden,Sec=(raised by failure of run-time check)}
+Constraint_Error is raised if this check fails. The
address@hidden denotes the object or
+subprogram designated by the value of the reference discriminant of the
+named reference object.]}
+
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0268-1]}
address@hidden,address@hidden Barrel @key[is tagged] ...  -- @Examcom{holds 
objects of type Element}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0299-1]}
address@hidden,address@hidden Ref_Element(Data : @key[access] Element) @key[is 
limited private]
+   @key[with] Implicit_Dereference => Data;
+      -- @Examcom{This Ref_Element type is a "reference" type.}
+      -- @ExamCom{"Data" is its reference discriminant.}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0268-1]}
address@hidden,address@hidden Find (B : @key[aliased in out] Barrel; Key : 
String) @key[return] Ref_Element;
+   -- @Examcom{Return a reference to an element of a barrel.}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0268-1],ARef=[AI05-0299-1]}
address@hidden,Text=[B: @key[aliased] Barrel;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Text=[...]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0268-1]}
address@hidden,Text=[Find (B, "grape") := Element'(...);  -- @Examcom{Assign 
through a reference.}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0268-1]}
address@hidden,Text=[-- @Examcom{This is equivalent to:}
+Find (B, "grape")address@hidden := Element'(...);]}
+
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0139-2]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}The aspect
+  Implicit_Dereference and the @nt{generalized_reference} are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0138-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Defined Implicit_Dereference to be nonoveridable, which makes redefinitions
+  and hiding of the aspect illegal. It's possible that some program could
+  violate one of these new restrictions, but this is not very likely as
+  reference types are not likely to be used in a hierarchy.]}
address@hidden
+
+
address@hidden,Name=[User-Defined Indexing]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Type=[Leading],Text=[Given a tagged type @i<T>,
+the following type-related, operational aspects
+may be specified:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden aspect shall be specified by
+a @nt{name} that denotes one or more functions declared immediately within the
+same declaration list in which @i<T> is declared. All such functions shall
+have at least two parameters, the first of which is of type @i<T> or
address@hidden<T>'Class, or is an access-to-constant parameter with designated 
type @i<T> or
address@hidden<T>'address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Constant_Indexing],
+    address@hidden,Text=[Defines function(s) to implement
+      user-defined @nt{indexed_component}s.]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden aspect shall be specified
+by a @nt{name} that denotes one or more functions declared immediately within
+the same declaration list in which @i<T> is declared. All such functions
+shall have at least two parameters, the first of which is of type @i<T> or
address@hidden<T>'Class, or is an access parameter with designated type @i<T> 
or @i<T>'Class.
+All such functions shall have a return type that is a reference
+type (see @RefSecNum{User-Defined References}), whose reference discriminant
+is of an access-to-variable address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We require these functions to return a reference
+  type so that the object returned from the function can act like a variable.
+  We need no similar rule for Constant_Indexing, since all functions return
+  constant objects.]}
address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Variable_Indexing],
+    address@hidden,Text=[Defines function(s) to implement
+      user-defined @nt{indexed_component}s.]}]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0104-1]}
address@hidden,Text=[These aspects are inherited by descendants of @i<T>
+(including the class-wide type @i<T>'Class)address@hidden,New=[],Old=[
address@hidden aspects shall not be overridden, but the functions they denote
+may be.]]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Indexing can be provided for multiple index types
+  by overloading routines with different parameter profiles. For instance, the
+  map containers provide indexing on both cursors and keys by providing
+  pairs of overloaded routines to the Constant_Indexing and Variable_Indexing
+  aspects.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,Text=[An @i<indexable container type> is (a view of) a
+tagged type with at least one of the aspects Constant_Indexing or
+Variable_Indexing address@hidden container type}
+An @i<indexable container object> is an object of an indexable container
address@hidden container object} @Redundant[A @nt{generalized_indexing} is
+a @nt{name} that denotes the result of calling a function named by a
+Constant_Indexing or Variable_Indexing aspect.]]}
+
address@hidden,Kind=[Added],Term=<Indexable container type>,
+Text=<@ChgAdded{Version=[3],Text=[An indexable container type is one that has
+user-defined behavior for indexing, via the Constant_Indexing or
+Variable_Indexing aspects.]}>}
+
address@hidden,Kind=[Added],ARef=[AI12-0138-1]}
address@hidden,Text=[The Constant_Indexing and Variable_Indexing aspects
+are nonoverridable (see @RefSecNum{Aspect Specifications}).]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This ensures that all descendants of an
+  indexable container type have aspects with the same properties. This prevents
+  generic contract problems with formal derived types.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0104-1],ARef=[AI12-0138-1]}
+  @ChgAdded{Version=[4],Text=[A nonoverridable aspect allows the replacement
+    of the implementation of an indexing function and the addition of a
+    new indexing function for a derived type, but not the removal of an
+    indexing function. This is necessary so that indexing can be used on
+    objects of T'Class. So long as the tag of O is that of its nominal
+    subtype, we do not want T'Class(O)(I) to mean something different
+    than O(I). Thus we cannot allow a change in the function identified.
+    As T'Class(O)(I) expands into a dispatching call, we need to ensure that
+    there is a body for each such function -- but it is OK for that body to be
+    changed from the original body (that's just normal dispatching).]}
address@hidden
+
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraphs 6 through 9
+were deleted.>address@hidden message should be
+deleted if the paragraphs are ever renumbered. Note that this is under the
+wrong heading, so that the heading can also be eliminated.}
address@hidden
+
address@hidden
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI12-0138-1]}
address@hidden,Type=[Leading],address@hidden,New=[The
+Constant_Indexing or Variable_Indexing aspect shall not be 
specified:],Old=[]}]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden,New=[on a derived type
+if the parent type has the
+corresponding aspect specified or inherited; or],Old=[]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden,New=[on a
address@hidden if the type has
+a tagged partial view.],Old=[]}]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden,address@hidden contract issue}
+In addition to the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}),
+these rules apply also in the private part of an instance of a
+generic unit.],Old=[]}]}
+
address@hidden
+  @ChgNote{The following notes were moved to @RefSecNum{Aspect Specifications}
+  along with the rules (now part of the definition of "nonoverridable 
aspect").}
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[4],address@hidden,New=[In order to enforce
+  these rules without breaking privacy, we cannot allow a tagged private type
+  to have hidden indexing aspects. There is no problem if the private type
+  is not tagged (as the indexing aspects cannot be specified on
+  descendants in that case).],Old=[]}]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[4],address@hidden,New=[We don't need
+  an assume-the-worst rule as deriving from formal tagged types is not
+  allowed in generic bodies.],Old=[]}]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<generalized_indexing>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<@address@hidden 
@Syn2{actual_parameter_part}>,Old=<>}"}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,Text=[The expected type for the
address@hidden@nt{prefix} of a @nt{generalized_indexing}
+is any indexable container address@hidden type],
+  Sec=(@address@hidden)}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,Type=[Leading],Text=[If the Constant_Indexing aspect is
+specified for the type of the @address@hidden of a
address@hidden, then the @nt{generalized_indexing} is interpreted as
+a @i<constant indexing> under the following
+circumstances:@Defn{constant address@hidden,Sec=[constant]}]}
+
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[when the Variable_Indexing aspect is not 
specified
+     for the type of the @address@hidden;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[when the @address@hidden
+    denotes a constant;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[when the @nt{generalized_indexing} is used within
+    a @nt{primary} where a @nt{name} denoting a constant is permitted.]}
+
+    @begin{Ramification}
+      @ChgRef{Version=[3],Kind=[AddedNormal]}
+      @ChgAdded{Version=[3],Text=[This means it is not interpreted as a
+        constant indexing for the @address@hidden in the LHS of an
+        assignment (not inside a @nt{primary}), nor for the @nt{name} used
+        for an @key[out] or @key[in out] parameter (not allowed to be
+        a constant), nor for the @nt{name} in an object renaming
+        (not inside a primary), unless
+        there is no Variable_Indexing aspect defined.]}
+    @end{Ramification}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Otherwise, the @nt{generalized_indexing} is
+interpreted as a
address@hidden address@hidden address@hidden,Sec=[variable]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[When a @nt{generalized_indexing} is interpreted as a
+constant (or variable) indexing, it is equivalent to a call on a prefixed view
+of one of the functions named by the Constant_Indexing (or Variable_Indexing)
+aspect of the type of the @address@hidden with the given
address@hidden, and with the @address@hidden as
+the @nt{prefix} of the prefixed view.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[In other words, the
+    @nt{generalized_indexing} is equivalent to:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden@nt{prefix}.Indexing @nt{actual_parameter_part}]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[where Indexing is the @nt{name}
+    specified for the Constant_Indexing or Variable_Indexing
+    address@hidden,New=[ This equivalence is then resolved in the
+    normal way; the aspect specifies a @nt{name}, it does not denote
+    declarations.],Old=[]}]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0104-1]}
+  @ChgAdded{Version=[4],Text=[The Constant_Indexing and Variable_Indexing
+    aspects cannot be redefined when inherited for a derived type, but the
+    functions that they denote can be modified by overriding or overloading.]}
address@hidden
+
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0268-1],ARef=[AI05-0292-1]}
address@hidden,address@hidden Indexed_Barrel @key[is tagged] ...
+  @key[with] Variable_Indexing => Find;
+  -- @Examcom{Indexed_Barrel is an indexable container type,}
+  -- @Examcom{Find is the generalized indexing operation.}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0268-1]}
address@hidden,address@hidden Find (B : @key[aliased in out] Indexed_Barrel; 
Key : String) @key[return] Ref_Element;
+   -- @Examcom{Return a reference to an element of a barrel (see 
@RefSecNum{User-Defined References}).}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0268-1]}
address@hidden,Text=[IB: @key[aliased] Indexed_Barrel;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0268-1]}
address@hidden,Text=[-- @Examcom{All of the following calls are then 
equivalent:}
+Find (IB,"pear")address@hidden := Element'(...); -- @Examcom{Traditional call}
+IB.Find ("pear")address@hidden := Element'(...); -- @Examcom{Call of prefixed 
view}
+IB.Find ("pear")          := Element'(...); -- @Examcom{Implicit dereference 
(see @RefSecNum{User-Defined References})}
+IB      ("pear")          := Element'(...); -- @Examcom{Implicit indexing and 
dereference}
+IB      ("pear")address@hidden := Element'(...); -- @Examcom{Implicit indexing 
only}]}
+
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0139-2]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Aspects
+  Constant_Indexing and Variable_Indexing, and the @nt{generalized_indexing}
+  syntax are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0104-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Converted confusing and
+    unnecessary normative wording about "overriding an aspect" into a note.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0138-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:>
+  Defined Constant_Indexing and Variable_Indexing to be nonoveridable.
+  This is merely a new description for @LegalityTitle which already applied
+  to these aspects.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden
+
address@hidden
address@hidden@Defn{literal}
+A @i(literal) represents a value literally, that is, by means
+of notation suited to its kind.]
+A literal is either a @nt<numeric_literal>, a @nt<character_literal>,
+the literal @key(null), or a @nt<string_literal>.
address@hidden,See=(literal)}
address@hidden(Discussion)
+  An enumeration literal that is an @nt<identifier>
+  rather than a @nt<character_literal> is not considered a @i(literal)
+  in the above sense, because it involves no special notation
+  @lquotes@;suited to its address@hidden@;
+  It might more properly be called an @ntf<enumeration_identifier>,
+  except for historical reasons.
address@hidden(Discussion)
address@hidden
+
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00230-01]}
address@hidden,address@hidden type],Sec=(null literal)}
+The expected type for a literal @key(null) shall be a single
+access type.]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[This new wording ("expected type ... shall be a
+single ... type") replaces the old "shall be determinable" stuff. It reflects
+an attempt to simplify and unify the description of the rules for resolving
+aggregates, literals, type conversions, etc. See
address@hidden Context of Overload Resolution} for the details.]}
address@hidden
+
address@hidden type],Sec=(character_literal)}
address@hidden profile],Sec=(character_literal)}
+For a @nt<name> that consists of a @nt<character_literal>,
+either its expected type shall be a single character type, in which case
+it is interpreted as a parameterless @nt<function_call> that yields
+the corresponding value of the character type,
+or its expected profile shall correspond to a parameterless
+function with a character result type, in which case it
+is interpreted as the name of the corresponding parameterless
+function declared as part of the character type's definition
+(see @RefSecNum(Enumeration Types)).
+In either case, the @nt{character_literal} denotes the
address@hidden
address@hidden
+  See @RefSecNum(Selected Components) for the resolution rules for a
+  @nt<selector_name> that is a @nt<character_literal>.
address@hidden
+
address@hidden type],Sec=(string_literal)}
+The expected type for a @nt{primary} that is a @nt<string_literal>
+shall be a single string type.
address@hidden
+
address@hidden
+A @nt{character_literal} that is a @nt<name> shall correspond to a
address@hidden<defining_character_literal> of the expected type, or
+of the result type of the expected profile.
+
+For each character of a @nt{string_literal} with a given
+expected string type, there shall be
+a corresponding @nt<defining_character_literal> of
+the component type of the expected string type.
+
address@hidden,Kind=[Deleted],ARef=[AI95-00230-01],ARef=[AI95-00231-01]}
address@hidden,Text=[A literal @s<null>@ChgNote{We use @S since this
+isn't a nonterminal, and since it is deleted we don't want to fix it.} shall
+not be of an anonymous
+access address@hidden, since such types do not have a null value
+(see @RefSecNum{Access Types})].]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[This is a legality rule rather than an overloading
+rule, to simplify implementations.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00230-01]}
+An integer literal is of type @i{universal_integer}.
+A real literal is of type @address@hidden,New=[ The literal
address@hidden<null> is of type @i<universal_access>address@hidden,
address@hidden@address@hidden,Old=[]}],Old=[]}
address@hidden
+
address@hidden
address@hidden, Sec=(numeric literal)}
address@hidden, Sec=(null literal)}
address@hidden access value}
address@hidden pointer],See=(null access value)}
+The evaluation of a numeric literal, or the literal @key(null),
+yields the represented value.
+
address@hidden, Sec=(string_literal)}
+The evaluation of a @nt{string_literal} that is a @nt<primary>
+yields an array value containing the value of each character of the
+sequence of characters of the @nt<string_literal>,
+as defined in @RefSecNum{String Literals}.
+The bounds of this array value are determined according to the rules for
address@hidden<positional_array_aggregate>s (see @RefSecNum{Array Aggregates}),
+except that for a null string literal, the upper bound is the predecessor
+of the lower bound.
+
address@hidden
+For the evaluation of a @nt<string_literal> of type @i(T),
+a check is made that the value of each
+character of the @nt<string_literal> belongs to the component
+subtype of @i(T).
+For the evaluation of a null string literal, a check is made that its
+lower bound is greater than the lower bound of the base range
+of the index type.
address@hidden,Sec=(raised by failure of run-time check)}
+The exception Constraint_Error is raised if either of these checks fails.
address@hidden
+The checks on the characters need not involve more than two
+checks altogether, since one need only check the characters
+of the string with the
+lowest and highest position numbers against the range of the
+component subtype.
address@hidden
address@hidden
+
address@hidden
+Enumeration literals that are @nt<identifier>s rather than
address@hidden<character_literal>s follow the normal rules for @nt<identifier>s
+when used in a @nt<name>
+(see @RefSecNum{Names} and @RefSecNum{Selected Components}).
address@hidden<Character_literal>s used as @nt<selector_name>s follow the normal
+rules for expanded names (see @RefSecNum{Selected Components}).
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of literals:)
address@hidden
address@hidden()@tabset(P16)
+3.14159_26536 @address@hidden  a real literal]
+1_345 @address@hidden  an integer literal]
+'A' @address@hidden  a character literal]
+"Some Text" @address@hidden  a string literal ]
address@hidden
address@hidden
+
address@hidden
address@hidden with Ada 83}
+Because @nt<character_literal>s are now treated like
+other literals, in that they are resolved using context
+rather than depending on direct visibility, additional
+qualification might be necessary when passing a @nt<character_literal>
+to an overloaded subprogram.
address@hidden
+
address@hidden
address@hidden to Ada 83}
address@hidden<Character_literal>s are now treated
+analogously to @key(null) and @nt<string_literal>s, in that
+they are resolved using context, rather than their content;
+the declaration of the corresponding @nt<defining_character_literal>
+need not be directly visible.
address@hidden
+
address@hidden
+Name Resolution rules for enumeration literals that are not
address@hidden<character_literal>s are not included anymore, since
+they are neither syntactically
+nor semantically "literals" but are rather names of parameterless
+functions.
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada address@hidden now has
+  type @i<universal_access>, which is similar to other literals. @key{Null}
+  can be used with anonymous access types.]}
address@hidden
+
+
address@hidden
+
address@hidden
address@hidden@Defn{aggregate}
+An @i(aggregate) combines component values
+into a composite value of an array type, record type, or record extension.]
address@hidden,See=(aggregate)}
address@hidden
+
address@hidden
address@hidden<aggregate>,rhs="@Syn2{record_aggregate} | 
@Syn2{extension_aggregate} | @Syn2{array_aggregate}"}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
address@hidden type],Sec=(aggregate)}
+The expected type for an @nt{aggregate} shall be a
+single @Chg{Version=[2],New=[],Old=[nonlimited ]}array
+type, record type, or record extension.
address@hidden
+See @RefSec{The Context of Overload Resolution}
+for the meaning of @lquotes@;shall be a single ... address@hidden@;
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,Text=[There are additional rules for each kind of
+aggregate. These aggregate rules are additive; a legal expression needs to
+satisfy all of the applicable rules. That means the rule given here must be
+satisfied even when it is syntactically possible to tell which specific kind of
+aggregate is being used.]}
address@hidden
address@hidden
+
address@hidden
+An @nt{aggregate} shall not be of a class-wide type.
address@hidden
+When the
+expected type in some context is class-wide, an aggregate has to
+be explicitly qualified by the specific type of value to be created,
+so that the expected type for the aggregate itself is specific.
address@hidden
address@hidden
+  We used to disallow @nt<aggregate>s of a type with unknown
+  discriminants. However, that was unnecessarily restrictive
+  in the case of an extension aggregate, and irrelevant to
+  a record aggregate (since a type that is legal for a record
+  aggregate could not possibly have unknown discriminants) and
+  to an array aggregate (the only specific types that can
+  have unknown discriminants are private types, private extensions,
+  and types derived from them).
address@hidden
+
address@hidden
+
address@hidden
address@hidden, Sec=(aggregate)}
+For the evaluation of an @nt<aggregate>, an anonymous object
+is created and values for the components or ancestor part
+are obtained (as described in the subsequent subclause for each
+kind of the @nt<aggregate>) and assigned into the corresponding
+components or ancestor part of the anonymous object.
address@hidden operation],
+  Sec=(during evaluation of an @nt{aggregate})}
+Obtaining the values and the assignments occur in an
+arbitrary address@hidden order],Sec=[allowed]}
+The value of the @nt{aggregate} is the value of this object.
address@hidden
+  The ancestor part is the set of components inherited from the
+  ancestor type. The syntactic category @nt<ancestor_part> is
+  the @nt<expression> or @nt<subtype_mark> that specifies
+  how the ancestor part of the anonymous object should be initialized.
address@hidden
address@hidden
+  The assignment operations do the necessary
+  value adjustment, as described in
+  @RefSecNum{Assignment and Finalization}.
+  Note that the value as a whole is not adjusted
+  @em just the subcomponents (and ancestor part, if any).
+  @RefSecNum{Assignment and Finalization} also describes
+  when this anonymous object is finalized.
+
+  If the @nt<ancestor_part> is a @nt<subtype_mark>
+  the Initialize procedure for the ancestor type is applied
+  to the ancestor part after default-initializing it,
+  unless the procedure is abstract, as described
+  in @RefSecNum{Assignment and Finalization}.
+  The Adjust procedure for the ancestor type is not called
+  in this case, since there is no assignment to the ancestor
+  part as a whole.
address@hidden
+
address@hidden
+If an @nt{aggregate} is of a tagged type, a check is made that
+its value belongs to the first subtype of the type.
address@hidden,Sec=(raised by failure of run-time check)}
+Constraint_Error is raised if this check fails.
address@hidden
+This check ensures that no values of a tagged type are
+ever outside the first subtype, as required
+for inherited dispatching operations to work properly
+(see @RefSecNum(Derived Types and Classes)). This check will always
+succeed if the first subtype is unconstrained.
+This check is not extended to untagged types
+to preserve upward compatibility.
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+We now allow @nt{extension_aggregate}s.
address@hidden
+
address@hidden
+We have adopted new wording
+for expressing the
+rule that the type of an aggregate shall be determinable
+from the outside, though using the fact that
+it is nonlimited record (extension) or array.
+
+An @nt{aggregate} now creates an anonymous object.
+This is necessary so that controlled types
+will work (see @RefSecNum{Assignment and Finalization}).
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],Type=[Leading],address@hidden with Ada 95}
+  In Ada 95, a limited type is not considered when resolving an @nt{aggregate}.
+  Since Ada 2005 now allows limited @nt{aggregate}s, we can have
+  incompatibilities. For example:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Lim @key{is} @key{limited}
+   @key{record}
+      Comp: Integer;
+   @key{end} @key{record};],Old=[]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Not_Lim @key{is}
+   @key{record}
+      Comp: Integer;
+   @key{end} @key{record};],Old=[]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden P(X: Lim);
address@hidden P(X: Not_Lim);],Old=[]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[P((Comp => 123)); -- @RI[Illegal in Ada 2005, legal in Ada 
95]]}
address@hidden
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]} @ChgAdded{Version=[2],Text=[The call
+  to P is ambiguous in Ada 2005, while it would not be ambiguous in Ada 95 as
+  the @nt{aggregate} could not have a limited type. Qualifying the
+  @nt{aggregate} will eliminate any ambiguity. This construction would be
+  rather confusing to a maintenance programmer, so it should be avoided, and
+  thus we expect it to be rare.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada address@hidden can
+  be of a limited type.]}
address@hidden
+
+
address@hidden Aggregates}
+
address@hidden
address@hidden a @nt<record_aggregate>, a value is specified for
+each component of the record or record extension value,
+using either a named or a positional association.]
address@hidden
+
address@hidden
address@hidden<record_aggregate>,rhs="(@Syn2{record_component_association_list})"}
+
address@hidden<record_component_association_list>,rhs="
+    @Syn2{record_component_association} {, @Syn2{record_component_association}}
+  | @key<null record>"}
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
address@hidden<record_component_association>,rhs="
+    address@hidden =>] @address@hidden,New=[
+   | @Syn2{component_choice_list} => <>],Old=[]}"}
+
address@hidden<component_choice_list>,rhs="
+     @address@hidden {| @address@hidden
+   | @key{others}"}
+
address@hidden(SyntaxText)
address@hidden component association}
+A @nt<address@hidden@!association> is a @i(named component association)
+if it has a @nt<component_choice_list>;
address@hidden component association}
+otherwise, it is a @i(positional component association).
+Any positional component associations shall precede any
+named component associations.
+If there is a named association with a @nt<component_choice_list>
+of @key(others), it shall come last.
address@hidden
+These rules were
+  implied by the BNF in an early version of the RM9X, but it
+  made the grammar harder to read, and was inconsistent
+  with how we handle discriminant constraints.
+  Note that for array aggregates we still express
+  some of the rules in the grammar, but array aggregates
+  are significantly different because an array aggregate
+  is either all positional (with a possible @key(others) at the
+  end), or all named.
address@hidden
+
+In the @nt<address@hidden@address@hidden> for a @nt<address@hidden>,
+if there is only one association, it shall be a named association.
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+  address@hidden,New=[,],Old=[]} the construct would be interpreted
+  as a parenthesized expression.
+  This is considered a syntax rule, since it is relevant to
+  overload resolution. We choose not to express it with BNF so we
+  can share the definition of @nt<record_component_association_list>
+  in both @nt<record_aggregate> and @nt<extension_aggregate>.
address@hidden
address@hidden
+  The @nt<record_component_association_list> of an @nt<extension_aggregate>
+  does not have such a restriction.
address@hidden
address@hidden(SyntaxText)
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
address@hidden type],Sec=(record_aggregate)}
+The expected type for a @nt{record_aggregate} shall be
+a single @Chg{Version=[2],New=[],Old=[nonlimited ]}record
+type or record extension.
address@hidden
+This rule is used to resolve whether an @nt{aggregate} is
+an @nt{array_aggregate} or a @nt{record_aggregate}.
+The presence of a @key(with) is used to resolve between
+a @nt{record_aggregate} and an @nt{extension_aggregate}.
address@hidden
+
address@hidden component],
+  Sec=(@nt<record_aggregate> @nt<record_component_association_list>)}
+For the @nt<address@hidden@address@hidden>
+of a @nt<address@hidden>,
+all components of the composite value defined by
+the aggregate are @i(needed)@Redundant[; for the association list of
+an @nt<extension_aggregate>,
+only those components not determined by the ancestor expression or
+subtype are needed
+(see @RefSecNum{Extension Aggregates}).]
+Each @address@hidden in a @address@hidden@!association} shall denote
+a needed component @Redundant[(including possibly a discriminant)].
address@hidden
+For the association list of a @nt{record_aggregate},
address@hidden@;needed address@hidden@; includes every component of the 
composite value, but
+does not include those in unchosen @nt{variant}s (see AI83-309).
+If there are @nt<variant>s, then
+the value specified for
+the discriminant that governs them
+determines which @nt<variant> is chosen, and hence which components
+are needed.
+
+If an extension defines a new @nt{known_discriminant_part}, then all of
+its discriminants are needed in the component association list of
+an extension
+aggregate for that type, even if the discriminants have the same
+names and types as discriminants of the type of the ancestor
+expression.
+This is necessary to ensure that the positions in
+the @nt<address@hidden@address@hidden>
+are well defined, and that discriminants that govern @nt{variant_part}s
+can be given by static expressions.
address@hidden
+
address@hidden@address@hidden type],
+  Sec=(record_component_association expression)}
+The expected type for the @nt<expression> of a
address@hidden<address@hidden@!association> is the type
+of the @i(associated) component(s);
address@hidden components],
+  Sec=(of a @nt<record_component_association>)}
+the associated component(s) are as follows:
address@hidden(itemize)
+  For a positional association,
+  the component @Redundant[(including possibly a discriminant)]
+  in the corresponding relative position (in the declarative region of
+  the type), counting only the
+  needed components;
address@hidden
+    This means that for
+    an association list of an @nt<extension_aggregate>,
+    only noninherited components are counted to determine
+    the position.
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[3],Text=[For a derived type (including type extensions),
+  the order of declaration is defined in @RefSec{Derived Types and Classes}.
+  In particular, all discriminants come first, regardless of whether they are
+  defined for the parent type or are newly added to the derived type.]}
address@hidden
+
+  For a named association with one or more
+  @i(component_)@nt<selector_name>s,
+  the named component(s);
+
+  For a named association with the reserved word @key(others),
+  all needed components
+  that are not associated with some previous association.
address@hidden(itemize)
address@hidden
+
address@hidden
+
+If the type of a @nt{record_aggregate} is a record extension,
+then it shall be a descendant of a record type, through one
+or more record extensions (and no private extensions).
+
address@hidden,Kind=[Revised],ARef=[AI05-0016-1]}
address@hidden,New=[The reserved words @key[null record] may appear only if],
+Old=[If]} there are no components needed in a given
address@hidden<address@hidden@address@hidden>@Chg{Version=[3],New=[],Old=[,
+then the reserved words @key(null record) shall appear rather
+than a list of @nt<address@hidden@!association>s]}.
address@hidden
+  For example, "(@key(null record))" is a @nt<record_aggregate>
+  for a null record type. Similarly, "(T'(A) @key(with null record))" is
+  an @nt<extension_aggregate> for a type defined as a null
+  record extension of T.
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0016-1]}
address@hidden,Text=[If no components are needed and @key[null record]
+  is not used, the @address@hidden@!association} must necessarily be
+  @key[others] => <>, as that is the only
+  @address@hidden@!association} that does not require an associated
+  component.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0199-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0046-1]}
+Each @nt<record_component_association>@Chg{Version=[2],New=[ other than an
address@hidden choice with a <>],Old=[]} shall have at least
+one associated component, and each needed component
+shall be associated with exactly
+one @nt<address@hidden@!association>.
+If a @nt<address@hidden@!association> @Chg{Version=[2],New=[with an
address@hidden ],Old=[]}has two or more associated components, all of them
+shall be of the same address@hidden,New=[, or all of them shall be of
+anonymous access types whose subtypes
+statically match],address@hidden,New=[
+In addition, @LegalityTitle are enforced separately for each associated
+component.],Old=[]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00287-01]}
+  These rules apply to an association with an @key(others)
+  address@hidden,New=[ with an expression. An @key(others) choice with
+  a <> can match zero components or several components with different
+  types],Old=[]}.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00287-01]}
+  Without these rules, there would be no way to know what
+  was the expected type for the @nt<expression> of the association.
+  @Chg{Version=[2],New=[Note that some of the rules do not apply to <>
+  associations, as we do not need to resolve anything. We allow @key{others}
+  => <> to match no components as this is similar to array aggregates.
+  That means that (@key{others} => <>) always represents a default-initialized
+  record or array value.],Old=[]}
address@hidden
address@hidden
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0046-1]}
+  @ChgAdded{Version=[4],Type=[Leading],address@hidden to get conditional 
"leading"}
+  AI83-00244 also requires that the @nt{expression} shall
+  be legal for each associated component. @Chg{Version=[4],New=[Ada 95
+  omitted this wording, as it was thought that all cases of
+  difference had been eliminated. That probably was true, but Ada 2005
+  reintroduced cases where the types match but the legality differs.
+  For example:],Old=[This is
+  because even though two components have the same type, they might have
+  different subtypes. Therefore, the legality of the
+  @nt<expression>, particularly if it is an array aggregate,
+  might differ depending on the associated component's subtype.
+  However, we have relaxed the rules on array aggregates slightly for Ada 95,
+  so the staticness of an applicable index constraint has no
+  effect on the legality of the array aggregate to which it applies.
+  See @RefSecNum{Array Aggregates}. This was the only case (that we know of)
+  where a subtype provided by context affected the legality
+  of an @nt{expression}.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden Rec (D : @key[access] Integer) @key[is record]
+          F : @key[access] Integer;
address@hidden record];]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[...
+X : @key[aliased] Integer;
+R : Rec := (D | F => X'Access); -- @examcom<Legal for D, illegal for F>]}
address@hidden
+
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Text=[There are additional ways for this to happen;
+  because of cases like the above we require that the @LegalityTitle are 
checked
+  individually for each associated component.]}
address@hidden
address@hidden
+  The rule that requires at least one associated component for
+  each @nt<record_component_association>
+  implies that there can be no extra associations for
+  components that don't exist in the composite value, or that
+  are already determined by the ancestor expression or subtype of
+  an @nt<extension_aggregate>.
+
+  The second part of the first sentence ensures that no
+  needed components are left out,
+  nor specified twice.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0220-1]}
address@hidden,New=[The],Old=[If the components of a @nt{variant_part}
+are needed, then the]} value of a discriminant that governs
address@hidden,New=[a],Old=[the]} @nt{variant_part}
address@hidden,address@hidden<P> ],Old=[]}shall be given
+by a static address@hidden,New=[, unless @i<P> is nested within
+a @nt{variant} @i<V> that is not selected by the discriminant value
+governing the @nt{variant_part} enclosing @i<V>],Old=[]}.
address@hidden
+This expression might either be given within the aggregate itself,
+or in a constraint on the parent subtype in a @nt<derived_type_definition>
+for some ancestor of the type of the aggregate.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00287-01]}
address@hidden,Text=[A @nt<record_component_association> for a discriminant
+without a @nt<default_expression> shall have an @nt<expression> rather
+than <>.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[A discriminant must always have a defined value,
+but <> means uninitialized for a discrete type unless the component has a
+default value.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden, Sec=(record_aggregate)}
+The evaluation of a @nt<record_aggregate> consists of the
+evaluation of the @nt<address@hidden@address@hidden>.
+
address@hidden, Sec=(record_component_association_list)}
+For the evaluation of a @address@hidden@address@hidden,
+any per-object constraints (see @RefSecNum(Record Types))
+for components specified in the association list are elaborated and
+any @nt<expression>s are evaluated and converted to the subtype of the
+associated component.
address@hidden subtype conversion],Sec=(expressions in aggregate)}
+Any constraint elaborations and @nt{expression} evaluations (and conversions)
+occur in an arbitrary order, except that the @nt<expression>
+for a discriminant is evaluated (and converted) prior to the
+elaboration of any per-object constraint that depends on it, which in
+turn occurs prior to the evaluation and conversion of the @nt{expression} for
+the component with the per-object address@hidden order],Sec=[allowed]}
address@hidden
+The conversion in the first rule might raise Constraint_Error.
address@hidden
address@hidden
+This check in the first rule presumably happened as part of the dependent
+compatibility check in Ada 83.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00287-01]}
address@hidden,Text=[For a @nt<record_component_association> with an
address@hidden<expression>, the @nt<expression> defines the value for the 
associated
+component(s). For a @nt<record_component_association> with <>, if the
address@hidden<component_declaration> has a @nt<default_expression>, that
address@hidden<default_expression> defines the value for the associated 
component(s);
+otherwise, the associated component(s) are initialized by default as for a
+stand-alone object of the component subtype
+(see @RefSecNum{Object Declarations}).]}
+
+The @nt<expression> of a @nt{record_component_association}
+is evaluated (and converted) once for each associated component.
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,Text=[We don't need similar language for <>,
+as we're considering the value of <> for each individual component.
+Each component has its own default expression or its own
+default initialization (they can be different for each component;
+the components even could have different types), and each one
+has to be evaluated. So there is no need to repeat that.]}
address@hidden
+
address@hidden
+
address@hidden
+For a @nt<record_aggregate> with positional associations, expressions
+specifying discriminant
+values appear first since the @nt<known_discriminant_part>
+is given first in the declaration of the type; they have to
+be in the same order as in the @nt<known_discriminant_part>.
address@hidden
+
address@hidden
address@hidden@address@hidden(Example of a record aggregate with positional 
associations:)
address@hidden
+(4, July, 1776)                                       address@hidden  see 
@RefSecNum{Record Types} ]
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of record aggregates with named 
associations:)
address@hidden
address@hidden
+(Day => 4, Month => July, Year => 1776)
+(Month => July, Day => 4, Year => 1776)
+
+(Disk, Closed, Track => 5, Cylinder => 12)            address@hidden  see 
@RefSecNum{Variant Parts and Discrete Choices}]
+(Unit => Disk, Status => Closed, Cylinder => 9, Track => 1)
address@hidden
+
address@hidden
address@hidden@address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
address@hidden(@Chg{Version=[2],New=[Examples],Old=[Example]} of component
address@hidden,New=[associations],Old=[association]} with
+several choices:)
address@hidden
address@hidden
address@hidden()@tabset(P50)
+(Value => 0, Succ|Pred => @key(new) Cell'(0, @key(null), @key(null))) 
@address@hidden  see @RefSecNum{Incomplete Type Declarations}]
+
+ address@hidden  The allocator is evaluated twice: Succ and Pred designate 
different cells]
+
address@hidden,Kind=[Added]}
address@hidden,New=[(Value => 0, Succ|Pred => <>) @address@hidden  see 
@RefSecNum{Incomplete Type Declarations}]],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,New=[ address@hidden  Succ and Pred will be set to 
@key{null}]],Old=[]}
+
address@hidden
+
address@hidden
address@hidden@address@hidden of record aggregates for tagged types
+(see @RefSecNum(Tagged Types and Type Extensions)
+and @RefSecNum{Type Extensions}):}
address@hidden
address@hidden
+Expression'(@key{null record})
+Literal'(Value => 0.0)
+Painted_Point'(0.0, Pi/2.0, Paint => Red)
address@hidden
+
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Null record aggregates may now be specified, via "(@key(null record))".
+However, this syntax is more useful for null record extensions in
+extension aggregates.
address@hidden
+
address@hidden
+Various AIs have been incorporated (AI83-00189, AI83-00244, and AI83-00309).
+In particular, Ada 83 did not explicitly disallow extra values in
+a record aggregate. Now we do.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}<> can be used in
+  place of an @nt{expression} in a @nt{record_aggregate}, default
+  initializing the component.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],Text=[Limited @nt{record_aggregate}s are allowed (since
+  all kinds of aggregates can now be limited, see @RefSecNum{Aggregates}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0220-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Corrected wording so that the rule for discriminants governing 
@nt{variant_part}s
+  was not effectively circular. The change makes a few @nt{aggregate}s where a
+  nonstatic discriminant governs an empty @nt{variant_part} illegal. However,
+  most Ada implementations already enforce some version of the new rule and
+  already reject these @nt{aggregate}s. So it is unlikely that any
+  incompatibility will be noticed in practice.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0016-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada address@hidden<Correction:> 
Fixed the wording so that
+  @key[others] => <> can be used in place of @key[null record].
+  This is needed to avoid a generic contract issue for generic bodies:
+  we do not want to have to assume the worst to disallow @key[others] => <>
+  if the record type @i{might} be a null record.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0199-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> We now allow multiple 
components
+  with anonymous access types to be specified with a single component
+  association. This is to be consistent with the capabilities of a named
+  access type.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0046-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> We explicitly say that the
+  @LegalityTitle have to be rechecked for each component individually.
+  This @i<seems> obvious, but as the AARM note @RefSecNum{Record Aggregates}
+  (16.c) appeared to say that this was not necessary, and since we explicitly
+  state this sort of thing for generic instances, it seemed better to be
+  explicit.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden Aggregates}
+
address@hidden
address@hidden @nt<extension_aggregate> specifies a value
+for a type that is a record extension by specifying a value
+or subtype
+for an ancestor of the type,
+followed by associations for
+any components not determined by the @nt<ancestor_part>.]
address@hidden
+
address@hidden
+The model underlying this syntax is that a record extension
+can also be viewed as a regular record type with an ancestor "prefix."
+The @nt<address@hidden@address@hidden> corresponds to
+exactly what would be needed
+if there were no ancestor/prefix type.
+The @nt{ancestor_part}
+determines the value of the ancestor/prefix.
address@hidden
+
address@hidden
address@hidden<extension_aggregate>,rhs="
+    (@Syn2{ancestor_part} @key(with) 
@Syn2{record_component_association_list})"}
+
address@hidden<ancestor_part>,
+  rhs="@Syn2{expression} | @Syn2{subtype_mark}"}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
address@hidden type], Sec=(extension_aggregate)}
+The expected type for an @nt{extension_aggregate} shall be
+a single @Chg{Version=[2],New=[],Old=[nonlimited ]}type that is a
+record extension.
address@hidden type],
+  Sec=(extension_aggregate ancestor expression)}
+If the @nt<ancestor_part> is an @nt<expression>,
+it is expected to be of any @Chg{Version=[2],New=[],Old=[nonlimited ]}tagged
+type.
address@hidden
+We could have made
+the expected type @i(T')Class where @i(T) is the ultimate ancestor of
+the type of the aggregate, or we could have made it even more
+specific than that. However, if the overload resolution rules
+get too complicated, the implementation gets more difficult and
+it becomes harder to produce good error messages.
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,Text=[This rule is additive with the rule given in
address@hidden That means the @RefSecNum{Aggregates} rule must be
+satisfied even though it is always syntactically possible to tell that
+something is an extension aggregate rather than another kind of aggregate.
+Specifically, that means that an extension aggregate is ambiguous if the
+context is overloaded on array and/or untagged record types, even though
+those are never legal contexts for an extension aggregate. Thus, this rule
+acts more like a @LegalityName than a @ResolutionName.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00306-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0115-1]}
+If the @nt<ancestor_part> is a @nt<subtype_mark>, it shall
+denote a specific tagged subtype.
address@hidden,New=[If the @nt{ancestor_part} is an @nt{expression}, it
+shall not be dynamically tagged. ],Old=[]}
+The type of the @nt{extension_aggregate} shall be
address@hidden,New=[a descendant of],Old=[derived from]} the type of the
address@hidden<ancestor_part>@Chg{Version=[3],New=[ (the @i<ancestor> 
type)@Defn2{Term=[ancestor type],
+Sec=<of an @nt<extension_aggregate>>}],Old=[]},
+through one or more record extensions (and no private
+extensions)address@hidden,New=[ If the @nt{ancestor_part} is a
address@hidden, the view of the ancestor type from which the type
+is descended (see @RefSecNum{Private Operations})
+shall not have unknown discriminants.],Old=[]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00306-01]}
+  @ChgAdded{Version=[2],Text=[The expression cannot be dynamically tagged to
+  prevent implicit "truncation" of a dynamically-tagged value to the specific
+  ancestor type. This is similar to the
+  rules in @RefSecNum{Dispatching Operations of Tagged Types}.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0067-1],ARef=[AI05-0244-1]}
address@hidden,Type=[Leading],Text=[If the type of the @nt{ancestor_part}
+is limited and at least one component is needed
+in the @nt{record_component_association_list}, then the @nt{ancestor_part}
+shall not be:]}
address@hidden
address@hidden,Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[a call to a function with an unconstrained result
+  subtype; nor]}
+
address@hidden,Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[a parenthesized or qualified expression whose
+  operand would violate this rule; nor]}
+
address@hidden,Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[a @nt{conditional_expression} having at least one
+  @address@hidden that would violate this rule.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0067-1],ARef=[AI05-0244-1]}
+  @ChgAdded{Version=[3],Text=[This restriction simplifies implementation,
+  because it ensures that either the caller or the callee knows the size to
+  allocate for the aggregate. Without this restriction, information from both
+  caller and callee would have to be combined to determine the appropriate
+  size.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0067-1]}
+  @ChgAdded{Version=[3],Text=[The (F(...) with null record) case is exempt from
+  this rule, because such extension
+  aggregates are created internally for inherited functions returning
+  null-extension types @em we can't very well make those illegal. Moreover, we
+  don't need the rule for null extensions, as the result can simply use
+  the space returned by the function call.]}
address@hidden
address@hidden
+
address@hidden
address@hidden component],
+  Sec=(@nt<extension_aggregate> @nt<record_component_association_list>)}
+For the @address@hidden@address@hidden
+of an @address@hidden,
+the only components @i(needed) are those of the composite value defined
+by the aggregate that are not inherited from the type of
+the @nt<address@hidden>, plus any inherited discriminants
+if the @nt<address@hidden> is a @nt<address@hidden> that
+denotes an unconstrained subtype.
address@hidden
+
address@hidden
address@hidden, Sec=(extension_aggregate)}
+For the evaluation of an @nt{extension_aggregate},
+the @address@hidden@address@hidden is evaluated.
+If the @nt<ancestor_part> is an @nt<expression>, it is also evaluated;
+if the @nt<ancestor_part> is a @nt<subtype_mark>,
+the components of the value of the aggregate not given by the
address@hidden<address@hidden@address@hidden> are initialized by default
+as for an object of the ancestor type.
+Any implicit initializations or evaluations are performed
+in an arbitrary order, except that the @nt<expression>
+for a discriminant is evaluated prior to any other evaluation
+or initialization that depends on address@hidden order],Sec=[allowed]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0282-1]}
address@hidden
+If the type of the @nt<ancestor_part> has
+discriminants @Chg{Version=[3],New=[and],Old=[that are not inherited by the
+type of the @nt{extension_aggregate},
+then, unless]} the @nt<ancestor_part> address@hidden,New=[ not],Old=[]}
+a @nt<subtype_mark> that
+denotes an unconstrained subtype,@Chg{Version=[3],New=[ then],Old=[]}
+a check is made that each discriminant @Chg{Version=[3],New=[determined by the
address@hidden,Old=[of the ancestor]}
+has the value specified for a corresponding 
discriminant,@Chg{Version=[3],New=[ if any,],Old=[]}
+either in the @address@hidden@address@hidden, or in
+the @nt<derived_type_definition> for some ancestor of the type of
+the @nt{extension_aggregate}.
address@hidden,Sec=(raised by failure of run-time check)}
+Constraint_Error is raised if this check fails.
address@hidden
+  Corresponding and specified
+  discriminants are defined in @RefSecNum{Discriminants}.
+  The rules requiring static compatibility between
+  new discriminants of a derived type
+  and the parent discriminant(s) they constrain
+  ensure that at most one check is required per discriminant
+  of the ancestor expression.
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0282-1]}
+  @ChgAdded{Version=[3],Text=[The check needs to be made any time that the
+  ancestor is constrained; the source of the discriminants or the constraints
+  is irrelevant.]}
address@hidden
address@hidden
+
address@hidden
+If all components of the value of the @nt<extension_aggregate>
+are determined by the @nt<ancestor_part>, then
+the @nt<address@hidden@address@hidden> is required to be
+simply @key(null record).
+
+If the @nt<ancestor_part> is a @nt<subtype_mark>,
+then its type can be abstract. If its type is controlled,
+then as the last step of evaluating the aggregate,
+the Initialize procedure of the ancestor type is called,
+unless the Initialize procedure is abstract
+(see @RefSecNum{Assignment and Finalization}).
address@hidden
+
address@hidden
address@hidden@address@hidden of extension aggregates (for types defined in 
@RefSecNum{Type Extensions}):}
address@hidden(example)
+Painted_Point'(Point @key{with} Red)
+(Point'(P) @key{with} Paint => Black)
+
+(Expression @key{with} Left => 1.2, Right => 3.4)
+Addition'(Binop @key{with null record})
+             address@hidden presuming Binop is of type Binary_Operation]
address@hidden(example)
+
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The extension aggregate syntax is new.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00306-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] Eliminated implicit @lquotes@;address@hidden
+  of a dynamically tagged value when it is used as an ancestor
+  @nt{expression}. If an @nt{aggregate} includes such an @nt{expression},
+  it is illegal in Ada 2005. Such @nt{aggregate}s are thought to be rare;
+  the problem can be fixed with a type conversion to the appropriate
+  specific type if it occurs.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],Text=[Limited @nt{extension_aggregate}s are allowed 
(since
+  all kinds of aggregates can now be limited, see @RefSecNum{Aggregates}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0282-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden:]
+  An @nt{extension_aggregate} with an @nt{ancestor_part} whose discriminants
+  are constrained and inherited might now raise Constraint_Error if the
+  @nt{aggregate}'s type is constrained, while it was OK in Ada 2005. In almost
+  all cases, this will make no difference as the constraint will be checked
+  by the immediately following use of the @nt{aggregate}, but it is possible to
+  compare such an aggregate for equality;
+  in this case, no exception would be raised by Ada 2005, while Ada 2012 will
+  raise Constraint_Error. This should be very rare, and having the possibility
+  means that the representation of the aggregate type has to be able to support
+  unconstrained values of the type, even if the first subtype is constrained
+  and no such objects can be created any other way.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0067-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden:]
+  A limited unconstrained ancestor expression that is a function call is now
+  illegal unless the extension part is null.
+  Such @nt{aggregate}s were first introduced in Ada 2005 and are very complex
+  to implement as they must be built-in-place with an unknown size; as such,
+  it is unlikely that they are implemented correctly in existing compilers and
+  thus not often used in existing code.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0115-1]}
+  @ChgAdded{Version=[3],address@hidden:] An @nt{ancestor_part} that is a
+  subtype with unknown discriminants is now explicitly illegal. Such a
+  subtype should not be used to declare an object, and the @nt{ancestor_part}
+  acts like an object. The Ada 95 rules did not disallow such cases, so it
+  is possible that code exists that uses such an ancestor, but this should
+  be rare.]}
address@hidden
+
+
address@hidden Aggregates}
+
address@hidden
+
address@hidden an @nt<array_aggregate>, a value is specified
+for each component of an array, either positionally or by
+its index.]
+For a @nt{positional_array_aggregate},
+the components are given in increasing-index order,
+with a final @key[others], if any,
+representing any remaining components.
+For a @nt{named_array_aggregate},
+the components are identified by the values covered by the
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised]}
+The rules in this subclause are based on
+terms and rules for @nt{discrete_choice_list}s
+defined in @RefSec{Variant Parts and Discrete Choices}.
address@hidden example, the requirements that @key(others) come last and stand
+alone are found there.],address@hidden question is asked periodically, so
+we answer it explicitly.}
address@hidden
+
address@hidden
address@hidden<array_aggregate>,rhs="
+  @Syn2{positional_array_aggregate} | @Syn2{named_array_aggregate}"}
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
address@hidden<positional_array_aggregate>,rhs="
+    (@Syn2{expression}, @Syn2{expression} {, @Syn2{expression}})
+  | (@Syn2{expression} {, @Syn2{expression}}, @key(others) => 
@Syn2{expression})@Chg{Version=[2],New=[
+  | (@Syn2{expression} {, @Syn2{expression}}, @key(others) => <>)],Old=[]}"}
+
+
address@hidden<named_array_aggregate>,rhs="
+    (@Syn2{array_component_association} {, 
@Syn2{array_component_association}})"}
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
address@hidden<array_component_association>,rhs="
+    @Syn2{discrete_choice_list} => @address@hidden,New=[
+  | @Syn2{discrete_choice_list} => <>],Old=[]}"}
+
address@hidden
+
address@hidden
address@hidden @nt<array_aggregate>}
+An @i(n-dimensional) @nt<array_aggregate> is one that is written as
+n levels of nested @nt{array_aggregate}s (or at the bottom level,
+equivalent @nt{string_literal}s).
address@hidden, Sec=(of an @nt{array_aggregate})}
+For the multidimensional case (n >= 2) the @nt<array_aggregate>s
+(or equivalent @nt<string_literal>s)
+at the address@hidden@;1 lower levels are called @i(subaggregate)s of the
+enclosing n-dimensional @nt<array_aggregate>.
address@hidden component expression}
+The @nt<expression>s of the bottom level subaggregates (or of the
address@hidden<array_aggregate> itself if one-dimensional)
+are called the @i(array component expressions) of the enclosing
+n-dimensional @nt<array_aggregate>.
address@hidden(Ramification)
+  Subaggregates do not have a type. They correspond to part of
+  an array. For example, with a matrix, a subaggregate would correspond to
+  a single row of the matrix.
+  The definition of "n-dimensional" @nt<array_aggregate>
+  applies to subaggregates as well
+  as @nt<aggregate>s that have a type.
address@hidden(Ramification)
address@hidden(Honest)
address@hidden choice}
+An @i(@key(others) choice) is
+the reserved word @key(others) as it appears in
+a @nt{positional_array_aggregate} or as the
address@hidden of the @nt{discrete_choice_list}
+in an @nt{array_component_association}.
address@hidden(Honest)
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
address@hidden type], Sec=(array_aggregate)}
+The expected type for an @nt{array_aggregate} (that is not
+a subaggregate) shall be a
+single @Chg{Version=[2],New=[],Old=[nonlimited ]}array type.
address@hidden type],
+  Sec=(array_aggregate component expression)}
+The component type of this array type is the
+expected type for each array component expression of
+the @nt<array_aggregate>.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
+We already require a single array or record type or
+record extension for an @nt{aggregate}.
+The above rule requiring a single @Chg{Version=[2],New=[],
+Old=[nonlimited ]}array type
+(and similar ones for record and extension aggregates)
+resolves which kind of aggregate you have.
address@hidden
+
address@hidden type],
+  Sec=(array_aggregate discrete_choice)}
+The expected type for each
address@hidden in any @nt{discrete_choice_list} of
+a @nt{named_array_aggregate} is the type of the @i(corresponding index);
address@hidden index], Sec=(for an @nt{array_aggregate})}
+the corresponding index for an @nt<array_aggregate> that is not
+a subaggregate is the first index of its type; for an 
(address@hidden@;m)-dimensional
+subaggregate within an @nt<array_aggregate> of an n-dimensional type,
+the corresponding index is the index in position m+1.
address@hidden
+
address@hidden
+An @nt<array_aggregate> of an n-dimensional array type shall be
+written as an n-dimensional @nt<array_aggregate>.
address@hidden(Ramification)
+In an m-dimensional @nt<array_aggregate> @Redundant[(including a 
subaggregate)],
+where m >= 2, each of the @nt<expression>s
+has to be an (address@hidden@;1)-dimensional subaggregate.
address@hidden(Ramification)
+
address@hidden@;An @key(others) choice is allowed for an @nt<array_aggregate>
+only if an @i(applicable index
+constraint) applies to the @nt{array_aggregate}.
address@hidden index constraint}
address@hidden applicable index constraint is
+a constraint provided by certain contexts where an @nt{array_aggregate}
+is permitted that can be used
+to determine the bounds of the array value specified by the aggregate.]
+Each of the following contexts (and none other)
+defines an applicable index constraint:
address@hidden(itemize)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00318-02]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0157-1]}
+  For an @nt{explicit_actual_parameter},
+  an @nt{explicit_generic_actual_parameter},
+  the @nt{expression} of a
+  @Chg{Version=[2],New=[return statement],address@hidden,
+  @Chg{Version=[4],New=[the return expression of an expression
+  function, ],Old=[]}the initialization expression
+  in an @address@hidden, or a @address@hidden
+  @Redundant[(for a parameter or a component)],
+  when the nominal subtype
+  of the corresponding formal parameter, generic formal parameter,
+  function @Chg{Version=[2],New=[return object],Old=[result]},
+  @Chg{Version=[4],New=[expression function return object, ],Old=[]}object, or
+  component is a constrained array subtype, the
+  applicable index constraint is the constraint of the subtype;
+
+  For the @nt{expression} of an @nt{assignment_statement} where
+  the @nt{name} denotes an array variable, the
+  applicable index constraint is the constraint of the array variable;
address@hidden
+  This case is broken out because the constraint comes from the actual
+  subtype of the variable (which is always constrained)
+  rather than its nominal subtype (which might be unconstrained).
address@hidden
+
+  For the operand of a @nt{qualified_expression}
+  whose @nt{subtype_mark}
+  denotes a constrained array subtype, the applicable index constraint
+  is the constraint of the subtype;
+
+  For a component @nt{expression} in an @nt{aggregate},
+  if the component's nominal subtype is a constrained
+  array subtype, the applicable index constraint is the constraint
+  of the subtype;
+  @begin{Discussion}
+  Here, the @nt{array_aggregate} with @key[others]
+  is being used within a larger aggregate.
+  @end{Discussion}
+
address@hidden,Kind=[Revised],ARef=[AI05-0147-1]}
+  For a parenthesized @nt{expression}, the
+  applicable index constraint is that, if any, defined for the
+  @address@hidden,New=[;],Old=[.]}
address@hidden
+RM83 omitted this
+  case, presumably as an oversight. We want to minimize situations
+  where an @nt{expression} becomes illegal if parenthesized.
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0147-1]}
address@hidden,Text=[For a @nt{conditional_expression}, the
+applicable index constraint for each @SynI<dependent_>@nt{expression} is that,
+if any, defined for the @nt{conditional_expression}.]}
address@hidden(itemize)
+
+The applicable index constraint @i(applies) to an @nt{array_aggregate}
+that appears in such a context, as well as to any subaggregates thereof.
+In the case of an @nt<explicit_actual_parameter> (or @nt<default_expression>)
+for a call on a generic formal subprogram,
+no applicable index constraint is defined.
address@hidden(Reason)
+  This avoids generic contract model problems,
+  because only mode conformance is required when matching
+  actual subprograms with generic formal subprograms.
address@hidden(Reason)
+
address@hidden,Kind=[Revised],ARef=[AI05-0153-3]}
+The @nt{discrete_choice_list} of an
address@hidden is allowed to
+have a @nt{discrete_choice} that is a nonstatic
address@hidden,address@hidden<choice_expression>],address@hidden<expression>]}
+or that is a @Chg{Version=[3],address@hidden or @nt{range}],
address@hidden that defines a nonstatic or
+null range, only if it is the single @nt{discrete_choice} of
+its @nt{discrete_choice_list}, and there is only one
address@hidden in the @nt<array_aggregate>.
address@hidden
+We now allow a nonstatic @key(others) choice even if there are
+other array component expressions as well.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
+In a @nt<named_array_aggregate>
address@hidden,New=[where all @nt{discrete_choice}s are
+static],Old=[with more than one @nt<discrete_choice>]},
+no two @nt<discrete_choice>s are allowed to
+cover the same value (see @RefSecNum{Variant Parts and Discrete Choices});
+if there is no @key[others] choice, the @nt<discrete_choice>s taken
+together shall
+exactly cover a contiguous sequence of values of the corresponding index type.
address@hidden
+  This implies that each component must be
+  specified exactly once. See AI83-309.
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Text=[This has to apply even if there is only one
+  static @nt{discrete_choice}; a single choice has to represent a contiguous
+  range (a @nt{subtype_mark} with a static predicate might represent a
+  discontiguous set of values). If the (single) choice is a dynamic subtype, we
+  don't need to make this check as no predicates are allowed (see
+  @RefSecNum{Subtype Predicates}) and
+  thus the range has to be contiguous.]}
address@hidden
+
+A bottom level subaggregate of a multidimensional @nt<array_aggregate>
+of a given array type
+is allowed to be a @nt<string_literal> only if the component type of the
+array type is a character type;
+each character of such a @nt{string_literal} shall correspond to
+a @nt<defining_character_literal> of the component type.
address@hidden
+
address@hidden
+A subaggregate that is a @nt<string_literal> is equivalent
+to one that is a @nt<positional_array_aggregate> of the same length,
+with each @nt<expression> being the @nt<character_literal>
+for the corresponding character of the @nt<string_literal>.
address@hidden
+
address@hidden
address@hidden@PDefn2{Term=[evaluation], Sec=(array_aggregate)}
+The evaluation of an @nt{array_aggregate} of a given array type
+proceeds in two steps:
address@hidden(enumerate)
+  Any @nt{discrete_choice}s of this aggregate and of its subaggregates
+  are evaluated in an arbitrary order, and converted to the corresponding
+  index type;@PDefn2{Term=[arbitrary order],Sec=[allowed]}
+  @PDefn2{Term=[implicit subtype conversion],Sec=(choices of aggregate)}
+
+  The array component expressions of the aggregate
+  are evaluated in an arbitrary order and
+  their values are converted to the component subtype of
+  the array type; an array component expression
+  is evaluated once for each associated component.
+  @PDefn2{Term=[implicit subtype conversion],Sec=(expressions of aggregate)}
+  @PDefn2{Term=[arbitrary order],Sec=[allowed]}
address@hidden(enumerate)
address@hidden(Ramification)
+  Subaggregates are not separately evaluated.
+  The conversion of the value of the component expressions
+  to the component subtype might raise Constraint_Error.
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,Text=[We don't need to say that <> is
+  evaluated once for each component, as <> means that each component
+  is @i{initialized by default}. That means that the actions defined
+  for default initialization are applied to each component individually.
+  Initializing one component by default and copying
+  that to the others would be an incorrect implementation in general
+  (although it might be OK if the default initialization is known
+  to be constant).]}
address@hidden(Ramification)
+
address@hidden,Kind=[Added],ARef=[AI95-00287-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0084-1]}
address@hidden,Text=[Each @nt<expression> in an
address@hidden<array_component_association> defines the value for the associated
+component(s). For an @nt<array_component_association> with <>, the associated
+component(s) are initialized @Chg{Version=[4],New=[to the 
Default_Component_Value
+of the array type if this aspect has been specified for the array type;
+otherwise, they are initialized ],Old=[]}by default
+as for a stand-alone object of the
+component subtype (see @RefSecNum{Object Declarations}).]}
+
address@hidden@Defn2{Term=[bounds],
+  Sec=(of the index range of an @nt{array_aggregate})}
+The bounds of the index range of an @nt{array_aggregate} @Redundant[(including
+a subaggregate)]
+are determined as follows:
address@hidden(itemize)
+  For an @nt{array_aggregate} with an @key(others) choice, the bounds are
+  those of the corresponding index range from the applicable
+  index constraint;
+
+  For a @nt{positional_array_aggregate} @Redundant[(or equivalent
+  @nt<string_literal>)]
+  without an @key(others)
+  choice, the lower bound is that of the corresponding index range in the
+  applicable index constraint, if defined, or that of the corresponding
+  index subtype, if not; in either case, the upper bound is
+  determined from the lower bound and the number of @nt<expression>s
+  @Redundant[(or the length of the @nt<string_literal>)];
+
+  For a @nt{named_array_aggregate} without an @key(others) choice,
+  the bounds are determined by the smallest and largest index values
+  covered by any @nt{discrete_choice_list}.
address@hidden
+  We don't need to say that each index value has to be covered exactly
+  once, since that is a ramification of the general rule
+  on @nt{aggregate}s that each component's value has to be specified
+  exactly once.
address@hidden
address@hidden(itemize)
+
address@hidden
+For an @nt<array_aggregate>, a check is made
+that the index range defined by its bounds
+is compatible with the corresponding index subtype.
address@hidden
+In RM83, this was
+phrased more explicitly, but once we define "compatibility"
+between a range and a subtype, it seems to make sense to
+take advantage of that definition.
address@hidden
address@hidden(Ramification)
+  The definition of compatibility handles the special case
+  of a null range, which is always compatible with
+  a subtype. See AI83-00313.
address@hidden(Ramification)
+
address@hidden,Kind=[Revised],ARef=[AI05-0037-1]}
address@hidden
+For an @nt{array_aggregate} with an @key(others) choice,
+a check is made that no @nt<expression>@Chg{Version=[3],New=[ or <>],Old=[]}
+is specified for an index value outside the bounds determined by the
+applicable index constraint.
address@hidden
+RM83 omitted this case,
+apparently through an oversight. AI83-00309 defines this
+as a dynamic check, even though other Ada 83 rules ensured
+that this check could be performed statically. We now allow
+an @key(others) choice to be dynamic, even if
+it is not the only choice, so this check now needs to be
+dynamic, in some cases. Also, within a generic unit,
+this would be a nonstatic check in some cases.
address@hidden
+
address@hidden
+For a multidimensional @nt{array_aggregate}, a check is made
+that all subaggregates that correspond to the same index have the same bounds.
address@hidden
+  No array bounds @lquotes@;address@hidden@; is performed on subaggregates.
address@hidden
address@hidden
+  If sliding were performed, it would not be obvious which
+  subaggregate would determine the bounds of the corresponding index.
address@hidden
+
address@hidden,Sec=(raised by failure of run-time check)}
+The exception Constraint_Error is raised if any of the above
+checks fail.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0004-1]}
+In an @nt<array_aggregate>, positional notation may only be used
+with two or more @nt<expression>s; a single @nt<expression>
+in parentheses is interpreted as a
address@hidden,New=[parenthesized expression],address@hidden
+A @nt<named_array_aggregate>, such as (1 => X), may be used to specify
+an array with a single component.
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of array aggregates with positional 
associations:)
address@hidden
+(7, 9, 5, 1, 3, 2, 4, 8, 6, 0)
+Table'(5, 8, 4, 1, @key(others) => 0)  address@hidden  see @RefSecNum{Array 
Types} ]
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of array aggregates with named 
associations:)
address@hidden
address@hidden
+(1 .. 5 => (1 .. 8 => 0.0))      address@hidden  two-dimensional]
+(1 .. N => @key(new) Cell)             address@hidden  N new cells, in 
particular for N = 0]
+
+Table'(2 | 4 | 10 => 1, @key(others) => 0)
+Schedule'(Mon .. Fri => True,  @key(others) => False)  address@hidden  see 
@RefSecNum{Array Types}]
+Schedule'(Wed | Sun  => False, @key(others) => True)
+Vector'(1 => 2.5)                                address@hidden  
single-component vector]
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of two-dimensional array aggregates:)
address@hidden
address@hidden
address@hidden Three aggregates for the same value of subtype Matrix(1..2,1..3) 
(see @RefSecNum{Array Types}):]
+
+((1.1, 1.2, 1.3), (2.1, 2.2, 2.3))
+(1 => (1.1, 1.2, 1.3), 2 => (2.1, 2.2, 2.3))
+(1 => (1 => 1.1, 2 => 1.2, 3 => 1.3), 2 => (1 => 2.1, 2 => 2.2, 3 => 2.3))
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of aggregates as initial values:)
address@hidden
address@hidden
+A : Table := (7, 9, 5, 1, 3, 2, 4, 8, 6, 0);        address@hidden A(1)=7, 
A(10)=0]
+B : Table := (2 | 4 | 10 => 1, @key(others) => 0);        address@hidden 
B(1)=0, B(10)=1]
+C : @key(constant) Matrix := (1 .. 5 => (1 .. 8 => 0.0)); address@hidden 
C'Last(1)=5, C'Last(2)=8]
+
+D : Bit_Vector(M .. N) := (M .. N => True);         address@hidden see 
@RefSecNum{Array Types}]
+E : Bit_Vector(M .. N) := (@key(others) => True);
+F : String(1 .. 1) := (1 => 'F');  address@hidden a one component aggregate: 
same as "F"]
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,Type=[Leading],KeepNext=[T],address@hidden of an array
+aggregate with defaulted others choice and with an applicable index constraint
+provided by an enclosing record aggregate:}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Buffer'(Size => 50, Pos => 1, Value => String'('x', 
@key(others) => <>))  address@hidden see @RefSecNum{Discriminants}]]}
address@hidden
address@hidden
+
address@hidden
address@hidden,address@hidden AI-00016}
address@hidden,Type=[Leading],address@hidden with Ada 83}
+In Ada 95, no applicable index constraint is defined for a parameter
+in a call to a generic formal subprogram; thus, some aggregates that are
+legal in Ada 83 are illegal in Ada 95. For example:]}
address@hidden
address@hidden,address@hidden AI-00016}
address@hidden@key[subtype] S3 @key[is] String (1 .. 3);
+...
address@hidden
+   @key[with function] F (The_S3 : @key[in] S3) @key[return] Integer;
address@hidden Gp @key[is]
+   I : constant Integer := F ((1 => '!', others => '?'));
+       -- @RI{The aggregate is legal in Ada 83, illegal in Ada 95.}
address@hidden Gp;],Old=[]}
address@hidden
address@hidden,address@hidden AI-00016}
address@hidden change eliminates generic contract model problems.],Old=[]}
address@hidden
+
address@hidden
address@hidden to Ada 83}
+We now allow "named with others" aggregates in all contexts
+where there is an applicable index constraint, effectively
+eliminating what was RM83-4.3.2(6). Sliding never occurs
+on an aggregate with others, because its bounds come from
+the applicable index constraint, and therefore already match
+the bounds of the target.
+
+The legality of an @key(others) choice is no longer affected
+by the staticness of the applicable index constraint.
+This substantially simplifies several rules, while being slightly
+more flexible for the user. It obviates the rulings
+of AI83-00244 and AI83-00310, while taking advantage of the dynamic nature
+of the "extra values" check required by AI83-00309.
+
+Named array aggregates are permitted even if the
+index type is descended from a formal scalar type.
+See @RefSecNum(Static Expressions and Static Subtypes) and AI83-00190.
address@hidden
+
address@hidden
+We now separate named and positional array aggregate syntax,
+since, unlike other aggregates, named and positional
+associations cannot be mixed in array aggregates (except
+that an @key(others) choice is allowed in a positional array aggregate).
+
+We have also reorganized the presentation to handle
+multidimensional and one-dimensional aggregates more uniformly,
+and to incorporate the rulings of AI83-00019, AI83-00309, etc.
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}<> can be used in
+  place of an @nt{expression} in an @nt{array_aggregate}, default-initializing
+  the component.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],Text=[Limited @nt{array_aggregate}s are allowed (since
+  all kinds of aggregates can now be limited, see @RefSecNum{Aggregates}).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],Text=[Fixed @nt{aggregate}s to use the subtype of
+  the return object of a function, rather than the result subtype, because
+  they can be different for an @nt{extended_return_statement}, and we want
+  to use the subtype that's explicitly in the code at the point of the
+  @nt{expression}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0037-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Fixed so the check
+  for components outside of the array applies to both @nt<expression>s and
+  <>s. As <> was a new feature in Ada 2005, there should be little existing
+  code that depends on a <> component that is specified outside of the array
+  (and that is nonsense anyway, that a compiler is likely to detect even
+  without an explicit language rule disallowing it).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0147-1]}
+  @ChgAdded{Version=[3],Text=[Added a definition of the applicable index
+  constraint for @nt{conditional_expression}s (which are new).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0084-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Fixed so that the Default_Component_Value (if any) is used to initialize
+  components specified with <>. This is what users would expect, and all
+  Ada 2012 implementation known at the time of this writing initialize with
+  the Default_Component_Value, so it is unlikely that anyone will be affected
+  by this inconsistency.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0157-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:>
+  Added expression functions to the contexts that provide an applicable
+  index constraint, because expression functions are handled separately in
+  static semantics and legality rules.]}
address@hidden
+
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0147-1],ARef=[AI05-0158-1],ARef=[AI05-0176-1]}
address@hidden
+An @i(expression) is a formula that defines the computation or retrieval
+of a value.
+In this International Standard, the term @lquotes@;address@hidden@; refers to 
a construct
+of the syntactic category @nt<expression> or of any of the
address@hidden,New=[following categories: @nt{choice_expression}, 
@nt{choice_relation},
address@hidden, @nt{simple_expression}, @nt{term}, @nt{factor}, @nt{primary},
address@hidden, @nt{quantified_expression}],Old=[other five syntactic 
categories defined
+below]}.
address@hidden address@hidden,Sec=(and)}
address@hidden address@hidden,Sec=(or)}
address@hidden address@hidden,Sec=(xor)}
address@hidden then (short-circuit control form)}
address@hidden else (short-circuit control form)}
address@hidden address@hidden,Sec=(=)}
address@hidden address@hidden,Sec=(equal)}
address@hidden/= address@hidden,Sec=(/=)}
address@hidden equal address@hidden,Sec=(not equal)}
address@hidden< address@hidden,Sec=(<)}
address@hidden than address@hidden,Sec=(less than)}
address@hidden<= address@hidden,Sec=(<=)}
address@hidden than or equal address@hidden,Sec=(less than or equal)}
address@hidden> address@hidden,Sec=(>)}
address@hidden than address@hidden,Sec=(greater than)}
address@hidden>= address@hidden,Sec=(>=)}
address@hidden than or equal address@hidden,Sec=(greater than or equal)}
address@hidden (membership test)}
address@hidden in (membership test)}
address@hidden address@hidden,Sec=(+)}
address@hidden address@hidden,Sec=(plus)}
address@hidden address@hidden,Sec=(-)}
address@hidden address@hidden,Sec=(minus)}
address@hidden& address@hidden,Sec=(&)}
address@hidden address@hidden,Sec=(ampersand)}
address@hidden address@hidden,Sec=(concatenation)}
address@hidden operator],See=(concatenation operator)}
address@hidden address@hidden,Sec=(*)}
address@hidden address@hidden,Sec=(multiply)}
address@hidden address@hidden,Sec=(times)}
address@hidden/ address@hidden,Sec=(/)}
address@hidden address@hidden,Sec=(divide)}
address@hidden address@hidden,Sec=(mod)}
address@hidden address@hidden,Sec=(rem)}
address@hidden address@hidden,Sec=(**)}
address@hidden address@hidden,Sec=(exponentiation)}
address@hidden address@hidden,Sec=(abs)}
address@hidden value}
address@hidden address@hidden,Sec=(not)}
address@hidden
+
address@hidden
address@hidden, lhs=<expression>,rhs="
+     @Syn2{relation} address@hidden @Syn2{relation}} @\| @Syn2{relation} 
address@hidden @key{then} @Syn2{relation}}
+   | @Syn2{relation} address@hidden @Syn2{relation}} @\| @Syn2{relation} 
address@hidden @key{else} @Syn2{relation}}
+   | @Syn2{relation} address@hidden @Syn2{relation}}"}
+
address@hidden,Kind=[Added],ARef=[AI05-0158-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<choice_expression>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<
+     @Syn2[choice_relation] address@hidden @Syn2[choice_relation]}
+   | @Syn2[choice_relation] address@hidden @Syn2[choice_relation]}
+   | @Syn2[choice_relation] address@hidden @Syn2[choice_relation]}
+   | @Syn2[choice_relation] address@hidden then] @Syn2[choice_relation]}
+   | @Syn2[choice_relation] address@hidden else] 
@Syn2[choice_relation]}>,Old=<>}"}
+
address@hidden,Kind=[Added],ARef=[AI05-0158-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<choice_relation>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<
+     @Syn2{simple_expression} address@hidden 
@Syn2{simple_expression}]>,Old=<>}"}
+
address@hidden,Kind=[Revised],ARef=[AI05-0158-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0022-1],ARef=[AI12-0039-1]}
address@hidden<relation>,rhs="
+     @Syn2{simple_expression} address@hidden @Syn2{simple_expression}]
+   | @Chg{Version=[4],address@hidden@Syn2{simple_expression}],address@hidden 
address@hidden @key{in} @Chg{Version=[3],address@hidden@Chg{Version=[4],New=[
+   | @Syn2{raise_expression}],Old=[]}],Old="@Syn2{range}
+   | @Syn2{simple_expression} address@hidden @key{in} @Syn2{subtype_mark}"}"}
+
address@hidden,Kind=[Added],ARef=[AI05-0158-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<membership_choice_list>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<@Syn2{membership_choice} {| 
@Syn2{membership_choice}}>,Old=<>}"}
+
address@hidden,Kind=[Added],ARef=[AI05-0158-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0039-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<membership_choice>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<@Chg{Version=[4],New=<@address@hidden>,Old=<@Syn2{choice_expression}>}
 | @Syn2{range} | @Syn2{subtype_mark}>,Old=<>}"}
+
address@hidden<simple_expression>,rhs="address@hidden @Syn2{term} 
address@hidden @Syn2{term}}"}
+
+
address@hidden<term>,rhs="@Syn2{factor} address@hidden @Syn2{factor}}"}
+
+
address@hidden<factor>,rhs="@Syn2{primary} [** @Syn2{primary}] | @key{abs} 
@Syn2{primary} | @key{not} @Syn2{primary}"}
+
address@hidden,Kind=[Revised],ARef=[AI05-0003-1],ARef=[AI05-0147-1],ARef=[AI05-0176-1]}
address@hidden<primary>,rhs="
+   @Syn2{numeric_literal} | @key{null} | @Syn2{string_literal} | 
@Syn2{aggregate}
+ | @Syn2{name} | @Chg{Version=[3],New=[],address@hidden | address@hidden | 
(@Syn2{expression})@Chg{Version=[3],New=[
+ | (@Syn2{conditional_expression}) | (@Syn2{quantified_expression})],Old=[]}"}
address@hidden
+
address@hidden
+A @nt<name> used as a @nt<primary> shall resolve to denote an object
+or a value.
address@hidden
+This replaces RM83-4.4(3). We don't need to mention named numbers
+explicitly, because the name of a named number denotes a value.
+We don't need to mention attributes explicitly, because
+attributes now denote (rather than yield) values in general.
+Also, the new wording allows attributes that denote objects,
+which should always have been allowed (in case the implementation chose to
+have such a thing).
address@hidden
address@hidden
+  It might seem odd that this is an overload resolution rule,
+  but it is relevant during overload resolution. For example,
+  it helps ensure that a @nt<primary> that consists of only
+  the identifier of a parameterless function is interpreted as a
+  @nt<function_call> rather than directly as a @nt<direct_name>.
address@hidden
address@hidden
+
address@hidden
+Each expression has a type; it specifies the
+computation or retrieval of a value of that type.
address@hidden
+
address@hidden
address@hidden, Sec=(primary that is a name)}
+The value of a @nt<primary> that is a @nt{name} denoting an object
+is the value of the object.
address@hidden
+
address@hidden
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+For the evaluation of
+a @nt<primary> that is a @nt<name> denoting an object of an
+unconstrained numeric subtype,
+if the value of the object is outside the base range of its type,
+the implementation may either raise Constraint_Error
+or return the value of the object.
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  This means that if extra-range intermediates are used to
+  hold the value of an object of an unconstrained numeric subtype,
+  a Constraint_Error can be raised on a read of the object, rather than
+  only on an assignment to it. Similarly, it means that
+  computing the value of an object of such a subtype
+  can be deferred until the first read of the object
+  (presuming no side effects other than failing an Overflow_Check
+  are possible). This permission is over and above that provided
+  by @Chg{Version=[3],New=[subclause],Old=[clause]}
+  @RefSecNum(Exceptions and Optimization), since
+  this allows the Constraint_Error to move to a different handler.
address@hidden
address@hidden
+  This permission is intended to allow extra-range registers
+  to be used efficiently to hold parameters and local variables,
+  even if they might need to be transferred into smaller registers
+  for performing certain predefined operations.
address@hidden
address@hidden
+  There is no need to mention other kinds of @nt<primary>s, since any
+  Constraint_Error to be raised can be @lquotes@;address@hidden@; to the 
evaluation
+  of the particular kind of @nt<primary>.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of primaries:)
address@hidden
address@hidden@;4.0                address@hidden  real literal]
+Pi                 address@hidden  named number]
+(1 .. 10 => 0)     address@hidden  array aggregate]
+Sum                address@hidden  variable]
+Integer'Last       address@hidden  attribute]
+Sine(X)            address@hidden  function call]
+Color'(Blue)       address@hidden  qualified expression]
+Real(M*N)          address@hidden  conversion]
+(Line_Count + 10)  address@hidden  parenthesized expression ]
address@hidden
+
address@hidden@address@hidden(Examples of expressions:)
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
+Volume                      address@hidden primary]
address@hidden(not) Destroyed               address@hidden factor]
+2*Line_Count                address@hidden term]
+-4.0                        address@hidden simple expression]
+-4.0 + A                    address@hidden simple expression]
+B**2 - 4.0*A*C              address@hidden simple address@hidden,New=[
+R*Sin(@unicode<952>)*Cos(@unicode<966>)             address@hidden simple 
expression]],Old=[]}
+Password(1 .. 3) = "Bwv"    address@hidden relation]
+Count @key(in) Small_Int          address@hidden relation]
+Count @key(not) @key(in) Small_Int      address@hidden relation]
+Index = 0 @key(or) Item_Hit       address@hidden expression]
+(Cold @key(and) Sunny) @key(or) Warm    address@hidden expression (parentheses 
are required)]
+A**(B**C)                   address@hidden expression (parentheses are 
required)]
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+In Ada 83, @key{out} parameters and their nondiscriminant
+subcomponents are not allowed as @ntf{primaries}.
+These restrictions are eliminated in Ada 95.
+
+In various contexts throughout the language where Ada 83 syntax rules
+had @nt<simple_expression>, the corresponding Ada 95 syntax
+rule has @nt<expression> instead. This reflects the inclusion
+of modular integer types, which makes the logical operators
+"@key[and]", "@key[or]", and "@key[xor]" more useful in expressions of
+an integer type.
+Requiring parentheses to use these operators in such contexts
+seemed unnecessary and potentially confusing.
+Note that the bounds of a @nt<range> still have to be
+specified by @nt<simple_expression>s, since otherwise @nt<expression>s
+involving membership tests might be ambiguous.
+Essentially, the operation ".." is of higher precedence than the
+logical operators, and hence uses of logical operators
+still have to be parenthesized when used in a bound of a range.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0003-1]}
+  @ChgAdded{Version=[3],Text=[Moved @nt{qualified_expression}
+  from @nt{primary} to @nt{name} (see @RefSecNum{Names}). This allows the
+  use of @nt{qualified_expression}s in more places.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0147-1],ARef=[AI05-0176-1]}
+  @ChgAdded{Version=[3],Text=[Added @nt{conditional_expression} and
+  @nt{quantified_expression} to @nt{primary}.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0158-1]}
+  @ChgAdded{Version=[3],Text=[Expanded membership test syntax (see
+  @RefSecNum{Relational Operators and Membership Tests}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0039-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Revised membership syntax to eliminate ambiguities. In some cases,
+  previously ambiguous membership expressions will now have an unambiguous
+  meaning. If an Ada 2012 implementation chose the "wrong" meaning, the
+  expression could silently change meaning. Virtually all such expressions
+  will become illegal because of type mismatches (and thus be incompatible,
+  not inconsistent). However, if the choices
+  are all of a Boolean type, resolution might succeed. For instance, @exam{A
+  @key[in] B | C @key[and] D} now always means @exam{(A @key[in] B | C)
+  @key[and] D}, but the original Ada 2012 syntax would have allowed it to mean
+  @exam{A @key[in] B | (C @key[and] D)}. If a compiler allowed the expression
+  and interpreted it as the latter, the meaning of the expression would 
silently
+  change. We expect this to be extremely rare as membership operations on
+  Boolean types are unlikely (and this can happen only in code written for Ada
+  2012).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0039-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  The revised membership syntax will require
+  parentheses in @nt{membership_choice_list}s in some cases where the
+  Ada 2012 grammar did not require them. For instance,
+  @exam{A @key[in] B @key[in] C | D}
+  is now illegal. However, such expressions can be interpreted in multiple ways
+  (either @exam{A @key[in] (B @key[in] C) | D} or
+  @exam{A @key[in] (B @key[in] C | D)} for this example), so using such
+  expressions is likely to be dangerous (another compiler might interpret the
+  expression differently). In addition, all such expressions occur only in
+  Ada 2012 syntax; so they should be rare.]}
address@hidden
+
+
+
address@hidden and Expression Evaluation}
+
address@hidden
address@hidden@Defn{precedence of operators}
address@hidden precedence}
+The language defines the following six categories
+of operators (given in order of increasing
+precedence). The corresponding @nt<operator_symbol>s,
+and only those, can be used as @nt<designator>s in declarations
+of functions for user-defined operators. See @RefSec(Overloading of 
Operators).]
address@hidden
+
address@hidden
address@hidden, lhs=<logical_operator>,
+    rhs="@\ @key{and} | @key{or}  | @key{xor}"}
address@hidden, lhs=<relational_operator>,rhs="@\ =   | /=  | <   | <= | > | 
>="}
address@hidden, lhs=<binary_adding_operator>,rhs="@\ +   | @en   | &"}
address@hidden, lhs=<unary_adding_operator>,rhs="@\ +   | @en"}
address@hidden, lhs=<multiplying_operator>,rhs="@\ *   | /   | @key{mod} | 
@key{rem}"}
address@hidden, lhs=<highest_precedence_operator>,rhs="@\ **  | @key{abs} | 
@key{not}"}
address@hidden(Discussion)
+  Some of the above syntactic categories are not used in other
+  syntax rules. They are just used for classification.
+  The others are used for both classification and parsing.
address@hidden(Discussion)
address@hidden
+
address@hidden
+For a sequence of operators of the same precedence level, the
+operators are associated with their operands
+in textual order from left to right.
+Parentheses can be used to impose specific associations.
address@hidden
+  The left-associativity is not directly inherent in the grammar of
+  @RefSecNum{Expressions},
+  though in @RefSecNum{Method of Description and Syntax Notation}
+  the definition of the metasymbols @b({}) implies left
+  associativity. So this could be seen as redundant, depending on
+  how literally one interprets the definition of the @b({}) metasymbols.
+
+  See the Implementation Permissions below regarding flexibility
+  in reassociating operators of the same precedence.
address@hidden
+
address@hidden address@hidden,Sec=(predefined)}
+For each form of type definition, certain of the above operators are
address@hidden(predefined);
+that is, they are implicitly declared immediately after the type definition.
address@hidden address@hidden,Sec=(binary)}
address@hidden address@hidden,Sec=(unary)}
+For each such implicit operator declaration, the
+parameters are called Left and Right for @i(binary) operators;
+the single parameter is called Right for @i(unary) operators.
address@hidden expression of the form X op Y,
+where op is a binary operator,
+is equivalent to a @nt<function_call> of the form "op"(X, Y).
+An expression of the form op Y,
+where op is a unary operator,
+is equivalent to a @nt<function_call> of the form "op"(Y).
+The predefined operators and their effects are described
+in subclauses @RefSecNum(Logical Operators and Short-Circuit Control Forms)
+through @RefSecNum(Highest Precedence Operators).]
address@hidden
+
address@hidden
address@hidden@Defn2{Term=[Constraint_Error],Sec=(raised by failure of run-time 
check)}
+The predefined operations on integer types either yield the mathematically
+correct result or raise the exception Constraint_Error.
+For implementations that support the Numerics Annex,
+the predefined operations on real types yield results whose
+accuracy is defined in @RefSecNum(Numerics), or
+raise the exception Constraint_Error.
+]
address@hidden
+  Predefined operations on real types can @lquotes@;address@hidden@; give 
wrong results
+  when the Machine_Overflows attribute is false, and the
+  computation overflows.
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+The implementation of a predefined operator
+that delivers a result of an integer or fixed point type may
+raise Constraint_Error only if the result is outside
+the base range of the result type.
+
address@hidden,Sec=(raised by failure of run-time check)}
+The implementation of a predefined operator
+that delivers a result of a floating point type may raise Constraint_Error
+only if the result is outside the safe range of the
+result type.
address@hidden
+
+An exception is made for exponentiation by a negative exponent in
address@hidden Precedence Operators}.
+
address@hidden
address@hidden
+
address@hidden
+For a sequence of predefined operators of the same precedence
+level (and in the absence of parentheses imposing a specific association),
+an implementation may impose any association of the operators with
+operands so long as the result produced is
+an allowed result for the left-to-right association, but ignoring
+the potential for failure of language-defined checks in either the
+left-to-right or chosen order of association.
address@hidden
+  Note that the permission to reassociate the operands in
+  any way subject to producing a result allowed for
+  the left-to-right association is not much help
+  for most floating point operators, since reassociation may
+  introduce significantly different round-off errors, delivering
+  a result that is outside the model interval for the left-to-right
+  association. Similar problems arise for division with
+  integer or fixed point operands.
+
+  Note that this permission does not apply to user-defined
+  operators.
address@hidden
address@hidden
+
address@hidden
+The two operands of an expression of the form X op Y, where
+op is a binary operator, are evaluated in an arbitrary order,
+as for any @nt<function_call> (see @RefSecNum(Subprogram Calls)).
+
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of precedence:)
address@hidden
address@hidden(not) Sunny @key(or) Warm    address@hidden  same as (not Sunny) 
or Warm]
+X > 4.0 @key(and) Y > 0.0  address@hidden  same as (X > 4.0) and (Y > 0.0)]
+
+-4.0*A**2            address@hidden  same as @en@;(4.0 * (A**2))]
address@hidden(abs)(1 + A) + B       address@hidden  same as (abs (1 + A)) + B]
+Y**(-3)              address@hidden  parentheses are necessary]
+A / B * C            address@hidden  same as (A/B)*C]
+A + (B + C)          address@hidden  evaluate B + C before adding it to A ]
address@hidden
address@hidden
+
address@hidden
+We don't give a detailed definition of precedence, since
+it is all implicit in the syntax rules anyway.
+
+The permission to reassociate is moved here from RM83-11.6(5), so
+it is closer to the rules defining operator association.
address@hidden
+
+
address@hidden Operators and Short-circuit Control Forms}
+
address@hidden
address@hidden control form}
address@hidden then (short-circuit control form)}
address@hidden else (short-circuit control form)}
+An @nt<expression> consisting of two @nt<relation>s
+connected by @key(and then) or @key(or else)
+(a @i(short-circuit control form))
+shall resolve to be of some boolean type;
address@hidden type],Sec=(short-circuit control form relation)}
+the expected type for both @nt<relation>s
+is that same boolean type.
address@hidden(Reason)
+  This rule is written this way so that overload resolution treats
+  the two operands symmetrically; the resolution of overloading
+  present in either one can benefit from the resolution of the other.
+  Furthermore, the type expected by context can help.
address@hidden(Reason)
address@hidden
+
address@hidden
address@hidden@Defn{logical address@hidden,Sec=(logical)}
address@hidden address@hidden,Sec=(and)}
address@hidden address@hidden,Sec=(or)}
address@hidden address@hidden,Sec=(xor)}
+The following logical operators are predefined for every
+boolean type @i(T),
+for every modular type @i(T), and
+for every one-dimensional array type @i(T) whose
+component type is a boolean type:
address@hidden string],See=(logical operators on boolean arrays)}
address@hidden
address@hidden()
address@hidden "@key(and)"(Left, Right : @RI(T)) @key[return] @RI(T)
address@hidden "@key(or)" (Left, Right : @RI(T)) @key[return] @RI(T)
address@hidden "@key(xor)"(Left, Right : @RI(T)) @key[return] @RI(T)
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Deleted],ARef=[AI95-00145-01]}
+  @ChgDeleted{Version=[2],Text=[For predefined operators, the parameter
+  and result subtypes shown as @i(T) are actually the unconstrained
+  subtype of the type.]}
+  @ChgNote{Sorry, Bob, but there is no "honesty" issue here. And
+  "unconstrained" is wrong.}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00145-01]}
+  @ChgAdded{Version=[2],Text=[For these operators, we are talking about
+  the type without any (interesting) subtype, and not some subtype with a
+  constraint or exclusion. Since it's possible that there is no name for
+  the @lquotes@;address@hidden subtype, we denote the type
+  with an italicized @i(T).
+  This applies to the italicized @i(T) in many other predefined operators and
+  attributes as address@hidden,Sec=[italicized]}]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00145-01]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[In many cases, there is a subtype
+  with the correct properties available. The italicized @i(T) means:]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],address@hidden(T)'Base, for scalars;]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[the first subtype of @i(T), for tagged types;]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[a subtype of the type @i(T) without any
+  constraint or null exclusion, in other cases.]}
address@hidden
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Note that @lquotes@;without a address@hidden
+  is not the same as unconstrained. For instance, a record type with no
+  discriminant part is considered constrained; no subtype of it has a
+  constraint, but the subtype is still constrained.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Thus, the last case often is the same as
+  the first subtype of @i(T), but that isn't the case for constrained array
+  types (where the correct subtype is unconstrained) and for access types
+  with a @nt{null_exclusion} (where the correct subtype does not
+  exclude null).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This italicized @i(T) is used for defining
+  operators and attributes of the language. The meaning is intended to be
+  as described here.]}
address@hidden
+
+For boolean types, the predefined logical operators
address@hidden, @key{or}, and @key{xor}
+perform the conventional operations of conjunction, inclusive
+disjunction, and exclusive disjunction, respectively.
+
+For modular types, the predefined logical operators
+are defined on a bit-by-bit basis, using the binary
+representation of the value of the operands to
+yield a binary representation for the result,
+where zero represents False and one represents True.
+If this result is outside the base range of the type,
+a final subtraction by the modulus is performed to bring the
+result into the base range of the type.
+
+The logical operators on arrays are performed on a
+component-by-component basis on
+matching components (as for equality @em
+see @RefSecNum{Relational Operators and Membership Tests}),
+using the predefined logical operator for the component type. The bounds of
+the resulting array are those of the left operand.
+
address@hidden
+
address@hidden
address@hidden, Sec=(short-circuit control form)}
+The short-circuit control forms @key{and then} and @key{or else}
+deliver the same result as the corresponding predefined @key{and} and @key{or}
+operators for boolean types, except that the left operand is always
+evaluated first, and the right operand is not evaluated if the
+value of the left operand determines the result.
+
address@hidden
+For the logical operators on arrays,
+a check is made that
+for each component of the left operand there is a matching component of the
+right operand, and vice versa.
address@hidden
+Also, a check is made that each component
+of the result belongs to the component subtype.
address@hidden,Sec=(raised by failure of run-time check)}
+The exception Constraint_Error is raised if
+either of the above checks fails.
address@hidden
+  The check against the component subtype is per AI83-00535.
address@hidden
+
address@hidden
+
address@hidden
address@hidden@;The conventional meaning of the logical operators is given by 
the
+following truth table:
address@hidden(Display)
address@hidden()
address@hidden(P4, P20, P36, P52, P68)
address@hidden@ @ address@hidden@ @ address@hidden(A @key(and) B)@\(A @key(or) 
B)@\(A @key(xor) B)@*
address@hidden  @\True  @\True  @\True  @\False
address@hidden  @\False @\False @\True  @\True
address@hidden @\True  @\False @\True  @\True
address@hidden @\False @\False @\False @\False
address@hidden(Display)
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of logical operators:)
address@hidden
+Sunny @key(or) Warm
+Filter(1 .. 10) @key(and) Filter(15 .. 24)   address@hidden   see 
@RefSecNum{Index Constraints and Discrete Ranges} ]
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of short-circuit control forms:)
address@hidden
address@hidden
+Next_Car.Owner /= @key(null) @key(and) @key(then) Next_Car.Owner.Age > 25   
address@hidden   see @RefSecNum{Incomplete Type Declarations}]
+N = 0 @key(or) @key(else) A(N) = Hit_Value
address@hidden
address@hidden
+
+
address@hidden Operators and Membership Tests}
+
address@hidden
address@hidden@Defn{relational address@hidden,Sec=(relational)}
address@hidden operator],See=(relational operator)}
address@hidden address@hidden,Sec=(equality)}
+The @i(equality operators)
+= (equals) and /= (not equals) are predefined for nonlimited types.
address@hidden address@hidden,Sec=(ordering)}
+The other @nt<relational_operator>s are the @i(ordering operators)
+< (less than), <= (less than or
+equal), > (greater than), and >= (greater than or equal).
address@hidden address@hidden,Sec=(=)}
address@hidden address@hidden,Sec=(equal)}
address@hidden/= address@hidden,Sec=(/=)}
address@hidden equal address@hidden,Sec=(not equal)}
address@hidden< address@hidden,Sec=(<)}
address@hidden than address@hidden,Sec=(less than)}
address@hidden<= address@hidden,Sec=(<=)}
address@hidden than or equal address@hidden,Sec=(less than or equal)}
address@hidden> address@hidden,Sec=(>)}
address@hidden than address@hidden,Sec=(greater than)}
address@hidden>= address@hidden,Sec=(>=)}
address@hidden than or equal address@hidden,Sec=(greater than or equal)}
address@hidden array type}
+The ordering operators are predefined for scalar
+types, and for @i(discrete array types), that is,
+one-dimensional array types whose components are of
+a discrete type.
address@hidden
+The equality operators are not defined for @i{every} nonlimited
+type @em see below for the exact rule.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0262-1],ARef=[AI05-0269-1]}
address@hidden test}
address@hidden (membership test)}
address@hidden in (membership test)}
+A @i(membership test), using @key(in) or @key(not in),
+determines whether or not a value
+belongs to @chg{Version=[3],New=[any],Old=[a]} given subtype or range,
address@hidden,New=[is equal to any given value,],Old=[or]} has a tag
+that identifies a type that is covered by a given address@hidden,New=[,
+or is convertible to and has an accessibility level appropriate for a given
+access type],Old=[]}. Membership tests are allowed for all types.]
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00251-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0158-1]}
address@hidden type],
+  Sec=(membership test simple_expression)}
address@hidden type], Sec=(of a membership test)}
+The @i(tested type) of a membership test
address@hidden,New=[],Old=[ the type of the @nt<range> or the type]}
+determined by the @Chg{Version=[3],address@hidden<membership_choice>s of the
address@hidden<membership_choice_list>. Either all @nt{membership_choice}s of 
the
address@hidden shall resolve to the same type, which is the tested
+type; or each @nt{membership_choice} shall be of an elementary type, and the
+tested type shall be covered by each of these elementary
+types.],address@hidden<subtype_mark>. If the tested type is tagged, then the
address@hidden<simple_expression> shall resolve to be of a type that
address@hidden,New=[is convertible (see @RefSecNum{Type Conversions})
+to],Old=[covers or is covered by]} the tested type; if untagged, the expected
+type for the @nt<simple_expression> is the tested type.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0158-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0039-1]}
address@hidden,Text=[If the tested type is tagged, then the
address@hidden,address@hidden@nt{simple_expression}],address@hidden
+shall resolve to be of a type that is
+convertible (see @RefSecNum{Type Conversions}) to the tested
+type; if untagged, the expected type for the
address@hidden,address@hidden@nt{simple_expression}],address@hidden
+is the tested type. The expected type of a
address@hidden,address@hidden@nt{simple_expression}],address@hidden
+in a @nt{membership_choice}, and of a @nt{simple_expression} of a @nt{range} in
+a @nt{membership_choice}, is the tested type of the membership operation.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00230-01]}
+  The part of the rule for untagged types is stated in a way
+  that ensures that operands
+  like @Chg{Version=[2],New=[a string literal],address@hidden(null)]} are still
+  legal as operands of a membership test.
+
address@hidden,Kind=[Revised],ARef=[AI95-00251-01]}
address@hidden,Kind=[Revised],ARef=[AI12-0039-1]}
+  The significance of @lquotes@;@Chg{Version=[2],New=[is convertible to],
+  Old=[covers or is covered address@hidden@; is that we allow the
+  @Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden
+  to be of any class-wide type that @Chg{Version=[2],
+  New=[could be converted to],Old=[covers]} the tested type, not just the
+  one rooted at the tested address@hidden,New=[ This includes any
+  class-wide type that covers the tested type, along with class-wide interfaces
+  in some cases.],Old=[]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0158-1]}
address@hidden,Text=[The special rule for determining the tested type for
+  elementary types is to allow numeric literals in 
@nt{membership_choice_list}s.
+  Without the rule, @exam{A @key[in] B | 1} would be illegal as B and 1 would
+  have different types (the literal having type @i<universal integer>).]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI12-0039-1]}
+For a membership test, if the
address@hidden,address@hidden@nt{simple_expression}],address@hidden
+is of a tagged class-wide type,
+then the tested type shall be (visibly) tagged.
address@hidden
+Untagged types covered by the tagged class-wide type
+  are not permitted. Such types can exist if they are
+  descendants of a private type whose full type is tagged.
+  This rule is intended to avoid confusion since such derivatives
+  don't have their @lquotes@;address@hidden@; tag, and hence are 
indistinguishable
+  from one another at run time once converted to a covering
+  class-wide type.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0158-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0039-1]}
address@hidden,Text=[If a membership test includes one or more
address@hidden,address@hidden@nt{simple_expression}s],address@hidden
+and the tested type of the membership test is limited, then the
+tested type of the membership test shall have a visible primitive equality
+operator.]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0158-1]}
address@hidden,Text=[A visible equality operator is required in order
+to avoid breaking privacy; that is, we don't want to depend on a hidden
+equality operator.]}
address@hidden
address@hidden
+
address@hidden
+The result type of a membership test is the predefined type Boolean.
+
address@hidden@;The equality operators are predefined for every specific
+type @i(T) that is not limited,
+and not an anonymous access type,
+with the following specifications:
address@hidden(example)
address@hidden(function) "=" (Left, Right : @RI(T)) @key(return) Boolean
address@hidden(function) "/="(Left, Right : @RI(T)) @key(return) Boolean
address@hidden(example)
+
address@hidden,Kind=[Added],ARef=[AI95-00230-01]}
address@hidden,Type=[Leading],Text=[The following additional equality
+operators for the
address@hidden<universal_access> type are declared in package Standard for use 
with
+anonymous access types:]}
address@hidden(example)
address@hidden,Kind=[Added]}
address@hidden,address@hidden<function> "=" (Left, Right : 
@i<universal_access>) @key<return> Boolean
address@hidden<function> "/="(Left, Right : @i<universal_access>) @key<return> 
Boolean]}
address@hidden(example)
+
address@hidden@;The ordering operators are predefined for every specific
+scalar type @i(T), and for every discrete array type
address@hidden(T), with the following specifications:
address@hidden(example)
address@hidden(function) "<" (Left, Right : @RI(T)) @key(return) Boolean
address@hidden(function) "<="(Left, Right : @RI(T)) @key(return) Boolean
address@hidden(function) ">" (Left, Right : @RI(T)) @key(return) Boolean
address@hidden(function) ">="(Left, Right : @RI(T)) @key(return) Boolean
address@hidden(example)
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00230-01],ARef=[AI95-00420-01]}
address@hidden,Type=[Leading],Text=[At least one of the operands of an equality
+operator for @i<universal_access> shall be of a specific anonymous access type.
+Unless the predefined equality operator is identified using an expanded name
+with @nt{prefix} denoting the package Standard, neither operand shall be of an
+access-to-object type whose designated type is @i<D> or @i<D>'Class, where
address@hidden<D> has a user-defined primitive equality operator such that:]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[its result type is Boolean;]}
+
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0020-1]}
+  @ChgAdded{Version=[2],Text=[it is declared immediately within the same
+  declaration list as @i<D>@Chg{Version=[3],New=[ or any partial or incomplete
+  view of @i<D>],Old=[]}; and]}
+
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[at least one of its operands is an
+  access parameter with designated type @i<D>.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The first sentence prevents compatibility
+  problems by ensuring that these operators are not used for named access
+  types. Also, universal access types do not count for the purposes of this
+  rule. Otherwise, equality expressions like (X = @key{null}) would be
+  ambiguous for normal access types.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The rest of the rule makes it possible to
+  call (including a dispatching call) user-defined "=" operators for anonymous
+  access-to-object types (they'd be hidden
+  otherwise), and to write user-defined "=" operations for anonymous access
+  types (by making it possible to see the universal operator using the
+  Standard prefix).]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We don't need a similar rule for anonymous
+  access-to-subprogram types because they can't be primitive for any type.
+  Note that any nonprimitive user-defined equality operators still are hidden
+  by the universal operators; they'll have to be called with a package
+  prefix, but they are likely to be very uncommon.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00230-01]}
address@hidden,Text=[At least one of the operands of the equality
+operators for @i<universal_access> shall be of type @i<universal_access>, or
+both shall be of access-to-object types, or both shall be of
+access-to-subprogram types. Further:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[When both are of access-to-object types, the
+designated types shall be the same or one shall cover the
+other, and if the designated types are elementary or array types,
+then the designated subtypes shall statically match;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[When both are of access-to-subprogram types,
+the designated profiles shall be subtype conformant.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We don't want to allow completely arbitrary
+  comparisons, as we don't want to insist that all access types are represented
+  in ways that are convertible to one another. For instance, a compiler could
+  use completely separate address spaces or incompatible representations.
+  Instead, we allow compares if there exists an access parameter to which both
+  operands could be converted. Since the user could write such an subprogram,
+  and any reasonable meaning for "=" would allow using it in such a subprogram,
+  this doesn't impose any further restrictions on Ada implementations.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0123-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0101-1]}
address@hidden,Text=[If the profile of an explicitly declared primitive
+equality operator of an untagged record type is type conformant with that of 
the
+corresponding predefined equality operator, the declaration shall occur before
+the type is address@hidden,New=[],Old=[ In addition, if the untagged
+record type has a nonlimited partial view, then the declaration shall occur
+in the visible part of the enclosing package.]}
address@hidden contract issue}
+In addition to the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}),
+this rule applies also in the private part of an instance of a generic unit.]}
address@hidden
+
address@hidden
+For discrete types, the predefined relational operators are
+defined in terms of corresponding mathematical operations on
+the position numbers of the values of the operands.
+
+For real types, the predefined relational operators are
+defined in terms of the corresponding mathematical operations
+on the values of the operands, subject to the accuracy of the
+type.
address@hidden
+  For floating point types, the results of comparing
+  @i(nearly) equal values depends on the accuracy of
+  the implementation
+  (see @RefSec{Model of Floating Point Arithmetic}
+  for implementations that support the Numerics Annex).
address@hidden
address@hidden
+  On a machine with signed zeros,
+  if the generated code generates both plus zero and minus zero,
+  plus and minus zero must be equal
+  by the predefined equality operators.
address@hidden
+
+Two access-to-object values are equal if they designate the same
+object, or if both are equal to the null value of the access type.
+
+Two access-to-subprogram values are equal if they are the
+result of the same evaluation of an Access @nt<attribute_reference>,
+or if both
+are equal to the null value of the access type. Two
+access-to-subprogram values are unequal if they designate
+different subprograms.
address@hidden
address@hidden is unspecified whether
+two access values that designate the same subprogram but are
+the result of distinct evaluations of
+Access @nt<attribute_reference>s are equal
+or unequal.]
address@hidden
+This allows each Access @nt<attribute_reference>
+  for a subprogram to designate a distinct @lquotes@;address@hidden@; 
subprogram
+  if necessary to support an indirect call.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0123-1]}
address@hidden operator],Sec=(special inheritance rule for tagged types)}
+For a type extension, predefined equality
+is defined in terms of the primitive @Redundant[(possibly
+user-defined)] equals operator
address@hidden,New=[for],Old=[of]} the parent type and
address@hidden,New=[for],Old=[of]} any @Chg{Version=[3],New=[],Old=[tagged 
]}components
address@hidden,New=[that have a record type in],Old=[of]} the extension part, 
and
+predefined equality
+for any other components not inherited from the parent type.
address@hidden
+  Two values of a type extension are not equal if there is
+  a @nt<variant_part> in the extension part and the two
+  values have different @nt<variant>s present.
+  This is a ramification of the requirement that a
+  discriminant governing such a @nt<variant_part> has to be a 
@lquotes@;address@hidden@;
+  discriminant, and so has to be equal in the two values for
+  the values to be equal. Note that @nt<variant_part>s in
+  the parent part need not match if the primitive equals operator
+  for the parent type considers them equal.
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00349-01]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[The full type extension's 
operation
+  is used for a private extension. This follows as only full types have parent 
types;
+  the type specified in a private extension is an ancestor, but not necessarily
+  the parent type. For instance, in:]}
+  @begin(Example)
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Pak1;
address@hidden Pak2 @key{is}
+   @key{type} Typ3 @key{is} @key{new} Pak1.Typ1 @key{with} @key{private};
address@hidden
+   @key{type} Typ3 @key{is} @key{new} Pak1.Typ2 @key{with} @key{null} 
@key{record};
address@hidden Pak2;],Old=[]}
+  @end(Example)
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @Chg{Version=[2],New=[the parent type is Pak1.Typ2, not Pak1.Typ1, and the
+  equality operator of Pak1.Typ2 is used to create predefined equality for
+  Typ3.],Old=[]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0123-1]}
address@hidden,Text=[For a derived type whose parent is an untagged
+record type, predefined equality is defined in terms of the primitive (possibly
+user-defined) equals operator of the parent type.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This prevents predefined equality from
+  reemerging in generic units for untagged record types. For other uses
+  the primitive equality is inherited and the inherited routine is primitive.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0123-1]}
+For a private type, if its full type is
address@hidden,New=[a record type],Old=[tagged]}, predefined
+equality is defined in terms of the primitive equals operator of the
+full type; @Chg{Version=[3],New=[otherwise],Old=[if the full type is 
untagged]},
+predefined equality for the private type is that of its full type.
+
address@hidden@Defn{matching components}
+For other composite types, the predefined equality operators
address@hidden(and
+certain other predefined operations on composite types @em
+see @RefSecNum(Logical Operators and Short-circuit Control Forms)
+and @RefSecNum(Type Conversions))] are defined
+in terms of the corresponding operation on
address@hidden(matching components), defined as follows:
address@hidden(itemize)
+  For two composite objects or values of the same non-array type,
+  matching components are those that correspond to the
+  same @nt<component_declaration> or @nt<discriminant_specification>;
+
+  For two one-dimensional arrays of the same type, matching components are
+  those (if any) whose index values match in the following sense: the
+  lower bounds of the index ranges are defined to match, and the successors
+  of matching indices are defined to match;
+
+  For two multidimensional arrays of the same type, matching components
+  are those whose index values match in successive index positions.
address@hidden(itemize)
+
+The analogous definitions apply if the types of the two objects or values
+are convertible, rather than being the same.
address@hidden
+  Ada 83 seems to
+  omit this part of the definition, though it is used in array type
+  conversions. See @RefSecNum{Type Conversions}.
address@hidden
+
address@hidden@;Given the above definition of matching components,
+the result of the predefined equals operator for composite types (other than
+for those composite types covered earlier) is defined as follows:
address@hidden(Itemize)
+  If there are no components, the result is defined to be True;
+
+  If there are unmatched components, the result is defined to be False;
+
address@hidden,Kind=[Revised],ARef=[AI05-0123-1]}
+  Otherwise, the result is defined in terms of
+  the primitive equals operator for any
+  matching @Chg{Version=[3],New=[],Old=[tagged address@hidden,New=[ that
+  are records],Old=[]}, and
+  the predefined equals for any @Chg{Version=[3],New=[other ],Old=[]}matching
+  @Chg{Version=[3],New=[],Old=[untagged ]}components.
+  @begin{Reason}
+    @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0123-1]}
+    This asymmetry between @Chg{Version=[3],New=[],Old=[tagged and
+    untagged ]}components @Chg{Version=[3],New=[with and without a record type 
],Old=[]}is
+    necessary to preserve @Chg{Version=[3],New=[most ],Old=[]}upward 
compatibility and corresponds
+    with the corresponding situation with generics, where the
+    predefined operations @lquotes@;address@hidden@; in a generic for
+    @Chg{Version=[3],New=[non-record],Old=[untagged]} types, but do not
+    for @Chg{Version=[3],New=[record],Old=[tagged]} types. Also, only
+    tagged types support user-defined assignment
+    (see @RefSecNum{Assignment and Finalization}),
+    so only tagged types
+    can fully handle levels of indirection in the implementation
+    of the type. For untagged types, one reason for
+    a user-defined equals operator might be to allow values with different
+    bounds or discriminants to compare equal in certain cases.
+    When such values are matching components, the bounds or discriminants
+    will necessarily match anyway if the
+    discriminants of the enclosing values match.
+  @end{Reason}
address@hidden(Itemize)
address@hidden
+  Two null arrays of the same type are always equal;
+  two null records of the same type are always equal.
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0123-1]}
+  Note that if a composite object has a component
+  of a floating point type, and the floating point type
+  has both a plus and minus zero, which are considered
+  equal by the predefined equality, then a block compare
+  cannot be used for the predefined composite equality.
+  Of course, with user-defined equals operators for
+  @Chg{Version=[3],New=[],Old=[tagged address@hidden,New=[ that
+  are records],Old=[]},
+  a block compare breaks down anyway, so this is not the only
+  special case that requires component-by-component comparisons.
+  On a one's complement machine, a similar situation might
+  occur for integer types, since one's complement machines
+  typically have both a plus and minus (integer) zero.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01]}
+  @ChgAdded{Version=[2],Text=[For a component with an anonymous access type,
+  @lquotes@;predefined address@hidden@; is that defined for the
+  @i<universal_access> type (anonymous access types have no equality operators
+  of their own).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0123-1]}
+  @ChgAdded{Version=[2],Text=[For a component with a 
@Chg{Version=[3],New=[record],
+  Old=[tagged]} type @i{T},
+  @lquotes@;the primitive equals address@hidden@; is the one with two
+  parameters of @i(T) which returns Boolean. We're not talking about some
+  random other primitive function named "=".]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0123-1]}
address@hidden,Text=[If the primitive equals operator for an untagged
+record type is abstract, then Program_Error is raised at the point of any
+(implicit) call to that abstract subprogram.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[An explicit call to an abstract subprogram is
+  illegal. This rule is needed in order to define the effect of an implicit 
call
+  such as a call that is part of the predefined equality operation for an
+  enclosing composite type that has a component of an untagged record type that
+  has an abstract primitive equals operator. For tagged types, an abstract
+  primitive equals operator is only allowed for an abstract type, and abstract
+  types cannot be components, so this case does not occur.]}
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0016],ARef=[AI95-00123-01]}
address@hidden,Text=[For any composite type, the order in which "="
+is called for components is unspecified. Furthermore, if the result can be
+determined before calling "=" on some components, it is unspecified whether
+"=" is called on those address@hidden
+
+The predefined "/=" operator gives the complementary result
+to the predefined "=" operator.
address@hidden
+Furthermore,
+  if the user defines an "=" operator that returns Boolean,
+  then a "/=" operator is implicitly declared in terms of
+  the user-defined "=" operator so as to give the complementary
+  result. See @RefSecNum(Overloading of Operators).
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden order}
+For a discrete array type, the predefined ordering operators
+correspond to @i(lexicographic order) using the predefined order
+relation of the component type: A null array is lexicographically
+less than any array having at least one component.
+In the case of nonnull arrays, the left operand is lexicographically
+less than the right operand if the first component of
+the left operand is less than that of the right; address@hidden,New=[,],Old=[]}
+the left operand is lexicographically less than the right operand
+only if their first components are equal and the tail of the
+left operand is lexicographically less than that of the right (the
address@hidden(tail) consists of the remaining components beyond the first and
+can be null).
+
address@hidden,Kind=[Added],ARef=[AI05-0269-1]}
address@hidden,Text=[An @i<individual membership test> is the
+membership test of a single @address@hidden membership test}]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0158-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0039-1]}
address@hidden, Sec=(membership test)}
+For the evaluation of a membership address@hidden,New=[ using @key[in]
+whose @nt{membership_choice_list} has a single @nt{membership_choice}],Old=[]},
+the
address@hidden,address@hidden@nt{simple_expression}],address@hidden
+and the @Chg{Version=[3],address@hidden,address@hidden<range> (if any)]}
+are evaluated in an arbitrary address@hidden,New=[; the result is the
+result of the individual membership test for
+the @nt{membership_choice}],address@hidden order],Sec=[allowed]}
+
address@hidden,Kind=[Added],ARef=[AI05-0158-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0039-1]}
address@hidden,Text=[For the evaluation of a membership test using
address@hidden whose @nt{membership_choice_list} has more than one
address@hidden, the
address@hidden,address@hidden@nt{simple_expression}],address@hidden
+of the membership test is evaluated first and the
+result of the operation is equivalent to that of a sequence consisting
+of an individual membership test on each @nt{membership_choice}
+combined with the short-circuit control form @b[or else].]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0158-1]}
+  @ChgAdded{Version=[3],Text=[This equivalence includes the evaluation of the
+  @nt{membership_choice}s; evaluation stops as soon as an individual choice
+  evaluates to True.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0158-1],ARef=[AI05-0269-1]}
address@hidden@;@Chg{Version=[3],New=[An individual membership test],Old=[A
+membership test using @key(in)]} yields the result True if:
address@hidden(itemize)
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0158-1],ARef=[AI05-0264-1]}
+  @ChgRef{Version=[4],Kind=[RevisedAdded],ARef=[AI12-0039-1]}
+  @ChgAdded{Version=[3],Text=[The @nt{membership_choice} is a
+  @Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden,
+  and the
+  @Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden
+  is equal to the value of the @nt{membership_choice}.
+  If the tested type is a record type or a limited type, the test uses the
+  primitive equality for the type; otherwise, the test uses predefined 
equality.]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0153-3],ARef=[AI05-0158-1]}
+  @ChgRef{Version=[4],Kind=[RevisedAdded],ARef=[AI12-0039-1]}
+  @ChgAdded{Version=[3],Text=[The @nt{membership_choice} is a @nt{range}
+  and the value of the
+  @Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden
+  belongs to the given @nt<range>.]}
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0153-3],ARef=[AI05-0158-1]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0039-1],ARef=[AI12-0071-1]}
+  @Chg{Version=[3],New=[The @nt{membership_choice} is a @nt{subtype_mark},
+  the],Old=[The]} tested type is scalar, @Chg{Version=[3],New=[],Old=[and ]}the
+  value of the
+  @Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden
+  belongs to the
+  @Chg{Version=[3],New=[],Old=[given @nt<range>, or the ]}range of the
+  named address@hidden,New=[, and the @Chg{Version=[4],New=[value
+  satisfies the predicates],Old=[predicate]} of the named
+  address@hidden,New=[],Old=[ evaluates to address@hidden,
+  address@hidden satisfied required],Sec=[membership]}],address@hidden 
evaluated],Sec=[membership]}]}],Old=[; or]}
address@hidden
+    @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0153-3]}
+    The scalar membership test only does a range address@hidden,New=[
+    and a predicate check],Old=[]}.
+    It does not perform any other check, such as whether
+    a value falls in a @lquotes@;address@hidden@; of a 
@lquotes@;address@hidden@; enumeration type.
+    The Pos attribute function can be used for that purpose.
+
+    Even though Standard.Float is an unconstrained subtype,
+    the test @lquotes@;X in address@hidden@; will still return False
+    (presuming the evaluation of X does not raise Constraint_Error)
+    when X is outside Float'Range.
address@hidden
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00231-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0153-3],ARef=[AI05-0158-1]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0039-1],ARef=[AI12-0071-1]}
+  @ChgAdded{Version=[2],Type=[Leading],address@hidden get conditional Leading}
+  @Chg{Version=[3],New=[The @nt<membership_choice> is a
+  @nt<subtype_mark>, the],Old=[The]} tested type is not scalar, 
@Chg{Version=[3],New=[],Old=[and ]}
+  the value of the
+  @Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden
+  satisfies any constraints
+  of the named subtype, @Chg{Version=[3],New=[the @Chg{Version=[4],New=[value
+  satisfies the predicates],Old=[predicate]} of the named
+  address@hidden,New=[],Old=[ evaluates to
+  True]}, ],address@hidden,New=[:],Old=[, if the type of
+  the @nt{simple_expression} is class-wide, the value has a tag that
+  identifies a type covered by the tested type.]}
+  @begin{Inneritemize}
+    @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00231-01]}
+    @ChgRef{Version=[4],Kind=[RevisedAdded],ARef=[AI12-0039-1]}
+    @ChgAdded{Version=[2],Text=[if the type of the
+    @Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden
+    is class-wide, the value has a tag that identifies a type covered by the
+    tested type;]}
+    @begin{Ramification}
+      @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0039-1]}
+      Note that the tag is not checked if the
+      @Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden
+      is of a specific type.
+    @end{Ramification}
+    @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00231-01]}
+    @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0149-1]}
+    @ChgRef{Version=[4],Kind=[RevisedAdded],ARef=[AI12-0039-1]}
+    @ChgAdded{Version=[2],Text=[if the tested type is an access type and the
+    named subtype excludes null, the value of the
+    @Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden
+    is not address@hidden,New=[;],Old=[.]}]}
+
+    @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0149-1]}
+    @ChgRef{Version=[4],Kind=[RevisedAdded],ARef=[AI12-0039-1]}
+    @ChgAdded{Version=[3],Text=[if the tested type is a general 
access-to-object
+    type, the type of the
+    @Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden
+    is convertible to the tested
+    type and its accessibility level is no deeper than that of the tested type;
+    further, if the designated type of the tested type is tagged and the
+    @Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden
+    is nonnull, the tag of the object designated by the
+    value of the
+    @Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden
+    is covered by the designated type of the tested type.]}
+  @end{Inneritemize}
address@hidden(itemize)
+
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,New=[,],Old=[]} the test yields the result False.
+
+A membership test using @key(not in) gives the complementary result to
+the corresponding membership test using @key(in).
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0158-1]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0039-1]}
+  @ChgAdded{Version=[3],address@hidden@i<X> @key[not in] @i<A> | @i<B> | @i<C>}
+  is intended to be exactly equivalent to @address@hidden (@i<X> @key[in] 
@i<A> | @i<B> | @i<C>)},
+  including the order of evaluation of the
+  @Chg{Version=[4],address@hidden@nt{simple_expression}],address@hidden
+  and @nt{membership_choice}s.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0016],ARef=[AI95-00123-01]}
address@hidden,Text=[For all nonlimited types declared in
+language-defined packages, the "=" and "/=" operators of the type shall behave
+as if they were the predefined equality operators for the purposes of the
+equality of composite types and generic formal types.]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00123-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0123-1]}
address@hidden,Text=[If any language-defined types are implemented with
+a user-defined "=" operator, then either the full type must be 
@Chg{Version=[3],
+New=[a record type],Old=[tagged]}, or the compiler must
+use @lquotes@;address@hidden@; to implement equality for this type. A normal
+user-defined "=" operator for @Chg{Version=[3],New=[a non-record],Old=[an 
untagged]}
+type does @i{not} meet this requirement.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00230-01]}
address@hidden,Text=[No exception is ever raised by a membership test,
+by a predefined ordering operator, or by a predefined equality operator for an
+elementary type, but an exception can be raised by the evaluation of the
+operands. A predefined equality operator for a composite type can only raise an
+exception if the type has a tagged part whose primitive equals operator
+propagates an exception.]}
+
+If a composite type has components that depend on discriminants, two values
+of this type have matching components if and only if their
+discriminants are equal. Two nonnull arrays have matching components
+if and only if the length of each dimension is the same for both.
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of expressions involving relational 
operators and
+membership tests:)
address@hidden
+X /= Y
+
+"" < "A" @key(and) "A" < "Aa"     address@hidden  True]
+"Aa" < "B" @key(and) "A" < "A  "  address@hidden  True]
+
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
+My_Car = @key(null)               address@hidden 
@Chg{Version=[3],New=[True],Old=[true]} if My_Car has been set to null (see 
@RefSecNum{Incomplete Type Declarations})]
+My_Car = Your_Car           address@hidden 
@Chg{Version=[3],New=[True],Old=[true]} if we both share the same car]
address@hidden = address@hidden   address@hidden 
@Chg{Version=[3],New=[True],Old=[true]} if the two cars are identical]
+
address@hidden,Kind=[Revised],ARef=[AI05-0158-1]}
+N @key(not) @key(in) 1 .. 10            address@hidden range membership test]
+Today @key(in) Mon .. Fri         address@hidden range membership test]
+Today @key(in) Weekday            address@hidden subtype membership test (see 
@RefSecNum{Enumeration Types})address@hidden,New=[
+Card @key(in) Clubs | Spades      address@hidden list membership test (see 
@RefSecNum{Enumeration Types})]],Old=[]}
+Archive @key(in) Disk_Unit        address@hidden subtype membership test (see 
@RefSecNum{Variant Parts and Discrete Choices})]
address@hidden(all) @key(in) Addition'Class  address@hidden class membership 
test (see @RefSecNum{Type Extensions})]
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Membership tests can be used to test the tag of a class-wide value.
+
+Predefined equality for a composite type
+is defined in terms of the primitive equals operator
+for tagged components or the parent part.
address@hidden
+
address@hidden
+The term @lquotes@;membership address@hidden@; refers to the @nt<relation> "X 
in S" rather
+to simply the reserved word @key(in) or @key(not in).
+
+We use the term @lquotes@;equality address@hidden@; to refer to both
+the = (equals) and /= (not equals) operators.
+Ada 83 referred to = as @i(the) equality operator, and
+/= as the inequality operator. The new wording is more
+consistent with the ISO 10646 name for "=" (equals sign) and provides a
+category similar to @lquotes@;ordering address@hidden@; to refer to both
+= and /=.
+
+We have changed the term @lquotes@;address@hidden@; to 
@lquotes@;address@hidden@;.
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01],ARef=[AI95-00420-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}The @i{universal_access}
+  equality operators are new. They provide equality operations (most
+  importantly, testing against @key{null}) for anonymous access types.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],Ref=[8652/0016],ARef=[AI95-00123-01]}
address@hidden,address@hidden<Corrigendum:> Wording was added to clarify that
+the order of calls (and whether the calls are made at all) on "=" for
+components is unspecified. Also clarified that "=" must compose properly for
+language-defined types.],Old=[]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01]}
address@hidden,New=[Memberships were adjusted to allow interfaces which don't
+cover the tested type, in order to be consistent with type
+conversions.],Old=[]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0123-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  User-defined untagged record equality is now defined to compose and be used 
in
+  generics. Any code which assumes that the predefined equality reemerges
+  in generics and in predefined equals for composite types could fail.
+  However, it is much more likely that this change will fix bugs, as the
+  behavior that would be expected (the user-defined "=" is used) will be
+  true in more cases.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0123-1]}
+  @ChgAdded{Version=[3],Text=[If a composite type contains
+  a component of an untagged record type with an abstract equality operation,
+  calling "=" on the composite type will raise Program_Error, while in the
+  past a result will be returned using the predefined equality. This is
+  quite possible in ASIS programs; it will detect a bug in such programs but
+  of course the programs will need to be fixed before they will work.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0123-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  Late and hidden overriding of equality for untagged record types is now
+  prohibited. This is necessary to make composition of equality predictable.
+  It should always be possible to move the overriding to an earlier spot
+  where it will be legal.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0149-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Membership tests
+  for valid accessibility levels and tag coverage by the designated type
+  for general access types are new.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0153-3]}
+  @ChgAdded{Version=[3],Text=[Membership tests now include a predicate check.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0158-1]}
+  @ChgAdded{Version=[3],Text=[Membership tests now allow multiple choices.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0020-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Wording was added to 
clarify
+  that @i{universal_access} "=" does not apply if an appropriate operator is
+  declared for a partial or incomplete view of the designated type.
+  Otherwise, adding a partial or incomplete view could make some "=" operators
+  ambiguous.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0101-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden:}
+  Removed the incompatible rule preventing the declaration of "=" in the
+  private part of a package specification for an untagged record type that
+  completes a private type. Any code that calls the
+  predefined "=" on the private type will now execute the body for the
+  redefined "=" instead for the predefined "=". Eliminating the rule eliminates
+  an unnecessary incompatibility (especially for programs that never call the
+  predefined "="). Moreover, (like the composition of untagged record "=" in
+  Ada 2012) this is more likely to fix bugs than cause
+  them (who defines an "=" with a presumably different result and does not want
+  clients to us it?).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0039-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Reworded membership tests 
to use
+  the syntax items @address@hidden and
+  @address@hidden This was necessary to eliminate
+  wording ambiguities introduced when the grammar was corrected to eliminate
+  syntax ambiguities. (Both of the above are now @nt{simple_expression}s, so
+  merely talking about a @nt{simple_expression} is insufficient.)]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0071-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Updated wording of the
+  membership tests to use the new term "satisfies the predicates"
+  (see @RefSecNum{Subtype Predicates}).]}
address@hidden
+
+
+
address@hidden Adding Operators}
+
address@hidden
address@hidden@Defn{binary adding address@hidden,Sec=(binary adding)}
address@hidden address@hidden,Sec=(+)}
address@hidden address@hidden,Sec=(plus)}
address@hidden address@hidden,Sec=(-)}
address@hidden address@hidden,Sec=(minus)}
+The binary adding operators + (addition) and @en (subtraction) are predefined
+for every specific numeric type @i(T) with their
+conventional meaning.
+They have the following specifications:
address@hidden(example)
address@hidden(function) "+"(Left, Right : @RI(T)) @key(return) @RI(T)
address@hidden(function) "-"(Left, Right : @RI(T)) @key(return) @RI(T)
address@hidden(example)
+
address@hidden@Defn{& address@hidden,Sec=(&)}
address@hidden address@hidden,Sec=(ampersand)}
address@hidden address@hidden,Sec=(concatenation)}
address@hidden operator],See=(concatenation operator)}
+The concatenation operators & are predefined for
+every nonlimited,
+one-dimensional array type @i(T) with component type @i(C).
+They have the following specifications:
address@hidden(example)
address@hidden(function) "&"(Left : @RI(T); Right : @RI(T)) @key(return) @RI(T)
address@hidden(function) "&"(Left : @RI(T); Right : @RI(C)) @key(return) @RI(T)
address@hidden(function) "&"(Left : @RI(C); Right : @RI(T)) @key(return) @RI(T)
address@hidden(function) "&"(Left : @RI(C); Right : @RI(C)) @key(return) @RI(T)
address@hidden(example)
address@hidden
+
address@hidden
+
address@hidden@PDefn2{Term=[evaluation], Sec=(concatenation)}
+For the evaluation of a concatenation with result type @i(T),
+if both operands are of type @i(T), the result of the concatenation
+is a one-dimensional array whose length is the sum of the lengths
+of its operands, and whose components comprise the components of
+the left operand followed by the components of the right operand.
+If the left operand is a null array, the result of the
+concatenation is the right operand.
+Otherwise, the lower bound of the result is determined as
+follows:
address@hidden(Itemize)
+  If the ultimate ancestor of the array type was defined
+  by a @nt<constrained_array_definition>, then
+  the lower bound of the result is that of the index subtype;
+  @begin(Reason)
+    This rule avoids Constraint_Error when using concatenation
+    on an array type whose first subtype is constrained.
+  @end(Reason)
+
+  If the ultimate ancestor of the array type was defined
+  by an @nt<unconstrained_array_definition>, then
+  the lower bound of the result is that of the left operand.
address@hidden(Itemize)
+
address@hidden upper bound is determined by the lower bound and the length.]
address@hidden
+A check is made that the upper bound of the result of the
+concatenation belongs to the range of the index subtype, unless the
+result is a null array.
address@hidden,Sec=(raised by failure of run-time check)}
+Constraint_Error is raised if this check fails.
+
+If either operand is of the component type @i(C), the result of the
+concatenation is given by the above rules, using in place of such an operand
+an array having this operand as its only component (converted
+to the component subtype)
+and having the lower bound
+of the index subtype of the array type as its lower bound.
address@hidden subtype conversion],Sec=(operand of concatenation)}
address@hidden
+  The conversion might raise Constraint_Error.
+  The conversion provides @lquotes@;address@hidden@;
+  for the component in the case of an array-of-arrays, consistent with
+  the normal Ada 95 rules that allow sliding during parameter passing.
address@hidden
+
address@hidden operation], Sec=(during evaluation of concatenation)}
+The result of a concatenation is defined in terms of an
+assignment to an anonymous object,
+as for any function call (see @RefSecNum{Return Statements}).
address@hidden
+This implies that value adjustment is performed as appropriate
address@hidden see @RefSecNum{Assignment and Finalization}.
+We don't bother saying this for other predefined operators,
+even though they are all function calls,
+because this is the only one where it matters.
+It is the only one that can return a value having controlled parts.
address@hidden
address@hidden
+
address@hidden
+As for all predefined operators on modular types, the binary adding
+operators + and @en on modular types include a final
+reduction modulo the modulus if the result is outside
+the base range of the type.
address@hidden
+A full "modulus" operation need not be performed after
+addition or subtraction of modular types. For binary moduli,
+a simple mask is sufficient. For nonbinary moduli, a check after
+addition to see if the value is greater than the high bound of
+the base range can be followed by a conditional subtraction of the modulus.
+Conversely, a check after subtraction to see if a "borrow" was
+performed can be followed by a conditional addition of the modulus.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of expressions involving binary adding 
operators:)
address@hidden
+Z + 0.1      address@hidden  Z has to be of a real type ]
+
+"A" & "BCD"  address@hidden  concatenation of two string literals]
+'A' & "BCD"  address@hidden  concatenation of a character literal and a string 
literal]
+'A' & 'A'    address@hidden  concatenation of two character literals ]
address@hidden
address@hidden
+
address@hidden
address@hidden with Ada 83}
+The lower bound of the result of concatenation,
+for a type whose first subtype is constrained, is
+now that of the index subtype. This is inconsistent with Ada 83,
+but generally only for Ada 83 programs that raise Constraint_Error.
+For example, the concatenation operator in
address@hidden(Example)
+X : @key(array)(1..10) @key(of) Integer;
address@hidden(begin)
+X := X(6..10) & X(1..5);
address@hidden(Example)
+
+would raise Constraint_Error in Ada 83 (because
+the bounds of the result of the concatenation would be 6..15, which is outside
+of 1..10),
+but would succeed and swap the halves of X (as expected) in Ada 95.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Concatenation is now useful for array types whose
+first subtype is constrained.
+When the result type of a concatenation
+is such an array type,
+Constraint_Error is avoided by effectively
+first sliding the left operand (if nonnull) so that
+its lower bound is that of the index subtype.
address@hidden
+
address@hidden Adding Operators}
+
address@hidden
address@hidden@Defn{unary adding address@hidden,Sec=(unary adding)}
address@hidden address@hidden,Sec=(+)}
address@hidden address@hidden,Sec=(plus)}
address@hidden address@hidden,Sec=(-)}
address@hidden address@hidden,Sec=(minus)}
+The unary adding operators + (identity) and @en (negation) are predefined
+for every specific numeric type @i(T) with their
+conventional meaning.
+They have the following specifications:
address@hidden(example)
address@hidden(function) "+"(Right : @RI(T)) @key(return) @RI(T)
address@hidden(function) "-"(Right : @RI(T)) @key(return) @RI(T)
address@hidden(example)
address@hidden
+
address@hidden
+For modular integer types, the unary adding operator @en, when
+given a nonzero operand, returns the result of subtracting
+the value of the operand from the modulus;
+for a zero operand, the result is zero.
address@hidden
+
address@hidden Operators}
+
address@hidden
address@hidden@Defn{multiplying address@hidden,Sec=(multiplying)}
address@hidden address@hidden,Sec=(*)}
address@hidden address@hidden,Sec=(multiply)}
address@hidden address@hidden,Sec=(times)}
address@hidden/ address@hidden,Sec=(/)}
address@hidden address@hidden,Sec=(divide)}
address@hidden address@hidden,Sec=(mod)}
address@hidden address@hidden,Sec=(rem)}
+The multiplying operators * (multiplication), / (division),
address@hidden(mod) (modulus), and @key(rem) (remainder)
+are predefined for every specific integer type @i(T):
address@hidden(example)
address@hidden(function) "*"  (Left, Right : @RI(T)) @key(return) @RI(T)
address@hidden(function) "/"  (Left, Right : @RI(T)) @key(return) @RI(T)
address@hidden(function) "@key(mod)"(Left, Right : @RI(T)) @key(return) @RI(T)
address@hidden(function) "@key(rem)"(Left, Right : @RI(T)) @key(return) @RI(T)
address@hidden(example)
+
+Signed integer multiplication has its conventional meaning.
+
address@hidden@keepnext@;Signed integer division and remainder are defined by 
the relation:
address@hidden(example)
+A = (A/B)*B + (A @key(rem) B)
address@hidden(example)
+
address@hidden@;where (A @key(rem) B) has the sign of A and an absolute value 
less than
+the absolute value of B. Signed integer division satisfies the identity:
address@hidden(example)
+(-A)/B = -(A/B) = A/(-B)
address@hidden(example)
+
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0260-1]}
+The signed integer modulus operator is defined such
+that the result of A @key(mod) B @Chg{Version=[3],New=[is either zero,
+or ],Old=[]}has the sign of B and an absolute value less than the
+absolute value of B; in addition, for some signed integer value N, this result
+satisfies the relation:
address@hidden(example)
+A = B*N + (A @key(mod) B)
address@hidden(example)
+
+The multiplying operators on modular types are defined in terms
+of the corresponding signed integer address@hidden, followed by a reduction
+modulo the modulus if the result is outside
+the base range of the type] @Redundant[(which is only possible for the "*"
+operator)].
address@hidden
+The above identity satisfied by signed integer
+division is not satisfied by modular division
+because of the difference in effect of negation.
address@hidden
address@hidden
+
address@hidden@;Multiplication and division operators are predefined for
+every specific floating point type @i(T):
address@hidden(example)
address@hidden(function) "*"(Left, Right : @RI(T)) @key(return) @RI(T)
address@hidden(function) "/"(Left, Right : @RI(T)) @key(return) @RI(T)
address@hidden(example)
+
address@hidden@;The following multiplication and division operators, with
+an operand of the predefined type Integer, are predefined
+for every specific fixed point type @i(T):
address@hidden(example)
address@hidden(function) "*"(Left : @RI(T); Right : Integer) @key(return) @RI(T)
address@hidden(function) "*"(Left : Integer; Right : @RI(T)) @key(return) @RI(T)
address@hidden(function) "/"(Left : @RI(T); Right : Integer) @key(return) @RI(T)
address@hidden(example)
+
address@hidden@Redundant[All of the above multiplying operators
+are usable with an operand
+of an appropriate universal numeric type.] The following additional
+multiplying operators for @i(root_real) are address@hidden,
+and are usable when both operands are of an appropriate universal or
+root numeric type, and the result is allowed to be of
+type @i(root_real), as in a @nt<number_declaration>]:
address@hidden
+These operators
+are analogous to the multiplying operators
+involving fixed or floating point types
+where @i(root_real) substitutes for the
+fixed or floating point type,
+and @i(root_integer) substitutes for Integer.
+Only values of the corresponding universal numeric types are
+implicitly convertible to these root numeric types,
+so these operators are really restricted to use with
+operands of a universal type, or the specified
+root numeric types.
address@hidden
address@hidden(example)
address@hidden(function) "*"(Left, Right : @RI(root_real)) @key(return) 
@RI(root_real)
address@hidden(function) "/"(Left, Right : @RI(root_real)) @key(return) 
@RI(root_real)
+
address@hidden(function) "*"(Left : @RI(root_real); Right : @RI(root_integer)) 
@key(return) @RI(root_real)
address@hidden(function) "*"(Left : @RI(root_integer); Right : @RI(root_real)) 
@key(return) @RI(root_real)
address@hidden(function) "/"(Left : @RI(root_real); Right : @RI(root_integer)) 
@key(return) @RI(root_real)
address@hidden(example)
+
address@hidden@;Multiplication and division between any two fixed point types 
are
+provided by the following two predefined operators:
address@hidden
address@hidden(Universal_fixed) is the universal type for the class of
+fixed point types, meaning that these operators take operands
+of any fixed point types (not necessarily the same)
+and return a result that is implicitly (or explicitly) convertible to
+any fixed point type.
address@hidden
address@hidden(example)
address@hidden(function) "*"(Left, Right : @RI(universal_fixed)) @key(return) 
@RI(universal_fixed)
address@hidden(function) "/"(Left, Right : @RI(universal_fixed)) @key(return) 
@RI(universal_fixed)
address@hidden(example)
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00364-01],ARef=[AI95-00420-01]}
address@hidden,Type=[Leading],Text=[The above two fixed-fixed
+multiplying operators shall
+not be used in a context where the expected type for the result is itself
address@hidden(universal_fixed) @address@hidden the context has to identify 
some other
+numeric type to which the result is to be converted, either explicitly or
+implicitly]. Unless the predefined universal operator is identified using an
+expanded name with @nt{prefix} denoting the package Standard, an explicit
+conversion is required on the result when using the above fixed-fixed
+multiplication operator if either operand is of a type having a user-defined
+primitive multiplication operator such that:]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  
@ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0020-1],ARef=[AI05-0209-1]}
+  @ChgAdded{Version=[2],Text=[it is declared immediately within the same
+  declaration list as the address@hidden,New=[ or any partial
+  or incomplete view thereof],Old=[]}; and]}
+
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[both of its formal parameters are of a
+  fixed-point type.]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00364-01],ARef=[AI95-00420-01]}
address@hidden,Text=[A corresponding requirement applies to the
+universal fixed-fixed division operator.]}
+
address@hidden(Discussion)
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The @i(small) of @i(universal_fixed) is
+infinitesimal; no loss of precision is permitted.
+However, fixed-fixed division is impractical to implement when
+an exact result is required,
+and multiplication will sometimes result in unanticipated overflows
+in such circumstances,
+so we require an explicit conversion to be inserted in
+expressions like A * B * C if A, B, and C are each of some fixed point
+type.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[On the other hand, X := A * B; is permitted by
+this rule, even if X, A, and B
+are all of different fixed point types, since the expected type
+for the result of the multiplication is the type of X, which is necessarily
+not @i(universal_fixed).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00364-01],ARef=[AI95-00420-01]}
address@hidden,Text=[We have made these into Name Resolution rules to
+ensure that user-defined primitive fixed-fixed operators are not made unusable
+due to the presence of these universal fixed-fixed operators. But we do allow
+these operators to be used if prefixed by package Standard, so that they can be
+used in the definitions of user-defined operators.]}
address@hidden(Discussion)
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00364-01]}
address@hidden,Text=[The above two fixed-fixed multiplying operators
+shall not be used in a context where the expected type for the result
+is itself @i(universal_fixed) @em @Redundant[the context has to
+identify some other numeric type to which the result is to be converted,
+either explicitly or implicitly].]}
address@hidden(Discussion)
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[The @i(small) of @i(universal_fixed) is infinitesimal; no 
loss
+of precision is permitted.
+However, fixed-fixed division is impractical to implement when
+an exact result is required,
+and multiplication will sometimes result in unanticipated overflows
+in such circumstances,
+so we require an explicit conversion to be inserted in
+expressions like A * B * C if A, B, and C are each of some fixed point
+type.]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[On the other hand, X := A * B; is permitted by this rule, 
even if X, A, and B
+are all of different fixed point types, since the expected type
+for the result of the multiplication is the type of X, which is necessarily
+not @i(universal_fixed).]}
address@hidden(Discussion)
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraph 20 was
+deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered.}
address@hidden
+
address@hidden
+The multiplication and division operators for real types have
+their conventional meaning.
address@hidden floating point types, the accuracy of the result is
+determined by the precision of the result type.
+For decimal fixed point types, the result is truncated toward zero
+if the mathematical result is between two multiples of the @i(small)
+of the specific result type (possibly determined by context);
+for ordinary fixed point types, if the mathematical result is
+between two multiples of the @i(small), it is unspecified
+which of the two is the result.
address@hidden
+
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+The exception Constraint_Error is raised by
+integer division, @key(rem),
+and @key(mod) if the right operand is zero.
address@hidden, for a real type @i(T) with @i(T')Machine_Overflows
+True, division by zero raises Constraint_Error.]
address@hidden
+
address@hidden
address@hidden@Keepnext@;For positive A and B, A/B is the quotient and A 
@key(rem) B is
+the remainder when A is divided by B. The following relations are satisfied
+by the rem operator:
address@hidden
+     A  @key(rem) (-B) =   A @key(rem) B
+   (-A) @key(rem)   B  = -(A @key(rem) B)
address@hidden
+
address@hidden@keepnext@;For any signed integer K, the following identity holds:
address@hidden
+   A @key(mod) B   =   (A + K*B) @key(mod) B
address@hidden
address@hidden
address@hidden@Leading@;The relations between signed integer
+division, remainder, and modulus are
+illustrated by the following table:
address@hidden
+   A      B   A/B   A @key(rem) B  A @key(mod) B     A     B    A/B   A 
@key(rem) B   A @key(mod) B
+
+   10     5    2       0        0       -10    5    -2       0         0
+   11     5    2       1        1       -11    5    -2      -1         4
+   12     5    2       2        2       -12    5    -2      -2         3
+   13     5    2       3        3       -13    5    -2      -3         2
+   14     5    2       4        4       -14    5    -2      -4         1
+
+   A      B   A/B   A @key(rem) B  A @key(mod) B     A     B    A/B   A 
@key(rem) B   A @key(mod) address@hidden
+   10    -5   -2       0        0       -10   -5     2       0         0
+   11    -5   -2       1       -4       -11   -5     2      -1        -1
+   12    -5   -2       2       -3       -12   -5     2      -2        -2
+   13    -5   -2       3       -2       -13   -5     2      -3        -3
+   14    -5   -2       4       -1       -14   -5     2      -4        -4
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of expressions involving multiplying 
operators:)
address@hidden
+I : Integer := 1;
+J : Integer := 2;
+K : Integer := 3;
+
+X : Real := 1.0;                      address@hidden     see 
@RefSecNum{Floating Point Types}]
+Y : Real := 2.0;
+
+F : Fraction := 0.25;                 address@hidden     see @RefSecNum{Fixed 
Point Types}]
+G : Fraction := 0.5;
address@hidden
address@hidden
address@hidden()@tabset(P19, P31)
address@hidden(Expression)  @address@hidden(Value)  @address@hidden(Result 
Type)@*
address@hidden            @address@hidden      @address@hidden(same as I and J, 
that is, Integer)
address@hidden/J}            @address@hidden      @address@hidden(same as K and 
J, that is, Integer)
address@hidden @key(mod) J}  @address@hidden      @address@hidden(same as K and 
J, that is, Integer)@*
address@hidden/Y}            @address@hidden    @address@hidden(same as X and 
Y, that is, Real)
address@hidden/2}            @address@hidden  @address@hidden(same as F, that 
is, Fraction)@*
address@hidden            @address@hidden   @address@hidden(same as F, that is, 
Fraction)
address@hidden         @address@hidden  @address@hidden(universal_fixed, 
implicitly convertible)
+               @\       @address@hidden(to any fixed point type)
address@hidden(F*G)}  @address@hidden  @address@hidden(Fraction, as stated by 
the conversion)
address@hidden(J)*Y}      @address@hidden    @address@hidden(Real, the type of 
both operands after)
+               @\       @address@hidden(conversion of J)
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00364-01],ARef=[AI95-00420-01]}
address@hidden,address@hidden with Ada 83}The universal
+fixed-fixed multiplying operators are now directly available (see below).
+Any attempt to use user-defined fixed-fixed multiplying operators
+will be ambiguous with the universal ones. The only way to use the user-defined
+operators is to fully qualify them in a prefix call. This problem was not
+documented during the design of Ada 95, and has been mitigated by
+Ada 2005.],Old=[]}
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Explicit conversion of the result of multiplying
+or dividing two fixed point numbers is no longer required,
+provided the context uniquely determines some specific
+fixed point result type.
+This is to improve support for decimal fixed point, where
+requiring explicit conversion on every fixed-fixed multiply
+or divide was felt to be inappropriate.
+
+The type @i(universal_fixed) is covered by @i(universal_real),
+so real literals and fixed point operands may be multiplied
+or divided directly, without any explicit conversions required.
address@hidden
+
address@hidden
+We have used the normal syntax for function definition
+rather than a tabular format.
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00364-01]}
address@hidden,address@hidden with Ada 95}We have changed the
+resolution rules for the universal fixed-fixed multiplying operators to remove
+the incompatibility with Ada 83 discussed above. The solution is to hide
+the universal operators in some circumstances. As a result, some legal Ada 95
+programs will require the insertion of an explicit conversion around a
+fixed-fixed multiply operator. This change is likely to catch as many bugs as
+it causes, since it is unlikely that the user wanted to use predefined
+operators when they had defined user-defined versions.],Old=[]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0020-1],ARef=[AI05-0209-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Wording was added to 
clarify
+  that @i{universal_fixed} "*" and "/" does not apply if an appropriate
+  operator is declared for a partial (or incomplete) view of the designated 
type.
+  Otherwise, adding a partial (or incomplete) view could make some
+  "*" and "/" operators ambiguous.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0260-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> The wording for the 
@key[mod]
+  operator was corrected so that a result of 0 does not have to have
+  "the sign of B" (which is impossible if B is negative).]}
address@hidden
+
+
address@hidden Precedence Operators}
+
address@hidden
address@hidden@Defn{highest precedence address@hidden,Sec=(highest precedence)}
address@hidden address@hidden,Sec=(abs)}
address@hidden value}
+The highest precedence unary operator @key(abs) (absolute value)
+is predefined for every specific numeric type @i(T),
+with the following specification:
address@hidden(example)
address@hidden(function) "@key(abs)"(Right : @RI(T)) @key(return) @RI(T)
address@hidden(example)
+
address@hidden@Defn{not address@hidden,Sec=(not)}
address@hidden operator],See=(not operator)}
+The highest precedence unary operator @key(not) (logical negation) is
+predefined for every boolean type @i(T),
+every modular type @i(T),
+and for every one-dimensional array type @i(T) whose
+components are of a boolean type,
+with the following specification:
address@hidden(example)
address@hidden(function) "@key(not)"(Right : @RI(T)) @key(return) @RI(T)
address@hidden(example)
+
+The result of the operator @key(not) for a modular type is
+defined as the difference between the high bound of the base range
+of the type and the value of the operand. @Redundant[For
+a binary modulus, this corresponds to a bit-wise complement
+of the binary
+representation of the value
+of the operand.]
+
+The operator @key(not) that applies
+to a one-dimensional array of boolean
+components yields a one-dimensional boolean array with the same bounds;
+each component of the result is obtained by logical negation of the
+corresponding component of the operand (that is, the component that
+has the same index value).
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+A check is made that each component of the result belongs to the
+component subtype; the exception Constraint_Error is raised if this
+check fails.
address@hidden
+  The check against the component subtype is per AI83-00535.
address@hidden
+
address@hidden@Defn{exponentiation address@hidden,Sec=(exponentiation)}
address@hidden address@hidden,Sec=(**)}
+The highest precedence @i(exponentiation) operator ** is predefined
+for every specific integer type @i(T)
+with the following specification:
address@hidden(example)
address@hidden(function) "**"(Left : @RI(T); Right : Natural) @key(return) 
@RI(T)
address@hidden(example)
+
address@hidden@;Exponentiation is also predefined for
+every specific floating point type
+as well as @i{root_real},
+with the following specification (where @i(T) is @i{root_real}
+or the floating point type):
address@hidden(example)
address@hidden(function) "**"(Left : @RI(T); Right : Integer'Base) @key(return) 
@RI(T)
address@hidden(example)
+
address@hidden,Kind=[Revised],ARef=[AI05-0088-1]}
address@hidden
+The right operand of an exponentiation is the @i(exponent).
+The @Chg{Version=[3],New=[value of],Old=[expression]} X**N with the value of
+the exponent N positive is @Chg{Version=[3],New=[the same as the value of],
+Old=[equivalent to the expression]} X*X*...X (with address@hidden@;1 
multiplications)
+except that the multiplications
+are associated in an arbitrary order. With N equal to zero, the result is one.
+With the value of N negative
address@hidden(only defined for a floating point operand)],
+the result is the reciprocal of the result using the absolute value of
+N as the exponent.
address@hidden
+  The language does not specify the order of association of the multiplications
+  inherent in an exponentiation. For a floating point type,
+  the accuracy of the result might depend on the particular
+  association order chosen.
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+The implementation of
+exponentiation for the case of a negative exponent
+is allowed to raise Constraint_Error
+if the intermediate result of the repeated multiplications
+is outside the safe range of the type, even though the final
+result (after taking the reciprocal)
+would not be.
+(The best machine approximation to the
+final result in this case would generally be 0.0.)
address@hidden
+
address@hidden
address@hidden
+As implied by the specification given above
+for exponentiation of an integer type, a check is made that
+the exponent is not negative.
address@hidden,Sec=(raised by failure of run-time check)}
+Constraint_Error is raised if this check fails.
address@hidden
+
address@hidden
+  @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0100],ARef=[AI95-00018-01]}
+  @ChgAdded{Version=[1],address@hidden with Ada 83}
+  The definition of "**" allows arbitrary association of the
+  multiplications which make up the result. Ada 83 required left-to-right
+  associations (confirmed by AI83-00137). Thus it is possible that "**"
+  would provide a slightly different (and more potentially accurate) answer in
+  Ada 95 than in the same Ada 83 program.]}
address@hidden
+
address@hidden
+We now show the specification for "**" for integer types
+with a parameter subtype of Natural rather than Integer for the exponent.
+This reflects the fact that Constraint_Error is raised if
+a negative value is provided for the exponent.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0088-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> The equivalence definition
+  for "**" was corrected so that it does not imply that the operands
+  are evaluated multiple times.]}
address@hidden
+
+
address@hidden,Name=[Conditional Expressions]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0147-1],ARef=[AI05-0188-1],ARef=[AI05-0262-1]}
address@hidden,Text=[A @nt{conditional_expression} selects for evaluation
+at most one of the enclosed @SynI<dependent_>@nt{expression}s, depending on
+a decision among the alternatives. One
+kind of @nt{conditional_expression} is the @nt{if_expression}, which selects 
for
+evaluation a @SynI<dependent_>@nt{expression} depending on the value of one or 
more
+corresponding conditions. The other kind of @nt{conditional_expression} is the
address@hidden, which selects for evaluation one of a number of alternative
address@hidden<dependent_>@nt{expression}s; the chosen alternative is 
determined by the
+value of a @SynI<selecting_>@nt{expression}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0188-1]}
+  @ChgAdded{Version=[3],Text=[As previously noted, there are two kinds of
+  @nt{conditional_expression}, @nt{if_expression}s and @nt{case_expression}s.
+  Whenever possible, we have written the rules in terms of
+  @nt{conditional_expression}s to avoid duplication.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0147-1]}
+  @ChgAdded{Version=[3],Text=[The rules for @nt{conditional_expression}s
+  have been designed as much as possible to work similarly to a parenthesized
+  expression. The intent is that as much as possible, wherever a parenthesized
+  expression would be allowed, a @nt{conditional_expression} would be allowed,
+  and it should work the same way.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0188-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<conditional_expression>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<@Syn2{if_expression} | 
@Syn2{case_expression}>,Old=<>}"}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0147-1],ARef=[AI05-0188-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<if_expression>,Old=<>}>,
+rhs="
+   @Chg{Version=[3],New=<@key[if] @Syn2{condition} @key[then] @address@hidden
+   address@hidden @Syn2{condition} @key[then] @address@hidden
+   address@hidden @address@hidden>,Old=<>}"}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0147-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<condition>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<@address@hidden>,Old=<>}"}
address@hidden from "If Statements"}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0188-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<case_expression>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<
+    @key[case] @address@hidden @key[is]
+    @Syn2[case_expression_alternative] {,
+    @Syn2[case_expression_alternative]}>,Old=<>}"}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0188-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<case_expression_alternative>,Old=<>}>,
+rhs="@Chg{Version=[3],New=[
+    @key[when] @Syn2{discrete_choice_list} =>
+        @address@hidden,Old=<>}"}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0147-1]}
address@hidden,Text=[Wherever the Syntax Rules allow an @nt{expression},
+a @nt{conditional_expression} may be used in place of the @nt{expression}, so
+long as it is immediately surrounded by parentheses.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0147-1]}
+  @ChgAdded{Version=[3],Text=[The syntactic category 
@nt{conditional_expression}
+  appears only as a primary that is parenthesized. The above rule allows it to
+  additionally be used in other contexts where it would be directly surrounded
+  by parentheses.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The grammar makes the following 
directly legal:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[A := (@key[if] X @key[then] Y @key[else] Z); 
address@hidden parentheses required}
+A := B + (@key[if] X @key[then] Y @key[else] Z) + C; address@hidden 
parentheses required}]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The following procedure calls are
+  syntactically legal; the first uses the above rule to eliminate the redundant
+  parentheses found in the second:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[P(@key[if] X @key[then] Y @key[else] Z);
+P((@key[if] X @key[then] Y @key[else] Z)); address@hidden redundant 
parentheses}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[P((@key[if] X @key[then] Y @key[else] Z), 
Some_Other_Param);
+P(Some_Other_Param, (@key[if] X @key[then] Y @key[else] Z));
+P(Formal => (@key[if] X @key[then] Y @key[else] Z));]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[whereas the following are 
illegal:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[P(@key[if] X @key[then] Y @key[else] Z, Some_Other_Param);
+P(Some_Other_Param, @key[if] X @key[then] Y @key[else] Z);
+P(Formal => @key[if] X @key[then] Y @key[else] Z);]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[because in these latter cases, the
+  @nt{conditional_expression} is not immediately surrounded by parentheses 
(which
+  means on both sides!).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The English-language rule applies in all places
+  that could surround an expression with parentheses, including pragma
+  arguments, type conversion and qualified expression operands, and array index
+  expressions.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This English-language rule could have been
+  implemented instead by adding a nonterminal
+  @ntf{expression_within_parentheses}, which would consist of @nt{expression}s
+  and @nt{conditional_expression}s. Then, that could be used in all of the
+  syntax which could consist of parens directly around an @nt{expression}. We
+  did not do that because of the large amount of change required. A complete
+  grammar is given in @AILink{AI=[AI05-0147-1],Text=[AI05-0147-1]}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0147-1]}
+  @ChgAdded{Version=[3],Text=[Implementers are cautioned to consider error
+  detection when implementing the syntax for @nt{conditional_expression}s. An
+  @nt{if_expression} and an @nt{if_statement} are very similar syntactically, 
(as
+  are a @nt{case_expression} and a @nt{case_statement}) and simple mistakes can
+  appear to change one into the other, potentially causing errors to be moved
+  far away from their actual location. The absence of @key[end if] to terminate
+  an @nt{if_expression} (and @key[end case] for a @nt{case_expression}) also
+  may make error handling harder.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0147-1]}
address@hidden,Type=[Leading],Text=[If a @nt{conditional_expression} is
+expected to be of a type @i<T>, then each @address@hidden of
+the @nt{conditional_expression} is expected to be of type @i<T>. Similarly, if 
a
address@hidden is expected to be of some class of types, then each
address@hidden@nt{expression} of the @nt{conditional_expression} is subject
+to the same expectation. If a @nt{conditional_expression} shall resolve to be 
of
+a type @i<T>, then each @address@hidden shall resolve to be of
+type @i<T>address@hidden type],Sec=[dependent_expression]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0147-1]}
address@hidden,Type=[Leading],Text=[The possible types of a
address@hidden are further determined as follows:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If the @nt{conditional_expression} is the operand
+  of a type conversion, the type of the @nt{conditional_expression} is the
+  target type of the conversion; otherwise,]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[This rule distributes an enclosing
+  type conversion to the @address@hidden This means that]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[T(@key[if] C @key[then] A @key[else] B)]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[has the same semantics as]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[(@key[if] C @key[then] T(A) @key[else] T(B))]}
address@hidden
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If all of the @address@hidden
+  are of the same type, the type of the @nt{conditional_expression} is that
+  type; otherwise,]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If a @address@hidden is of an
+  elementary type, the type of the @nt{conditional_expression} shall be covered
+  by that type; otherwise,]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This rule supports the use of
+  numeric literals and universal expressions within a
+  @nt{conditional_expression}.]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If the @nt{conditional_expression} is expected to
+  be of type @i<T> or shall resolve to type @i<T>, then the
+  @nt{conditional_expression} is of type @i<T>.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If the type of the @nt{conditional_expression}
+  cannot be determined by one of these rules, then Name Resolution has failed 
for
+  that expression, even if the @address@hidden would
+  resolve individually.]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0147-1]}
address@hidden,address@hidden type], Sec=(condition)}
+A @nt{condition} is expected to be of any boolean type.]}
address@hidden from "If Statements"}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0188-1]}
address@hidden,Text=[The expected type for the
address@hidden<selecting_>@nt{expression} and the @nt{discrete_choice}s are as 
for case
+statements
+(see @RefSecNum{Case Statements})address@hidden type],Sec=[case_expression 
selecting_expression]}
address@hidden type],Sec=[case_expression_alternative discrete_choice]}
address@hidden type],Sec=[selecting_expression case_expression]}]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0147-1],ARef=[AI05-0188-1]}
address@hidden,Text=[All of the @address@hidden
+shall be convertible (see @RefSecNum{Type Conversions}) to the type of the
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0147-1],ARef=[AI05-0188-1],ARef=[AI05-0269-1]}
address@hidden,Text=[If the expected type of a
address@hidden is a specific tagged type, all of the
address@hidden@nt{expression}s of the @nt{conditional_expression} shall be
+dynamically tagged, or none shall be dynamically tagged. In this case, the
address@hidden is dynamically tagged if all of the
address@hidden@nt{expression}s are dynamically tagged, is tag-indeterminate
+if all of the @address@hidden are tag-indeterminate, and is
+statically tagged otherwise.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0147-1],ARef=[AI05-0262-1]}
address@hidden,Text=[If there is no @key[else]
address@hidden@nt{expression}, the @nt{if_expression} shall be of
+a boolean type.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0188-1],ARef=[AI05-0269-1]}
address@hidden,Text=[All @LegalityTitle that apply to the
address@hidden of a @nt{case_statement} (see @RefSecNum{Case Statements})
+also apply to the @nt{discrete_choice}s of a @nt{case_expression} except
+within an instance of a generic unit.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[The exemption for a case expression
+that occurs in an instance allows the following example:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key[with function] Int_Func @key[return] Integer;
address@hidden G @key[is]
+   X : Float := (@key[case] Int_Func @key[is]
+                  @key[when] Integer'First .. -1 => -1.0,
+                  @key[when] 0 => 0.0,
+                  @key[when] Positive => 1.0);
address@hidden G;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Nat_Func @key[return] Natural @key[is] (123);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden I @key[is new] G (Int_Func => Nat_Func); -- 
@Examcom{Legal}]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Note that the @LegalityTitle still apply in the
+generic unit itself; they are just not enforced in an instance of the unit.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0147-1],ARef=[AI05-0188-1]}
address@hidden,Text=[For the evaluation of an @nt{if_expression}, the
address@hidden specified after @key[if], and any @nt{condition}s specified
+after @key[elsif], are evaluated in succession (treating a final @key[else]
+as @key[elsif] True @key[then]), until one evaluates to True or
+all @nt{condition}s are evaluated and yield False. If a @nt{condition}
+evaluates to True, the associated @address@hidden is evaluated,
+converted to the type of the @nt{if_expression}, and the resulting value is the
+value of the @nt{if_expression}. Otherwise (when there is no @key[else] 
clause),
+the value of the @nt{if_expression} is address@hidden,Sec=[if_expression]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],address@hidden is required unless the
+  @nt{if_expression} has a boolean type, so the last sentence can only apply to
+  @nt{if_expression}s with a boolean type.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0188-1]}
address@hidden,Text=[For the evaluation of a @nt{case_expression}, the
address@hidden<selecting_>@nt{expression} is first evaluated.
+If the value of the @SynI<selecting_>@nt{expression}
+is covered by the @nt{discrete_choice_list} of some
address@hidden, then the @SynI<dependent_>@nt{expression} of
+the @nt{case_expression_alternative} is evaluated, converted to the type of the
address@hidden, and the resulting value is the value of the
address@hidden@IndexCheck{Overflow_Check}
address@hidden,Sec=(raised by failure of run-time check)}
+Otherwise (the value is not covered by any
address@hidden, perhaps due to being outside the base range),
+Constraint_Error is address@hidden,Sec=[case_expression]}]}
+
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0147-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}If expressions
+  and case expressions are new.]}
address@hidden
+
+
address@hidden,Name=[Quantified Expressions]}
+
address@hidden,Kind=[Added],ARef=[AI12-0158-1]}
address@hidden,Text=[Quantified expressions provide a way to write
+universally and existentially quantified predicates over containers and
+arrays.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0176-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<quantified_expression>,Old=<>}>,
+rhs="@Chg{Version=[3],address@hidden @Syn2{quantifier} 
@Syn2{loop_parameter_specification} => @Syn2{predicate}
+  | @key[for] @Syn2{quantifier} @Syn2{iterator_specification} => 
@Syn2{predicate}],Old=<>}"}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,lhs=<@Chg{Version=[3],New=<quantifier>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<@key[all] | @key[some]>,Old=<>}"}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,lhs=<@Chg{Version=[3],New=<predicate>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<@SynI<boolean_>@Syn2{expression}>,Old=<>}"}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0176-1]}
address@hidden,Text=[Wherever the Syntax Rules allow an @nt{expression}, a
address@hidden may be used in place of the @nt{expression}, so
+long as it is immediately surrounded by parentheses.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The syntactic category @nt{quantified_expression}
+  appears only as a @nt{primary} that is parenthesized. The above rule allows 
it to additionally
+  be used in other contexts where it would be directly surrounded by
+  parentheses. This is the same rule that is used for 
@nt{conditional_expression}s;
+  see @RefSecNum{Conditional Expressions} for a detailed discussion of the
+  meaning and effects of this rule.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0176-1]}
address@hidden,address@hidden type],Sec=[quantified_expression]}
+The expected type of a @nt{quantified_expression} is
+any Boolean type. The @nt{predicate} in a @nt{quantified_expression} is
+expected to be of the same address@hidden expressions}]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0176-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0158-1]}
address@hidden,Text=[For the evaluation of a @nt{quantified_expression},
+the @nt{loop_parameter_specification} or @nt{iterator_specification} is first 
elaborated. The evaluation of a
address@hidden then evaluates the @nt{predicate} for
address@hidden,New=[the values],Old=[each value]} of the loop
address@hidden,New=[],Old=[. These values are examined]} in the
+order specified by the
address@hidden (see @RefSecNum{Loop Statements}) or
address@hidden (see @RefSecNum{Generalized Loop 
Iteration})address@hidden,Sec=[quantified_expression]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0176-1]}
address@hidden,Type=[Leading],Text=[The value of the
address@hidden is determined as follows:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0158-1]}
+  @ChgAdded{Version=[3],Text=[If the @nt{quantifier} is @key[all], the
+  expression is @Chg{Version=[4],New=[False],Old=[True]} if the evaluation
+  of @Chg{Version=[4],New=[any],Old=[the]} @nt{predicate} yields
+  @Chg{Version=[4],New=[False; evaluation of the
+  @nt{quantified_expression} stops at that point. Otherwise (every
+  predicate has been evaluated and yielded True), the expression is
+  True],Old=[True for
+  each value of the loop parameter. It is False otherwise. Evaluation of
+  the @nt{quantified_expression} stops when all values of the domain have been
+  examined, or when the @nt{predicate} yields False for a given value]}. Any
+  exception raised by evaluation of the @nt{predicate} is propagated.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The @nt{expression} is True if the domain
+  contains no values.]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0158-1]}
+  @ChgAdded{Version=[3],Text=[If the @nt{quantifier} is @key[some], the
+  expression is True if the evaluation of
+  @Chg{Version=[4],New=[any],Old=[the]} @nt{predicate} yields
+  address@hidden,New=[; evaluation of the
+  @nt{quantified_expression} stops at that point. Otherwise (every
+  predicate has been evaluated and yielded False), the expression is
+  False],Old=[ for
+  some value of the loop parameter. It is False otherwise. Evaluation of
+  the @nt{quantified_expression} stops when all values of the domain have been
+  examined, or when the @nt{predicate} yields True for a given value]}. Any
+  exception raised by evaluation of the @nt{predicate} is propagated.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The @nt{expression} is False if the domain
+  contains no values.]}
address@hidden
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0176-1]}
address@hidden,Type=[Leading],Text=[The postcondition for a sorting
+routine on an array A with an index subtype T can be written:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Post => (A'Length < 2 @key[or else]
+   (@key[for all] I @key[in] A'First .. T'Pred(A'Last) => A (I) <= A (T'Succ 
(I))))]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0176-1]}
address@hidden,Type=[Leading],Text=[The assertion that a positive number
+is composite (as opposed to prime) can be written:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Assert (@key[for some] X @key[in] 2 .. N / 2 => N 
@key[mod] X = 0);]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0176-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Quantified
+  expressions are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0158-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Revised the wording to 
make it
+  clear that the semantics is short-circuited, and what the result is when
+  there are no values for the loop parameter.]}
address@hidden
diff --git a/packages/ada-ref-man/source_2012/04b.mss 
b/packages/ada-ref-man/source_2012/04b.mss
new file mode 100755
index 0000000..68897d0
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/04b.mss
@@ -0,0 +1,3082 @@
address@hidden(04, Root="ada.mss")
+
address@hidden: 2014/07/24 04:20:38 $}
+
address@hidden: e:\\cvsroot/ARM/Source/04b.mss,v $}
address@hidden: 1.66 $}
+
address@hidden Conversions}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden type conversions, both
+value conversions and view conversions, are
+allowed between closely related
+types as defined below. This @Chg{Version=[3],New=[subclause],Old=[clause]}
+also defines rules for value and view
+conversions to a particular subtype of a type,
+both explicit ones and those implicit in other constructs.
address@hidden conversion],See=(type conversion)}
address@hidden conversion}
address@hidden
address@hidden,See=(type conversion)}]
address@hidden conversion],See=(implicit subtype conversion)}
address@hidden conversion, implicit],See=(implicit subtype conversion)}
address@hidden
+
address@hidden
address@hidden<type_conversion>,rhs="
+    @Syn2{subtype_mark}(@Syn2{expression})
+  | @Syn2{subtype_mark}(@Syn2{name})"}
+
address@hidden
+
address@hidden
address@hidden subtype], Sec=(of a @nt<type_conversion>)}
+The @i(target subtype) of a @nt<type_conversion> is the subtype
+denoted by the @nt{subtype_mark}.
address@hidden, Sec=(of a @nt<type_conversion>)}
+The @i(operand) of a @nt<type_conversion> is the
address@hidden or @nt{name} within the parentheses;
address@hidden type], Sec=(of a @nt<type_conversion>)}
+its type is the @i(operand type).
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden
+One type is @i(convertible) to a second type if a @nt<type_conversion>
+with the first type as operand type and the second type as target type
+is legal according to the rules of this 
@Chg{Version=[3],New=[subclause],Old=[clause]}.
+Two types are convertible if each is convertible to the other.
address@hidden
+  Note that @lquotes@;address@hidden@; is defined in terms of legality
+  of the conversion. Whether the conversion would raise an exception
+  at run time is irrelevant to this definition.
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0017],ARef=[AI95-00184-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00330-01]}
address@hidden conversion}
address@hidden,Sec=(view)}
+A @nt{type_conversion} whose operand is the
address@hidden<name> of an object is called a @i(view conversion) if
address@hidden ],Old=[]}its target type
address@hidden operand type are],Old=[is]} tagged, or if it
address@hidden,New=[ in a call],Old=[]} as an actual parameter of mode
address@hidden or @key[in out];
address@hidden conversion}
address@hidden,Sec=(value)}
+other @nt<type_conversion>s are called @i(value conversions).
address@hidden,See=(view conversion)}
address@hidden
+  A view conversion to a tagged type can appear in
+  any context that requires an object @nt<name>, including in
+  an object renaming, the @nt<prefix> of a @nt<selected_component>,
+  and if the operand is a variable, on the left side of an
+  @nt<assignment_statement>. View conversions to other types only
+  occur as actual parameters. Allowing view conversions of untagged
+  types in all contexts seemed to incur an undue implementation burden.
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00330-01]}
+  @ChgAdded{Version=[2],Text=[A type conversion appearing as an @key{in out}
+  parameter in a generic instantiation is not a view conversion; the second
+  part of the rule only applies to subprogram calls, not instantiations.]}
address@hidden
address@hidden
+
address@hidden
address@hidden type],
+  Sec=(type_conversion operand)}
+The operand of a @nt<type_conversion> is expected to be of any type.
address@hidden
+  This replaces the "must be determinable" wording of Ada 83.
+  This is equivalent to (but hopefully more intuitive than) saying
+  that the operand of a @nt<type_conversion>
+  is a @lquotes@;complete address@hidden@;
address@hidden
+
+The operand of a view conversion
+is interpreted only as a @nt<name>;
+the operand of a value conversion
+is interpreted as an @nt<expression>.
address@hidden
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0005-1]}
+  This formally resolves the syntactic ambiguity between
+  the two forms of @nt<type_conversion>@Chg{Version=[4],New=[.
+  This matters as an @nt{expression} that is a @nt{name} is evaluated and
+  represents a value while a @nt{name} by itself can be an object; we want
+  a view conversion to be an object],Old=[, not that it really matters]}.
address@hidden
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[4],Text=[This wording uses "interpreted as" rather than
+  "shall be" so that this rule is not used to resolve overloading; it is
+  solely about evaluation as described above.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00251-01]}
address@hidden,New=[In a view conversion for an untagged type,
+the target type shall be convertible (back) to the operand type.],
address@hidden conversion],sec=(numeric)}
address@hidden,sec=(numeric)}
+If the target type is a numeric type, then the operand type
+shall be a numeric type.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=<Untagged view conversions appear only as 
address@hidden
+  @key{out}
+  parameters. Hence, the reverse conversion must be legal as well.
+  The forward conversion must be legal even for an @key{out} parameter,
+  because (for example) actual parameters of an access type are always
+  copied in anyway.>}
address@hidden
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 9
+through 20 were reorganized and moved below.>address@hidden message should be
+deleted if the paragraphs are ever renumbered.}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01]}
address@hidden,Text=[The entire @LegalityTitle section has been
+reorganized to eliminate an
+unintentional incompatibility with Ada 83. In rare cases, a type conversion
+between two types related by derivation is not allowed by Ada 95, while it is
+allowed in Ada 83. The reorganization fixes this.
+Much of the wording of the legality section is unchanged, but it is reordered
+and reformatted. Because of the limitations of our tools, we had to delete and
+replace nearly the entire section. The text of Ada 95 paragraphs 8 through 12,
+14, 15, 17, 19, 20, and 24 are unchanged (just moved); these are now
+24.1 through 24.5, 24.12, 24.13, 24.17, 24.19, 24.20, and 8.]}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00251-01]}
address@hidden,Type=[Leading],address@hidden conversion],sec=(array)}
address@hidden,sec=(array)}
+If the target type is an array type, then the operand type shall
+be an array type. Further:]}
address@hidden(itemize)
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00251-01]}
+  @ChgDeleted{Version=[2],Text=[The types shall have the same dimensionality;]}
+
address@hidden,Kind=[Revised],Ref=[8652/0008],ARef=[AI95-00168-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00251-01]}
+  @ChgDeleted{Version=[2],Text=[Corresponding index types shall be 
convertible;@Chg{New=[],Old=[ and]}
+  @PDefn2{Term=[convertible],Sec=(required)}]}
+
address@hidden,Kind=[Revised],Ref=[8652/0008],ARef=[AI95-00168-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00251-01]}
+  @ChgDeleted{Version=[2],Text=[The component subtypes shall statically 
address@hidden; and],Old=[.]}
+  @PDefn2{Term=[statically matching],Sec=(required)}]}
+
address@hidden,Kind=[Added],Ref=[8652/0008],ARef=[AI95-00168-01]}
address@hidden,Kind=[DeletedAddedNoDelMsg],ARef=[AI95-00251-01]}
address@hidden,address@hidden a view conversion, the target type and the 
operand type shall
+both or neither have aliased components.],Old=[]}]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[DeletedAddedNoDelMsg]}
address@hidden,address@hidden this rule, it is possible to violate the 
constrained status
+of aliased array components. Consider:],Old=[]}]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[DeletedAddedNoDelMsg]}
address@hidden,address@hidden@key[package] P @key[is]
+   @key[type] T @key[is private];
+   A : @key[constant] T;
+   @key[type] A1 @key[is array] (1 .. 10) @key[of aliased] T;
+   @key[type] A2 @key[is array] (1 .. 10) @key[of] T;
address@hidden
+   @key[type] T (D : Integer := 0) @key[is null record];
+   A : @key[constant] T := (D => 1);
address@hidden P;],Old=[]}]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[DeletedAddedNoDelMsg]}
address@hidden,address@hidden@key[with] P;
address@hidden Exam @key[is]
+   X : P.A1;
+   @key[procedure] S (Y : @key[in out] P.A2) @key[is]
+   @key[begin]
+      Y (1) := P.A;
+   @key[end];
address@hidden
+   S (P.A2 (X)); -- This call will change the discriminant of X (1),
+                 -- so we cannot allow the conversion.
address@hidden;],Old=[]}]}
address@hidden
address@hidden
address@hidden(itemize)
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00251-01]}
address@hidden,Type=[Leading],address@hidden conversion],sec=(access)}
address@hidden,sec=(access)}
+If the target type is a general access type, then the operand type
+shall be an access-to-object type. Further:]}
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[The @LegalityTitle and @RunTimeTitle are worded
+  so that a @nt{type_conversion} T(X) (where T is an access type) is (almost)
+  equivalent to the @nt{attribute_reference} address@hidden'Access, where the
+  result is of type T. The @nt{type_conversion} accepts a null value, whereas
+  the @nt{attribute_reference} would raise Constraint_Error.]}
address@hidden
address@hidden(itemize)
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00251-01]}
+  @ChgDeleted{Version=[2],Text=[If the target type is an access-to-variable
+  type, then the operand type shall be an access-to-variable type;]}
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[If the target type is an access-to-constant
+  type, then the operand type
+  can be access-to-constant or access-to-variable.]}
address@hidden
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00251-01]}
+  @ChgDeleted{Version=[2],Text=[If the target designated type is tagged,
+  then the operand designated type
+  shall be convertible to the target designated type;
+  @PDefn2{Term=[convertible],Sec=(required)}]}
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00251-01]}
+  @ChgDeleted{Version=[2],Text=[If the target designated type is not tagged,
+  then the designated types shall be the same,
+  and either the designated subtypes shall statically match or
+  the target designated subtype shall be discriminated and unconstrained; and
+  @PDefn2{Term=[statically matching],Sec=(required)}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[These rules are designed to ensure that
+  aliased array objects only @i(need) "dope" if their nominal subtype is 
unconstrained,
+  but they can always @i(have) dope if required by the run-time model
+  (since no sliding is permitted as part of access type conversion).
+  By contrast, aliased discriminated objects will always @i(need) their
+  discriminants stored with them, even if nominally constrained.
+  (Here, we are assuming an implementation that represents
+  an access value as a single pointer.)]}
address@hidden
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00251-01]}
+  @ChgDeleted{Version=[2],address@hidden rule],Sec=(type conversion)}
+  The accessibility level of the operand type shall not be statically
+  deeper than that of the target type.
+  @PDefn{generic contract issue}
+  In addition to the places where @LegalityTitle normally apply
+  (see @RefSecNum{Generic Instantiation}),
+  this rule applies also in the private part of an
+  instance of a generic unit.]}
+  @begin{Ramification}
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[The access parameter case is handled by a 
run-time check.
+  Run-time checks are also done in instance bodies.]}
+  @end{Ramification}
address@hidden(itemize)
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00251-01]}
address@hidden,Type=[Leading],address@hidden conversion],sec=(access)}
address@hidden,sec=(access)}
+If the target type is an access-to-subprogram type, then the operand
+type shall be an access-to-subprogram type. Further:]}
address@hidden(itemize)
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00251-01]}
+  @ChgDeleted{Version=[2],Text=[The designated profiles shall be
+  address@hidden conformance],Sec=(required)}]}
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00251-01]}
+  @ChgDeleted{Version=[2],address@hidden rule],Sec=(type conversion)}
+  The accessibility level of the operand type shall not be statically
+  deeper than that of the target type.
+  @PDefn{generic contract issue}
+  In addition to the places where @LegalityTitle normally apply
+  (see @RefSecNum{Generic Instantiation}),
+  this rule applies also in the private part of an
+  instance of a generic unit.
+  If the operand type is declared within a generic body,
+  the target type shall be declared within the generic body.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[The reason it is illegal to convert from
+  an access-to-subprogram type
+  declared in a generic body to one declared outside that body
+  is that in an implementation that shares generic bodies,
+  procedures declared inside the generic need to have a different
+  calling convention @em they need an extra parameter pointing to the
+  data declared in the current instance.
+  For procedures declared in the spec,
+  that's OK, because the compiler can know about them at compile time of
+  the instantiation.]}
address@hidden
address@hidden(itemize)
+
address@hidden start the new text here, so we can modify the handful of rules
+that are not reformatted. (Except the first rule is at the top.)}
+
address@hidden,Kind=[Revised],ARef=[AI95-00251-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0115-1]}
address@hidden@Defn2{Term=[type conversion],sec=[composite (non-array)]}
address@hidden,sec=[composite (non-array)]}
address@hidden,New=[If there is a address@hidden,New=[ (other than a
+root numeric type)],Old=[]} that is an ancestor of both the target
+type and the operand type, or both types are class-wide types, then at least
+one of the following rules shall apply:],address@hidden 
conversion],sec=(enumeration)}
address@hidden,sec=(enumeration)}
+If the target type is not included in any of the above four
+cases, there shall be a type that is an ancestor of both
+the target type and the operand type.
+Further, if the target type is tagged, then either:]}
address@hidden(itemize)
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],address@hidden conversion],sec=(enumeration)}
+  @Defn2{Term=[conversion],sec=(enumeration)}The target type shall be
+  untagged; or]}
+
+  The operand type shall be covered by or
+  descended from the target type; or
+  @begin{Ramification}
+    This is a conversion
+    toward the root, which is always safe.
+  @end{Ramification}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00251-01]}
+  The operand type shall be a class-wide type that covers the target
+  address@hidden,New=[; or],Old=[.]}
+  @begin{Ramification}
+    This is a conversion of a class-wide type toward the leaves,
+    which requires a tag check. See @RunTimeTitle.
+
+    @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00251-01]}
+    These two rules imply that a conversion from @Chg{Version=[2],New=[an
+    ancestor],Old=[a parent]} type
+    to a type extension is not permitted, as this would require
+    specifying the values for additional components, in general,
+    and changing the tag. An @nt<extension_aggregate> has to be used
+    instead, constructing a new value, rather than converting an
+    existing value. However, a conversion
+    from the class-wide type rooted at @Chg{Version=[2],New=[an
+    ancestor],Old=[the parent]} type is permitted;
+    such a conversion just verifies that the operand's tag is
+    a descendant of the target.
+  @end{Ramification}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Text=[The operand and target types shall both be 
class-wide
+  types and the specific type associated with at least one of them shall be an
+  interface type.]}
+  @begin{Ramification}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[We allow converting any class-wide type 
T'Class to
+    or from a class-wide interface type even if the specific type T does not
+    have an appropriate
+    interface ancestor, because some extension of T might have the needed
+    ancestor. This is similar to a conversion of a class-wide type toward the
+    leaves of the tree, and we need to be consistent. Of course, there is
+    a run-time check that the actual object has the needed interface.]}
+  @end{Ramification}
address@hidden(itemize)
+
address@hidden,Kind=[Revised],ARef=[AI95-00251-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0115-1]}
address@hidden,New=[If there is no address@hidden,New=[ (other than a
+root numeric type)],Old=[]} that is the ancestor of both the
+target type and the operand type, and they are not both class-wide types, one
+of the following rules shall apply:], Old=[In a view conversion for
+an untagged type, the target type shall be convertible (back) to the operand 
type.]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=<Untagged view conversions appear only as [in] out
+  parameters. Hence, the reverse conversion must be legal as well.
+  The forward conversion must be legal even if an out parameter,
+  because actual parameters of an access type are always
+  copied in anyway.>}
address@hidden
+
address@hidden(itemize)
address@hidden,Kind=[Added],ARef=[AI95-00251-01]}
address@hidden,address@hidden conversion],sec=(numeric)}
address@hidden,sec=(numeric)}
+If the target type is a numeric type, then the operand type
+shall be a numeric type.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00251-01]}
address@hidden,Type=[Leading],address@hidden conversion],sec=(array)}
address@hidden,sec=(array)}
+If the target type is an array type, then the operand type shall
+be an array type. Further:]}
+
address@hidden(inneritemize)
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00251-01]}
+  @Chg{Version=[2],New=[The types shall have the same dimensionality;],Old=[]}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00251-01]}
+  @Chg{Version=[2],New=[Corresponding index types shall be convertible;
+  @PDefn2{Term=[convertible],Sec=(required)}],Old=[]}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00251-01]}
+  @Chg{Version=[2],New=[The component subtypes shall statically match;
+  @PDefn2{Term=[statically matching],Sec=(required)}],Old=[]}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00392-01]}
+  @Chg{Version=[2],New=[If the component types are anonymous access types, 
then the
+  accessibility level of the operand type shall not be statically deeper
+  than that of the target type;
+  @PDefn2{Term=[accessibility rule],Sec=(type conversion, array 
components)}],Old=[]}
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[For unrelated array types, the component types
+    could have different accessibility, and we had better not allow a
+    conversion of a local type into a global type, in case the local type
+    points at local objects. We don't need a check for other types of
+    components; such components necessarily are for related types, and
+    either have the same accessibility or (for access discriminants) cannot
+    be changed so the discriminant check will prevent problems.]}
+  @end{Reason}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00246-01]}
+  @ChgAdded{Version=[2],Text=[Neither the target type nor the operand type 
shall be
+  limited;]}
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[We cannot allow conversions between unrelated 
limited
+    types, as they may have different representations, and (since the types
+    are limited), a copy cannot be made to reconcile the representations.]}
+  @end{Reason}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00251-01],ARef=[AI95-00363-01]}
+  @ChgAdded{Version=[2],Text=[If the target type of a view conversion has
+  aliased components, then so shall the operand type; and]}
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00363-01]}
+    @ChgAdded{Version=[2],Text=[We cannot allow a view conversion from an 
object
+    with unaliased components to an object with aliased components, because
+    that would effectively allow pointers to unaliased components. This rule
+    was missing from Ada 95.]}
+  @end{Reason}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00246-01],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Text=[The operand type of a view conversion shall not
+  have a tagged, private, or volatile subcomponent.]}
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00246-01]}
+    @ChgAdded{Version=[2],Text=[We cannot allow view conversions between 
unrelated
+    might-be-by-reference types, as they may have different representations,
+    and a copy cannot be made to reconcile the representations.]}
+  @end{Reason}
+  @begin{Ramification}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[These rules only apply to unrelated array
+    conversions; different (weaker) rules apply to conversions between related
+    types.]}
+  @end{Ramification}
address@hidden(inneritemize)
+
address@hidden,Kind=[Added],ARef=[AI95-00230-01]}
address@hidden,New=[If the target type is @i<universal_access>, then the
+operand type shall be an access type.],Old=[]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Such a conversion cannot be written explicitly,
+  of course, but it can be implicit (see below).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00230-01],ARef=[AI95-00251-01]}
address@hidden,Type=[Leading],address@hidden conversion],sec=(access)}
address@hidden,sec=(access)}If the target type is a general access-to-object 
type, then
+the operand type shall be @i<address@hidden> or an access-to-object type.
+Further, if the operand type is not @i<address@hidden>:]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The @LegalityTitle and @RunTimeTitle are worded
+  so that a @nt{type_conversion} T(X) (where T is an access type) is
+  (almost) equivalent to the @nt{attribute_reference}
+  address@hidden'Access, where the result is of type T.
+  The only difference is that the @nt{type_conversion} accepts a null value,
+  whereas the @nt{attribute_reference} would raise Constraint_Error.]}
address@hidden
+
address@hidden(inneritemize)
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00251-01]}
+  @Chg{Version=[2],New=[If the target type is an access-to-variable
+  type, then the operand type shall be an access-to-variable type;],Old=[]}
+  @begin{Ramification}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[If the target type is an access-to-constant 
type,
+    then the operand type can be access-to-constant or access-to-variable.]}
+  @end{Ramification}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Text=[If the target designated type is tagged, then the
+  operand designated type shall be convertible to the target designated type;
+  @PDefn2{Term=[convertible],Sec=(required)}]}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00251-01],ARef=[AI95-00363-01]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[If the target designated type is
+  not tagged, then the designated types shall be the same, and either:]}
+
+  @begin(innerinneritemize)
+    @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00363-01]}
+    @Chg{Version=[2],New=[the designated subtypes shall statically match;
+    address@hidden matching],Sec=(required)}],Old=[]}
+
+    @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00363-01],ARef=[AI95-00384-01]}
+    @Chg{Version=[2],New=[the designated type shall be discriminated in its
+    full view and unconstrained in any partial view, and one of the designated
+    subtypes shall be unconstrained;],Old=[]}
+
+    @begin{Ramification}
+      @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00363-01]}
+      @ChgAdded{Version=[2],Text=[This does not require that types have a 
partial view
+      in order to allow the conversion, simply that any partial view that does
+      exist is unconstrained.]}
+
+      @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00384-01]}
+      @ChgAdded{Version=[2],Text=[This allows conversions both ways (either 
subtype
+      can be unconstrained); while Ada 95 only allowed the conversion if the
+      target subtype is unconstrained. We generally want type conversions to be
+      symmetric; which type is the target shouldn't matter for legality.]}
+    @end{Ramification}
+
+    @begin{Reason}
+      @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00363-01]}
+      @ChgAdded{Version=[2],Text=[If the visible partial view is constrained, 
we
+      do not allow conversion between unconstrained and constrained subtypes.
+      This means that whether the full type had discriminants is not visible
+      to clients of the partial view.]}
+    @end{Reason}
+
+    @begin{Discussion}
+      @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0095-1]}
+      @ChgAdded{Version=[4],Text=[We assume the worst in a generic body whether
+      or not a formal subtype has a constrained partial view; specifically, in 
a
+      generic body a discriminated subtype is considered to have a constrained
+      partial view if it is a descendant of an untagged generic formal private
+      or derived type (see @RefSecNum{Formal Private and Derived Types} for the
+      formal definition of this rule).]}
+    @end{Discussion}
+
+  @end(innerinneritemize)
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[These rules are designed to ensure that 
aliased array objects
+    only @i(need) "dope" if their nominal subtype is unconstrained,
+    but they can always @i(have) dope if required by the run-time model
+    (since no sliding is permitted as part of access type conversion).
+    By contrast, aliased discriminated objects will always @i(need) their
+    discriminants stored with them, even if nominally constrained.
+    (Here, we are assuming an implementation that represents
+    an access value as a single pointer.)]}
+  @end{Reason}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00251-01]}
+  
@ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0148-1],ARef=[AI05-0248-1]}
+  @ChgRef{Version=[4],Kind=[RevisedAdded],ARef=[AI12-0027-1]}
+  @Chg{Version=[2],address@hidden rule],Sec=(type conversion)}
+  The accessibility level of the operand type shall not be statically
+  deeper than that of the target address@hidden,New=[, unless the target
+  type is an anonymous access type of a stand-alone object. If the target type
+  is that of such a stand-alone object, the accessibility level of the operand
+  type shall not be statically deeper than that of the declaration of the
+  stand-alone object],address@hidden,New=[],Old=[
+  @PDefn{generic contract issue}
+  In addition to the places where @LegalityTitle normally apply
+  (see @RefSecNum{Generic Instantiation}),
+  this rule applies also in the private part of an
+  instance of a generic unit.]}],Old=[]}
+  @begin{Ramification}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0148-1]}
+    @ChgAdded{Version=[2],Text=[The access parameter case is handled by a 
run-time
+    check. Run-time checks are also done in instance address@hidden,
+    New=[, and for stand-alone objects of anonymous access types],Old=[]}.]}
+  @end{Ramification}
+  @begin{Reason}
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[We prohibit storing accesses to objects deeper
+    than a stand-alone object of an anonymous access-to-object (even while we
+    allow storing all other accesses) in order to prevent dangling accesses.]}
+  @end{Reason}
+
address@hidden(inneritemize)
+
address@hidden,Kind=[Added],ARef=[AI95-00230-01]}
address@hidden,address@hidden conversion],sec=(access)}
address@hidden,sec=(access)}If the target type is a pool-specific
+access-to-object type, then
+the operand type shall be @i<universal_access>.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This allows @b<null> to be converted to 
pool-specific
+  types. Without it, @b<null> could be converted to general access types but
+  not pool-specific ones, which would be too inconsistent. Remember that these
+  rules only apply to unrelated types, so we don't have to talk about
+  conversions to derived or other related types.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00230-01],ARef=[AI95-00251-01]}
address@hidden,Type=[Leading],address@hidden conversion],sec=(access)}
address@hidden,sec=(access)}
+If the target type is an access-to-subprogram type, then the operand type
+shall be @i<address@hidden> or an access-to-subprogram type. Further, if
+the operand type is not @i<address@hidden>:]}
+
address@hidden(inneritemize)
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00251-01]}
+  @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0239-1]}
+  @Chg{Version=[2],New=[The designated profiles shall be
+  @Chg{Version=[3],New=[subtype conformant],Old=[subtype-conformant]}.
+  @Defn2{Term=[subtype conformance],Sec=(required)}],Old=[]}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00251-01]}
+  @ChgRef{Version=[4],Kind=[RevisedAdded],ARef=[AI12-0027-1]}
+  @Chg{Version=[2],address@hidden rule],Sec=(type conversion)}
+  The accessibility level of the operand type shall not be statically
+  deeper than that of the target address@hidden,New=[],Old=[
+  @PDefn{generic contract issue}
+  In addition to the places where @LegalityTitle normally apply
+  (see @RefSecNum{Generic Instantiation}),
+  this rule applies also in the private part of an
+  instance of a generic unit.]}
+  If the operand type is declared within a generic body,
+  the target type shall be declared within the generic body.],Old=[]}
+
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[The reason it is illegal to convert from an
+    access-to-subprogram type declared in a generic body to one declared 
outside
+    that body is that in an implementation that shares generic bodies,
+    procedures declared inside the generic need to have a different
+    calling convention @em they need an extra parameter pointing to the
+    data declared in the current instance. For procedures declared in the spec,
+    that's OK, because the compiler can know about them at compile time of
+    the instantiation.]}
+  @end{Reason}
address@hidden(inneritemize)
+
address@hidden(itemize)
+
address@hidden,Kind=[Added],ARef=[AI12-0027-1]}
address@hidden,address@hidden contract issue}
+In addition to the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}),
+these rules apply also in the private part of an
+instance of a generic unit.]}
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This applies to @i<all> of the @LegalityTitle
+  in this section. It won't matter for the majority of these rules, but
+  in any case that it does, we want to apply the same recheck in the private
+  part. (Ada got the default wrong for these, as there is only one known case
+  where we don't want to recheck in the private part,
+  see derivations without record extensions in
+  @RefSecNum{Derived Types and Classes}.)]}
address@hidden
+
address@hidden
+
address@hidden
+A @nt{type_conversion} that is a value conversion denotes the value
+that is
+the result of converting the value of the operand to the target subtype.
+
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
+A @nt{type_conversion} that is a view conversion
+denotes a view of the object denoted by the operand. This
+view is a variable of the target type if the operand denotes
+a variable; address@hidden,New=[,],Old=[]}
+it is a constant of the target type.
+
address@hidden subtype], Sec=(associated with a @nt<type_conversion>)}
+The nominal subtype of a @nt<type_conversion> is its target subtype.
address@hidden
+
address@hidden
address@hidden@PDefn2{Term=[evaluation], Sec=(value conversion)}
address@hidden value],
+  Sec=(of the target type of a conversion)}
address@hidden
+For the evaluation of a @nt<type_conversion> that is a value conversion,
+the operand is evaluated, and then
+the value of the operand is @i(converted) to a @i(corresponding)
+value of the target type, if any.
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+If there is no value
+of the target type that corresponds to the operand value,
+Constraint_Error is address@hidden; this can only
+happen on conversion to a modular type,
+and only when the operand value is outside the base range of
+the modular type.]
+Additional rules follow:
address@hidden(itemize)
address@hidden conversion],sec=(numeric)}
address@hidden,sec=(numeric)}
+Numeric Type Conversion
address@hidden(inneritemize)
+  If the target and the operand types are both integer types, then
+  the result is the value of the target type that corresponds
+  to the same mathematical integer as the operand.
+
+  If the target type is a decimal fixed point type, then the result is
+  truncated (toward 0) if the
+  value of the operand is not a multiple of the @i{small} of the target
+  type.
+
+  @Defn{accuracy}
+  If the target type is some other real type,
+  then the result is within the accuracy of the target type
+  (see @RefSec{Numeric Performance Requirements},
+  for implementations that support the Numerics Annex).
+  @begin(Discussion)
+    An integer type might have more bits of precision than a real type,
+    so on conversion (of a large integer), some precision might be lost.
+  @end(Discussion)
+
+  If the target type is an integer type and the operand type is real,
+  the result is rounded to the nearest integer (away from zero
+  if exactly halfway between two integers).
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00267-01]}
+  This was implementation defined in Ada 83.
+    There seems no reason to preserve the nonportability
+    in Ada 95. Round-away-from-zero is the conventional
+    definition of rounding, and standard Fortran and COBOL both specify
+    rounding away from zero, so for interoperability, it seems important
+    to pick this. This is also the most easily @lquotes@;address@hidden@; by 
hand.
+    Round-to-nearest-even is an alternative, but that is quite complicated
+    if not supported by the hardware. In any case, this operation is not
+    @Chg{Version=[2],New=[usually],Old=[expected to be]} part of an inner loop,
+    so predictability and portability are judged most important.
+    @Chg{Version=[2],New=[A],Old=[We anticipate that
+    a]} floating point attribute function Unbiased_Rounding @Chg{Version=[2],
+    New=[is],Old=[will be]} address@hidden,
+    New=[ (see @RefSecNum{Attributes of Floating Point Types})],Old=[]}
+    for those applications that require address@hidden,
+    New=[, and a floating point attribute function Machine_Rounding (also see
+    @RefSecNum{Attributes of Floating Point Types}) is provided for those
+    applications that require the highest possible performance], Old=[]}.
+    @lquotes@;address@hidden@; rounding is required for static
+    conversions to integer as well.
+    See @RefSecNum{Static Expressions and Static Subtypes}.
address@hidden
address@hidden(inneritemize)
+
address@hidden conversion],sec=(enumeration)}
address@hidden,sec=(enumeration)}
+Enumeration Type Conversion
address@hidden(inneritemize)
+  The result is the value of the target type with the same
+  position number as that of the operand value.
address@hidden(inneritemize)
+
address@hidden conversion],sec=(array)}
address@hidden,sec=(array)}
+Array Type Conversion
address@hidden(inneritemize)
+  @IndexCheck{Length_Check}
+  If the target subtype is a constrained array subtype, then
+  a check is made that the length of each dimension of the value of
+  the operand equals the length of the corresponding dimension of the
+  target subtype.
+  The bounds of the result are those of the target subtype.
+
+  @IndexCheck{Range_Check}
+  If the target subtype is an unconstrained array subtype, then the
+  bounds of the result are obtained by converting each bound of the value
+  of the operand to the corresponding index type of the target type.
+  @PDefn2{Term=[implicit subtype conversion],Sec=(array bounds)}
+  For each nonnull index range, a check is made that the
+  bounds of the range belong to the corresponding index subtype.
+  @begin(Discussion)
+    Only nonnull index ranges are checked, per AI83-00313.
+  @end(Discussion)
+
+  In either array case, the value of each component of the result is that
+  of the matching component of the operand value
+  (see @RefSecNum{Relational Operators and Membership Tests}).
+  @begin{Ramification}
+    This applies whether or not the component is initialized.
+  @end{Ramification}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00392-01]}
+  @ChgAdded{Version=[2],Text=[If the component types of the array types are
+  anonymous access types, then a check is made that the accessibility level
+  of the operand type is not deeper than that of the target type.
+  @IndexCheck{Accessibility_Check}]}
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[This check is needed for operands that are 
access
+    parameters and in instance bodies. Other cases are handled by the
+    legality rule given previously.]}
+  @end{Reason}
+
address@hidden(inneritemize)
+
address@hidden conversion],sec=[composite (non-array)]}
address@hidden,sec=[composite (non-array)]}
+Composite (Non-Array) Type Conversion
address@hidden(inneritemize)
+  The value of each nondiscriminant component of the result
+  is that of the matching component of the operand value.
+  @begin{Ramification}
+    This applies whether or not the component is initialized.
+  @end{Ramification}
+
+  @Redundant[The tag of the result is that of the operand.]
+  @IndexCheck{Tag_Check}
+  If the operand type is class-wide,
+  a check is made that the tag of the operand identifies
+  a (specific) type that is covered by or descended from
+  the target type.
+  @begin{Ramification}
+    This check is certain to succeed
+    if the operand type is itself covered by or descended from
+    the target type.
+  @end{Ramification}
+  @begin{TheProof}
+    The fact that a @nt{type_conversion} preserves the tag
+    is stated officially in @RefSec{Tagged Types and Type Extensions}
+  @end{TheProof}
+
+  For each discriminant of the target type that corresponds to
+  a discriminant of the operand type, its value is that of
+  the corresponding discriminant of the operand value;
+  @IndexCheck{Discriminant_Check}
+  if it corresponds
+  to more than one discriminant of the operand type, a check is made
+  that all these discriminants are equal in the operand value.
+
+  For each discriminant of the target type that corresponds to
+  a discriminant that is specified by the @nt<derived_type_definition>
+  for some ancestor of the operand type (or if class-wide,
+  some ancestor of the specific type identified by the tag
+  of the operand), its
+  value in the result is that specified by the @nt<derived_type_definition>.
address@hidden
+  It is a ramification of the rules for the discriminants of derived types
+  that each discriminant of the result is covered either by this
+  paragraph or the previous one. See @RefSecNum(Discriminants).
address@hidden
+
+  @IndexCheck{Discriminant_Check}
+  For each discriminant of the operand type that corresponds
+  to a discriminant that is specified by the @nt<derived_type_definition>
+  for some ancestor of the target type,
+  a check is made that in the operand value it equals the value
+  specified for it.
+
+  @IndexCheck{Range_Check}
+  For each discriminant of the result, a check is made that its
+  value belongs to its subtype.
address@hidden(inneritemize)
+
address@hidden conversion],sec=(access)}
address@hidden,sec=(access)}
+Access Type Conversion
address@hidden(inneritemize)
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0148-1],ARef=[AI05-0248-1]}
+  For an access-to-object type,
+  a check is made that the accessibility level of the operand
+  type is not deeper than that of the target address@hidden,New=[,
+  unless the target type is an anonymous access type of a stand-alone
+  object. If the target type is that of such a stand-alone object, a check is
+  made that the accessibility level of the operand type is not deeper than that
+  of the declaration of the stand-alone address@hidden; then if the check
+  succeeds, the accessibility level of the target type becomes that of the
+  operand type]],Old=[]}.
+  @IndexCheck{Accessibility_Check}
+
+  @begin{Ramification}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0148-1]}
+  This check is needed for operands that are access
+  address@hidden,New=[, for stand-alone anonymous access objects,],Old=[]}
+  and in instance bodies.
+
+  Note that this check can never fail for the implicit conversion
+  to the anonymous type of an access parameter that is done when
+  calling a subprogram with an access parameter.
+  @end{Ramification}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00231-01]}
+  If the @Chg{Version=[2],New=[],Old=[target type is an anonymous access type,
+  a check is made that the value of the operand is not null;
+  if the target is not an anonymous access type, then the
+  result is null if the ]}operand value is address@hidden,New=[, the
+  result of the conversion is the null value of the target type.],Old=[.
+  @IndexCheck{Access_Check}]}
+  @begin{Ramification}
+    @ChgRef{Version=[2],Kind=[Revised]}
+    A conversion to an anonymous access type
+    happens implicitly as part of initializing
+    @Chg{Version=[2],New=[or assigning to an anonymous access object],
+    Old=[an access discriminant or access parameter]}.
+  @end{Ramification}
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00231-01]}
+    @ChgDeleted{Version=[2],Text=[As explained in @RefSec{Access Types},
+    it is important that a value of an anonymous access type
+    can never be null.]}
+  @end{Reason}
+
+  If the operand value is not null, then
+  the result designates the same
+  object (or subprogram) as is designated by the operand value,
+  but viewed as being of the target designated subtype (or profile);
+  any checks associated with evaluating a conversion to
+  the target designated subtype are performed.
address@hidden
+  The checks are certain to succeed if
+  the target and operand designated subtypes statically match.
address@hidden
address@hidden(inneritemize)
address@hidden(itemize)
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0153-3],ARef=[AI05-0290-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0071-1]}
address@hidden
address@hidden
address@hidden
address@hidden,address@hidden,Old=[]}
+After conversion of the value to the target type,
+if the target subtype is constrained,
+a check is performed that the value satisfies this address@hidden,
+New=[ If the target subtype excludes null,
+then a check is made that the value is not null.],address@hidden,
+New=[ If predicate checks are enabled
+for the target subtype (see @RefSecNum{Subtype Predicates}), a check
+is performed that the @Chg{Version=[4],New=[value satisfies the
+predicates],Old=[predicate]} of the target
address@hidden,New=[],Old=[ is satisfied for the
address@hidden check],
+Sec=[subtype address@hidden, language-defined],
+Sec=[controlled by assertion policy]}],Old=[]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00231-01]}
+  The @Chg{Version=[2],New=[first],Old=[above]} check
+  @Chg{Version=[2],New=[above ],Old=[]}is a Range_Check for scalar subtypes, a
+  Discriminant_Check or Index_Check for access subtypes, and a 
Discriminant_Check
+  for discriminated subtypes. The Length_Check for an array conversion is
+  performed as part of the conversion to the target address@hidden,
+  New=[ The check for exclusion of null is an Access_Check.],Old=[]}
address@hidden
+
address@hidden, Sec=(view conversion)}
+For the evaluation of a view conversion, the operand @nt<name> is
+evaluated, and a new view of the
+object denoted by the operand is created, whose type is the
+target type;
address@hidden
address@hidden
address@hidden
+if the target type is composite, checks are
+performed as above for a value conversion.
+
address@hidden@;The properties of this new view are as follows:
address@hidden(itemize)
address@hidden,Kind=[Revised],Ref=[8652/0017],ARef=[AI95-00184-01]}
+  If the target type is composite, the bounds or discriminants (if any)
+  of the view are as defined above for a value conversion;
+  each nondiscriminant component of the view denotes the matching
+  component of the operand object; the
+  subtype of the view is constrained if either the target subtype
+  or the operand object is constrained,
+  @Chg{New=[or if the target subtype is indefinite,],Old=[]}
+  or if the operand type is a descendant of the target address@hidden,Old=[,]}
+  and has discriminants that were not inherited from
+  the target type;
+
+  If the target type is tagged, then an assignment to the
+  view assigns to the corresponding part of the object denoted
+  by the operand; otherwise, an assignment to the view
+  assigns to the object, after converting
+  the assigned value to the subtype of the object (which
+  might raise Constraint_Error);
+  @PDefn2{Term=[implicit subtype conversion],Sec=(assignment to view 
conversion)}
+
address@hidden,Kind=[Revised],ARef=[AI12-0074-1]}
+  Reading the value of the view yields the result of converting
+  the value of the operand object to the target subtype
+  (which might raise Constraint_Error), except if the object
+  is of an @Chg{Version=[4],New=[elementary],Old=[access]} type and the
+  view conversion is passed as an @key(out) parameter;
+  in this latter case, the value of the operand object
+  @Chg{Version=[4],New=[may be],Old=[is]} used to initialize the
+  formal parameter without checking against any constraint of the
+  target subtype
+  (@Chg{Version=[4],New=[as described more precisely in],Old=[see]}
+  @RefSecNum(Parameter Associations)).
+  @PDefn2{Term=[implicit subtype conversion],Sec=(reading a view conversion)}
+  @begin(Reason)
+    @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0074-1]}
+    This ensures that even an @key(out) parameter of
+    an @Chg{Version=[4],New=[elementary],Old=[access]} type is
+    initialized reasonably.
+  @end(Reason)
address@hidden(itemize)
+
address@hidden,Kind=[Revised],ARef=[AI05-0290-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0096-1]}
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,Sec=(raised by failure of run-time check)address@hidden,New=[
address@hidden(Assertion_Error),Sec=(raised by failure of run-time 
check)}],Old=[]}
+If an Accessibility_Check fails, Program_Error is raised.
address@hidden,New=[If a predicate check fails, @Chg{Version=[4],New=[the
+effect is as defined in subclause @RefSec{Subtype Predicates}],
+Old=[Assertions.Assertion_Error is
+raised]}. ],Old=[]}Any other check associated with a conversion raises
+Constraint_Error if it fails.
+
+Conversion to a type is the same as conversion to an unconstrained
+subtype of the type.
address@hidden
+This definition is needed because the semantics of various
+constructs involves converting to a type,
+whereas an explicit @nt{type_conversion} actually converts to a subtype.
+For example, the evaluation of a @nt{range} is defined to convert the
+values of the expressions to the type of the range.
address@hidden
address@hidden
+A conversion to a scalar type, or, equivalently,
+to an unconstrained scalar subtype,
+can raise Constraint_Error if the value is outside the base range of the
+type.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0027-1]}
address@hidden,Type=[Leading],Text=[Evaluation of a value conversion of a
+composite type either creates a new anonymous address@hidden (similar to the
+object created by the evaluation of an @nt{aggregate} or a function call)] or
+yields a new view of the operand object without creating a new object:]}
+
address@hidden
+   @ChgRef{Version=[4],Kind=[Added]}
+   @ChgAdded{Version=[4],Text=[If the target type is a by-reference type and
+   there is a type that is an ancestor of both the target type and the operand
+   type then no new object is created;]}
+
+   @ChgRef{Version=[4],Kind=[Added]}
+   @ChgAdded{Version=[4],Text=[If the target type is an array type having
+   aliased components and the operand type is an array type having unaliased
+   components, then a new object is created;]}
+
+   @ChgRef{Version=[4],Kind=[Added]}
+   @ChgAdded{Version=[4],Text=[Otherwise, it is unspecified whether a new 
object
+   is address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0027-1]}
address@hidden,Text=[If a new object is created, then the initialization
+of that object is an assignment operation.]}
+
address@hidden
+   @ChgRef{Version=[4],Kind=[Added]}
+   @ChgAdded{Version=[4],Text=[This makes a difference in the case of 
converting
+   from an array type with unaliased components to one with aliased components
+   if the element type has a controlled part.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden subtype conversion}
+In addition to explicit @nt<type_conversion>s,
+type conversions are performed implicitly in situations where the
+expected type and the actual type of a construct differ,
+as is permitted by the type resolution rules
+(see @RefSecNum(The Context of Overload Resolution)).
+For example, an integer literal is
+of the type @i(universal_integer), and is implicitly converted
+when assigned to a target of some specific integer type.
+Similarly, an actual parameter of a specific
+tagged type is implicitly converted when the corresponding
+formal parameter is of a class-wide type.
+
address@hidden@;@RootDefn{implicit subtype conversion}
address@hidden,Sec=(raised by failure of run-time check)}
+Even when the expected and actual types are the same,
+implicit subtype conversions are performed to adjust the array bounds (if any)
+of an operand to match the desired target subtype, or to
+raise Constraint_Error if the (possibly adjusted) value does not satisfy
+the constraints of the target subtype.
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01]}
+A ramification of the
+overload resolution rules is that the operand of
+an (explicit) @nt<type_conversion> cannot be
address@hidden,New=[],Old=[the literal @key(null), ]}an @nt<allocator>,
+an @nt<aggregate>, a @nt<string_literal>,
+a @nt<character_literal>, or an @nt<attribute_reference>
+for an Access or Unchecked_Access attribute.
+Similarly, such an @nt{expression} enclosed by parentheses is not
+allowed. A @nt<qualified_expression> (see @RefSecNum(Qualified Expressions))
+can be used instead of such a @nt<type_conversion>.
+
+The constraint of the target subtype has no effect
+for a @nt<type_conversion> of an elementary type passed
+as an @key(out) parameter. Hence, it is recommended
+that the first subtype be specified
+as the target to minimize confusion
+(a similar recommendation applies to renaming and
+generic formal @key(in out) objects).
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of numeric type conversion:)
address@hidden
+Real(2*J)      @RI[--  value is converted to floating point]
+Integer(1.6)   @RI[--  value is 2]
+Integer(-0.4)  @RI[--  value is 0]
address@hidden
+
address@hidden
address@hidden@address@hidden(Example of conversion between derived types:)
address@hidden
address@hidden
address@hidden(type) A_Form @key(is) @key(new) B_Form;
+
+X : A_Form;
+Y : B_Form;
+
+X := A_Form(Y);
+Y := B_Form(X);  @RI[--  the reverse conversion ]
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of conversions between array types:)
address@hidden
+
address@hidden
address@hidden(type) Sequence @key(is) @key(array) (Integer @key(range) <>) 
@key(of) Integer;
address@hidden(subtype) Dozen @key(is) Sequence(1 .. 12);
+Ledger : @key(array)(1 .. 100) @key(of) Integer;
+
+Sequence(Ledger)            @RI[--  bounds are those of Ledger]
+Sequence(Ledger(31 .. 42))  @RI[--  bounds are 31 and 42]
+Dozen(Ledger(31 .. 42))     @RI[--  bounds are those of Dozen ]
address@hidden
address@hidden
+
address@hidden
address@hidden with Ada 83}
+A @nt<character_literal> is not allowed as the
+operand of a @nt<type_conversion>,
+since there are now two character types in package Standard.
+
+The component subtypes have to statically match in an array conversion,
+rather than being checked for matching constraints at run time.
+
+Because sliding of array bounds is now provided for operations where it
+was not in Ada 83,
+programs that used to raise Constraint_Error might now
+continue executing and produce a reasonable result.
+This is likely to fix more bugs than it creates.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+A @nt<type_conversion> is considered the name of an object
+in certain circumstances (such a @nt<type_conversion>
+is called a view conversion).
+In particular, as in Ada 83,
+a @nt<type_conversion> can appear as an @key(in out) or @key(out)
+actual parameter. In addition, if the target type is tagged
+and the operand is the @nt<name> of an object, then so
+is the @nt<type_conversion>, and it can be used as the @nt<prefix>
+to a @nt<selected_component>, in an @nt<object_renaming_declaration>, etc.
+
+We no longer require type-mark conformance between
+a parameter of the form of a type conversion, and the corresponding
+formal parameter. This had caused some problems for
+inherited subprograms (since there isn't really a type-mark
+for converted formals), as well as for renamings, formal subprograms,
+etc. See AI83-00245, AI83-00318, AI83-00547.
+
+We now specify @lquotes@;address@hidden@; rounding from real to integer types
+when the value of the operand is exactly between two integers
+(rounding is away from zero in this case).
+
address@hidden@;address@hidden@; of array bounds
+(which is part of conversion to an array subtype)
+is performed in more cases in Ada 95 than in Ada 83.
+Sliding is not performed on
+the operand of a membership test,
+nor on the operand of a @nt{qualified_expression}.
+It wouldn't make sense on a membership test,
+and we wish to retain a connection between subtype membership
+and subtype qualification. In general, a subtype membership test returns
+True if and only if a corresponding subtype qualification
+succeeds without raising an exception.
+Other operations that take arrays perform sliding.
address@hidden
+
address@hidden
+We no longer explicitly list the kinds of things that are not allowed
+as the operand of a @nt<type_conversion>, except in a NOTE.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The rules in this @Chg{Version=[3],New=[subclause],Old=[clause]} subsume the 
rules
+for "parameters of the form of a type conversion,"
+and have been generalized to cover the use of a type conversion
+as a @nt<name>.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00246-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] Conversions
+  between unrelated array types that are limited or (for view conversions)
+  might be by-reference types are now illegal. The representations of two such
+  arrays may differ, making the conversions impossible. We make the check here,
+  because legality should not be based on representation properties.
+  Such conversions are likely to be rare, anyway. There is a potential that
+  this change would make a working program illegal (if the types have the same
+  representation).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00363-01]}
+  @ChgAdded{Version=[2],Text=[If a discriminated full type has a partial view
+  (private type) that is constrained, we do not allow conversion between
+  access-to-unconstrained and access-to-constrained subtypes designating the
+  type. Ada 95 allowed this conversion and the declaration of various access
+  subtypes, requiring that the designated object be constrained and thus making
+  details of the implementation of the private type visible to the client of
+  the private type. See @RefSecNum{Allocators} for more on this topic.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}Conversion rules for
+  @i<universal_access> were defined. These allow the use of anonymous access
+  values in equality tests (see
+  @RefSecNum{Relational Operators and Membership Tests}), and also allow the
+  use of @b<null> in type conversions and other
+  contexts that do not provide a single expected type.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00384-01]}
+  @ChgAdded{Version=[2],Text=[A type conversion from
+  an access-to-discriminated and unconstrained object to an
+  access-to-discriminated and constrained one is allowed. Ada 95 only allowed
+  the reverse conversion, which was weird and asymmetric. Of course, a
+  constraint check will be performed for this conversion.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0017],ARef=[AI95-00184-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Wording was added to 
ensure that
+  view conversions are constrained, and that a tagged view conversion has a
+  tagged object. Both rules are needed to avoid having a way to change the
+  discriminants of a constrained object.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0008],ARef=[AI95-00168-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Wording was added to 
ensure
+  that the aliased status of array components cannot change in a view
+  conversion. This rule was needed to avoid having a way to change the
+  discriminants of an aliased object. This rule was repealed later, as
+  Ada 2005 allows changing the discriminants of an aliased object.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],Text=[Wording was added to check subtypes that exclude
+  null (see @RefSecNum{Access Types}).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Text=[The organization of the legality rules was
+  changed, both to make it clearer, and to eliminate an unintentional
+  incompatibility with Ada 83. The old organization prevented type conversions
+  between some types that were related by derivation (which Ada 83 always
+  allowed).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00330-01]}
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[Clarified that an untagged type conversion
+  appearing as a generic actual parameter for a generic @key{in out} formal
+  parameter is not a view conversion (and thus is illegal). This confirms
+  the ACATS tests, so all implementations already follow this
+  @Chg{Version=[3],New=[interpretation],Old=[intepretation]}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00363-01]}
+  @ChgAdded{Version=[2],Text=[Rules added by the Corrigendum to eliminate
+  problems with discriminants of aliased components changing were removed, as
+  we now generally allow discriminants of aliased components to be changed.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00392-01]}
+  @ChgAdded{Version=[2],Text=[Accessibility checks on conversions involving
+  types with anonymous access components were added. These components have
+  the level of the type, and conversions can be between types at different
+  levels, which could cause dangling access values in the absence of such
+  checks.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0148-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}A
+  stand-alone object of an anonymous access-to-object type now has dynamic
+  accessibility. Normally, this will make programs legal that were illegal
+  in Ada 2005. However, it is possible that a program that previously raised
+  Program_Error now will not. It is very unlikely that an existing program
+  intentionally depends on the exception being raised; the change is more 
likely
+  to fix bugs than introduce them.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0115-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified that a root 
numeric
+  type is not considered a common ancestor for a conversion.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0153-3],ARef=[AI05-0290-1]}
+  @ChgAdded{Version=[3],Text=[Added rules so that predicate aspects (see
+  @RefSecNum{Subtype Predicates}) are enforced on subtype conversion.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0095-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Because of a rule added in
+  @RefSecNum{Formal Private and Derived Types}, the checks for the
+  legality of an access type conversion in a generic body were strengthened
+  to use an assume the worst rule. This case is rather unlikely as a formal
+  private or derived type with discriminants is required along with a
+  conversion between two access types whose designated types don't statically
+  match, and any such programs were at risk having objects disappear while
+  valid access values still pointed at them.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0027-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Moved the generic 
boilerplate
+  so that it covers all @LegalityTitle in this subclause. This was always
+  intended, but it is not expected to change anything other than conversions
+  between unrelated arrays.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0027-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Added a formal definition 
of
+  the copy potentially created by a value conversion of a composite type,
+  so properties like finalization and accessibility are properly defined.
+  This model was always intended and expected (else
+  @RefSecNum{Change of Representation} would not work), but it was not
+  previously formally defined.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0071-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Updated wording of
+  type conversions to use the new term "satisfies the predicates"
+  (see @RefSecNum{Subtype Predicates}).]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0074-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified the wording
+  describing the effect of view conversions of @key[out] parameters
+  such that it is clear that the detailed effect is defined in
+  @RefSecNum(Parameter Associations), not here.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0096-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Updated wording of
+  type conversions so that the exception raise or other effect of a failed
+  predicate check is as defined in @RefSecNum{Subtype Predicates}; we don't
+  want to repeat those rules here. This doesn't change the behavior for
+  predicate checks possible in original Ada 2012, only ones using the new
+  aspect Predicate_Failure.]}
address@hidden
+
+
address@hidden Expressions}
+
address@hidden
address@hidden @nt<qualified_expression> is used to state explicitly the type,
+and to verify the subtype, of an operand that is either an @nt<expression>
+or an @nt<aggregate>.
address@hidden conversion],See=(qualified_expression)}]
address@hidden
+
address@hidden
address@hidden<qualified_expression>,rhs="
+   @address@hidden@;(@Syn2{expression}) | @address@hidden@Syn2{aggregate}"}
address@hidden
+
address@hidden
address@hidden, Sec=(of a @nt{qualified_expression})}
+The @i(operand) (the @nt{expression} or @nt{aggregate})
+shall resolve to be of the type determined by the @address@hidden,
+or a universal type that covers it.
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0003-1]}
address@hidden,address@hidden the operand of a @nt{qualified_expression}
+denotes an object, the @nt{qualified_expression} denotes a constant view
+of that object.] The nominal subtype of a @nt{qualified_expression}
+is the subtype denoted by the @nt{subtype_mark}.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0003-1]}
+  @ChgAdded{Version=[3],Text=[This is stated in @RefSecNum{Objects and Named 
Numbers}.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI12-0100-1]}
address@hidden, Sec=(qualified_expression)}
address@hidden
address@hidden
address@hidden
+The evaluation of a @nt{qualified_expression} evaluates the
+operand (and if of a universal type, converts it
+to the type determined by the @nt{subtype_mark})
+and checks that its value belongs to the subtype denoted by
+the @nt{subtype_mark}.
address@hidden subtype conversion],Sec=(qualified_expression)}
address@hidden,Sec=(raised by failure of run-time check)}
+The exception Constraint_Error is raised if this check address@hidden,
+New=[ Furthermore, if predicate checks are enabled for the subtype
+denoted by the @nt{subtype_mark}, a check is performed as defined in
+subclause @RefSec{Subtype Predicates} that the value satifies the predicates
+of the subtype.],Old=[]}
address@hidden
+  This is one of the few contexts in Ada 95 where implicit subtype conversion
+  is not performed prior to a constraint check, and hence no
+  @lquotes@;address@hidden@; of array bounds is provided.
+
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0100-1]}
+  @ChgAdded{Version=[4],Text=[The effect of a failed predicate check
+  is as defined in @RefSecNum{Subtype Predicates}; such a check could raise
+  any exception, not just Constraint_Error or Assertion_Error.]}
address@hidden
address@hidden
+  Implicit subtype conversion is not provided because a
+  @nt<qualified_expression> with a constrained target subtype is
+  essentially an assertion about the subtype of the operand, rather
+  than a request for conversion. An explicit @nt<type_conversion> can
+  be used rather than a @nt<qualified_expression> if subtype
+  conversion is desired.
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0100-1]}
+  @ChgAdded{Version=[4],Text=[We do a predicate check here so that
+  a @nt{qualified_expression} never allows something that the equivalent
+  @nt{type_conversion} would not allow.]}
address@hidden
address@hidden
+
address@hidden
+When a given context does not uniquely identify an expected type,
+a @nt<qualified_expression> can be used to do so.
+In particular, if an overloaded @nt<name> or
address@hidden<aggregate> is passed to an overloaded subprogram, it
+might be necessary to qualify the operand to resolve its type.
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of disambiguating expressions using 
qualification:)
address@hidden
address@hidden(type) Mask @key(is) (Fix, Dec, Exp, Signif);
address@hidden(type) Code @key(is) (Fix, Cla, Dec, Tnz, Sub);
+
+Print (Mask'(Dec));  @RI[--  Dec is of type Mask]
+Print (Code'(Dec));  @RI[--  Dec is of type Code ]
+
address@hidden(for) J @key(in) Code'(Fix) .. Code'(Dec) @key(loop) ... @RI[-- 
qualification needed for either Fix or Dec]
address@hidden(for) J @key(in) Code @key(range) Fix .. Dec @key(loop) ...    
@RI[-- qualification unnecessary]
address@hidden(for) J @key(in) Code'(Fix) .. Dec @key(loop) ...        @RI[-- 
qualification unnecessary for Dec]
+
+Dozen'(1 | 3 | 5 | 7 => 2, @key(others) => 0) @RI[-- see @RefSecNum{Type 
Conversions} ]
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0003-1]}
+  @ChgAdded{Version=[3],Text=[Added a definition of
+  the nominal subtype of a @nt{qualified_expression}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0100-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  A @nt{qualified_expression} now performs a predicate check for the named
+  subtype (if it is enabled). Original Ada 2012 did not include that check
+  (an omission). While this is formally inconsistent (an exception could
+  be raised when none would be raised by original Ada 2012), cases when this
+  could be the case are likely to be rare (the qualified expression would have
+  to have a stricter subtype than the following usage) and the check is more
+  likely to detect bugs than be unexpected.]}
address@hidden
+
+
address@hidden
+
address@hidden
address@hidden evaluation of an @nt<allocator> creates an object and yields
+an access value that designates the object.
address@hidden,See=(allocator)}
address@hidden,See=(allocator)}
address@hidden management],See=(allocator)}]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0111-3]}
address@hidden<allocator>,rhs="
+   @key{new} @Chg{Version=[3],New=<address@hidden 
>,Old=<>address@hidden@Chg{Version=[3],New=<
+>,Old=<>} | @key{new} @Chg{Version=[3],New=<address@hidden 
>,Old=<>address@hidden"}
+
address@hidden,Kind=[Added],ARef=[AI05-0111-3]}
address@hidden,lhs=<@Chg{Version=[3],New=<subpool_specification>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<(@address@hidden)>,Old=<>}"}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0104-1]}
address@hidden,Text=[For an @nt{allocator} with a @nt{subtype_indication},
+the @nt{subtype_indication} shall not specify a @nt{null_exclusion}.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Such an uninitialized @nt{allocator} would
+necessarily raise Constraint_Error, as the default value is @key[null].
+Also note that the syntax does not allow a @nt{null_exclusion} in
+an initialized @nt{allocator}, so it makes sense to make the
+uninitialized case illegal as well.]}
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0010],ARef=[AI95-00127-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0111-3],ARef=[AI05-0269-1]}
address@hidden type],Sec=(allocator)}
+The expected type for an @nt<allocator> shall be a single access-to-object
+type @Chg{New=[with],Old=[whose]} designated type
address@hidden@i<D> such that either @i<D>],Old=[]} covers the type determined
+by the @nt<subtype_mark> of the @nt<address@hidden> or
address@hidden<address@hidden>@Chg{New=[, or the expected type is anonymous and
+the determined type is @i<D>'Class],address@hidden,New=[
+A @address@hidden is expected to be of any type descended from
+Subpool_Handle, which is the type used to identify a subpool, declared
+in package System.Storage_Pools.Subpools
+(see @RefSecNum{Storage Subpools})address@hidden 
type],Sec=(subpool_handle_name)}],Old=[]}
address@hidden
+  See @RefSec(The Context of Overload Resolution) for the meaning
+  of @lquotes@;shall be a single ... type whose address@hidden@;
address@hidden
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0010],ARef=[AI95-00127-01]}
address@hidden @nt{allocator} is allowed as a controlling parameter of a 
dispatching
+call (see @RefSecNum{Dispatching Operations of Tagged Types}).],Old=[]}
address@hidden
address@hidden
+
address@hidden
address@hidden allocator}
+An @i(initialized) allocator is an @nt{allocator}
+with a @nt{qualified_expression}.
address@hidden allocator}
+An @i(uninitialized) allocator is one with
+a @nt{subtype_indication}.
+In the @nt<subtype_indication> of an uninitialized allocator, a
address@hidden<constraint> is permitted only if the @nt<subtype_mark> denotes an
address@hidden composite subtype;
+if there is no @nt<constraint>, then the @nt<subtype_mark>
+shall denote a definite subtype.
address@hidden,See=[initialized allocator]}
address@hidden
+  For example, ... @key[new] S'Class ... (with no initialization
+  expression) is illegal,
+  but ... @key[new] S'Class'(X) ... is legal,
+  and takes its tag and constraints from the initial value X.
+  (Note that the former case cannot have a constraint.)
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
+If the type of the @nt<allocator> is an access-to-constant type,
+the @nt<allocator> shall be an initialized allocator.
address@hidden,New=[],Old=[If the designated type is limited,
+the @nt<allocator> shall be an uninitialized allocator.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Deleted],ARef=[AI95-00287-01]}
+  @ChgDeleted{Version=[2],Text=[For an access-to-constant type whose designated
+  type is limited, @nt{allocator}s are illegal.
+  The Access attribute is legal for such a type, however.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0111-3]}
address@hidden,Text=[If a @nt{subpool_specification} is given,
+the type of the storage pool of the access type shall be a descendant
+of Root_Storage_Pool_With_Subpools.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00344-01]}
address@hidden,address@hidden the paragraph numbers changed}
address@hidden,Text=[If the designated type of the type of the
address@hidden is class-wide, the accessibility level of the type determined by 
the
address@hidden or @nt{qualified_expression} shall not be statically
+deeper than that of the type of the @nt{allocator}.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This prevents the allocated object from outliving
+  its type.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00416-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0051-1]}
address@hidden,Text=[If the @Chg{Version=[3],New=[subtype determined
+by the @nt{subtype_indication} or @nt{qualified_expression}],Old=[designated
+subtype of the type]} of the @nt{allocator} has one or more
address@hidden,New=[],Old=[unconstrained ]}access discriminants, then the
+accessibility level of the anonymous access type of each access
address@hidden,New=[],Old=[,
+as determined by the @nt{subtype_indication} or @nt{qualified_expression} of
+the @nt{allocator},]} shall not be statically deeper than that of the type
+of the @nt{allocator} (see @RefSecNum{Operations of Access Types}).]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This prevents the allocated object from outliving
+  its discriminants.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00366-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0052-1],ARef=[AI05-0157-1]}
address@hidden,Text=[An @nt{allocator} shall not be of an access type
+for which the Storage_Size has been specified by a static expression with value
+zero or is defined by the language to be zero. @Chg{Version=[3],New=[],
address@hidden contract issue}In addition to the places
+where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}), this rule applies also in the private
+part of an instance of a generic unit. This rule does not apply in the body of
+a generic unit or within a body declared within the declarative region of a
+generic unit, if the type of the allocator is a descendant of a formal access
+type declared within the formal part of the generic unit.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[An @nt{allocator} for an access type that has
+  Storage_Size specified to be zero is required to raise Storage_Error anyway.
+  It's better to detect the error at compile-time, as the @nt{allocator}
+  might be executed infrequently. This also simplifies the rules for Pure
+  units, where we do not want to allow any allocators for library-level access
+  types, as they would represent state.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0157-1]}
+  @ChgAdded{Version=[2],address@hidden,New=[We don't need a special
+  rule to cover generic formals (unlike many other similar @LegalityTitle).
+  There are only two cases of interest. For formal access types, the
+  Storage_Size property is not known in the generic, and surely isn't
+  static, so this @LegalityName can never apply. For a formal derived type,
+  this @LegalityName can only be triggered by a parent type having one of
+  the appropriate properties. But Storage_Size can never be specified for
+  a derived access type, so it always has the same value for all child types;
+  additionally, a type derived from a remote access type (which has 
Storage_Size
+  defined to be zero) is also a remote access type. That means that any actual
+  that would match the formal derived type necessarily has the same
+  Storage_Size properties, so it is harmless (and preferable) to check them
+  in the body - they are always known in that case.
+  For other formal types,@nt{allocator}s are not allowed, so we don't need
+  to consider them. So we don't need an assume-the-best rule
+  here.],Old=[The last sentence covers the case of children of
+  generics, and formal access types of formal packages of the generic unit.]}]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0052-1]}
address@hidden,Text=[If the designated type of the type of the
address@hidden is limited, then
+the @nt{allocator} shall not be used to define the value of an access
+discriminant, unless the discriminated type is immutably limited
+(see @RefSecNum{Limited Types}).]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Because coextensions work very much like parts,
+  we don't want users creating limited coextensions for nonlimited types. This
+  would be similar to extending a nonlimited type with a limited component. We
+  check this on the @nt{allocator}. Note that there is an asymmetry in what
+  types are considered limited; this is required to preserve privacy. We have
+  to assume that the designated type might be limited as soon as we see a
+  limited partial view, but we want to ensure that the containing object is of
+  a type that is always limited.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0052-1]}
address@hidden,address@hidden contract issue}In addition to
+the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}), these rules apply also in the private
+part of an instance of a generic unit.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This applies to all of the @LegalityTitle
+  of this subclause.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00363-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0041-1]}
+If the designated type of the type of the @nt<allocator> is elementary,
+then the subtype of the created object is the designated
+subtype.
+If the designated type is composite, then the
address@hidden,New=[subtype of the ],Old=[]}created object is
address@hidden,New=[the designated
+subtype when the designated subtype is constrained or there is
address@hidden,New=[an ancestor of the designated type that
+has a constrained],Old=[a]} partial
address@hidden,New=[],Old=[ of the designated type that is constrained]};
+otherwise, the created],Old=[always constrained;
+if the designated subtype is constrained,
+then it provides the constraint of the created object;
+otherwise, the]} object is constrained by its initial value
address@hidden(even if the designated subtype is unconstrained with defaults)].
address@hidden by its initial value}
+  @begin{Discussion}
+  See AI83-00331.
+  @end{Discussion}
+  @begin{Reason}
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00363-01]}
+  All objects created by an @Chg{Version=[2],address@hidden,Old=[allocator]}
+  are aliased,
+  and @Chg{Version=[2],New=[most],Old=[all]} aliased composite objects
+  need to be constrained so that access subtypes work reasonably.
+  @Chg{Version=[2],New=[Problematic access subtypes are prohibited for
+  types with a constrained partial view.],Old=[]}
+  @end{Reason}
+  @begin{Discussion}
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00363-01]}
+  @ChgAdded{Version=[2],Text=[If there is a constrained partial view of the 
type, this
+    allows the objects to be unconstrained. This eliminates privacy breaking
+    (we don't want the objects to act differently simply because they're
+    allocated). Such a created object is effectively constrained by its initial
+    value if the access type is an access-to-constant type, or the designated
+    type is limited (in all views), but we don't need to state that here. It is
+    implicit in other rules. Note, however, that a value of an
+    access-to-constant type can designate a variable object via 'Access or
+    conversion, and the variable object might be assigned by some other access
+    path, and that assignment might alter the discriminants.]}
+  @end{Discussion}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00373-01]}
address@hidden, Sec=(allocator)}
+For the evaluation of an @Chg{Version=[2],New=[initialized allocator],
address@hidden<allocator>]}, the @Chg{Version=[2],New=[],Old=[elaboration of
+the @nt<subtype_indication> or the ]}evaluation of the
address@hidden<qualified_expression> is performed first.
address@hidden, Sec=(initialized allocator)}
address@hidden operation], Sec=(during evaluation of an
+initialized allocator)}
address@hidden,New=[An],Old=[For the evaluation of an initialized allocator,
+an]} object of the designated type is created and the value of the
address@hidden<qualified_expression> is converted to the designated subtype
+and assigned to the object.
address@hidden subtype conversion],Sec=(initialization expression of allocator)}
address@hidden
+  The conversion might raise Constraint_Error.
address@hidden
+
address@hidden, Sec=(uninitialized allocator)}
address@hidden@keepnext@;@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00373-01]}
+For the evaluation of an uninitialized address@hidden,New=[, the
+elaboration of the @nt{subtype_indication} is performed first. Then],Old=[]}:
address@hidden(itemize)
address@hidden operation], Sec=(during evaluation of an
+uninitialized allocator)}
+  If the designated type is elementary, an object of the
+  designated subtype is created and any implicit initial value is assigned;
+
address@hidden,Kind=[Revised],Ref=[8652/0002],ARef=[AI95-00171-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00373-01]}
address@hidden,New=[],address@hidden operation],
+Sec=(during evaluation of an uninitialized allocator)}]}
+  If the designated type is composite, an object of the
+  designated type is created with tag, if any, determined
+  by the @nt<subtype_mark> of the 
@nt<subtype_indication>@Chg{Version=[2],New=[.
+  This object is then initialized by default (see
+  @RefSecNum{Object Declarations}) using],Old=[;
+  any per-object constraints on subcomponents are elaborated
+  @Chg{New=[(see @RefSecNum{Record Types}) ],Old=[]}and any implicit initial
+  values for the subcomponents of the object are obtained as determined by]}
+  the @nt<subtype_indication>
+  @Chg{Version=[2],New=[to determine its nominal subtype],
+  Old=[and assigned to the corresponding subcomponents]}.
+  @IndexCheck{Index_Check}
+  @IndexCheck{Discriminant_Check}
+  A check is made that the value of the object belongs to the designated
+  subtype.
+  @Defn2{Term=[Constraint_Error],Sec=(raised by failure of run-time check)}
+  Constraint_Error is raised if this check fails.
+  This check and the initialization of the object are performed in
+  an arbitrary address@hidden order],Sec=[allowed]}
+
address@hidden
+AI83-00150.
address@hidden
address@hidden(itemize)
+
address@hidden,Kind=[Added],ARef=[AI95-00344-01],ARef=[AI95-00416-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0024-1],ARef=[AI05-0051-1],ARef=[AI05-0234-1]}
address@hidden,Text=[For any @nt{allocator}, if the designated type of
+the type of the @nt{allocator}
+is class-wide, then a check is made that the @Chg{Version=[3],New=[master],
+Old=[accessibility level]} of the type
+determined by the @nt{subtype_indication}, or by the tag of the value of the
address@hidden, @Chg{Version=[3],New=[includes the elaboration],
+Old=[is not deeper than that]} of the type of the @nt{allocator}. If
address@hidden,New=[any part of ],Old=[]}the
address@hidden,New=[subtype determined by the @nt{subtype_indication} or
address@hidden,Old=[designated subtype]} of the @nt{allocator}
address@hidden,New=[(or by the tag of the value if the type of the
address@hidden is class-wide) ],Old=[]}has
+one or more @Chg{Version=[3],New=[],Old=[unconstrained ]}access
+discriminants, then a check is made that the accessibility
+level of the anonymous access type of each access discriminant is
+not deeper than that of the type of the @nt{allocator}.
+Program_Error is raised
+if either such check address@hidden
address@hidden,Sec=(raised by failure of run-time check)}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00344-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0024-1]}
+  @ChgAdded{Version=[2],Text=[The
+  @Chg{Version=[3],New=[master],Old=[accessibility]} check on class-wide types
+  prevents the allocated object from outliving its type. We need the run-time
+  check in instance bodies, or when the type of the @nt{qualified_expression}
+  is class-wide (other cases are statically detected).]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0024-1]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[We can't use the normal
+    accessibility level @lquotes@;deeper address@hidden@; check
+    here because we may have @lquotes@;address@hidden@; levels if
+    the appropriate master and the type declaration belong to two different
+    tasks. This can happen when
+    checking the master of the tag for an allocator initialized by
+    a parameter passed in to an accept statement, if the type of the allocator
+    is an access type declared in the enclosing task body. For example:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden body] TT @key[is]
+   @key[type] Acc_TC @key[is access] T'Class;
+   P : Acc_TC;
address@hidden
+   @key[accept] E(X : T'Class) @key[do]
+      P := @key[new] T'Class'(X);
+         @RI[--  Master check on tag of X.]
+         @RI[--  Can't use "accessibility levels" since they might be 
incomparable.]
+         @RI[--  Must revert to checking that the master of the type 
identified by]
+         @RI[--  X'tag includes the elaboration of Acc_TC, so it is sure to 
outlive it.]
+   @key[end] E;]}
address@hidden
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[The accessibility check on access discriminants
+  prevents the allocated object from outliving its discriminants.]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00280-01]}
address@hidden,New=[If the object to be created by an @nt<allocator> has a
+controlled or protected part, and the finalization of the collection of the
+type of the @nt{allocator} (see @RefSecNum{Completion and Finalization}) has
+started, Program_Error is address@hidden
address@hidden,Sec=(raised by failure of run-time check)}],Old=[]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If the object has a controlled or protected 
part, its
+  finalization is likely to be nontrivial. If the allocation was allowed,
+  we could not know whether the finalization would actually be performed.
+  That would be dangerous to otherwise safe abstractions, so we mandate
+  a check here. On the other hand, if the finalization of the object will
+  be trivial, we do not require (but allow) the check, as no real harm
+  could come from late allocation.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This check can only fail if an @nt{allocator}
+  is evaluated in code reached from a Finalize routine for a type declared
+  in the same master. That's highly unlikely; Finalize routines are much
+  more likely to be deallocating objects than allocating them.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00280-01]}
address@hidden,New=[If the object to be created by an @nt<allocator>
+contains any tasks, and the master of the type of the @nt<allocator> is
+completed, and all of the dependent tasks of the master are terminated
+(see @RefSecNum{Task Dependence - Termination of Tasks}), then
+Program_Error is address@hidden
address@hidden,Sec=(raised by failure of run-time check)}],Old=[]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[A task created after waiting for tasks has
+  finished could depend on freed data structures, and certainly would never
+  be awaited.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0111-3]}
address@hidden,Text=[If the @nt{allocator} includes a
address@hidden@nt{name}, Constraint_Error is raised if the subpool
+handle is @key[null]. Program_Error is raised if the subpool does not 
@i<belong>
+(see @RefSecNum{Storage Subpools}) to the storage pool of the access type of 
the
address@hidden@address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,Sec=(raised by failure of run-time check)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This can be implemented by comparing the result 
of
+  Pool_of_Subpool to a reference to the storage pool object. Pool_of_Subpool's
+  parameter is @key[not null], so the check for null falls out naturally.]}
address@hidden
+
address@hidden
+   @ChgRef{Version=[3],Kind=[AddedNormal]}
+   @ChgAdded{Version=[3],Text=[This detects cases where the subpool belongs to
+   another pool, or to no pool at all. This includes detecting dangling subpool
+   handles so long as the subpool object (the object designated by the handle)
+   still exists. (If the subpool object has been deallocated, execution is
+   erroneous; it is likely that this check will still detect the problem, but
+   there cannot be a guarantee.)]}
address@hidden
+
address@hidden the created object contains any tasks,
+they are activated
+(see @RefSecNum(Task Execution - Task Activation)).]
+Finally, an access value that designates the created object is returned.
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00280-01]}
address@hidden,address@hidden(bounded error),Sec=(cause)} It is a
+bounded error if the finalization of the collection of the type (see
address@hidden and Finalization}) of the @nt<allocator> has started. If
+the error is detected, Program_Error is raised. Otherwise, the allocation
+proceeds normally.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This check is required in some cases; see 
above.]}
address@hidden
address@hidden
+
address@hidden
+Allocators cannot create objects of an abstract type.
+See @RefSecNum{Abstract Types and Subprograms}.
+
+If any part of the created object is controlled, the initialization
+includes calls on corresponding Initialize or Adjust procedures.
+See @RefSecNum{Assignment and Finalization}.
+
+As explained in @RefSec{Storage Management},
+the storage for an object allocated by an @nt{allocator} comes from a
+storage pool (possibly user defined).
address@hidden,Sec=(raised by failure of run-time check)}
+The exception Storage_Error is raised by an @nt<allocator> if there
+is not enough storage.
+Instances of Unchecked_Deallocation may be used to explicitly reclaim
+storage.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+Implementations are permitted, but not required,
+to provide garbage address@hidden,New=[],Old=[
+(see @RefSecNum{Default Storage Pools})]}.
address@hidden
+  Note that in an @nt<allocator>,
+  the exception Constraint_Error can be
+  raised by the evaluation of the @nt<qualified_expression>,
+  by the elaboration of the @nt<subtype_indication>, or by the
+  initialization.
address@hidden
address@hidden
+  By default, the implementation provides the storage pool.
+  The user may exercise more control over storage management by
+  associating a user-defined pool with an access type.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of allocators:}
address@hidden
address@hidden(new) Cell'(0, @key(null), @key(null))                          
@RI[-- initialized explicitly, see @RefSecNum{Incomplete Type Declarations}]
address@hidden(new) Cell'(Value => 0, Succ => @key(null), Pred => @key(null)) 
@RI[-- initialized explicitly]
address@hidden(new) Cell                                          @RI[-- not 
initialized]
+
address@hidden(new) Matrix(1 .. 10, 1 .. 20)                      @RI[-- the 
bounds only are given]
address@hidden(new) Matrix'(1 .. 10 => (1 .. 20 => 0.0))          @RI[-- 
initialized explicitly]
+
address@hidden(new) Buffer(100)                                   @RI[-- the 
discriminant only is given]
address@hidden(new) Buffer'(Size => 80, Pos => 0, Value => (1 .. 80 => 'A')) 
@RI[-- initialized explicitly]
+
+Expr_Ptr'(@key(new) Literal)                  @RI[-- allocator for 
access-to-class-wide type, see @RefSecNum{Type Extensions}]
+Expr_Ptr'(@key(new) Literal'(Expression @key[with] 3.5))      @RI[-- 
initialized explicitly]
+
address@hidden
address@hidden
+
address@hidden
address@hidden,address@hidden AI-00019}
address@hidden with Ada 83}
+The @nt<subtype_indication> of an uninitialized allocator may
+not have an explicit @nt<constraint> if the designated type is an access type.
+In Ada 83, this was permitted even though the @nt<constraint> had
+no @Chg{New=[e],Old=[a]}ffect on the subtype of the created object.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Allocators creating objects of type @i(T)
+are now overloaded on access types designating
address@hidden(T')Class and all class-wide types that cover @i(T).
+
+Implicit array subtype conversion (sliding) is now performed
+as part of an initialized allocator.
address@hidden
+
address@hidden
+We have used a new organization, inspired by the ACID
+document, that makes it clearer what is the subtype of
+the created object, and what subtype conversions take place.
+
+Discussion of storage management issues,
+such as garbage collection and the raising of Storage_Error,
+has been moved to @RefSec{Storage Management}.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00363-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}If the
+  designated type has a constrained partial view,
+  the allocated object can be unconstrained. This might cause the object to
+  take up a different amount of memory, and might cause the operations to work
+  where they previously would have raised Constraint_Error. It's unlikely that
+  the latter would actually matter in a real program (Constraint_Error usually
+  indicates a bug that would be fixed, not left in a program.) The former
+  might cause Storage_Error to be raised at a different time than in an Ada 95
+  program.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00366-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}An
+  @nt{allocator} for an access type that has Storage_Size specified to be
+  zero is now illegal. Ada 95 allowed the @nt{allocator}, but it had to
+  raise Storage_Error if executed. The primary impact of this change should
+  be to detect bugs.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0010],ARef=[AI95-00127-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada address@hidden<Corrigendum:> An
+  @nt{allocator} can be a controlling parameter of a dispatching call. This
+  was an oversight in Ada 95.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],Text=[Initialized @nt{allocator}s are allowed when
+  the designated type is limited.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0002],ARef=[AI95-00171-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified the elaboration 
of
+  per-object constraints for an uninitialized allocator.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00280-01]}
+  @ChgAdded{Version=[2],Text=[Program_Error is now raised if the @nt{allocator}
+  occurs after the finalization of the collection or the waiting for tasks.
+  This is not listed as an incompatibility as the Ada 95 behavior was
+  unspecified, and Ada 95 implementations tend to generate programs that crash
+  in this case.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00344-01]}
+  @ChgAdded{Version=[2],Text=[Added accessibility checks to class-wide
+  @nt{allocator}s. These checks could not fail in Ada 95 (as all of the
+  designated types had to be declared at the same level, so the access type
+  would necessarily have been at the same level or more nested than the type
+  of allocated object).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00373-01]}
+  @ChgAdded{Version=[2],Text=[Revised the description of evaluation of
+  uninitialized allocators to use @lquotes@;initialized by address@hidden
+  so that the ordering requirements are the same for all kinds of objects
+  that are default-initialized.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[Added accessibility checks to access
+  discriminants of @nt{allocator}s. These checks could not fail in Ada 95
+  as the discriminants always have the accessibility of the object.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0052-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Added a rule to prevent limited coextensions of nonlimited types. Allowing
+  this would have far-reaching implementation costs. Because of those costs, it
+  seems unlikely that any implementation ever supported it properly and thus it
+  is unlikely that any existing code depends on this capability.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0104-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a rule to
+  make @nt{null_exclusion}s illegal for uninitialized @nt{allocator}s,
+  as such an @nt{allocator} would always raise Constraint_Error.
+  Programs that depend on the unconditional raising of a predefined
+  exception should be very rare.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0111-3]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Subpool handles
+  (see @RefSecNum{Storage Subpools}) can be specified in an @nt{allocator}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0024-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the master check
+  for tags since the masters may be for different tasks and thus 
incomparable.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0041-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the rules for
+  when a designated object is constrained by its initial value so that
+  types derived from a partial view are handled properly.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0051-1],ARef=[AI05-0234-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the accessibility
+  check for access discriminants so that it does not depend on the
+  designated type (which might not have discriminants when the allocated
+  type does).]}
address@hidden
+
+
+
address@hidden Expressions and Static Subtypes}
+
address@hidden
+Certain expressions of a scalar or string type are defined to be static.
+Similarly, certain discrete ranges are defined to be static, and
+certain scalar and string subtypes are defined to be static subtypes.
address@hidden@Defn{static}
address@hidden(Static) means determinable at compile time,
+using the declared properties or values of the program entities.]
address@hidden,See=(static)}
address@hidden
+  As opposed to more elaborate data flow analysis, etc.
address@hidden
address@hidden
+
address@hidden
+For an expression to be static,
+it has to be calculable at compile time.
+
+Only scalar and string expressions are static.
+
+To be static, an expression cannot have any nonscalar, nonstring
+subexpressions (though it can have nonscalar constituent @nt<name>s).
+A static scalar expression cannot have any nonscalar subexpressions.
+There is one exception @em a membership test for a string subtype
+can be static, and the result is scalar, even though a subexpression
+is nonscalar.
+
+The rules for evaluating static expressions are designed
+to maximize portability of static calculations.
address@hidden
+
address@hidden
address@hidden@Defn2{Term=[static], Sec=(expression)}
+A static expression is
address@hidden scalar or string expression that is]
+one of the following:
+
address@hidden
+a @nt{numeric_literal};
address@hidden
+  A @nt<numeric_literal> is always a static expression, even if
+  its expected type is not that of a static subtype. However, if its value
+  is explicitly converted to, or qualified by, a nonstatic subtype,
+  the resulting expression is nonstatic.
address@hidden
+
+a @nt{string_literal} of a static string subtype;
address@hidden(Ramification)
+  That is, the constrained subtype defined by the index range
+  of the string is static. Note that elementary values don't
+  generally have subtypes, while composite values do (since
+  the bounds or discriminants are inherent in the value).
address@hidden(Ramification)
+
+a @nt{name}
+that denotes the declaration
+of a named number or a static constant;
address@hidden
+Note that enumeration
+literals are covered by the @nt{function_call} case.
address@hidden
+
+a @nt{function_call}
+whose @address@hidden or
address@hidden@nt{prefix} statically denotes a static function,
+and whose actual parameters, if any (whether given explicitly or by default),
+are all static expressions;
address@hidden
+This includes uses of operators that are equivalent to
address@hidden
address@hidden
+
+
+an @nt{attribute_reference} that denotes a scalar value,
+and whose @nt{prefix} denotes a static scalar subtype;
+
address@hidden
+  Note that this does not include the case of an attribute
+that is a function;
+a reference to
+such an attribute is not even an expression.
+See above for function @i{calls}.
+
+An implementation may define the staticness and other
+properties of implementation-defined attributes.
address@hidden
+
+an @nt{attribute_reference} whose
address@hidden statically denotes a statically constrained array
+object or array subtype,
+and whose @nt<attribute_designator>
+is First, Last, or Length,
+with an optional dimension;
+
+a @nt{type_conversion}
+whose @nt{subtype_mark} denotes a static scalar subtype,
+and whose operand is a static expression;
+
+a @nt{qualified_expression}
+whose @nt{subtype_mark} denotes a
+static @Redundant[(scalar or string)] subtype,
+and whose operand is a static expression;
address@hidden
+This rules out the @nt{subtype_mark}'@nt{aggregate} case.
address@hidden
address@hidden
+Adding qualification to an expression shouldn't make it nonstatic, even
+for strings.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0158-1],ARef=[AI05-0269-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0039-1]}
+a membership test whose
address@hidden,address@hidden@nt{simple_expression}],address@hidden
+is a static expression,
+and whose @Chg{Version=[3],address@hidden consists only of
address@hidden that are either static
address@hidden,address@hidden@nt{simple_expression}s],address@hidden,
+static @nt{range}s, or @nt{subtype_mark}s that denote],address@hidden
+is a static range or whose @nt{subtype_mark} denotes]} a
+static @Redundant[(scalar or string)] subtype;
address@hidden
+Clearly, we should allow membership tests in exactly the same cases
+where we allow @nt{qualified_expression}s.
address@hidden
+
+a short-circuit control form
+both of whose @nt{relation}s are static expressions;
+
address@hidden,Kind=[Added],ARef=[AI05-0147-1],ARef=[AI05-0188-1]}
address@hidden,Text=[a @nt{conditional_expression} all of whose
address@hidden, @address@hidden, and
address@hidden@nt{expression}s are static expressions;]}
+
+a static expression enclosed in parentheses.
address@hidden
address@hidden(Discussion)
+  @Defn2{Term=[static], Sec=(value)}
+  Informally, we talk about a @i(static value). When we do,
+  we mean a value specified by a static expression.
address@hidden(Discussion)
address@hidden
+  The language requires a static
+  expression in a @nt<number_declaration>,
+  a numeric type definition, a @nt<discrete_choice> (sometimes),
+  certain representation items, an @nt<attribute_designator>,
+  and when specifying the value of a discriminant
+  governing a @nt{variant_part}
+  in a @nt<record_aggregate> or @nt<extension_aggregate>.
address@hidden
+
address@hidden@Defn2{Term=[statically], Sec=(denote)}
+A @nt{name} @i(statically denotes) an entity if it
+denotes the entity and:
address@hidden(itemize)
+  It is a @nt<direct_name>, expanded name, or
+  @nt{character_literal},
+  and it denotes a declaration other than a @nt<renaming_declaration>;
+  or
+
+  It is an @nt{attribute_reference} whose @nt{prefix} statically denotes
+  some entity; or
+
+  It denotes a @nt<renaming_declaration> with a @nt<name> that
+  statically denotes the renamed entity.
address@hidden(itemize)
address@hidden
address@hidden that are not expanded names
+and @nt{indexed_component}s do not statically denote things.
address@hidden
+
address@hidden@Defn2{Term=[static], Sec=(function)}
+A @i{static function} is one of the following:
address@hidden
+  These are the functions whose calls can be static expressions.
address@hidden
address@hidden
+a predefined operator whose parameter and result
+types are all scalar types none of which are descendants of
+formal scalar types;
+
+a predefined concatenation operator whose result type is a string type;
+
+an enumeration literal;
+
+a language-defined attribute that is a function,
+if the @nt{prefix} denotes a static scalar subtype,
+and if the parameter and result types are scalar.
address@hidden
+
+In any case, a generic formal subprogram is not a static function.
+
address@hidden, Sec=(constant)}
+A @i(static constant) is
+a constant view declared by a full constant declaration
+or an @nt<address@hidden@!declaration> with a static nominal subtype,
+having a value defined by a static scalar expression or by
+a static string expression whose value has a length not exceeding
+the maximum length of a @address@hidden in the implementation.
address@hidden
+A deferred constant is not static;
+the view introduced by the corresponding full constant declaration
+can be static.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The reason for restricting the length of static string constants is so
+that compilers don't have to store giant strings in their symbol tables.
+Since most string constants will be initialized
+from @nt{string_literal}s, the length limit seems pretty natural.
+The reason for avoiding nonstring types is also to save symbol table
+space.
+We're trying to keep it cheap and simple
+(from the implementer's viewpoint),
+while still allowing, for example,
+the @Chg{Version=[3],address@hidden for a Link_Name aspect],
+Old=[link name of a pragma Import]} to contain a concatenation.
+
+The length we're talking about is the maximum number of characters in
+the value represented by a @nt{string_literal},
+not the number of characters in the source representation;
+the quotes don't count.
address@hidden
+
address@hidden, Sec=(range)}
+A @i(static range) is a @nt{range} whose bounds are
+static expressions,
address@hidden a @nt<address@hidden@!reference> that is equivalent to
+such a @nt<range>.]
address@hidden, Sec=(discrete_range)}
+A @i(static @nt<address@hidden>) is one that is a static range
+or is a @nt<address@hidden> that defines a static scalar subtype.
+The base range of a scalar type is a static range, unless the
+type is a descendant of a formal scalar type.
+
address@hidden,Kind=[Revised],ARef=[AI95-00263-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0153-3]}
address@hidden, Sec=(subtype)}
+A @i(static subtype) is either a @i(static scalar subtype) or a
address@hidden(static string subtype).
address@hidden, Sec=(scalar subtype)}
+A static scalar subtype is an unconstrained scalar subtype whose
+type is not a descendant of a
+formal @Chg{Version=[2],New=[],Old=[scalar ]}type, or
+a constrained scalar subtype formed by imposing a compatible
+static constraint on a static scalar subtype.
address@hidden, Sec=(string subtype)}
+A static string subtype is an unconstrained string subtype
+whose index subtype and component subtype are
address@hidden,New=[],Old=[ (and whose type is not a descendant
+of a formal array type)]},
+or a constrained string subtype formed by imposing a compatible static
+constraint on a static string subtype.
+In any case, the subtype of a generic formal object of mode @key[in out],
+and the result subtype of a generic formal function, are not address@hidden,
+New=[ Also, a subtype is not static if any Dynamic_Predicate specifications
+apply to it.],Old=[]}
address@hidden
+  String subtypes are the only composite subtypes that can be static.
address@hidden
address@hidden
address@hidden@;The part about generic formal objects of mode @key[in out]
+is necessary because the subtype of the formal is not required
+to have anything to do with the subtype of the actual.
+For example:
address@hidden
address@hidden Int10 @key[is] Integer @key[range] 1..10;
+
address@hidden
+    F : @key[in] @key[out] Int10;
address@hidden G;
+
address@hidden G @key[is]
address@hidden
+    @key[case] F @key[is]
+        @key[when] 1..10 => @key[null];
+        address@hidden Illegal!}
+    @key[end] @key[case];
address@hidden G;
+
+X : Integer @key[range] 1..20;
address@hidden I @key[is] @key[new] G(F => X); address@hidden OK.}
address@hidden
+
+The @nt{case_statement} is illegal, because the subtype of F is not
+static, so the choices have to cover all values of Integer,
+not just those in the range 1..10.
+A similar issue arises for generic formal functions,
+now that function calls are object names.
address@hidden
+
address@hidden@Defn2{Term=[static], Sec=(constraint)}
+The different kinds of @i(static constraint) are defined as follows:
address@hidden(itemize)
+  A null constraint is always static;
+
+  @Defn2{Term=[static], Sec=(range constraint)}
+  @Defn2{Term=[static], Sec=(digits constraint)}
+  @Defn2{Term=[static], Sec=(delta constraint)}
+  A scalar constraint is static if it has no
+  @nt<range_constraint>,
+  or one with a static range;
+
+  @Defn2{Term=[static], Sec=(index constraint)}
+  An index constraint is static if each
+  @nt<discrete_range> is static, and each index subtype of the
+  corresponding array type is static;
+
+  @Defn2{Term=[static], Sec=(discriminant constraint)}
+  A discriminant constraint is static if
+  each @nt<expression> of the constraint is static,
+  and the subtype of each discriminant is static.
address@hidden(itemize)
+
address@hidden,Kind=[Added],ARef=[AI95-00311-01]}
address@hidden,New=[In any case, the constraint of the first subtype of a
+scalar formal type is neither static nor null.],Old=[]}
+
address@hidden, Sec=(constrained)}
+A subtype is @i(statically constrained) if it is constrained,
+and its constraint is static.
+An object is @i(statically constrained) if its nominal subtype is
+statically constrained,
+or if it is a static string constant.
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0147-1]}
address@hidden,Type=[Leading],Text=[An expression is @i<statically
+unevaluated> if it is part of:@Defn{statically unevaluated}]}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0147-1]}
address@hidden,Text=[the right operand of a static short-circuit control
+form whose value is determined by its left operand; or]}
+
address@hidden,Kind=[Added],ARef=[AI05-0147-1],ARef=[AI05-0188-1]}
address@hidden,Text=[a @address@hidden of an
address@hidden whose
+associated @nt{condition} is static and equals False; or]}
+
address@hidden,Kind=[Added],ARef=[AI05-0147-1],ARef=[AI05-0188-1]}
address@hidden,Text=[a @nt{condition} or @address@hidden
+of an @nt{if_expression} where the @nt{condition} corresponding to at least one
+preceding @address@hidden of the @nt{if_expression} is static
+and equals True; or]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[We need this bullet so that only a
+  single @address@hidden is evaluated in a static
+  @nt{if_expression} if there is more than one @nt{condition} that evaluates to
+  True. The part about @nt{condition}s makes]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[(@key[if] N = 0 @key[then] Min @key[elsif] 10_000/N > Min 
@key[then] 10_000/N @key[else] Min)]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[legal if N and Min are static and N = 0.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0147-1],ARef=[AI05-0188-1]}
address@hidden,Text=[We need the "of the @nt{if_expression}" here so
+there is no confusion for nested @nt{if_expression}s; this rule only applies to
+the @nt{condition}s and @address@hidden of a single
address@hidden Similar
+reasoning applies to the "of a @nt{case_expression}" of the last bullet.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0188-1],ARef=[AI05-0269-1]}
address@hidden,Text=[a @address@hidden of a
address@hidden whose @address@hidden is static and
+whose value is not covered by the corresponding @nt{discrete_choice_list}; or]}
+
address@hidden,Kind=[Added],ARef=[AI05-0158-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0039-1]}
address@hidden,Text=[a
address@hidden,address@hidden@nt{simple_expression}],address@hidden
+(or a @nt{simple_expression}
+of a @nt{range} that occurs as a @nt{membership_choice} of a
address@hidden) of a static membership test that is preceded in
+the enclosing @nt{membership_choice_list} by another item whose individual
+membership test (see @RefSecNum{Relational Operators and Membership Tests})
+statically yields True.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0147-1]}
address@hidden@;A static expression is evaluated at compile time except when it 
is
address@hidden,New=[statically unevaluated],Old=[part
+of the right operand of a static short-circuit control form whose value
+is determined by its left operand]}.
address@hidden,New=[The compile-time],Old=[This]} evaluation
address@hidden,New=[of a static expression ],Old=[]}is performed exactly,
+without performing Overflow_Checks.
+For a static expression that is evaluated:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
+The expression is illegal if its evaluation fails a language-defined
+check other than address@hidden@Chg{Version=[3],New=[ For the purposes of
+this evaluation, the assertion policy is assumed to be Check.],Old=[]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Text=[Assertion policies can control whether checks are
+  made, but we don't want assertion policies to affect legality. For Ada 2012,
+  subtype predicates are the only checks controlled by the assertion policy 
that
+  can appear in static expressions.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00269-01]}
+If the expression is not part of a larger static
address@hidden,New=[ and the expression is expected to be of a
+single specific type],Old=[]},
+then its value shall be within the base range of its expected type.
+Otherwise, the value may be arbitrarily large or small.
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00269-01]}
+  @ChgAdded{Version=[2],Text=[If the expression is expected to be of a 
universal
+  type, or of @lquotes@;any integer address@hidden, there are no limits on the
+  value of the expression.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00269-01]}
+If the expression is of type @i<universal_real> and its expected type is
+a decimal fixed point type,
+then its value shall be a multiple of the @i<small> of the decimal
address@hidden,New=[ This restriction
+does not apply if the expected type is a
+descendant of a formal scalar type
+(or a corresponding actual type in an instance).],Old=[]}
address@hidden
+  This means that a @nt{numeric_literal} for a decimal type cannot have
+  @lquotes@;address@hidden@; significant digits.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00269-01]}
+  @ChgAdded{Version=[2],Text=[The small is not known for a generic formal
+  type, so we have to exclude formal types from this check.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00269-01]}
address@hidden,address@hidden contract issue}
+In addition to the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}),
+the above restrictions also apply in the private part of an
+instance of a generic unit.],Old=[The last two restrictions above
+do not apply if the expected type is a descendant of a formal scalar type
+(or a corresponding actual type in an instance).]}
+
address@hidden
+  Values outside the base range are not permitted
+  when crossing from the @lquotes@;address@hidden@; domain to the 
@lquotes@;address@hidden@; domain.
+  This rule is designed to enhance portability of programs
+  containing static expressions.
+  Note that this rule applies to the exact value,
+  not the value after any rounding or truncation.
+  (See below for the rounding and truncation requirements.)
+
+  @Leading@;Short-circuit control forms are a special case:
address@hidden
+N: @key[constant] := 0.0;
+X: @key[constant] Boolean := (N = 0.0) @key[or] @key[else] (1.0/N > 0.5); 
address@hidden Static.}
address@hidden
+
+The declaration of X is legal, since the divide-by-zero part of the
+expression is not evaluated.
+X is a static constant equal to True.
+
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00269-01]}
+  @ChgDeleted{Version=[2],Text=[There is no requirement to recheck these rules
+  in an instance; the base range check will generally be performed at run time
+  anyway.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00268-01],ARef=[AI95-00269-01]}
+For a real static expression that is not part of a larger static
+expression,
+and whose expected type is not a descendant of a formal
address@hidden,New=[],Old=[scalar ]}type,
+the implementation shall round or truncate
+the value (according to the Machine_Rounds
+attribute of the expected type) to the nearest machine
+number of the expected type;
+if the value is exactly half-way between two machine
+numbers, @Chg{Version=[2],New=[the],Old=[any]} rounding
address@hidden,New=[],Old=[shall be ]}performed
address@hidden,New=[is implementation-defined],Old=[away from zero]}.
+If the expected type is a descendant of a formal
address@hidden,New=[],Old=[scalar ]}type,
address@hidden,New=[or if the static expression appears in
+the body of an instance of a generic unit and the corresponding expression is
+nonstatic in the corresponding generic body, then],Old=[]}
+no special rounding or truncating is required @em normal
+accuracy rules apply (see @RefSecNum(Numerics)).
address@hidden,Kind=[Added],address@hidden,New=[Rounding of
+real static expressions which are exactly half-way between two machine 
numbers.],Old=[]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00268-01]}
+  Discarding extended precision enhances portability
+  by ensuring that the value of a
+  static constant of a real type is always a machine number of the type.
+  @Chg{Version=[2],New=[],Old=[Deterministic rounding of exact halves also 
enhances portability.]}
+
+  When the expected type is a descendant of a formal floating point type,
+  extended precision (beyond that of the machine numbers)
+  can be retained when evaluating
+  a static expression, to ease code sharing for generic
+  instantiations. For similar reasons,
+  normal (nondeterministic) rounding or truncating rules apply
+  for descendants of a formal fixed point type.
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00269-01]}
+  @ChgAdded{Version=[2],Text=[There is no requirement for exact evaluation or
+  special rounding in an instance body (unless the expression is static in
+  the generic body). This eliminates a potential contract issue where the
+  exact value of a static expression depends on the actual parameters (which
+  could then affect the legality of other code).]}
address@hidden
address@hidden
+
+  Note that the implementation of static expressions has to keep track
+  of plus and minus zero for a type whose Signed_Zeros attribute is
+  True.
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00100-01]}
+  Note that the only @Chg{Version=[2],New=[machine numbers],Old=[values]} of
+  a fixed point type are the multiples of
+  the small, so a static conversion to a fixed-point type, or division
+  by an integer, must do truncation to a multiple of small.
+  It is not correct for the implementation to do all static calculations
+  in infinite precision.
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00268-01]}
address@hidden,Text=[For a real static expression that is not part of a
+larger static expression, and whose expected type is not a descendant of a
+formal type, the rounding should be the same as the default rounding
+for the target system.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[A real static expression with a nonformal type that is not part of a
+larger static expression should be rounded the same as the target system.]}]}
address@hidden
+
address@hidden
+An expression can be static even if it occurs in a context where
+staticness is not required.
address@hidden
+
address@hidden@keepnext@;For example:
address@hidden
+X : Float := Float'(1.0E+400) + 1.0 - Float'(1.0E+400);
address@hidden
+
+The expression is static,
+which means that the value of X must be exactly 1.0,
+independent of the accuracy or range of the run-time floating point
+implementation.
+
+The following kinds of expressions are never static:
address@hidden,
address@hidden,
address@hidden,
address@hidden,
address@hidden,
address@hidden
address@hidden
+
+A static (or run-time) @nt<type_conversion> from a real type to
+an integer type performs rounding. If the operand value is exactly half-way
+between two integers, the rounding is performed away from zero.
address@hidden
+  We specify this for portability. The reason for not choosing
+  round-to-nearest-even, for example, is that this method is easier
+  to undo.
address@hidden
address@hidden
+  The attribute Truncation
+  (see @RefSecNum{Attributes of Floating Point Types})
+  can be used to perform a (static) truncation prior to conversion,
+  to prevent rounding.
address@hidden
address@hidden
+
+  The value of the literal
+  0E999999999999999999999999999999999999999999999
+  is zero.
+  The implementation must take care to evaluate such literals properly.
+
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden(Examples of static expressions:)
address@hidden
+1 + 1       @RI[-- 2]
address@hidden(abs)(-10)*3  @RI[-- 30]
+
+Kilo : @key(constant) := 1000;
+Mega : @key(constant) := Kilo*Kilo;   @RI[-- 1_000_000]
+Long : @key(constant) := Float'Digits*2;
+
+Half_Pi    : @key(constant) := Pi/2;           @RI[-- see @RefSecNum(Number 
Declarations)]
+Deg_To_Rad : @key(constant) := Half_Pi/90;
+Rad_To_Deg : @key(constant) := 1.0/Deg_To_Rad; @RI[-- equivalent to 
1.0/((3.14159_26536/2)/90)]
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The rules for static expressions and static subtypes are generalized
+to allow more kinds of compile-time-known expressions to be used
+where compile-time-known values are required, as follows:
address@hidden(itemize)
+Membership tests and short-circuit control forms
+may appear in a static expression.
+
+The bounds and length of
+statically constrained array objects or subtypes are static.
+
+The Range attribute of a statically constrained array subtype or
+object gives a static range.
+
+A @nt{type_conversion} is static if the @nt{subtype_mark} denotes a
+static scalar subtype and the operand is a static expression.
+
+All numeric literals are now static, even if the expected
+type is a formal scalar type.
+This is useful in @nt{case_statement}s and @nt{variant_part}s,
+which both now allow a value of a formal scalar type to
+control the selection, to
+ease conversion of a package into a generic package.
+Similarly, named array aggregates are also permitted for array
+types with an index type that is a formal scalar type.
address@hidden(itemize)
+
+The rules for the evaluation of static expressions
+are revised to require exact evaluation at compile time,
+and force a machine number result when crossing from the static realm
+to the dynamic realm,
+to enhance portability and predictability.
+Exact evaluation is not required for
+descendants of a formal scalar type,
+to simplify generic code sharing and to avoid generic
+contract model problems.
+
address@hidden@;Static expressions are legal even if an intermediate
+in the expression goes outside the base range of the type. Therefore, the
+following will succeed in Ada 95, whereas it might raise an
+exception in Ada 83:
address@hidden
address@hidden Short_Int @key[is] @key[range] -32_768 .. 32_767;
+I : Short_Int := -32_768;
address@hidden
+
+This might raise an exception in Ada 83 because "32_768" is out of range,
+even though "@en@;32_768" is not. In Ada 95, this will always succeed.
+
+
+Certain expressions involving string operations
+(in particular concatenation and membership tests)
+are considered static in Ada 95.
+
+
+The reason for this change is to simplify the rule requiring
+compile-time-known string expressions as the link name in an interfacing
+pragma, and to simplify the preelaborability rules.
address@hidden
+
address@hidden
address@hidden with Ada 83}
+An Ada 83 program that uses an out-of-range static value
+is illegal in Ada 95, unless the expression is part of a larger
+static expression, or the expression is not evaluated due to being on
+the right-hand side of a short-circuit control form.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause]}
+(and @RefSec{Multiplying Operators})
+subsumes the RM83 section on Universal Expressions.
+
+The existence of static string expressions
+necessitated changing the definition of static subtype to
+include string subtypes.
+Most occurrences of "static subtype" have been changed to "static scalar
+subtype",
+in order to preserve the effect of the Ada 83 rules.
+This has the added benefit of clarifying the difference between "static
+subtype" and "statically constrained subtype", which has been a source
+of confusion.
+In cases where we allow static string subtypes,
+we explicitly use phrases like "static string subtype"
+or "static (scalar or string) subtype",
+in order to clarify the meaning for those who have gotten used to the
+Ada 83 terminology.
+
+
address@hidden@;In Ada 83, an expression was considered nonstatic if it raised 
an
+exception.
+Thus, for example:
address@hidden
+Bad: @key[constant] := 1/0; address@hidden Illegal!}
address@hidden
+
+was illegal because 1/0 was not static.
+In Ada 95, the above example is still illegal,
+but for a different reason:
+1/0 is static, but there's a separate rule forbidding the exception
+raising.
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00268-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] Rounding of
+  static real expressions is implementation-defined in Ada 2005, while it was
+  specified as away from zero in (original) Ada 95. This could make subtle
+  differences in programs. However, the original Ada 95 rule required rounding
+  that (probably) differed from the target processor, thus creating anomalies
+  where the value of a static expression was required to be different than the
+  same expression evaluated at run-time.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00263-01],ARef=[AI95-00268-01]}
+  @ChgAdded{Version=[2],Text=[The Ada 95 wording that defined static subtypes
+  unintentionally failed to exclude formal derived types that happen to be
+  scalar (these aren't formal scalar types); and had a parenthetical remark
+  excluding formal string types - but that was neither necessary nor
+  parenthetical (it didn't follow from other wording). This issue also
+  applies to the rounding rules for real static expressions.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00269-01]}
+  @ChgAdded{Version=[2],Text=[Ada 95 didn't clearly define the bounds of a 
value of
+  a static expression for universal types and for "any integer/float/fixed
+  type". We also make it clear that we do not intend exact evaluation of
+  static expressions in an instance body if the expressions aren't static in 
the
+  generic body.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00311-01]}
+  @ChgAdded{Version=[2],Text=[We clarify that the first subtype of a scalar
+  formal type has a nonstatic, nonnull constraint.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0147-1],ARef=[AI05-0188-1]}
+  @ChgAdded{Version=[3],Text=[Added wording to define staticness and
+  the lack of evaluation for @nt{if_expression}s and @nt{case_expression}s.
+  These are new and defined elsewhere.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0153-3]}
+  @ChgAdded{Version=[3],Text=[Added wording to prevent subtypes that have
+  dynamic predicates (see @RefSecNum{Subtype Predicates}) from being static.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0158-1]}
+  @ChgAdded{Version=[3],Text=[Revised wording for membership tests to allow
+  for the new possibilities allowed by the @nt{membership_choice_list}.]}
address@hidden
+
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Matching Constraints and Subtypes}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00311-01]}
address@hidden matching], Sec=(for constraints)}
+A constraint @i(statically matches) another
+constraint address@hidden,New=[:],Old=[ both are null constraints, both are
+static and have equal corresponding bounds or discriminant values,
+or both are nonstatic and result from the same elaboration of
+a @nt<constraint>
+of a @nt<address@hidden> or the same evaluation of a @nt<range>
+of a @nt<address@hidden@!definition>.]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,New=[both are null constraints;],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,New=[both are static and have equal corresponding bounds or 
discriminant
+values;],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,New=[both are nonstatic and result from the same elaboration
+of a @nt<constraint>
+of a @nt<address@hidden> or the same evaluation of a @nt<range>
+of a @nt<address@hidden@!definition>; or],Old=[]}
+
address@hidden,Kind=[Added],ARef=[AI95-00311-01]}
address@hidden,New=[both are nonstatic and come from the same
address@hidden,Old=[]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01],ARef=[AI95-00254-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0153-3]}
address@hidden matching], Sec=(for subtypes)}
+A subtype @i(statically matches) another subtype of the same type
+if they have statically matching address@hidden,New=[,
address@hidden,New=[all predicate specifications that apply to
+them come from the same declarations, ],Old=[]}and, for
+access subtypes, either both or neither exclude null],Old=[]}.
+Two anonymous address@hidden,New=[-to-object],Old=[]} subtypes
+statically match if their designated subtypes statically
address@hidden,New=[, and either both or neither
+exclude null, and either both or neither are access-to-constant. Two anonymous
+access-to-subprogram subtypes statically match if their designated profiles are
+subtype conformant, and either both or neither exclude null],Old=[]}.
address@hidden
+  Statically matching constraints and subtypes are the basis
+  for subtype conformance of profiles (see @RefSecNum(Conformance Rules)).
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Even though anonymous access types always
+  represent different types, they can statically match. That's important so
+  that they can be used widely. For instance, if this wasn't true, access
+  parameters and access discriminants could never conform, so they couldn't
+  be used in separate specifications.]}
address@hidden
+
address@hidden matching], Sec=(for ranges)}
+Two ranges of the same type @i{statically match} if both result
+from the same evaluation of a @nt{range},
+or if both are static and have equal corresponding bounds.
address@hidden
+The notion of static matching of ranges is used in
address@hidden Array Types};
+the index ranges of formal and actual constrained array subtypes have to
+statically match.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0086-1],ARef=[AI05-0153-3]}
address@hidden compatible],
+  Sec=(for a constraint and a scalar subtype)}
+A constraint is @i(statically compatible) with a scalar subtype if
+it statically matches the constraint of the subtype, or if both
+are static and the constraint is compatible with the subtype.
address@hidden compatible],
+  Sec=(for a constraint and an access or composite subtype)}
+A constraint is @i(statically compatible) with an access or composite subtype
+if it statically matches the constraint of the subtype, or
+if the subtype is address@hidden,New=[],Old=[
address@hidden compatible],
+  Sec=(for two subtypes)}
+One subtype is @i(statically compatible) with a second subtype if
+the constraint of the first is statically compatible with the
+second subtype.]}
address@hidden
+  Static compatibility is required when constraining a parent subtype
+  with a discriminant from a new @nt<discriminant_part>.
+  See @RefSecNum{Discriminants}. Static compatibility is also used
+  in matching generic formal derived types.
+
+  Note that
+  statically compatible with a subtype does not imply
+  compatible with a type. It is OK since the terms are
+  used in different contexts.
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0153-3]}
address@hidden,Type=[Leading],address@hidden compatible],
+  Sec=(for two subtypes)}Two statically matching subtypes are statically
+compatible with each other. In addition, a subtype @i<S1> is statically
+compatible with a subtype @i<S2> if:]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[the constraint of @i<S1> is statically compatible
+  with @i<S2>, and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0086-1]}
+  @ChgAdded{Version=[3],Text=[if @i<S2> excludes null, so does @i<S1>, and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[either:]}
+  @begin{InnerItemize}
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[all predicate specifications that apply to
+    @i<S2> apply also to @i<S1>, or]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0290-1]}
+    @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0071-1]}
+    @ChgAdded{Version=[3],Text=[both subtypes are static, every value that
+    satisfies the @Chg{Version=[4],New=[predicates],Old=[predicate]} of @i<S1>
+    also satisfies the @Chg{Version=[4],New=[predicates],Old=[predicate]} of
+    @i<S2>, and it is not the case that both types each have at least one
+    applicable predicate specification, predicate checks are enabled (see
+    @RefSecNum{Pragmas Assert and Assertion_Policy}) for @i<S2>, and
+    predicate checks are not enabled for @i<S1>.]}
+  @end{InnerItemize}
address@hidden
address@hidden
+
address@hidden
+This subclause is new to Ada 95.
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01],ARef=[AI95-00254-01]}
+  @ChgAdded{Version=[2],Text=[Added static matching rules for null exclusions
+  and anonymous access-to-subprogram types; both of these are new.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00311-01]}
+  @ChgAdded{Version=[2],Text=[We clarify that the constraint of the first
+  subtype of a scalar formal type statically matches itself.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0086-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Updated the statically compatible rules to take null exclusions into account.
+  This is technically incompatible, as it could cause a legal Ada 2005 program
+  to be rejected; however, such a program violates the intent of the rules
+  (for instance, @RefSecNum{Discriminants}(15)) and this probably will simply
+  detect bugs.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0153-3],ARef=[AI05-0290-1]}
+  @ChgAdded{Version=[3],Text=[Modified static matching and static compatibility
+  to take predicate aspects (see @RefSecNum{Subtype Predicates}) into 
account.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0071-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Updated wording of
+  static compatibility to use the new term "satisfies the predicates"
+  (see @RefSecNum{Subtype Predicates}).]}
address@hidden
diff --git a/packages/ada-ref-man/source_2012/05.mss 
b/packages/ada-ref-man/source_2012/05.mss
new file mode 100755
index 0000000..a3be867
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/05.mss
@@ -0,0 +1,1942 @@
address@hidden(05, Root="ada.mss")
+
address@hidden: 2016/02/09 04:55:40 $}
address@hidden
+
address@hidden: e:\\cvsroot/ARM/Source/05.mss,v $}
address@hidden: 1.65 $}
+
address@hidden
address@hidden @nt{statement} defines an action to be performed upon
+its execution.]
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[clause],Old=[section]} describes the
+general rules applicable to all @nt{statement}s.
+Some @nt{statement}s are discussed in later 
@Chg{Version=[3],New=[clauses],Old=[sections]}:
address@hidden@address@hidden and
address@hidden,New=[return statements],address@hidden@!statement}s]} are
+described in @RefSec{Subprograms}.
address@hidden@address@hidden, @address@hidden,
address@hidden@!statement}s, @address@hidden,
address@hidden@!statement}s, and @address@hidden are described in
address@hidden and Synchronization}.
address@hidden@!statement}s are described in @RefSec{Exceptions},
+and @address@hidden in
address@hidden Issues}.
+The remaining forms of @nt{statement}s are presented in this
address@hidden,New=[clause],Old=[section]}.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
+The description of
address@hidden,New=[return statements],address@hidden@!statement}s]}
+has been moved to
address@hidden Statements}, so that it is closer to the
+description of subprograms.
address@hidden
+
address@hidden and Compound Statements - Sequences of Statements}
+
address@hidden
address@hidden @nt<statement> is either simple or compound.
+A @nt<simple_statement> encloses
+no other @nt<statement>. A @nt<compound_statement> can enclose
address@hidden<simple_statement>s and other @nt<compound_statement>s.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0179-1]}
address@hidden<sequence_of_statements>,rhs="@Syn2{statement} 
address@hidden@Chg{Version=[3],New=[ address@hidden,Old=[]}"}
+
+
address@hidden<statement>,rhs="
+   address@hidden @Syn2{simple_statement} | address@hidden 
@Syn2{compound_statement}"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden, lhs=<simple_statement>,rhs="@Syn2{null_statement}
+   | @address@hidden| @Syn2{exit_statement}
+   | @address@hidden| @Syn2{procedure_call_statement}
+   | @Chg{Version=[2],address@hidden,address@hidden@\| 
@Syn2{entry_call_statement}
+   | @address@hidden| @Syn2{delay_statement}
+   | @address@hidden| @Syn2{raise_statement}
+   | @Syn2{code_statement}"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden, lhs=<compound_statement>,rhs="
+     @address@hidden| @Syn2{case_statement}
+   | @address@hidden| @address@hidden,New=[
+   | @Syn2{extended_return_statement}],Old=[]}
+   | @address@hidden| @Syn2{select_statement}"}
+
address@hidden<null_statement>,rhs="@key{null};"}
+
address@hidden<label>,rhs="<<@address@hidden>>"}
+
address@hidden<statement_identifier>,rhs="@Syn2{direct_name}"}
+
address@hidden(SyntaxText)
+The @nt<direct_name> of a @nt<statement_identifier> shall
+be an @nt<identifier> (not an @nt<operator_symbol>).
address@hidden(SyntaxText)
address@hidden
+
address@hidden
+The @nt<direct_name> of a @nt<statement_identifier> shall resolve to
+denote its corresponding implicit declaration (see below).
address@hidden
+
address@hidden
+Distinct @nt{identifier}s shall be used for all
address@hidden<statement_identifier>s that
+appear in the same body, including
+inner @nt{block_statement}s
+but excluding inner program units.
address@hidden
+
address@hidden
+For each @nt<statement_identifier>,
+there is an implicit declaration (with the specified @nt<identifier>)
+at the end of the @nt{declarative_part} of the
+innermost @nt{block_statement} or body that
+encloses the @nt{statement_identifier}.
+The implicit declarations occur in the same order as the
address@hidden<statement_identifier>s occur in the source text.
+If a usage name denotes such an implicit declaration, the entity it
+denotes is the @nt<label>, @nt<loop_statement>,
+or @nt<block_statement> with the given @nt<statement_identifier>.
address@hidden
+  We talk in terms of individual @nt<statement_identifier>s here
+  rather than in terms of the corresponding statements, since
+  a given @nt{statement} may have multiple @nt<statement_identifier>s.
+
+  A @nt{block_statement} that has no
+  explicit @nt{declarative_part} has an implicit empty
+  @nt{declarative_part},
+  so this rule can safely
+  refer to the @nt{declarative_part} of a @nt<block_statement>.
+
+  The scope of a declaration starts at the place of the declaration
+  itself (see @RefSecNum{Scope of Declarations}).
+  In the case of a label, loop, or block name, it
+  follows from this rule that the scope of the implicit declaration
+  starts before the first explicit occurrence of the corresponding
+  name, since this occurrence is either in a statement label, a
+  @nt{loop_statement}, a @nt{block_statement}, or a
+  @nt{goto_statement}. An implicit
+  declaration in a @nt{block_statement} may hide a declaration given in an
+  outer program unit or @nt{block_statement} (according to the usual rules
+  of hiding explained in @RefSecNum{Visibility}).
+
+  The syntax rule for @nt{label} uses @nt{statement_identifier} which
+  is a @nt<direct_name> (not a @nt{defining_identifier}),
+  because labels are implicitly declared. The same applies to loop and
+  block names.
+  In other words, the @nt{label} itself is not the defining occurrence;
+  the implicit declaration is.
+
+  @Leading@;We cannot consider the @nt{label} to be a defining occurrence.
+  An example that can tell the difference is this:
+  @begin{example}
address@hidden
+    address@hidden Label Foo is implicitly declared here.}
address@hidden
+    @key[for] Foo @key[in] ... @key[loop]
+        ...
+        <<Foo>> address@hidden Illegal.}
+        ...
+    @key[end] @key[loop];
address@hidden;
+  @end{example}
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  The label in this example is hidden from itself by the loop parameter
+  with the same name;
+  the example is illegal.
+  We considered creating a new syntactic category name, separate from
+  @nt{direct_name} and @nt{selector_name}, for use in the case of statement
+  labels.
+  However, that would confuse the rules in 
@Chg{Version=[3],New=[Clause],Old=[Section]}
+  8, so we didn't do it.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0179-1]}
address@hidden,Text=[If one or more @nt{label}s end a
address@hidden, an implicit @nt{null_statement}
+follows the @nt{label}s before any following constructs.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[The semantics of a @nt{goto_statement} is
+  defined in terms of the statement having (following) that label. Thus
+  we ensure that every label has a following statement, which might be
+  implicit.]}
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(null_statement)}
+The execution of a @nt{null_statement} has no effect.
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden of control}
+A @i{transfer of control} is
+the run-time action of an @nt{exit_statement},
address@hidden,New=[return statement],address@hidden,
address@hidden,
+or @nt{requeue_statement},
+selection of a @nt{terminate_alternative},
+raising of an exception,
+or an abort,
+which causes
+the next action performed to be one other than what would normally be
+expected from the other rules of the language.
address@hidden explained in
address@hidden and Finalization},
+a transfer of control can cause the execution of constructs to be
+completed and then left,
+which may trigger finalization.]
+
address@hidden, Sec=(sequence_of_statements)}
+The execution of a @nt{sequence_of_statements} consists of the execution
+of the individual @nt{statement}s in succession
+until the @ntf{sequence_} is completed.
address@hidden
+It could be completed by reaching the end of it,
+or by a transfer of control.
address@hidden
address@hidden
+
address@hidden
+A @nt<statement_identifier> that appears immediately within
+the declarative region of a
+named @nt<loop_statement> or an @nt<accept_statement> is nevertheless
+implicitly declared immediately within the declarative region
+of the innermost enclosing body or @nt<block_statement>;
+in other words, the expanded name for a named statement is
+not affected by whether the statement occurs inside or outside
+a named loop or an @nt<accept_statement> @em only nesting
+within @nt<block_statement>s is relevant to the form of its
+expanded name.
address@hidden
address@hidden@keepnext@;Each comment in the following example gives the
+expanded name associated with an entity declared in the task body:
address@hidden
address@hidden(task body) Compute @key(is)
+   Sum : Integer := 0;                       address@hidden Compute.Sum]
address@hidden(begin)
+ Outer:                                      address@hidden Compute.Outer]
+   @key(for) I @key(in) 1..10 @key(loop)     address@hidden Compute.Outer.I]
+    Blk:                                     address@hidden Compute.Blk]
+      @key(declare)
+         Sum : Integer := 0;                 address@hidden Compute.Blk.Sum]
+      @key(begin)
+         @key(accept) Ent(I : out Integer; J : in Integer) @key(do)
+                                             address@hidden Compute.Ent.I, 
Compute.Ent.J]
+            Compute.Ent.I := Compute.Outer.I;
+          Inner:                             address@hidden Compute.Blk.Inner]
+            @key(for) J @key(in) 1..10 @key(loop)
+                                             address@hidden 
Compute.Blk.Inner.J]
+               Sum := Sum + Compute.Blk.Inner.J * Compute.Ent.J;
+            @key(end loop) Inner;
+         @key(end) Ent;
+         Compute.Sum := Compute.Sum + Compute.Blk.Sum;
+      @key(end) Blk;
+   @key(end loop) Outer;
+   Record_Result(Sum);
address@hidden(end) Compute;
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of labeled statements:}
address@hidden
+<<Here>> <<Ici>> <<Aqui>> <<Hier>> @key[null];
+
+<<After>> X := 1;
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The @nt{requeue_statement} is new.
address@hidden
+
address@hidden
+We define the syntactic category @nt<statement_identifier> to simplify
+the description. It is used for labels, loop names, and block names.
+We define the entity associated with the implicit declarations
+of statement names.
+
+Completion includes completion caused by a transfer of control,
+although RM83-5.1(6) did not take this view.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The @nt{extended_return_statement} is new (@nt{simple_return_statement}
+  is merely renamed).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI95-0179-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  A @nt{label} can end a @nt{sequence_of_statements},
+  eliminating the requirement for having an explicit @key[null]; statement
+  after an ending label (a common use).]}
address@hidden
+
+
address@hidden Statements}
+
address@hidden
address@hidden @nt{assignment_statement}
+replaces the current value of
+a variable with the result of evaluating an
address@hidden<expression>.]
address@hidden
+
address@hidden
address@hidden<assignment_statement>,rhs="
+   @address@hidden := @Syn2{expression};"}
address@hidden
+
address@hidden
+The execution of an @nt<assignment_statement> includes
+the evaluation of the @nt<expression> and the @i(assignment)
+of the value of the @nt<expression> into the @i(target).
address@hidden operation}
address@hidden, See=(assignment operation)}
address@hidden assignment operation (as opposed to
+an @nt<address@hidden>) is performed in other contexts
+as well, including object initialization and by-copy parameter
+passing.]
address@hidden, Sec=(of an assignment operation)}
address@hidden, Sec=(of an @nt{assignment_statement})}
+The @i{target} of an assignment operation
+is the view of the object to which a value is being assigned;
+the target of an @address@hidden is the variable denoted by
+the @address@hidden
address@hidden
+Don't confuse this notion of the @lquotes@;address@hidden@; of an assignment
+with the notion of the @lquotes@;target address@hidden@; of an entry call or 
requeue.
+
+Don't confuse the term @lquotes@;assignment address@hidden@; with the
address@hidden
+The assignment operation is just one part of the execution of an
address@hidden
+The assignment operation is also a part of the execution of various
+other constructs; see @RefSec{Completion and Finalization} for a complete
+list.
+Note that when we say, @lquotes@;such-and-such is assigned to address@hidden@;,
+we mean that the assignment operation is being applied, and that
+so-and-so is the target of the assignment operation.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
address@hidden type],
+  Sec=(assignment_statement variable_name)}
+The @i(variable_)@nt<name> of an @nt<assignment_statement>
+is expected to be of any @Chg{Version=[2],New=[],Old=[nonlimited ]}type.
address@hidden type],
+  Sec=(assignment_statement expression)}
+The expected type for the @nt<expression> is
+the type of the target.
address@hidden
address@hidden@keepnext@;An @nt<assignment_statement> as a whole is a "complete 
context,"
+so if the @address@hidden<name> of an @nt<assignment_statement> is
+overloaded, the @nt<expression> can be used to help disambiguate it.
+For example:
address@hidden
+  @key[type] P1 @key[is access] R1;
+  @key[type] P2 @key[is access] R2;
+
+  @key[function] F return P1;
+  @key[function] F return P2;
+
+  X : R1;
address@hidden
+  F.all := X;  address@hidden Right hand side helps resolve left hand side]
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
+The target @Redundant[denoted by the
address@hidden(variable_)@nt<name>] shall be a address@hidden,New=[ of a
+nonlimited type],Old=[]}.
+
+If the target is of a tagged class-wide type @i(T)'Class, then
+the @nt<expression> shall either be dynamically tagged,
+or of type @i(T) and tag-indeterminate
+(see @RefSecNum{Dispatching Operations of Tagged Types}).
address@hidden
+  This is consistent with the general rule that a single
+  dispatching operation shall not have both dynamically tagged and
+  statically tagged operands. Note that for an object
+  initialization (as opposed to the @nt{assignment_statement}),
+  a statically tagged initialization expression is permitted,
+  since there is no chance for confusion (or Tag_Check failure).
+  Also, in an object initialization, tag-indeterminate expressions
+  of any type covered by @i(T)'Class would be allowed, but with
+  an @nt{assignment_statement}, that might not work if the tag of the target
+  was for a type that didn't have one of the dispatching operations
+  in the tag-indeterminate expression.
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(assignment_statement)}
+For the execution of an @nt{assignment_statement},
+the @i(variable_)@nt<name> and the @nt<expression>
+are first evaluated in an arbitrary address@hidden order],Sec=[allowed]}
address@hidden
+  Other rules of the language may require that the
+  bounds of the variable be determined prior to evaluating
+  the @nt<expression>, but that does not necessarily require
+  evaluation of the @i(variable_)@nt<name>, as pointed out by the ACID.
address@hidden
+
address@hidden@keepnext@;When the type of the target is class-wide:
address@hidden(itemize)
+  @PDefn2{Term=[controlling tag value], Sec=(for the @nt{expression} in an 
@nt{assignment_statement})}
+  If the @nt<expression> is tag-indeterminate
+  (see @RefSecNum{Dispatching Operations of Tagged Types}), then the 
controlling
+  tag value for the @nt<expression> is the tag of the target;
address@hidden
+    See @RefSec(Dispatching Operations of Tagged Types).
address@hidden
+
+  @IndexCheck{Tag_Check}
+  @Defn2{Term=[Constraint_Error],Sec=(raised by failure of run-time check)}
+  Otherwise @Redundant[(the @nt<expression> is dynamically tagged)],
+  a check is made that the tag of
+  the value of the @nt<expression>
+  is the same as that of the target;
+  if this check fails, Constraint_Error is raised.
address@hidden(itemize)
+
+The value of the @nt<expression> is converted to the subtype of the
+target. @Redundant[The conversion might raise an exception
+(see @RefSecNum{Type Conversions}).]
address@hidden subtype conversion],Sec=(assignment_statement)}
address@hidden
+  @RefSec(Type Conversions) defines what actions
+  and checks are associated with subtype conversion.
+  For non-array subtypes, it is just a constraint
+  check presuming the types match.
+  For array subtypes, it checks the lengths and slides if the
+  target is constrained.
+  @lquotes@;address@hidden@; means the array doesn't have to have the same 
bounds,
+  so long as it is the same length.
address@hidden
+
+In cases involving controlled types, the target is finalized,
+and an anonymous object might be used as an intermediate in the assignment,
+as described in @RefSec{Completion and Finalization}.
address@hidden operation}
address@hidden operation],
+Sec=(during execution of an @nt{assignment_statement})}
+In any case,
+the converted value of the @nt<expression> is then @i(assigned) to the target,
+which consists of the following two steps:
address@hidden
address@hidden and Finalization} actually says that
+finalization happens always, but unless controlled types are involved,
+this finalization during an @nt{assignment_statement} does
+nothing.
address@hidden
address@hidden(itemize)
+  The value of the target becomes the converted value.
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  If any part of the target is controlled, its value
+  is adjusted as explained in @Chg{Version=[3],New=[subclause],Old=[clause]}
+  @RefSecNum{Assignment and Finalization}.
address@hidden, Sec=(as part of assignment)}
address@hidden
+    If any parts of the object are controlled,
+    abort is deferred during the assignment operation itself,
+    but not during the rest of the execution of an
+    @nt<assignment_statement>.
address@hidden
address@hidden(itemize)
+
address@hidden
+
address@hidden
+The tag of an object never changes;
+in particular, an
address@hidden
+does not change the tag of the target.
+
address@hidden,Kind=[Deleted],ARef=[AI95-00363-01]}
address@hidden,Text=[The values of the discriminants of an object
+designated by an access value cannot be changed (not even by assigning a
+complete value to the object itself) since such objects are always constrained;
+however, subcomponents of such objects may be unconstrained.]}
address@hidden
+The implicit subtype conversion described above for
address@hidden
+is performed only for the value of the right-hand side
+expression as a whole; it is not performed for subcomponents of the
+value.
+
+The determination of the type of the variable of an
address@hidden may require consideration of the expression
+if the variable
+name can be interpreted as the name of a variable designated by the
+access value returned by a function call, and similarly, as a
+component or slice of such a variable
+(see @RefSec{The Context of Overload Resolution}).
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of assignment statements:}
address@hidden
+Value := Max_Value - 1;
+Shade := Blue;
+
+Next_Frame(F)(M, N) := 2.5;        address@hidden  see @RefSecNum{Indexed 
Components}}
+U := Dot_Product(V, W);            address@hidden  see @RefSecNum{Subprogram 
Bodies}}
+
address@hidden,Kind=[Revised],ARef=[AI12-0056-1]}
+Writer := (Status => Open, Unit => Printer, Line_Count => 60);  address@hidden 
see @RefSecNum{Variant Parts and Discrete Choices}}
address@hidden,New=[Next],address@hidden := (72074, @address@hidden,New=[, 
Head],Old=[]});@Chg{Version=[4],New=[],Old=[ ]}   address@hidden  see 
@RefSecNum{Incomplete Type Declarations}}
address@hidden
+
address@hidden
address@hidden@address@hidden involving scalar subtype conversions:}
address@hidden
address@hidden
+I, J : Integer @key[range] 1 .. 10 := 5;
+K    : Integer @key[range] 1 .. 20 := 15;
+ ...
+
+I := J;  address@hidden  identical ranges}
+K := J;  address@hidden  compatible ranges}
+J := K;  address@hidden  will raise Constraint_Error if K > 10}
address@hidden
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden
address@hidden@address@hidden involving array subtype conversions:}
address@hidden
address@hidden
+A : String(1 .. 31);
+B : String(3 .. 33);
+ ...
+
+A := B;  address@hidden  same number of components}
+
+A(1 .. 9)  := "tar sauce";
+A(4 .. 12) := A(1 .. 9);  address@hidden  A(1 .. 12) = "tartar sauce"}
address@hidden
address@hidden
+
address@hidden
address@hidden on the examples:}
address@hidden are allowed even in the case of overlapping
+slices of the same array,
+because the @address@hidden and @nt{expression}
+are both evaluated before copying the value into the variable.
+In the above example, an
+implementation yielding A(1 .. 12) = "tartartartar" would be
+incorrect.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+We now allow user-defined finalization and value adjustment actions
+as part of @nt{assignment_statement}s
+(see @RefSec{Assignment and Finalization}).
address@hidden
+
address@hidden
+The special case of array assignment is subsumed by the concept
+of a subtype conversion, which is applied for all kinds of types,
+not just arrays. For arrays it provides @lquotes@;address@hidden@;. For numeric
+types it provides conversion of a value of a universal type to
+the specific type of the target. For other types,
+it generally has no run-time effect, other than a constraint
+check.
+
+We now cover in a general way in @RefSecNum{Operations of Discriminated Types}
+the erroneous execution possible due to
+changing the value of a discriminant when
+the variable in an @nt<assignment_statement> is a subcomponent
+that depends on discriminants.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00287-01]}
address@hidden,address@hidden with Ada 95}
+The change of the limited check from a resolution rule to
+a legality rule is not quite upward compatible. For example]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden AccNonLim @key{is} @key{access} NonLim;
address@hidden Foo (Arg : in Integer) @key{return} AccNonLim;
address@hidden AccLim @key{is} @key{access} Lim;
address@hidden Foo (Arg : in Integer) @key{return} AccLim;
+Foo(2)address@hidden := Foo(1)address@hidden;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[where NonLim is a nonlimited type and Lim is a
+limited type. The assignment is legal in Ada 95 (only the first Foo would be
+considered), and is ambiguous in Ada 2005. We made the change because we want
+limited types to be as similar to nonlimited types as possible. Limited
+expressions are now allowed in all other contexts (with a similar
+incompatibility), and it would be odd if assignments had different resolution
+rules (which would eliminate ambiguities in some cases). Moreover, examples
+like this one are rare, as they depend on assigning into overloaded function
+calls.]}
address@hidden
+
+
address@hidden Statements}
+
address@hidden
address@hidden @nt{if_statement} selects for execution at most one of
+the enclosed @ntf{sequences_of_statements}, depending on the (truth)
+value of one or more corresponding @nt{condition}s.]
address@hidden
+
address@hidden
address@hidden<if_statement>,rhs="
+    @key{if} @Syn2{condition} @key{then}
+      @Syn2{sequence_of_statements}
+   address@hidden @Syn2{condition} @key{then}
+      @Syn2{sequence_of_statements}}
+   address@hidden
+      @Syn2{sequence_of_statements}]
+    @key{end} @key{if};"}
+
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0147-1]}
address@hidden,LHS=<@Chg{Version=[3],New=[],Old=[condition]}>,
+RHS="@Chg{Version=[3],New=[],address@hidden@Syn2{expression}]}"}
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0147-1]}
address@hidden,address@hidden type], Sec=(condition)}
+A @nt{condition} is expected to be of any boolean type.]}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraphs 3 and 4
+were deleted.>address@hidden message should be
+deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden, Sec=(if_statement)}
+For the execution of an @nt{if_statement}, the @nt{condition} specified
+after @key{if}, and any @nt{condition}s specified after @key{elsif}, are
+evaluated in succession (treating a final @key{else} as @key{elsif} True
address@hidden), until one evaluates to True or
+all @nt{condition}s are evaluated and
+yield False.
+If a @nt{condition} evaluates to True, then the
+corresponding @nt{sequence_of_statements} is executed;
address@hidden,New=[,],Old=[]}
+none of them is executed.
address@hidden
+  The part about all evaluating to False can't happen if
+  there is an @key{else}, since that is herein considered equivalent to
+  @key{elsif} True @key{then}.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of if statements:}
address@hidden
address@hidden Month = December @key[and] Day = 31 @key[then]
+   Month := January;
+   Day   := 1;
+   Year  := Year + 1;
address@hidden @key[if];
+
address@hidden Line_Too_Short @key[then]
+   @key[raise] Layout_Error;
address@hidden Line_Full @key[then]
+   New_Line;
+   Put(Item);
address@hidden
+   Put(Item);
address@hidden @key[if];
+
address@hidden My_Car.Owner.Vehicle /= My_Car @key[then]            
address@hidden  see @RefSecNum{Incomplete Type Declarations}}
+   Report ("Incorrect data");
address@hidden @key[if];
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0147-1]}
+  @ChgAdded{Version=[3],Text=[Moved definition of @nt{condition} to
+  @RefSecNum{Conditional Expressions} in order to eliminate a forward 
reference.]}
address@hidden
+
+
address@hidden Statements}
+
address@hidden
address@hidden @nt{case_statement} selects for execution one of a
+number of alternative @ntf{sequences_of_statements}; the chosen
+alternative is defined by the value of an expression.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0188-1]}
address@hidden<case_statement>,rhs="
+   @key{case} @Chg{Version=[3],address@hidden,address@hidden @key{is}
+       @Syn2{case_statement_alternative}
+      address@hidden
+   @key{end} @key{case};"}
+
+
address@hidden<case_statement_alternative>,rhs="
+   @key{when} @Syn2{discrete_choice_list} =>
+      @Syn2{sequence_of_statements}"}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0188-1]}
address@hidden,address@hidden type], Sec=(case_statement selecting_expression)}
address@hidden type], Sec=(selecting_expression 
case_statement)}],address@hidden type], Sec=(case expression)}]}
+The @Chg{Version=[3],address@hidden,address@hidden is
+expected to be of any discrete type.
address@hidden type],
+  Sec=(case_statement_alternative discrete_choice)}
+The expected type for each @nt{discrete_choice} is the type of the
address@hidden,address@hidden,address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0153-3]}
+The @Chg{Version=[3],address@hidden,
address@hidden,],address@hidden and
address@hidden,address@hidden,address@hidden given as
address@hidden of a @nt{case_statement} shall be static.
address@hidden @nt{discrete_choice} @key(others), if present,
+shall appear alone and in the last @nt{discrete_choice_list}.]
+
address@hidden,Kind=[Revised],ARef=[AI05-0188-1],ARef=[AI05-0240-1]}
+The possible values of the
address@hidden,address@hidden,address@hidden shall be
+covered @Chg{Version=[3],New=[(see @RefSecNum{Variant Parts and Discrete 
Choices}) ],
+Old=[]}as follows:
+  @begin{Discussion}
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0240-1]}
+    @ChgAdded{Version=[3],Text=[The meaning of "covered" here and in the
+    following rules is that of the term "cover a value" that is defined in
+    @RefSecNum{Variant Parts and Discrete Choices}.]}
+  @end{Discussion}
address@hidden
+  
@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0003-1],ARef=[AI05-0153-3],ARef=[AI05-0188-1],ARef=[AI05-0262-1]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0071-1]}
+  If the @Chg{Version=[3],address@hidden,address@hidden is a @nt{name}
+  @Redundant[(including a
+  @nt<type_conversion>@Chg{Version=[3],New=[, 
@nt{qualified_expression},],Old=[]}
+  or @Chg{Version=[3],New=[],Old=[a address@hidden<function_call>)] having
+  a static and constrained nominal subtype,@Chg{Version=[3],New=[],Old=[ or
+  is a @nt{qualified_expression} whose
+  @nt{subtype_mark} denotes a static and constrained
+  scalar subtype,]}
+  then each address@hidden @nt{discrete_choice} shall cover only values in
+  that address@hidden,New=[ that satisfy its
+  @Chg{Version=[4],New=[predicates],Old=[predicate]} (see
+  @RefSecNum{Subtype Predicates})],Old=[]},
+  and each value of that address@hidden,New=[ that satisfies its
+  @Chg{Version=[4],New=[predicates],Old=[predicate]}],Old=[]} shall be
+  covered by some @nt{discrete_choice}
+  @Redundant[(either explicitly or by @key(others))].
+  @begin{Ramification}
+    Although not official @nt<name>s of objects, a value conversion
+    still has a defined nominal subtype, namely its target subtype.
+    See @RefSecNum{Type Conversions}.
+  @end{Ramification}
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0188-1]}
+  If the type of the @Chg{Version=[3],address@hidden,address@hidden is
+  @i(root_integer), @i(universal_integer), or a descendant of a
+  formal scalar type,
+  then the @nt{case_statement} shall have an @key{others}
+  @nt{discrete_choice}.
address@hidden
+  This is because the base range is
+  implementation defined for @i(root_integer) and @i(universal_integer),
+  and not known statically in the case of a formal scalar type.
address@hidden
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0188-1]}
+  Otherwise, each value of the base range of the type of the
+  @Chg{Version=[3],address@hidden,address@hidden shall
+  be covered
+  @Redundant[(either explicitly or by @key(others))].
address@hidden
+
+Two distinct @nt{discrete_choice}s of a
address@hidden shall not cover the same value.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0188-1]}
+The goal of these coverage rules is
+that any possible value of the @Chg{Version=[3],address@hidden,address@hidden 
of a
address@hidden should be covered by exactly one
address@hidden of the
address@hidden, and that this should be checked at compile time.
+The goal is achieved in most cases, but there are two minor
+loopholes:
address@hidden
+If the expression reads an object with an invalid representation
+(e.g. an uninitialized object),
+then the value can be outside the covered range.
+This can happen for static constrained subtypes, as well as nonstatic or
+unconstrained subtypes.
+It cannot, however, happen if the @nt{case_statement} has the
address@hidden @key{others}, because @key{others} covers all values,
+even those outside the subtype.
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0188-1]}
+If the compiler chooses to represent the value of an expression of an
+unconstrained subtype in a way that includes values outside the bounds of the
+subtype, then those values can be outside the covered range.
+For example, if X: Integer := Integer'Last;, and the case 
@Chg{Version=[3],address@hidden,address@hidden is
+X+1, then the implementation might choose to produce the correct value, which
+is outside the bounds of Integer.
+(It might raise Constraint_Error instead.)
+This case can only happen for nongeneric subtypes that are either
+unconstrained or
address@hidden,New=[],address@hidden spelling consistent}static
+(or both).
+It can only happen if there is no @key{others} @nt{discrete_choice}.
address@hidden
+
+In the uninitialized variable case, the value might be anything; hence, any
+alternative can be chosen, or Constraint_Error can be raised. (We intend to
+prevent, however, jumping to random memory locations and the like.)
+In the out-of-range case, the behavior is more sensible: if there is an
address@hidden, then the implementation may choose to raise Constraint_Error
+on the evaluation of the @nt{expression} (as usual), or it may choose
+to correctly evaluate the @nt{expression} and therefore choose the
address@hidden alternative.
+Otherwise (no @key{others}), Constraint_Error is raised either way @em on
+the @nt{expression} evaluation, or for the @nt{case_statement} itself.
+
+For an enumeration type with a discontiguous set of internal codes
+(see @RefSecNum{Enumeration Representation Clauses}),
+the only way to get values in between the proper values
+is via an object with an invalid representation;
+there is no @lquotes@;address@hidden@; situation that can produce them.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0188-1]}
address@hidden, Sec=(case_statement)}
+For the execution of a @nt{case_statement} the
address@hidden,address@hidden,address@hidden
+is first evaluated.
+
address@hidden,Kind=[Revised],ARef=[AI05-0188-1]}
+If the value of the @Chg{Version=[3],address@hidden,address@hidden
+is covered by the @address@hidden@!list} of some
address@hidden@address@hidden, then the
address@hidden@!statements} of the @ntf{_alternative} is executed.
+
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+Otherwise (the value is not covered by any
address@hidden,
+perhaps due to being outside the base range),
+Constraint_Error is raised.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI12-0005-1]}
+  In this case, the value @Chg{Version=[5],New=[fails to satisfy its
+  (static) predicate (possible when the predicate is disabled),],Old=[]}
+  is outside the base range of its type,
+  or is an invalid representation.
+
address@hidden
address@hidden
+
address@hidden
+The execution of a @nt{case_statement} chooses one and only one
+alternative.
+Qualification of the expression of a @nt{case_statement} by a static
+subtype can often be used to limit the number of choices that need be
+given explicitly.
address@hidden
+
address@hidden
address@hidden@address@hidden of case statements:}
address@hidden
address@hidden()@tabset(P22)
address@hidden Sensor @key[is]
+   @key[when] address@hidden> Record_Elevation(Sensor_Value);
+   @key[when] address@hidden> Record_Azimuth  (Sensor_Value);
+   @key[when] address@hidden> Record_Distance (Sensor_Value);
+   @key[when] @address@hidden> @key[null];
address@hidden @key[case];
+
address@hidden()@tabset(P22)
address@hidden Today @key[is]
+   @key[when] address@hidden> Compute_Initial_Balance;
+   @key[when] address@hidden> Compute_Closing_Balance;
+   @key[when] Tue .. address@hidden> Generate_Report(Today);
+   @key[when] Sat .. address@hidden> @key[null];
address@hidden @key[case];
+
address@hidden()@tabset(P16)
address@hidden Bin_Number(Count) @key[is]
+   @key[when] address@hidden> Update_Bin(1);
+   @key[when] address@hidden> Update_Bin(2);
+   @key[when] 3 | address@hidden>
+      Empty_Bin(1);
+      Empty_Bin(2);
+   @key[when] @address@hidden> @key[raise] Error;
address@hidden @key[case];
address@hidden
address@hidden
+
address@hidden
address@hidden,address@hidden AI-00020}
address@hidden@Defn{incompatibilities with Ada 83}
+In Ada 95, @nt{function_call}s and @nt{type_conversion}s are @nt{name}s, 
whereas
+in Ada 83, they were @nt{expression}s. Therefore, if the @nt{expression} of a
address@hidden is a @nt{function_call} or @nt{type_conversion}, and the
+result subtype is static, it is illegal to specify a choice outside the bounds
+of the subtype. For this case in Ada 83 choices only are required to be in the
+base range of the type.],Old=[]}
+
address@hidden,address@hidden AI-00020}
address@hidden addition, the rule about which choices must be covered is
+unchanged in Ada 95. Therefore, for a @nt{case_statement} whose @nt{expression}
+is a @nt{function_call} or @nt{type_conversion}, Ada 83 required covering all
+choices in the base range, while Ada 95 only requires covering choices in the
+bounds of the subtype. If the @nt{case_statement} does not include an 
@key{others}
address@hidden, then a legal Ada 83 @nt{case_statement} will be illegal
+in Ada 95 if the bounds of the subtype are different than the bounds of the
+base type.],Old=[]}
address@hidden
+
address@hidden
address@hidden to Ada 83}
+In Ada 83, the @nt{expression} in a @nt{case_statement} is not allowed to
+be of a generic formal type.
+This restriction is removed in Ada 95; an @key{others} @nt{discrete_choice}
+is required instead.
+
+In Ada 95, a function call is the name of an object;
+this was not true in Ada 83 (see @RefSec{Names}).
+This change makes the following @nt{case_statement} legal:
address@hidden
address@hidden S @key[is] Integer @key[range] 1..2;
address@hidden F @key[return] S;
address@hidden F @key[is]
+   @key[when] 1 => ...;
+   @key[when] 2 => ...;
+   address@hidden No @key{others} needed.}
address@hidden @key[case];
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+Note that the result subtype given in a function
address@hidden is ignored;
+for a @nt{case_statement} whose expression calls a such a function, the
+full coverage rules are checked using the result subtype of the original
+function.
+Note that predefined operators such as "+" have an unconstrained result
+subtype (see @RefSecNum{Logical Operators and Short-circuit Control Forms}).
+Note that generic formal functions do not have static result subtypes.
+Note that the result subtype of an inherited subprogram need not
+correspond to any @Chg{Version=[3],New=[nameable],Old=[namable]} subtype;
+there is still a perfectly good result subtype, though.
address@hidden
+
address@hidden
+Ada 83 forgot to say what happens for @lquotes@;address@hidden@; out-of-bounds 
values.
+
+We take advantage of rules and terms (e.g. @i(cover a value))
+defined for @nt{discrete_choice}s and @nt{discrete_choice_list}s
+in @RefSec{Variant Parts and Discrete Choices}.
+
+In the @ResolutionName for the case expression,
+we no longer need RM83-5.4(3)'s @lquotes@;which must be determinable
+independently of the context in which the expression occurs, but
+using the fact that the expression must be of a discrete type,@rquotes@;
+because the @nt{expression} is now a complete context.
+See @RefSec{The Context of Overload Resolution}.
+
+Since @nt<type_conversion>s are now defined as @nt<name>s,
+their coverage rule is now covered under the general rule
+for @nt<name>s, rather than being separated out along with
address@hidden<qualified_expression>s.
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0003-1]}
+  @ChgAdded{Version=[3],Text=[Rewording to reflect that
+  a @nt{qualified_expression} is now a @nt{name}.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0153-3]}
+  @ChgAdded{Version=[3],Text=[Revised for changes to @nt{discrete_choice}s
+  made to allow static predicates (see @RefSecNum{Subtype Predicates}) as
+  case choices (see @RefSecNum{Variant Parts and Discrete Choices}).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0188-1]}
+  @ChgAdded{Version=[3],Text=[Added the @SynI{selecting_} prefix to
+  make this wording consistent with @nt{case_expression}, and to clarify
+  which @nt{expression} is being talked about in the wording.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0071-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Updated wording of
+  case coverage to use the new term "satisfies the predicates"
+  (see @RefSecNum{Subtype Predicates}).]}
address@hidden
+
+
address@hidden Statements}
+
address@hidden
address@hidden @nt{loop_statement} includes a
address@hidden that is to be executed repeatedly,
+zero or more times.]
address@hidden
+
address@hidden
address@hidden<loop_statement>,rhs="
+   address@hidden@Syn2{statement_identifier}:]
+      address@hidden @key{loop}
+         @Syn2{sequence_of_statements}
+       @key{end} @key{loop} address@hidden@Syn2{identifier}];"}
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0139-2]}
address@hidden<iteration_scheme>,rhs="@key{while} @Syn2{condition}
+   | @key{for} @address@hidden,New=[
+   | @key{for} @Syn2{iterator_specification}],Old=[]}"}
+
address@hidden<loop_parameter_specification>,rhs="
+   @Syn2{defining_identifier} @key{in} address@hidden 
@Syn2{discrete_subtype_definition}"}
+
address@hidden(SyntaxText)
+If a @nt{loop_statement} has a @address@hidden,
+then the @nt<identifier> shall be repeated after the @key{end loop};
+otherwise, there shall not be an @nt<identifier> after the @key{end loop}.
address@hidden(SyntaxText)
address@hidden
+
address@hidden
address@hidden parameter}
+A @nt{loop_parameter_specification} declares a @i{loop parameter},
+which is an object whose
+subtype is that defined by the @nt{discrete_subtype_definition}.
address@hidden,See=[loop parameter]}
address@hidden
+
address@hidden
address@hidden, Sec=(loop_statement)}
+For the execution of a @nt{loop_statement},
+the @nt{sequence_of_statements} is executed repeatedly,
+zero or more times,
+until the @nt{loop_statement} is complete.
+The @nt{loop_statement} is complete when a transfer
+of control occurs that transfers control out of the loop, or, in the
+case of an @nt{iteration_scheme}, as specified below.
+
address@hidden,
+  Sec=(loop_statement with a while iteration_scheme)}
+For the execution of a @nt{loop_statement} with a @key{while}
address@hidden, the condition is evaluated before each
+execution of the @address@hidden; if the value of the
address@hidden is True, the @address@hidden is executed;
+if False, the execution of the @address@hidden is complete.
+
address@hidden,Kind=[Revised],ARef=[AI05-0139-2],ARef=[AI05-0262-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0071-1]}
address@hidden,
+  Sec=(loop_statement with a for iteration_scheme)}
address@hidden, Sec=(loop_parameter_specification)}
+For the execution of a @nt{loop_statement} with
address@hidden,New=[the],Old=[a @key{for}]}
address@hidden@Chg{Version=[3],New=[ being @key[for]
address@hidden@address@hidden,Old=[]},
+the @address@hidden@!specification} is first elaborated. This
+elaboration creates the loop parameter and elaborates the
address@hidden@address@hidden
+If the @address@hidden@!definition} defines a subtype
+with a null range,
+the execution of the
address@hidden is complete. Otherwise, the
address@hidden@!statements} is executed once for each value of the
+discrete subtype defined by the
address@hidden@address@hidden
address@hidden,New=[that satisfies the
address@hidden,New=[predicates],Old=[predicate]} of the subtype ],Old=[]}(or
+until the loop is left as a consequence of a transfer of control).
address@hidden operation], Sec=(during execution of a @key{for} loop)}
+Prior to each such iteration,
+the corresponding value of the discrete subtype is assigned to the
+loop parameter. These values are assigned in increasing order unless
+the reserved word @key{reverse} is present, in which case the values
+are assigned in decreasing order.
address@hidden
+The order of creating the loop parameter and evaluating the
address@hidden doesn't matter,
+since the creation of the loop parameter has no side effects (other
+than possibly raising Storage_Error, but anything can do that).
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0262-1]}
address@hidden,Text=[The predicate (if any) necessarily has to be a
+static predicate as a dynamic predicate is explicitly disallowed @em
+see @RefSecNum{Subtype Predicates}.]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[If there is a predicate, the loop
+  still visits the values in the order of the underlying base type; the order 
of
+  the values in the predicate is irrelevant. This is the case so that the
+  following loops have the same sequence of calls and parameters on procedure
+  Call for any subtype S:]}
address@hidden
address@hidden,address@hidden I @key[in] S @key[loop]
+   Call (I);
address@hidden loop];]}
+
address@hidden,address@hidden I @key[in] S'Base @key[loop]
+   @key[if] I @key[in] S @key[then]
+      Call (I);
+   @key[end if];
address@hidden loop];]}
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0262-1]}
address@hidden,address@hidden details about the execution of a
address@hidden with the @nt{iteration_scheme} being @key[for]
address@hidden, see @RefSecNum{Generalized Loop Iteration}.]]}
+
address@hidden
+
address@hidden
+A loop parameter is a constant;
+it cannot be updated within the
address@hidden of the loop
+(see @RefSecNum{Objects and Named Numbers}).
+
+An @nt{object_declaration} should not be given for a loop parameter,
+since the loop parameter is automatically declared by
+the @nt{loop_parameter_specification}.
+The scope of a loop parameter extends from the
address@hidden to the end of the
address@hidden, and the visibility
+rules are such that a loop parameter is only visible within the
address@hidden of the loop.
address@hidden
+An implementation could give a warning if a variable is hidden by a
address@hidden
address@hidden
+
+The @nt<discrete_subtype_definition> of a for loop is elaborated
+just once. Use of the
+reserved word @key[reverse] does not alter the discrete subtype defined,
+so that the following @nt{iteration_scheme}s are not equivalent; the
+first has a null range.
address@hidden
address@hidden J @key[in] @key[reverse] 1 .. 0
address@hidden J @key[in] 0 .. 1
address@hidden
address@hidden
+If a @nt{loop_parameter_specification} has a static discrete range,
+the subtype of the loop parameter is static.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of a loop statement without an iteration scheme:}
address@hidden
address@hidden
+   Get(Current_Character);
+   @key[exit] @key[when] Current_Character = '*';
address@hidden @key[loop];
address@hidden
+
address@hidden
address@hidden@address@hidden of a loop statement with a @key[while] iteration 
scheme:}
address@hidden
address@hidden
address@hidden Bid(N).Price < Cut_Off.Price @key[loop]
+   Record_Bid(Bid(N).Price);
+   N := N + 1;
address@hidden @key[loop];
address@hidden
+
address@hidden
address@hidden@address@hidden of a loop statement with a @key[for] iteration 
scheme:}
address@hidden
address@hidden
address@hidden J @key[in] Buffer'Range @key[loop]     address@hidden  works 
even with a null range}
+   @key[if] Buffer(J) /= Space @key[then]
+      Put(Buffer(J));
+   @key[end] @key[if];
address@hidden @key[loop];
address@hidden
+
address@hidden
address@hidden@address@hidden of a loop statement with a name:}
address@hidden
address@hidden
+Summation:
+   @key[while] Next /= Head @key[loop]       address@hidden see 
@RefSecNum{Incomplete Type Declarations}}
+      Sum  := Sum + Next.Value;
+      Next := Next.Succ;
+   @key[end] @key[loop] Summation;
address@hidden
address@hidden
+
address@hidden
+The constant-ness of loop parameters is specified in
address@hidden and Named Numbers}.
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0262-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[Generalized @nt{iterator_specification}s are
+  allowed in @key[for] loops; these are documented as an extension in the
+  appropriate subclause.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0071-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Updated wording of
+  loop execution to use the new term "satisfies the predicates"
+  (see @RefSecNum{Subtype Predicates}).]}
address@hidden
+
+
address@hidden,Name=[User-Defined Iterator Types]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The following
+language-defined generic library package exists:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden,address@hidden
+   @key[type] Cursor;
+   @key[with function] Has_Element (Position : Cursor) @key[return] Boolean;
address@hidden Ada.Iterator_Interfaces @key[is]
+   @key[pragma] Pure (Iterator_Interfaces);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Forward_Iterator} @key[is 
limited interface];
+   @key[function] @AdaSubDefn{First} (Object : Forward_Iterator) @key[return] 
Cursor @key[is abstract];
+   @key[function] @AdaSubDefn{Next} (Object : Forward_Iterator; Position : 
Cursor)
+      @key[return] Cursor @key[is abstract];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Reversible_Iterator} @key[is 
limited interface and] Forward_Iterator;
+   @key[function] @AdaSubDefn{Last} (Object : Reversible_Iterator) 
@key[return] Cursor @key[is abstract];
+   @key[function] @AdaSubDefn{Previous} (Object : Reversible_Iterator; 
Position : Cursor)
+      @key[return] Cursor @key[is abstract];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Iterator_Interfaces;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Text=[An @i<iterator type> is a type descended from
+the Forward_Iterator interface from some instance of
address@hidden type}
+A @i<reversible iterator type> is a type descended from the Reversible_Iterator
+interface from some instance of address@hidden iterator type}
+An @i<iterator object> is an object of an iterator address@hidden object}
+A @i<reversible iterator object> is an object
+of a reversible iterator address@hidden iterator object}
+The formal subtype Cursor from the associated
+instance of Ada.Iterator_Interfaces is the @i<iteration cursor subtype> for the
+iterator address@hidden cursor subtype}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,Type=[Leading],Text=[The following type-related
+operational aspects may be specified for an indexable container type @i<T> (see
address@hidden Indexing}):]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],address@hidden aspect is specified
+    by a @nt{name} that denotes exactly one function declared immediately 
within
+    the same declaration list in which @i<T> is declared, whose first parameter
+    is of type @i<T> or @i<T>'Class or an access parameter whose designated 
type
+    is type @i<T> or @i<T>'Class, whose other parameters, if any, have default
+    expressions, and whose result type is an iterator type. This function is 
the
+    @i<default iterator function> for @i<T>address@hidden iterator function}
+    Its result subtype is the @i<default iterator subtype> for
+    @i<T>address@hidden iterator subtype} The iteration cursor subtype for
+    the default iterator subtype is the @i<default cursor subtype>
+    for @i<T>address@hidden cursor address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Default_Iterator],
+    address@hidden,Text=[Default iterator to be used in @key[for]
+    loops.]}]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],address@hidden aspect is specified by a
+    @nt{name} that denotes a subtype. This is the @i<default element subtype>
+    for @i<T>address@hidden element address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Iterator_Element],
+    address@hidden,Text=[Element type to be used for user-defined
+      iterators.]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[These aspects are inherited by descendants of
+type @i<T> (including @i<T>'Class).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,Text=[An @i<iterable container type> is an indexable container 
type
+with specified Default_Iterator and Iterator_Element address@hidden container 
type}
+A @i<reversible iterable container type> is an iterable container type with 
the default iterator type
+being a reversible iterator address@hidden iterable container type}
+An @i<iterable container object> is an object of an iterable container 
address@hidden container object}
+A @i<reversible iterable container object> is an object of a reversible 
iterable container
address@hidden iterable container object}]}
+
address@hidden,Kind=[Added],Term=<Iterable container type>,
+Text=<@ChgAdded{Version=[3],Text=[An iterable container type is one that has
+user-defined behavior for iteration, via the Default_Iterator and
+Iterator_Element aspects.]}>}
+
address@hidden,Kind=[Added],ARef=[AI12-0138-1]}
address@hidden,Text=[The Default_Iterator and Iterator_Element aspects
+are nonoverridable (see @RefSecNum{Aspect Specifications}).]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This ensures that all descendants of an
+  iterable container type have aspects with the same properties. This prevents
+  generic contract problems with formal derived types.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,Type=[Leading],Text=[The Constant_Indexing aspect (if any)
+of an iterable container type @i<T> shall denote exactly one function with the 
following
+properties:]}
+
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[the result type of the function is covered by the
+    default element type of @i<T> or is a reference type (see
+    @RefSecNum{User-Defined References}) with an access discriminant 
designating
+    a type covered by the default element type of @i<T>;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[the type of the second parameter of the function
+    covers the default cursor type for @i<T>;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[if there are more than two parameters, the
+    additional parameters all have default expressions.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This function (if any) is the
address@hidden<default constant indexing function> for @i<T>address@hidden 
constant indexing function}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This does not mean that Constant_Indexing has to
+  designate only one subprogram, only that there is only one routine that meets
+  all of these properties. There can be other routines designated by
+  Constant_Indexing, but they cannot have the profile described above. For
+  instance, map containers have a version of Constant_Indexing that takes a
+  key instead of a cursor; this is allowed.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,Type=[Leading],Text=[The Variable_Indexing aspect (if any)
+of an iterable container type @i<T> shall denote exactly one function with the 
following
+properties:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[the result type of the function is a reference
+    type (see @RefSecNum{User-Defined References}) with an access discriminant
+    designating a type covered by the default element type of @i<T>;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[the type of the second parameter of the function
+    covers the default cursor type for @i<T>;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[if there are more than two parameters, the
+    additional parameters all have default expressions.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This function (if any) is the
address@hidden<default variable indexing function> for @i<T>address@hidden 
variable indexing function}]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0139-2]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}User-defined
+  iterator types are new in Ada 2012.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0138-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Defined Default_Iterator and Iterator_Element to be nonoveridable, which
+  makes redefinitions and hiding of these aspects illegal. It's possible that
+  some program could violate one of these new restrictions, but in most cases
+  this can easily be worked around by using overriding rather than
+  redefinition.]}
address@hidden
+
+
+
address@hidden,Name=[Generalized Loop Iteration]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Text=[Generalized forms of loop iteration are provided by
+an @nt{iterator_specification}.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<iterator_specification>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<
+    @Syn2{defining_identifier} @key[in] address@hidden @address@hidden
+  | @Syn2{defining_identifier} [: @Syn2{subtype_indication}] @key[of] 
address@hidden @address@hidden>,Old=<>}"}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,Text=[For the first form of @nt{iterator_specification},
+called a @i<generalized iterator>,@Defn{generalized 
address@hidden,Sec=[generalized]}
+the expected type for the @SynI<iterator_>@nt{name} is any iterator
address@hidden type],address@hidden<iterator_>@nt{name}]}
+For the second form of @nt{iterator_specification},
+the expected type for the @SynI<iterable_>@nt{name} is any array or iterable
+container address@hidden type],address@hidden<iterable_>@nt{name}]}
+If the @SynI<iterable_>@nt{name} denotes an array object, the
address@hidden is called an @i<array
+component iterator>;@Defn{array component address@hidden,Sec=[array component]}
+otherwise it is called a
address@hidden<container element iterator>address@hidden element 
address@hidden,Sec=[container element]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],Term=<Iterator>,
+Text=<@ChgAdded{Version=[3],Text=[An iterator is a construct that is used to
+loop over the elements of an array or container. Iterators may be user defined,
+and may perform arbitrary computations to access elements from a container.]}>}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Text=[If the reserved word @key[reverse] appears,
+the @nt{iterator_specification} is a @i<reverse iterator>;@Defn{reverse 
address@hidden,Sec=[reverse]}
+otherwise it is a @i<forward iterator>address@hidden 
address@hidden,Sec=[forward]}
+In a reverse generalized iterator, the
address@hidden<iterator_>@nt{name} shall be of a reversible iterator type.
+In a reverse container element iterator, the default iterator type for the type
+of the @SynI<iterable_>@nt{name} shall be a reversible iterator type.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Kind=[Revised],ARef=[AI12-0151-1]}
address@hidden,Text=[The @Chg{Version=[4],New=[subtype defined
+by],Old=[type of]} the @nt{subtype_indication}, if any, of an array component
+iterator shall @Chg{Version=[4],New=[statically match],Old=[cover]} the
+component @Chg{Version=[4],New=[subtype],Old=[type]} of the type of the
address@hidden<iterable_>@nt{name}. The @Chg{Version=[4],New=[subtype defined
+by],Old=[type of]} the @nt{subtype_indication}, if any, of a container element
+iterator shall @Chg{Version=[4],New=[statically match],Old=[cover]} the default
+element @Chg{Version=[4],New=[subtype],Old=[type]} for the type of the
address@hidden<iterable_>@nt{name}.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Text=[In a container element iterator whose
address@hidden<iterable_>@nt{name} has type @i<T>, if the 
@SynI<iterable_>@nt{name}
+denotes a constant or the Variable_Indexing aspect is not specified for @i<T>,
+then the Constant_Indexing aspect shall be specified for @i<T>.]}
+
address@hidden,Kind=[Added],ARef=[AI12-0047-1]}
address@hidden,Text=[The @SynI<iterator_>@nt{name} or
address@hidden<iterable_>@nt{name} of an @nt{iterator_specification} shall
+not denote a subcomponent that depends on discriminants of an object
+whose nominal subtype is unconstrained, unless the object is known
+to be constrained.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This is the same rule that applies to
+  renames; it serves the same purpose of preventing the object from
+  disappearing while the iterator is still using it.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0120-1]}
address@hidden,Text=[A container element iterator is illegal if the
+call of the default iterator function that creates the loop iterator
+(see below) is illegal.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This can happen if the parameter to the default
+  iterator function is @key[in out] and the @SynI<iterable_>@nt{name} is a
+  constant. The wording applies to any reason that the call would be illegal,
+  as it's possible that one of the default parameters would be illegal, or
+  that some accessibility check would fail.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0120-1]}
address@hidden,Text=[A generalized iterator is illegal if the iteration
+cursor subtype of the @SynI<iterator_>@nt{name} is a limited type at the point
+of the generalized iterator. A container element iterator is illegal if the
+default cursor subtype of the type of the @SynI<iterable_>@nt{name} is a 
limited
+type at the point of the container element iterator.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[If the cursor type is limited, the assignment to
+  the loop parameter for a generalized iterator would be illegal. The same is
+  true for a container element iterator. We have to say "at the point of the
+  iterator" as the limitedness of a type can change due to visibility.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0269-1],ARef=[AI05-0292-1]}
address@hidden,Text=[An @nt{iterator_specification} declares a
address@hidden<loop parameter>address@hidden parameter}
+In a generalized iterator, the nominal subtype of the loop parameter is
+the iteration cursor subtype. In an array component iterator or a
+container element iterator, if a @nt{subtype_indication} is present, it
+determines the nominal subtype of the loop parameter. In an array
+component iterator, if a @nt{subtype_indication} is not present, the
+nominal subtype of the loop parameter is the component subtype of the
+type of the @address@hidden In a container element iterator, if a
address@hidden is not present, the nominal subtype of the loop
+parameter is the default element subtype for the type of the
address@hidden@nt{name}.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,Text=[In a generalized iterator, the loop parameter
+is a constant. In an array component iterator, the loop parameter
+is a constant if the @SynI<iterable_>@nt{name} denotes a constant; otherwise
+it denotes a variable. In a container element iterator, the loop parameter
+is a constant if the @address@hidden denotes a constant, or if
+the Variable_Indexing aspect is not specified for the type of the
address@hidden@nt{name}; otherwise it is a variable.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0093-1]}
+  @ChgAdded{Version=[4],Text=[The loop parameter of a generalized iterator has
+  the same accessibility as the loop statement. This means that the loop
+  parameter object is finalized when the loop statement is left. (It also may 
be
+  finalized as part of assigning a new value to the loop parameter.) For array
+  component iterators and container element iterators, the loop parameter
+  directly denotes an element of the array or container and has the
+  accessibility of the associated array or container.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Text=[For the execution of a @nt{loop_statement} with
+an @nt{iterator_specification}, the @nt{iterator_specification} is
+first elaborated. This elaboration elaborates the @nt{subtype_indication},
+if any.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2]}
address@hidden,Text=[For a generalized iterator, the loop parameter is
+created, the @address@hidden is evaluated, and the denoted iterator
+object becomes the @i<loop iterator>address@hidden iterator} In a forward
+generalized iterator, the operation First of the iterator type is called on the
+loop iterator, to produce the initial value for the loop parameter. If the
+result of calling Has_Element on the initial value is False, then the execution
+of the @nt{loop_statement} is complete. Otherwise, the
address@hidden is executed and then the Next operation of the
+iterator type is called with the loop iterator and the current value of the 
loop
+parameter to produce the next value to be assigned to the loop parameter. This
+repeats until the result of calling Has_Element on the loop parameter is False,
+or the loop is left as a consequence of a transfer of control. For a reverse
+generalized iterator, the operations Last and Previous are called rather than
+First and Next.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0093-1]}
+  @ChgAdded{Version=[4],Text=[The loop parameter of a generalized iterator is a
+  variable of which the user only has a constant view. It follows the normal
+  rules for a variable of its nominal subtype. In particular, if the nominal
+  subtype is indefinite, the variable is constrained by its initial value.
+  Similarly, if the nominal subtype is class-wide, the variable (like all
+  variables) has the tag of the initial value. Constraint_Error may be raised 
by
+  a subsequent iteration if Next or Previous return an object with a different
+  tag or constraint.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,Text=[For an array component iterator, the
address@hidden<iterable_>@nt{name} is evaluated and
+the denoted array object becomes the @i<array for the
+loop>address@hidden for a loop} If the array for the loop is a null array,
+then the execution of the @nt{loop_statement} is complete. Otherwise, the
address@hidden is executed with the loop parameter denoting
+each component of the array for the loop, using a @i<canonical> order
+of components,@Defn{canonical order of array components}
+which is last dimension varying fastest (unless the
+array has convention Fortran, in which case it is first dimension
+varying fastest). For a
+forward array component iterator, the iteration starts with the
+component whose index values are each the first in their index range,
+and continues in the canonical order. For a reverse array component
+iterator, the iteration starts with the component whose index values
+are each the last in their index range, and continues in the reverse
+of the canonical order. The loop iteration proceeds until the
address@hidden has been executed for each component of the
+array for the loop, or until the loop is left as a consequence of a
+transfer of control.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,Text=[For a container element iterator, the 
@SynI<iterable_>@nt{name} is evaluated
+and the denoted iterable container object becomes the @i<iterable
+container object for the loop>address@hidden container object for a loop}
+The default iterator function for the type of
+the iterable container object for the loop is called on the iterable container 
object
+and the result is the @i<loop iterator>address@hidden iterator],Sec=[container 
element iterator]}
+An object of the default cursor subtype is created (the @i<loop 
cursor>)address@hidden cursor}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0139-2],ARef=[AI05-0292-1]}
address@hidden,Text=[For a forward container element iterator, the
+operation First of the iterator type is called on the loop iterator, to produce
+the initial value for the loop cursor. If the result of calling Has_Element on
+the initial value is False, then the execution of the @nt{loop_statement} is
+complete. Otherwise, the @nt{sequence_of_statements} is executed with the loop
+parameter denoting an indexing (see @RefSecNum{User-Defined Indexing}) into the
+iterable container object for the loop, with the only parameter to the 
indexing being the
+current value of the loop cursor; then the Next operation of the iterator type
+is called with the loop iterator and the loop cursor to produce the next value
+to be assigned to the loop cursor. This repeats until the result of calling
+Has_Element on the loop cursor is False, or until the loop is left as a
+consequence of a transfer of control. For a reverse container element iterator,
+the operations Last and Previous are called rather than First and Next. If the
+loop parameter is a constant (see above), then the indexing uses the default
+constant indexing function for the type of the iterable container object for 
the
+loop; otherwise it uses the default variable indexing function.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0120-1]}
address@hidden,Text=[Any exception propagated by the execution of a
+generalized iterator or container element iterator is propagated by the
+immediately enclosing loop statement.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This text covers exceptions raised by called
+  functions that make up the execution of the iterator as well as
+  exceptions raised by the assignment to the loop parameter or cursor.]}
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0269-1]}
address@hidden,Text=[-- @Examcom{Array component iterator example:}
address@hidden Element @key[of] Board @key[loop]  -- @Examcom{See 
@RefSecNum{Index Constraints and Discrete Ranges}.}
+   Element := Element * 2.0; -- @Examcom{Double each element of Board, a 
two-dimensional array.}
address@hidden loop];]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0268-1]}
address@hidden,Text=[For examples of use of generalized iterators,
+see @RefSecNum{Example of Container Use} and the corresponding container
+packages in @RefSecNum{The Generic Package Containers.Vectors} and
address@hidden Generic Package Containers.Doubly_Linked_Lists}.]}
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0139-2]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Generalized forms
+  of loop iteration are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0047-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada
+  address@hidden<Corrigendum:> Added a rule to ensure that the object being 
iterated
+  cannot be a component that could disappear before the loop completes. This
+  could be incompatible by making a loop that was legal (and worked correctly,
+  so long as the enclosing object is not modified during the loop) from the
+  original Ada 2012 illegal in corrected Ada 2012. Such loops should be pretty
+  rare, especially as these iterator forms are new to Ada 2012.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0120-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Added rules to reject 
loops
+  if the call to the default iterator function for a container element
+  iterator is illegal, or if the cursor type of an iterator is limited.
+  These are formally incompatible with original Ada 2012, but as it's unlikely
+  that any Ada 2012 compiler ever allowed the illegal usages in an expansion
+  of a loop (it's much more likely that they would have just caused an internal
+  error in the compiler), this should have no effect in practice.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0151-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Added a requirement that 
the
+  given subtype statically match the subtype of the element or component for
+  a component element iterator or array component iterator. Original Ada 2012
+  text allowed any type that covered the subtype of the element or component,
+  but that led to questions of what the meaning was if they are different.
+  In this case, the element is essentially a renaming of the container element,
+  and it doesn't make sense for the constraints to be different. Ignoring
+  explicitly defined constraints in renames is a mistake that we don't want
+  to continue, thus we require static matching. This means that some programs
+  might be illegal, but those programs were misleading at best, and
+  potentially would raise unexpected exceptions because the element values
+  might have been invalid or abnormal with respect to the declared 
constraint.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0120-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Added wording to specify 
that
+  a loop propagates any exceptions propagated by the execution of an iterator.
+  Since that's what naturally would happen from a macro-style expansion of the
+  parts of an iterator, and no other interpretation makes sense given the way
+  the rest of Ada works, we consider it so unlikely that any Ada 2012
+  implementation ever did anything else that we don't document this as a
+  possible inconsistency.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 95}
address@hidden@Comment{For printed version of Ada 95 + TC1 RM}
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden Statements}
+
address@hidden
address@hidden @nt{block_statement} encloses a
address@hidden
+optionally preceded by a @nt{declarative_part}.]
address@hidden
+
address@hidden
address@hidden<block_statement>,rhs="
+   address@hidden@Syn2{statement_identifier}:]
+       address@hidden
+            @Syn2{declarative_part}]
+        @key{begin}
+            @Syn2{handled_sequence_of_statements}
+        @key{end} address@hidden@Syn2{identifier}];"}
+
address@hidden(SyntaxText)
+If a @nt{block_statement} has a @address@hidden,
+then the @nt<identifier> shall be repeated after the @key{end};
+otherwise, there shall not be an @nt<identifier> after the @key{end}.
address@hidden(SyntaxText)
address@hidden
+
address@hidden
+A @nt{block_statement} that has no
+explicit @nt{declarative_part} has an implicit empty
address@hidden
address@hidden
+Thus, other rules can always
+refer to the @nt{declarative_part} of a @nt<block_statement>.
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(block_statement)}
+The execution of a @nt{block_statement} consists of the elaboration
+of its @nt{declarative_part} followed by the execution of
+its @nt{handled_sequence_of_statements}.
address@hidden
+
address@hidden
address@hidden@address@hidden of a block statement with a local variable:}
address@hidden
+Swap:
+   @key[declare]
+      Temp : Integer;
+   @key[begin]
+      Temp := V; V := U; U := Temp;
+   @key[end] Swap;
address@hidden
address@hidden
+If task objects are declared within a @nt{block_statement} whose execution
+is completed, the @nt{block_statement} is not left until all its dependent
+tasks are terminated
+(see @RefSecNum{Assignment and Finalization}).
+This rule applies to completion caused by a transfer of control.
+
+Within a @nt{block_statement}, the block name can be used in expanded
+names denoting local entities such as Swap.Temp in the above example
+(see @RefSecNum{Selected Components}).
address@hidden
address@hidden
+
address@hidden
+The syntax rule for @nt{block_statement} now uses the syntactic category
address@hidden
address@hidden
+
address@hidden Statements}
+
address@hidden
address@hidden @nt{exit_statement} is used to complete the execution
+of an enclosing @nt{loop_statement}; the
+completion is conditional if the @nt{exit_statement} includes a
address@hidden
address@hidden
+
address@hidden
address@hidden<exit_statement>,rhs="
+   @key{exit} address@hidden@Syn2{name}] address@hidden @Syn2{condition}];"}
address@hidden
+
address@hidden
+The @i(loop_)@nt{name}, if any, in an @nt{exit_statement} shall resolve to
+denote a @nt{loop_statement}.
address@hidden
+
address@hidden
address@hidden, Sec=(to a @nt{loop_statement} by an @nt{exit_statement})}
+Each @address@hidden @i{applies to} a
address@hidden@!statement}; this is the @address@hidden being exited.
+An @address@hidden with a @nt{name} is only allowed within the
address@hidden@!statement} denoted by the @nt{name},
+and applies to that @address@hidden
+An @address@hidden without a @nt{name} is only allowed within a
address@hidden@!statement}, and applies to the innermost enclosing one.
+An @address@hidden that applies to a given @address@hidden
+shall not appear within a body or @address@hidden, if
+this construct is itself enclosed by the given @nt{loop_statement}.
address@hidden
+
address@hidden
address@hidden, Sec=(exit_statement)}
+For the execution of an @nt{exit_statement}, the @nt{condition}, if
+present, is first evaluated.
+If the value of the @nt{condition} is True, or if there is no @nt{condition},
+a transfer of control is done to complete the @address@hidden
+If the value of the @nt{condition} is False, no transfer of control takes
+place.
address@hidden
+
address@hidden
+Several nested loops can be exited by an @nt{exit_statement} that names
+the outer loop.
address@hidden
+
address@hidden
address@hidden of loops with exit statements:}
address@hidden
address@hidden N @key[in] 1 .. Max_Num_Items @key[loop]
+   Get_New_Item(New_Item);
+   Merge_Item(New_Item, Storage_File);
+   @key[exit] @key[when] New_Item = Terminal_Item;
address@hidden @key[loop];
+
+Main_Cycle:
+   @key[loop]
+      address@hidden  initial statements}
+      @key[exit] Main_Cycle @key[when] Found;
+      address@hidden  final statements}
+   @key[end] @key[loop] Main_Cycle;
address@hidden
address@hidden
+
address@hidden Statements}
+
address@hidden
address@hidden @nt{goto_statement} specifies an explicit transfer of control
+from this @nt{statement} to a target
+statement with a given label.]
address@hidden
+
address@hidden
address@hidden<goto_statement>,rhs="@key{goto} @address@hidden;"}
address@hidden
+
address@hidden
address@hidden statement], Sec=(of a @nt{goto_statement})}
+The @i(label_)@nt{name} shall resolve to denote a @nt<label>;
+the @nt{statement} with that @nt{label} is the @i(target statement).
address@hidden
+
address@hidden
+The innermost @nt{sequence_of_statements} that encloses the target
+statement shall also enclose the @nt{goto_statement}.
+Furthermore, if a @nt{goto_statement} is enclosed by an
address@hidden or a body, then the target
+statement shall not be outside this enclosing construct.
address@hidden
+The @nt{goto_statement} can be a @nt{statement} of an inner
address@hidden
+
+It follows from the second rule that if the target @nt{statement}
+is enclosed by such a construct, then the @nt{goto_statement}
+cannot be outside.
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(goto_statement)}
+The execution of a @nt{goto_statement} transfers control to the
+target statement, completing the execution
+of any @nt<compound_statement> that encloses the @nt<goto_statement>
+but does not enclose the target.
address@hidden
+
address@hidden
+The above rules allow transfer of control to a @nt{statement} of an
+enclosing @nt{sequence_of_statements} but not the reverse. Similarly,
+they prohibit transfers of control such as between alternatives of a
address@hidden, @nt{if_statement}, or @nt{select_statement};
+between @nt{exception_handler}s; or from an @nt{exception_handler} of
+a @nt{handled_sequence_of_statements}
+back to its @nt{sequence_of_statements}.
address@hidden
+
address@hidden
address@hidden@address@hidden of a loop containing a goto statement:}
address@hidden
+<<Sort>>
address@hidden I @key[in] 1 .. N-1 @key[loop]
+   @key[if] A(I) > A(I+1) @key[then]
+      Exchange(A(I), A(I+1));
+      @key[goto] Sort;
+   @key[end] @key[if];
address@hidden @key[loop];
address@hidden
address@hidden
diff --git a/packages/ada-ref-man/source_2012/06.mss 
b/packages/ada-ref-man/source_2012/06.mss
new file mode 100755
index 0000000..088bae2
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/06.mss
@@ -0,0 +1,5368 @@
address@hidden(06, Root="ada.mss")
+
address@hidden: 2016/02/09 04:55:40 $}
address@hidden
+
address@hidden: e:\\cvsroot/ARM/Source/06.mss,v $}
address@hidden: 1.137 $}
+
address@hidden
address@hidden
address@hidden
address@hidden
+A subprogram is a program unit or intrinsic operation whose execution
+is invoked by a subprogram call.
+There are two forms of subprogram: procedures and functions.
+A procedure call is a @nt{statement}; a function call is an expression and
+returns a value.
+The definition of a subprogram can be given in two parts:
+a subprogram declaration defining its interface,
+and a @nt{subprogram_body} defining its execution.
address@hidden and enumeration literals are functions.]
address@hidden
+  A function call is an expression, but more specifically it is a @nt<name>.
address@hidden
address@hidden,Kind=[AddedNormal],Term=<Subprogram>,
+Text=<@ChgAdded{Version=[2],Text=[A subprogram is a section of a program that
+can be executed in various contexts. It is invoked by a subprogram call that
+may qualify the effect of the subprogram through the passing of parameters.
+There are two forms of subprograms: functions, which return values, and
+procedures, which do not.]}>}
address@hidden,Kind=[AddedNormal],Term=<Function>,
+Text=<@ChgAdded{Version=[2],Text=[A function is a form of subprogram that
+returns a result and can be called as part of an expression.]}>}
address@hidden,Kind=[AddedNormal],Term=<Procedure>,
+Text=<@ChgAdded{Version=[2],Text=[A procedure is a form of subprogram that
+does not return a result and can only be called by a @nt{statement}.]}>}
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden entity}
+A @i(callable entity) is a subprogram or entry (see
address@hidden,New=[Section 9],address@hidden and Accept Statements}]}).
address@hidden
+A callable entity is invoked by a @i{call};
+that is, a subprogram call or entry call.
address@hidden construct}
+A @i(callable construct) is a construct
+that defines the action of a call upon a callable entity:
+a @nt{subprogram_body},
address@hidden, or @nt{accept_statement}.
address@hidden
+Note that @lquotes@;callable address@hidden@;
+includes predefined operators, enumeration literals,
+and abstract subprograms.
address@hidden@;address@hidden@; includes calls of these things.
+They do not have callable constructs,
+since they don't have completions.
address@hidden
address@hidden
+
address@hidden Declarations}
+
address@hidden
address@hidden @nt{subprogram_declaration} declares a procedure or
+function.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00218-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<subprogram_declaration>,rhs="@Chg{Version=[2],New=<
+    address@hidden
+    >,Old=<>address@hidden@Chg{Version=[3],New=<
+        address@hidden>,Old=[]};"}
+
address@hidden,Kind=[Deleted],ARef=[AI95-00348-01]}
address@hidden,lhs=<@Chg{Version=[2],New=<>,Old=<abstract_subprogram_declaration>}>,
+rhs="@Chg{Version=[2],New=<>,Old=<@Syn2{subprogram_specification} @key{is} 
@key{abstract};>}"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00348-01]}
address@hidden<subprogram_specification>,rhs="@Chg{Version=[2],New=[
+    @Syn2{procedure_specification}
+  | @Syn2{function_specification}],Old=[
+    @key{procedure} @Syn2{defining_program_unit_name} @Syn2{parameter_profile}
+  | @key{function} @Syn2{defining_designator} 
@Syn2{parameter_and_result_profile}]}"}
+
address@hidden,Kind=[Added],ARef=[AI95-00348-01]}
address@hidden,lhs=<@Chg{Version=[2],New=<procedure_specification>,Old=<>}>,
+rhs="@Chg{Version=[2],New=<@key{procedure} @Syn2{defining_program_unit_name} 
@Syn2{parameter_profile}>,Old=<>}"}
+
address@hidden,Kind=[Added],ARef=[AI95-00348-01]}
address@hidden,lhs=<@Chg{Version=[2],New=<function_specification>,Old=<>}>,
+rhs="@Chg{Version=[2],New=<@key{function} @Syn2{defining_designator} 
@Syn2{parameter_and_result_profile}>,Old=<>}"}
+
address@hidden<designator>,rhs="address@hidden . address@hidden | 
@Syn2{operator_symbol}"}
+
address@hidden<defining_designator>,
+   rhs="@Syn2{defining_program_unit_name} | @Syn2{defining_operator_symbol}"}
+
address@hidden<defining_program_unit_name>,rhs="address@hidden . 
address@hidden"}
+
address@hidden
address@hidden optional @nt{parent_unit_name} is only allowed for
+library units (see @RefSecNum{Compilation Units - Library Units}).]
address@hidden
+
address@hidden<operator_symbol>,rhs="@Syn2{string_literal}"}
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00395-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The sequence of characters in an @nt{operator_symbol} shall @Chg{Version=[2],
+New=[form a reserved
+word, a delimiter, or compound delimiter that corresponds],Old=[correspond]} to
+an operator belonging to one of the six @Chg{Version=[2],New=[categories],
+Old=[classes]} of operators
+defined in @Chg{Version=[3],New=[subclause],Old=[clause]} @RefSecNum{Operators 
and Expression address@hidden,
+New=[],Old=[(spaces are not allowed and the case of letters
+is not significant)]}.
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00395-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0090-1]}
+  @ChgAdded{Version=[2],Text=[The @ldquote@;sequence of address@hidden
+  of the string literal of the operator is a technical term (see
+  @RefSecNum{String Literals}), and does not include the surrounding quote
+  characters. As defined in @RefSecNum{Lexical Elements, Separators, and 
Delimiters},
+  lexical elements are @lquotes@;address@hidden from a sequence of characters.
+  Spaces are not allowed, and upper and lower case is
+  not address@hidden,New=[],Old=[ See
+  @RefSecNum{Lexical Elements, Separators, and Delimiters} and
+  @RefSecNum{Reserved Words} for rules related to the use of @ntf{other_format}
+  characters in delimiters and reserved words.]}]}
address@hidden
+
address@hidden
+
address@hidden<defining_operator_symbol>,rhs="@Syn2{operator_symbol}"}
+
address@hidden<parameter_profile>,rhs="address@hidden"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01],ARef=[AI95-00318-02]}
address@hidden<parameter_and_result_profile>,rhs="@Chg{Version=[2],New=[
+    ],address@hidden @address@hidden,New=< address@hidden>,Old=<>} 
@address@hidden,New=<
+  | address@hidden @key{return} @Syn2{access_definition}>,Old=<>}"}
+
address@hidden<formal_part>,rhs="
+   (@Syn2{parameter_specification} {; @Syn2{parameter_specification}})"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0142-4]}
address@hidden<parameter_specification>,rhs="
+    @Syn2{defining_identifier_list} : @Chg{Version=[3],New=<address@hidden 
>,Old=<>address@hidden @Chg{Version=[2],New=<address@hidden>,Old=<>} 
@Syn2{subtype_mark} [:= @Syn2{default_expression}]
+  | @Syn2{defining_identifier_list} : @Syn2{access_definition} [:= 
@Syn2{default_expression}]"}
+
address@hidden<mode>,rhs="address@hidden | @key{in} @key{out} | @key{out}"}
address@hidden
+
address@hidden
address@hidden parameter], Sec=(of a subprogram)}
+A @i(formal parameter) is an object
address@hidden visible within a @nt{subprogram_body}]
+that represents the actual parameter passed to the subprogram in a
+call;
+it is declared by a @nt{parameter_specification}.
address@hidden type],
+  Sec=(parameter @nt{default_expression})}
+For a formal parameter,
+the expected type for its @nt<default_expression>,
+if any, is that of the formal parameter.
address@hidden,See=[formal parameter]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0143-1]}
address@hidden mode}
+The @i(parameter mode) of a formal parameter conveys the direction of
+information transfer with the actual parameter:
address@hidden(in), @key(in out), or @key(out).
+Mode @key(in) is the default,
+and is the mode of a parameter defined by an
address@hidden@Chg{Version=[3],New=[],Old=[ The formal parameters
+of a function, if any, shall have the mode @key(in).]}
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI05-0143-1]}
address@hidden,Text=[Access parameters are permitted.
+This restriction to @b(in) parameters is primarily a methodological
+restriction, though it also simplifies implementation for some compiler
+technologies.]}
address@hidden
+
+A @nt{default_expression} is only allowed in a @nt{parameter_specification}
+for a formal parameter of mode @key(in).
+
address@hidden,Kind=[Revised],ARef=[AI95-00348-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0177-1],ARef=[AI05-0229-1]}
address@hidden a completion], Sec=(@nt{subprogram_declaration})}
address@hidden a completion], Sec=(@nt{generic_subprogram_declaration})}
+A @nt{subprogram_declaration}
+or a @nt{generic_subprogram_declaration}
+requires a address@hidden,New=[],Old=[:]}
address@hidden@Chg{Version=[3],New=[unless the Import aspect (see
address@hidden Aspects}) is True for the declaration; the
+completion shall be ],Old=[]}a address@hidden,New=[ or],Old=[,]}
+a @nt<renaming_declaration>
+(see @RefSecNum(Renaming Declarations))@Chg{Version=[3],New=[],Old=[, or
+a @Chg{Version=[2],address@hidden,
address@hidden(pragma)]} Import (see @RefSecNum{Interfacing Aspects})]}].
address@hidden completion is not allowed
+for an @nt<abstract_subprogram_declaration>@Chg{Version=[2],New=[ (see
address@hidden Types and Subprograms})@Chg{Version=[3],New=[,],Old=[ or]} a
address@hidden (see @RefSecNum{Null Procedures})@Chg{Version=[3],New=[,
+or an @nt{expression_function_declaration} (see @RefSecNum{Expression 
Functions})],Old=[]}],Old=[]}.]
address@hidden(Ramification)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00348-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0177-1]}
+  Abstract subprograms @Chg{Version=[2],address@hidden,New=[,],Old=[and]}
+  null address@hidden,New=[, and expression functions],Old=[]} ],Old=[]}are
+  not declared by @nt{subprogram_declaration}s, and so do not require
+  address@hidden,New=[ (although the latter two can @i<be> 
completions)],Old=[]}.
+  Protected subprograms are declared by @nt{subprogram_declaration}s,
+  and so require completion.
+  Note that an abstract subprogram is a subprogram,
+  @Chg{Version=[3],New=[a null procedure is a subprogram, an expression 
function
+  is a subprogram, ],Old=[]}and a protected subprogram is a subprogram,
+  but a generic subprogram is not a address@hidden's the idiot that
+  came up with that??}
address@hidden(Ramification)
address@hidden(TheProof)
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[When the Import aspect is True for any entity,
+  no completion is allowed (see @RefSecNum{Interfacing Aspects}).]}
address@hidden
+
+
+A @nt{name} that denotes a formal parameter
+is not allowed within the @nt{formal_part} in which it is declared,
+nor within the @nt{formal_part} of a corresponding body or
address@hidden
address@hidden
+By contrast,
address@hidden<generic_formal_parameter_declaration>s are visible to subsequent
+declarations in the same @nt<generic_formal_part>.
address@hidden
address@hidden
+
address@hidden
address@hidden
+The @i(profile) of (a view of) a callable entity
+is either a @nt{parameter_profile} or
address@hidden@Redundant[;
+it embodies information about
+the interface to that entity @em for example, the profile includes
+information about parameters passed to the callable entity.
+All callable entities have a profile @em enumeration literals,
+other subprograms, and entries.
+An access-to-subprogram type has a designated profile.]
+Associated with a profile is a calling convention.
+A @nt<subprogram_declaration> declares a procedure or a function, as
+indicated by the initial reserved word, with name and profile as given by
+its specification.
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01],ARef=[AI95-00318-02]}
address@hidden subtype], Sec=(of a formal parameter)}
+The nominal subtype of a formal parameter is
+the subtype @Chg{Version=[2],New=[determined],Old=[denoted]} by
address@hidden,New=[the optional @nt{null_exclusion} and ], Old=[]}the
address@hidden, or defined by the @nt{access_definition}, in the
address@hidden@Chg{Version=[2],New=[ The nominal
+subtype of a function result is the subtype
+determined by the optional @nt{null_exclusion} and the @nt{subtype_mark}, or
+defined by the @nt{access_definition}, in the
address@hidden
address@hidden subtype], Sec=(of a function result)}], Old=[]}
+
address@hidden,Kind=[Added],ARef=[AI05-0142-4]}
address@hidden,address@hidden aliased address@hidden,Sec=(explicitly aliased)}An
address@hidden(explicitly aliased parameter) is a formal parameter whose
address@hidden includes the reserved word @key[aliased].]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01],ARef=[AI95-00254-01],ARef=[AI95-00318-02]}
address@hidden parameter}
+An @i(access parameter) is a formal @key[in] parameter
+specified by an @nt{access_definition}.
address@hidden result type}
address@hidden,New=[An @i(access result type) is a function result type 
specified by
+an @nt{access_definition}.],Old=[]}
+An access parameter @Chg{Version=[2],New=[or result type ],Old=[]}is of an
+anonymous
address@hidden,New=[access],Old=[general access-to-variable]} type (see
address@hidden Types}). @Redundant[Access parameters
address@hidden,New=[of an access-to-object type],Old=[]} allow dispatching
+calls to be controlled by access address@hidden,New=[ Access
+parameters of an access-to-subprogram type permit calls to subprograms passed
+as parameters irrespective of their accessibility level.],Old=[]}]
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00318-02]}
address@hidden,Text=[Access result types have normal accessibility and
+thus don't have any special properties worth noting here.]}
address@hidden
+
address@hidden@address@hidden, Sec=(of a profile)}
+The @i(subtypes of a profile) are:
address@hidden
+  For any non-access parameters, the nominal subtype of the parameter.
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00254-01]}
+  For any access address@hidden,New=[ of an access-to-object type],Old=[]},
+  the designated subtype of the parameter type.
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00254-01]}
+  @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0164-1]}
+  @ChgAdded{Version=[2],Text=[For any access parameters of an 
access-to-subprogram
+  type, the subtypes of the @Chg{Version=[3],New=[designated ],Old=[]}profile
+  of the parameter type.]}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00231-01],ARef=[AI95-00318-02]}
+  @Chg{Version=[2],New=[For any non-access result, the nominal subtype of the
+  function result.],Old=[For any result, the result subtype.]}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00318-02]}
+  @Chg{Version=[2],New=[For any access result type of an access-to-object type,
+  the designated subtype of the result type.],Old=[]}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00318-02]}
+  @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0164-1]}
+  @Chg{Version=[2],New=[For any access result type of an access-to-subprogram
+  type, the subtypes of the @Chg{Version=[3],New=[designated ],Old=[]}profile
+  of the result type.],Old=[]}
+
address@hidden
+
address@hidden@Defn2{Term=[types], Sec=(of a profile)}
+The @i{types of a profile} are the types of those subtypes.]
+
address@hidden,Kind=[Revised],ARef=[AI95-00348-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0177-1]}
address@hidden subprogram declared by an
address@hidden<abstract_subprogram_declaration>
+is abstract; a subprogram declared by a @nt<subprogram_declaration>
+is not. See @RefSec{Abstract Types and address@hidden,New=[
+Similarly, a procedure @Chg{Version=[3],New=[declared],Old=[defined]} by a
address@hidden is a null procedure; a procedure declared by
+a @nt{subprogram_declaration} is not. See @RefSec{Null address@hidden,New=[
+Finally, a function declared by an @nt{expression_function_declaration} is
+an expression function; a function declared by
+a @nt{subprogram_declaration} is not. See @RefSec{Expression 
Functions}.],Old=[]}],Old=[]}]
+
address@hidden,Kind=[Added],ARef=[AI95-00218-03]}
address@hidden,address@hidden @nt{overriding_indicator} is used to
+indicate whether overriding is intended. See @RefSec{Overriding Indicators}.]]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00348-01]}
address@hidden, Sec=(subprogram_declaration)address@hidden,New=[],Old=[
address@hidden, Sec=(abstract_subprogram_declaration)}]}
+The elaboration of a @address@hidden,New=[],Old=[
+or an @nt{abstract_subprogram_declaration}]} has no effect.
address@hidden
+
address@hidden
+A @nt{parameter_specification} with several identifiers is equivalent
+to a sequence of single @nt{parameter_specification}s, as explained
+in @RefSecNum{Objects and Named Numbers}.
+
+Abstract subprograms do not have bodies, and cannot be used
+in a nondispatching call (see @RefSec{Abstract Types and Subprograms}).
+
+The evaluation of @nt<default_expression>s is caused by certain
+calls, as described in @RefSecNum{Parameter Associations}.
+They are not evaluated during the elaboration of
+the subprogram declaration.
+
+Subprograms can be called recursively and can be called
+concurrently from multiple tasks.
address@hidden
+
address@hidden
address@hidden@address@hidden of subprogram declarations:}
address@hidden
address@hidden Traverse_Tree;
address@hidden Increment(X : @key[in] @key[out] Integer);
address@hidden Right_Indent(Margin : @key[out] Line_Size);          
address@hidden  see @RefSecNum{Integer Types}}
address@hidden Switch(From, To : @key[in] @key[out] Link);                
address@hidden  see @RefSecNum{Incomplete Type Declarations}}
+
address@hidden Random @key[return] Probability;                      
address@hidden  see @RefSecNum{Floating Point Types}}
+
address@hidden,Kind=[Revised],ARef=[AI12-0056-1]}
address@hidden Min_Cell(X : Link) @key[return] Cell;                 
address@hidden  see @RefSecNum{Incomplete Type Declarations}}
address@hidden Next_Frame(K : Positive) @key[return] Frame;          
address@hidden  see @RefSecNum{Access Types}}
address@hidden Dot_Product(Left, Right : Vector) @key[return] Real;  
address@hidden  see @RefSecNum{Array address@hidden,New=[
address@hidden Find(B : @key[aliased in out] Barrel; Key : String) @key[return] 
Real;
+                                                         address@hidden  see 
@RefSecNum{User-Defined References}}],Old=[]}
+
address@hidden "*"(Left, Right : Matrix) @key[return] Matrix;        
address@hidden  see @RefSecNum{Array Types}}
address@hidden
+
address@hidden
address@hidden@address@hidden of @key[in] parameters with default expressions:}
address@hidden
address@hidden
address@hidden Print_Header(Pages  : @key[in] Natural;
+            Header : @key[in] Line    :=  (1 .. Line'Last => ' ');  
address@hidden  see @RefSecNum{Array Types}}
+            Center : @key[in] Boolean := True);
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax for @nt{abstract_subprogram_declaration} is added.
+The syntax for @nt{parameter_specification} is revised to allow
+for access parameters (see @RefSecNum{Access Types})
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Program units that are library units may have
+a @nt{parent_unit_name} to indicate the parent of a child
+(see @Chg{Version=[3],address@hidden Units - Library Units}],Old=[Section 
10]}).
address@hidden
+
address@hidden
+We have incorporated the rules from
+RM83-6.5, @lquotes@;Function address@hidden@; here and in
address@hidden Bodies}
+
+We have incorporated the definitions of RM83-6.6, @lquotes@;Parameter and 
Result
+Type Profile - Overloading of address@hidden@; here.
+
+The syntax rule for @nt{defining_operator_symbol} is new.
+It is used for the defining occurrence of an @nt{operator_symbol},
+analogously to @nt{defining_identifier}.
+Usage occurrences use the @nt{direct_name} or @nt{selector_name}
+syntactic categories.
+The syntax rules for @nt{defining_designator} and
address@hidden are new.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00218-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Subprograms now allow @nt{overriding_indicator}s for better error checking
+  of overriding.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],Text=[An optional @nt{null_exclusion} can be used in a
+  formal parameter declaration. Similarly, an optional @nt{null_exclusion} can
+  be used in a function result.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],Text=[The return type of a function can be an
+  anonymous access type.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00254-01]}
+  @ChgAdded{Version=[2],Text=[A description of the purpose of anonymous
+  access-to-subprogram parameters and the definition of the profile of
+  subprograms containing them was added.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00348-01]}
+  @ChgAdded{Version=[2],Text=[Split the production for
+  @nt{subprogram_specification} in order to make the declaration
+  of null procedures (see @RefSecNum{Null Procedures}) easier.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00348-01]}
+  @ChgAdded{Version=[2],Text=[Moved the @SyntaxTitle and
+  @RuntimeTitle for @nt{abstract_subprogram_declaration} to
+  @RefSecNum{Abstract Types and Subprograms}, so that the syntax
+  and semantics are together. This also keeps abstract and null
+  subprograms similar.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00395-01]}
+  @ChgAdded{Version=[2],Text=[Revised to allow @ntf{other_format} characters
+  in @nt{operator_symbol}s in the same way as the underlying constructs.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0142-4]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Parameters can
+  now be explicitly aliased, allowing parts of function results to
+  designate parameters and forcing by-reference parameter passing.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0143-1]}
+  @ChgAdded{Version=[3],Text=[The parameters
+  of a function can now have any mode.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],Text=[An optional @nt{aspect_specification} can be
+  used in a @nt{subprogram_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0177-1]}
+  @ChgAdded{Version=[3],Text=[Added expression functions (see
+  @RefSecNum{Expression Functions}) to the wording.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,Name=[Preconditions and Postconditions]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0247-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0045-1]}
address@hidden,Type=[Leading],Text=[For a
address@hidden,New=[noninstance ],address@hidden,New=[,
+a generic subprogram,],Old=[]} or @Chg{Version=[4],New=[an ],Old=[]}entry,
+the following language-defined aspects may be specified with an
address@hidden (see @RefSecNum{Aspect Specifications}):]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI12-0045-1]}
address@hidden,address@hidden@;Noninstance address@hidden excludes
+a subprogram that is an instance of a generic subprogram. In that case, the
+aspects should be specified on the generic subprogram. If preconditions or
+postconditions need to be added to an instance of a generic subprogram, it
+can be accomplished by creating a separate subprogram specification and then
+completing that specification with a renames-as-body of the instance.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden aspect
+  specifies a specific precondition for a callable entity; it shall
+  be specified by an @nt{expression}, called a
+  @i<specific precondition
+  expression>address@hidden precondition address@hidden 
expression],Sec=[specific]}
+  If not specified for an entity, the specific precondition
+  expression for the entity is the enumeration literal
+  address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[In this and the following rules, we are talking
+  about the enumeration literal True declared in package Standard (see
+  @RefSecNum{The Package Standard}), and not some
+  other value or identifier True. That matters as some rules depend on full
+  conformance of these expressions, which depends on the specific declarations
+  involved.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],Aspect=[Pre],
+  address@hidden,Text=[Precondition; a condition that must hold
+    true before a call.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0254-1],ARef=[AI05-0262-1]}
address@hidden,Text=[Pre'address@hidden aspect
+  specifies a class-wide precondition for an operation of a tagged type and its
+  descendants; it shall be specified by an @nt{expression}, called a
+  @i<class-wide precondition expression>address@hidden precondition 
address@hidden expression],Sec=[class-wide]}
+  If not specified for an entity, then if no other
+  class-wide precondition applies to the entity, the class-wide precondition
+  expression for the entity is the enumeration literal
+  address@hidden'Class}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0254-1]}
+  @ChgAdded{Version=[3],Text=[If other class-wide preconditions apply to the
+  entity and no class-wide precondition is specified, no class-wide 
precondition
+  is defined for the entity; of course, the class-wide preconditions (of
+  ancestors) that apply are still going to be checked. We need subprograms that
+  don't have ancestors and don't specify a class-wide precondition to have a
+  class-wide precondition of True, so that adding such a precondition to a
+  descendant has no effect (necessary as a dispatching call through the root
+  routine would not check any precondition).]}
address@hidden
+
address@hidden,Kind=[AddedNormal],Aspect=[Pre'Class],
+  address@hidden,Text=[Precondition inherited on type
+    derivation.]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden aspect
+  specifies a specific postcondition for a callable entity; it shall be
+  specified by an @nt{expression}, called a @i<specific postcondition
+  expression>address@hidden postcondition address@hidden 
expression],Sec=[specific]}
+  If not specified for an entity, the specific postcondition
+  expression for the entity is the enumeration literal address@hidden
+
address@hidden,Kind=[AddedNormal],Aspect=[Post],
+  address@hidden,Text=[Postcondition; a condition that must hold
+    true after a call.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0262-1]}
address@hidden,Text=[Post'address@hidden aspect
+  specifies a class-wide postcondition for an operation of a tagged type and 
its
+  descendants; it shall be specified by an @nt{expression}, called a
+  @i<class-wide postcondition expression>address@hidden postcondition 
address@hidden expression],Sec=[class-wide]}
+  If not specified for an entity, the class-wide postcondition
+  expression for the entity is the enumeration literal address@hidden'Class}]}
address@hidden
+
address@hidden,Kind=[AddedNormal],Aspect=[Post'Class],
+  address@hidden,Text=[Postcondition inherited on type
+    derivation.]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2]}
address@hidden,Text=[The expected type for a precondition or
+postcondition expression is any boolean address@hidden type],
+Sec=(precondition expression)address@hidden type],
+Sec=(postcondition expression)}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0262-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0113-1],ARef=[AI12-0159-1]}
address@hidden,Text=[Within the expression for a Pre'Class or Post'Class aspect 
for a primitive
+subprogram @Chg{Version=[4],address@hidden<S> ],Old=[]}of a tagged type @i<T>, 
a
address@hidden,address@hidden<name>],Old=[name]} that denotes a formal parameter
address@hidden,New=[(or @i<S>'Result) ],Old=[]}of type
address@hidden<T> is interpreted as @Chg{Version=[4],New=[though it had a 
(notional) type
address@hidden<NT> that is a formal derived type whose ancestor type is @i<T>, 
with directly
+visible primitive operations],Old=[having type @i<T>'Class]}. Similarly, a
address@hidden,address@hidden<name>],Old=[name]} that denotes a
+formal access parameter @Chg{Version=[4],New=[(or @i<S>'Result) ],Old=[]}of
+type address@hidden<T> is interpreted as having type
address@hidden,address@hidden<NT>],address@hidden<T>'Class]}.
address@hidden@Chg{Version=[4],New=[The result of this interpretation
+is that the only operations that can be applied to such @nt{name}s are those
+defined for such a formal derived type.],Old=[This ensures that the
+expression is well-defined for a primitive subprogram of a type descended
+from @i<T>.]}]]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0159-1]}
+  @ChgAdded{Version=[4],Text=[This ensures that the
+  expression is well-defined for any primitive
+  subprogram of a type descended from @i<T>.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0264-1]}
address@hidden,Text=[For an attribute_reference with attribute_designator
+Old, if the attribute reference has an expected type or shall resolve to a 
given
+type, the same applies to the @nt{prefix}; otherwise, the @nt{prefix} shall be
+resolved independently of context.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0230-1]}
address@hidden,Text=[The Pre or Post aspect shall not be specified for an
+abstract subprogram or a null procedure. @Redundant[Only the Pre'Class and
+Post'Class aspects may be specified for such a subprogram.]]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],Text=[Pre'Class and Post'Class can only be specified
+  on primitive routines of tagged types, by a blanket rule found in
+  @RefSecNum{Aspect Specifications}.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0247-1],ARef=[AI05-0254-1]}
address@hidden,Type=[Leading],Text=[If a type @i<T> has an implicitly
+declared subprogram @i<P> inherited from a parent type @i<T1> and
+a homograph (see @RefSecNum{Visibility}) of @i<P> from a progenitor type
address@hidden<T2>, and]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[the corresponding primitive subprogram @i<P1> of
+  type @i<T1> is neither null nor abstract; and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[the class-wide precondition expression True does
+  not apply to @i<P1> (implicitly or explicitly); and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[there is a class-wide precondition expression 
that
+  applies to the corresponding primitive subprogram @i<P2> of @i<T2> that does
+  not fully conform to any class-wide precondition expression that applies to
+  @i<P1>,]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0247-1],ARef=[AI05-0254-1]}
address@hidden,Type=[Leading],Text=[then:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If the type @i<T> is abstract, the implicitly
+  declared subprogram @i<P> is @i<abstract>.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Otherwise, the subprogram @i<P>
+  @i{requires overriding} and shall be overridden with a
+  nonabstract address@hidden overriding}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We use the term "requires overriding" here so 
that
+    this rule is taken into account when calculating visibility in
+    @RefSecNum{Visibility}; otherwise we would have a mess when this routine is
+    overridden.]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Such an inherited subprogram would necessarily
+    violate the Liskov Substitutability Principle (LSP) if called via a
+    dispatching call from an ancestor other than the one that provides the
+    called body. In such a case, the class-wide precondition of the actual body
+    is stronger than the class-wide precondition of the ancestor. If we did not
+    enforce that precondition for the body, the body could be called when the
+    precondition it knows about is False @em such "counterfeiting" of
+    preconditions has to be avoided. But enforcing the precondition violates
+    LSP. We do not want the language to be implicitly creating bodies that
+    violate LSP; the programmer can still write an explicit body that calls the
+    appropriate parent subprogram. In that case, the violation of LSP is
+    explicitly in the code and obvious to code reviewers (both human and
+    automated).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We have to say that the subprogram is abstract 
for
+    an abstract type in this case, so that the next concrete type has to
+    override it for the reasons above. Otherwise, inserting an extra level of
+    abstract types would eliminate the requirement to override (as there is 
only
+    one declared operation for the concrete type), and that would be bad for 
the
+    reasons given above.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This requires the set of class-wide preconditions
+    that apply to the interface routine to be strictly stronger than those that
+    apply to the concrete routine. Since full conformance
+    requires each name to denote the same declaration, it is unlikely that
+    independently declared preconditions would conform. This rule does allow
+    "diamond inheritance" of preconditions, and of course no preconditions at
+    all match.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We considered adopting a rule that would allow
+    examples where the expressions would conform after all inheritance has been
+    applied, but this is complex and is not likely to be common in practice.
+    Since the penalty here is just that an explicit overriding is required, the
+    complexity is too much.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0247-1]}
address@hidden,Text=[If a renaming of a subprogram or entry @i<S1>
+overrides an inherited subprogram @i<S2>, then the overriding is illegal unless
+each class-wide precondition expression that applies to @i<S1> fully conforms 
to
+some class-wide precondition expression that applies to @i<S2> and each
+class-wide precondition expression that applies to @i<S2> fully conforms to 
some
+class-wide precondition expression that applies to @i<S1>.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Such an overriding subprogram would violate LSP,
+    as the precondition of @i<S1> would usually be different (and thus 
stronger)
+    than the one known to a dispatching call through an ancestor routine of 
@i<S2>.
+    This is always OK if the preconditions match, so we always allow that.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This only applies to primitives of tagged types;
+    other routines cannot have class-wide preconditions.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0131-1]}
address@hidden,Text=[Pre'Class shall not be specified for an overriding
+primitive subprogram of a tagged type @i<T> unless the Pre'Class aspect is
+specified for the corresponding primitive subprogram of some ancestor of 
@i<T>.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[Any such Pre'Class will have no effect, as it
+  will be @key[or]ed with True. As such, it is highly misleading for readers,
+  especially for those who are determining the assumptions that can
+  be made in the body of the primitive subprogram. Note that in this
+  case there is nothing explicit that might indicate that the
+  class-wide precondition is ineffective. This rule does not prevent
+  explicitly writing an ineffective class-wide precondition (for
+  instance, if the parent subprogram has explicitly specified a
+  precondition of True).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0131-1]}
address@hidden,address@hidden contract issue}
+In addition to the places where
address@hidden normally apply (see @RefSecNum{Generic Instantiation}),
+these rules also apply in the private part of an instance of a generic unit.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2]}
address@hidden,Kind=[Revised],ARef=[AI12-0113-1],ARef=[AI12-0131-1]}
address@hidden,Type=[Leading],address@hidden Leading}
address@hidden,Text=[If a Pre'Class or Post'Class aspect is specified for
+a primitive subprogram @Chg{Version=[4],address@hidden<S> ],Old=[]}of a tagged 
type
address@hidden<T>, @Chg{Version=[4],New=[or such an aspect defaults to True, 
],Old=[]}then
address@hidden,New=[a corresponding],Old=[the associated]} expression
+also applies to the corresponding primitive subprogram
address@hidden,address@hidden<S> ],Old=[]}of each descendant of
address@hidden<T>address@hidden,New=[ The @i<corresponding expression> is 
constructed
+from the associated expression as follows:@Defn2{Term=[corresponding 
expresssion],Sec=[class-wide precondition]}
address@hidden expresssion],Sec=[class-wide postcondition]}],Old=[]}]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[A Pre'Class defaults to True only if no 
class-wide
+  preconditions are inherited for the subprogram. The same is true for
+  Post'Class.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[We have to inherit precondition expressions that
+  default to True, so that later overridings don't strengthen the
+  precondition (a violation of LSP). We do the same for postconditions
+  for consistency.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0113-1]}
+  @ChgAdded{Version=[4],Text=[References to formal parameters of @i<S> (or to
+  @i<S> itself) are replaced with references to the corresponding formal
+  parameters of the corresponding inherited or overriding subprogram
+  @i<S> (or to the corresponding subprogram @i<S> itself).]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[We have to define the corresponding expression
+  this way as overriding routines are only required to be subtype conformant; 
in
+  particular, the parameter names can be different. So we have to talk about
+  corresponding parameters without mentioning any names.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0113-1]}
address@hidden,Text=[The primitive subprogram @i<S> is illegal if it is
+not abstract and the corresponding expression for a Pre'Class or Post'Class
+aspect would be illegal.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This can happen, for instance, if one of the
+  subprograms called in the corresponding expression is abstract. We made the
+  rule general so that we don't have to worry about exactly which cases
+  can cause this to happen, both now and in the future.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[We allow illegal corresponding expressions
+  on abstract subprograms as they could never be evaluated, and we need to
+  allow such expressions to contain calls to abstract subprograms.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0262-1],ARef=[AI05-0290-1]}
address@hidden,Text=[If performing checks is required by the Pre,
+Pre'Class, Post, or Post'Class assertion policies (see
address@hidden Assert and Assertion_Policy}) in effect at the point of a
+corresponding aspect specification applicable to a given subprogram or entry,
+then the respective precondition or postcondition expressions are considered
address@hidden<enabled>address@hidden,Sec=[precondition 
address@hidden,Sec=[postcondition expression]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0290-1]}
+  @ChgAdded{Version=[3],Text=[If a class-wide precondition or postcondition
+  expression is enabled, it remains enabled when inherited by an overriding
+  subprogram, even if the policy
+  in effect is Ignore for the inheriting subprogram.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0273-1]}
address@hidden,Type=[Leading],Text=[An @nt{expression} is
address@hidden unevaluated} if it occurs within:@Defn{potentially unevaluated 
expression}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[any part of an @nt{if_expression} other than the
+  first @nt{condition};]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[a @address@hidden of a
+  @nt{case_expression};]}
+
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0032-1]}
+  @ChgAdded{Version=[4],Text=[a @nt{predicate} of a
+  @nt{quantified_expression};]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[the right operand of a short-circuit control
+  form; or]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[a @nt{membership_choice} other than the first
+  of a membership operation.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2]}
address@hidden,Type=[Leading],Text=[For @PrefixType{a @nt{prefix} X that
+denotes an object of a nonlimited type}, the following attribute is defined:]}
address@hidden(description)
address@hidden Version=[3], Kind=[AddedNormal].}
address@hidden,Kind=[Revised],ChginAnnex=[T],
+  Leading=<F>, Prefix=<X>, AttrName=<Old>, ARef=[AI05-0145-2], 
ARef=[AI05-0262-1], ARef=[AI05-0273-1], ARef=[AI12-0032-1],
+  InitialVersion=[3],address@hidden,address@hidden,New=[Each],Old=[For each]}
+   X'Old in a postcondition expression that
+   is address@hidden,New=[ denotes],Old=[,]} a constant
+   @Chg{Version=[4],New=[that ],Old=[]}is implicitly
+   declared at the beginning of the subprogram
+   @Chg{Version=[4],New=[body,],Old=[or]}
+   address@hidden,New=[ body, or accept statement],address@hidden,New=[],Old=[
+   The constant is of the type of X and is initialized to the result
+   of evaluating X (as an expression) at the point of the constant declaration.
+   The value of X'Old in the postcondition expression is the value of this
+   constant; the type of X'Old is the type of X. These implicit constant
+   declarations occur in an
+   arbitrary address@hidden order],Sec=[allowed]}]}],address@hidden of Annex 
text here.}
+
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0032-1],ARef=[AI12-0159-1]}
+  @ChgAdded{Version=[4],Type=[Leading],NoPrefix=[T],Text=[The implicitly 
declared
+  entity denoted by each occurrence of X'Old is declared as follows:]}
+
+  @begin{Itemize}
+    @ChgRef{Version=[4],Kind=[Added]}
+    @ChgAdded{Version=[4],Type=[Leading],Text=[If X is of an anonymous access
+    type defined by an @nt{access_definition} @i<A> then]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden<X'Old> : @key[constant] @i<A> := X;]}
address@hidden
+
+    @ChgRef{Version=[4],Kind=[Added]}
+    @ChgAdded{Version=[4],Type=[Leading],Text=[If X is of a specific tagged 
type @i<T> then]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden<anonymous> : @key[constant] @i<T>'Class := 
@i<T>'Class(X);
address@hidden<X'Old> : @i<T> @key[renames] @i<T>(@examcom<anonymous>);]}
address@hidden
+    @ChgRef{Version=[4],Kind=[Added]}
+    @ChgAdded{Version=[4],NoPrefix=[T],Text=[where the name X'Old denotes
+      the object renaming.]}
+    @begin{Ramification}
+        @ChgRef{Version=[4],Kind=[AddedNormal]}
+        @ChgAdded{Version=[4],Text=[This means that the underlying tag 
associated
+          with X'Old is that of X and not that of the nominal type of X.]}
+    @end{Ramification}
+
+    @ChgRef{Version=[4],Kind=[Added]}
+    @ChgAdded{Version=[4],Type=[Leading],Text=[Otherwise]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden<X'Old> : @key[constant] @i<S> := X;]}
address@hidden
+    @ChgRef{Version=[4],Kind=[Added]}
+    @ChgAdded{Version=[4],NoPrefix=[T],Text=[where @i<S> is the nominal subtype
+      of X. This includes the case where the type of @i<S> is an anonymous 
array
+      type or a universal type.]}
+  @end{Itemize}
+
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0032-1]}
+  @ChgAdded{Version=[4],NoPrefix=[T],Text=[The nominal subtype of X'Old is as
+  implied by the above definitions. The expected type of the prefix of an Old
+  attribute is that of the attribute. Similarly, if an Old attribute shall
+  resolve to be of some type, then the prefix of the attribute shall resolve to
+  be of that type.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0145-2], 
ARef=[AI05-0262-1], ARef=[AI05-0273-1]}
+  @ChgAdded{Version=[3],NoPrefix=[T],Text=[Reference to this attribute is only
+  allowed within a postcondition expression. The @nt{prefix} of an Old
+  @nt{attribute_reference} shall not contain a Result @nt{attribute_reference},
+  nor an Old @nt{attribute_reference}, nor a use of an entity declared within
+  the postcondition expression but not within @nt{prefix} itself (for example,
+  the loop parameter of an enclosing @nt{quantified_expression}).
+  The @nt{prefix} of an Old @nt{attribute_reference} that is
+  potentially unevaluated shall statically denote an entity.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=<The @nt{prefix} X can be any
+  nonlimited object that obeys the syntax for prefix other than the few
+  exceptions given above (discussed below). Useful cases are: the @nt{name}
+  of a formal parameter of mode address@hidden @key[out], the @nt{name} of a 
global
+  variable updated by the subprogram, a function call passing those as
+  parameters, a subcomponent of those things, etc.>}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[A qualified expression can be used to make an
+  arbitrary expression into a valid prefix, so T'(X + Y)'Old is legal, even
+  though (X + Y)'Old is not. The value being saved here is the sum of X and Y 
(a
+  function result is an object). Of course, in this case "+"(X, Y)'Old is also
+  legal, but the qualified expression is arguably more readable.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Note that F(X)'Old and F(X'Old) are not
+  necessarily equal. The former calls F(X) and saves that value for later use
+  during the postcondition. The latter saves the value of X, and during the
+  postcondition, passes that saved value to F. In most cases, the former is 
what
+  one wants (but it is not always legal, see below).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0032-1]}
+  @ChgAdded{Version=[3],Text=[If X has controlled parts, adjustment and
+  finalization are implied by the implicit constant
+  address@hidden,New=[ Similarly, the implicit constant
+  declaration defines the accessibility level of X'Old.],Old=[]}]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If postconditions are disabled, we want the
+  compiler to avoid any overhead associated with saving 'Old values.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=['Old makes no sense for limited types, because 
its
+  implementation involves copying. It might make semantic sense to allow
+  build-in-place, but it's not worth the trouble.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0273-1]}
+  @ChgAdded{Version=[3],Text=[Since the @nt{prefix} is evaluated 
unconditionally
+  when the subprogram is called, we cannot allow it to include values that do
+  not exist at that time (like 'Result and loop parameters of 
@nt{quantified_expression}s).
+  We also do not allow it to include 'Old references, as those would be
+  redundant (the entire @nt{prefix} is evaluated when the subprogram is 
called),
+  and allowing them would require some sort of order to the implicit constant
+  declarations (because in A(I'Old)'Old, we surely would want the value of
+  I'Old evaluated before the A(I'Old) is evaluated).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0273-1]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[In addition, we only allow simple 
names as the
+  @nt{prefix} of the Old attribute if the @nt{attribute_reference} might not
+  be evaluated when the postcondition expression is evaluated. This is 
necessary because
+  the Old @nt{prefix}es have to be unconditionally evaluated when the 
subprogram
+  is called; the compiler cannot in general know whether they will be needed
+  in the postcondition expression. To see the problem, consider:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Table : @key[array] (1..10) @key[of] Integer := ...
address@hidden Bar (I : @key[in out] Natural)
+   @key[with] Post => I > 0 @key[and then] Table(I)'Old = 1; -- 
@Examcom{Illegal}]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[In this example, the compiler
+  cannot know the value of I when the subprogram returns (since the subprogram
+  execution can change it), and thus it does not know whether Table(I)'Old will
+  be needed then. Thus it has to always create an implicit constant
+  and evaluate Table(I) when Bar is called (because not having the value when
+  it is needed is not acceptable). But if I = 0 when the subprogram is called,
+  that evaluation will raise Constraint_Error, and that will happen even if I
+  is unchanged by the subprogram and the value of Table(I)'Old is not 
ultimately
+  needed. It's easy to see how a similar problem could occur for a dereference
+  of an access type. This would be mystifying (since the point of the short
+  circuit is to eliminate this possibility, but it cannot do so). Therefore, we
+  require the @nt{prefix} of any Old attribute in such a context to statically
+  denote an object, which eliminates anything that could change at during
+  execution.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[It is easy to work around most errors that occur
+  because of this rule. Just move the 'Old to the outer object, before any
+  indexing, dereferences, or components. (That does not work for function 
calls,
+  however, nor does it work for array indexing if the index can change during
+  the execution of the subprogram.)]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0032-1]}
+  @ChgAdded{Version=[4],Type=[Leading],Text=[An accept statement for a task
+  entry with enabled postconditions such as]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden E @key[do]
+   @examcom<statements>
address@hidden
+   @examcom<handlers>
address@hidden;]}
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Type=[Leading],Text=[behaves (at runtime) as follows:]}
address@hidden,Kind=[AddedNormal]}
address@hidden
address@hidden,address@hidden E @key[do]
+   @key[declare]
+      @examcom<declarations, if any, of 'Old constants>
+   @key[begin]
+      @key[begin]
+         @examcom<statements>
+      @key[exception]
+         @examcom<handlers>
+      @key[end];
+      @examcom<postcondition checks>
+   @key[end];
address@hidden;]}
address@hidden
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0032-1]}
+  @ChgAdded{Version=[4],Text=[Preconditions are checked by the caller before 
the
+  rendezvous begins. Postcondition expressions might, of course, reference 'Old
+  constants.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0032-1]}
+  @ChgAdded{Version=[4],Text=[In the case of a protected operation with
+  enabled postconditions, 'Old constant declarations (if any) are
+  elaborated after the start of the protected action. Postcondition checks
+  (which might reference these constants) are performed before the end of
+  the protected action as described below.]}
address@hidden
address@hidden(description)
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2]}
address@hidden,Type=[Leading],Text=[For @PrefixType{a @nt{prefix} F that
+denotes a function declaration}, the following attribute is defined:]}
address@hidden(description)
address@hidden,Kind=[AddedNormal],ChginAnnex=[T],
+  Leading=<F>, Prefix=<F>, AttrName=<Result>, ARef=[AI05-0145-2], 
ARef=[AI05-0262-1],
+  InitialVersion=[3],
+  address@hidden,New=[Within a postcondition expression for function F,
+  denotes the result object of the function. The type of this attribute is that
+  of the function result except within a Post'Class postcondition expression 
for
+  a function with a controlling result or with a controlling access result. For
+  a controlling result, the type of the attribute is @i<T>'Class, where @i<T> 
is
+  the function result type. For a controlling access result, the type of the
+  attribute is an anonymous access type whose designated type is @i<T>'Class,
+  where @i<T> is the designated type of the function result 
type.],address@hidden of Annex text here.}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],NoPrefix=[T],Text=[Use of this
+  attribute is allowed only within a postcondition expression
+  for F.]}
address@hidden(description)
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0247-1],ARef=[AI05-0290-1]}
address@hidden,Type=[Leading],Text=[Upon a call of the subprogram or
+entry, after evaluating any actual parameters, precondition checks are 
performed
+as follows:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The specific precondition check begins with the
+  evaluation of the specific precondition expression that applies to the
+  subprogram or entry, if it is enabled; if the expression evaluates to False,
+  Assertions.Assertion_Error is raised; if the expression is not enabled,
+  the check address@hidden(Assertion_Error),
+  Sec=(raised by failure of run-time check)address@hidden, language-defined],
+  Sec=[controlled by assertion address@hidden check],Sec=[specific]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The class-wide precondition check begins with the
+  evaluation of any enabled class-wide precondition expressions that apply
+  to the subprogram or entry. If and only if all the class-wide precondition
+  expressions evaluate to False, Assertions.Assertion_Error is 
address@hidden(Assertion_Error),
+  Sec=(raised by failure of run-time check)address@hidden, language-defined],
+  Sec=[controlled by assertion address@hidden check],Sec=[class-wide]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The class-wide precondition expressions of the
+    entity itself as well as those of any parent or progenitor operations are
+    evaluated, as these expressions apply to the corresponding operations
+    of all descendants.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Class-wide precondition checks are performed for
+    all appropriate calls, but only enabled precondition expressions are
+    evaluated. Thus, the check would be trivial if no precondition expressions
+    are enabled.]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0247-1],ARef=[AI05-0254-1],ARef=[AI05-0269-1]}
address@hidden,Text=[The precondition checks are performed in an
+arbitrary order,
+and if any of the class-wide precondition expressions evaluate to True, it is
+not specified whether the other class-wide precondition expressions are
+evaluated. The precondition checks and any check for elaboration of the
+subprogram body are performed in an arbitrary order. It is not
+specified whether in a call on a protected operation, the checks are performed
+before or after starting the protected action. For an entry
+call, the checks are performed prior to checking whether the entry is 
address@hidden(arbitrary order),
+  Sec=(allowed)address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We need to explicitly allow short-circuiting
+  of the evaluation of the class-wide precondition check if any expression
+  fails, as it consists of multiple expressions; we don't need a similar
+  permission for the specific precondition check as it consists only of a
+  single expression. Nothing is evaluated for the call after a check fails,
+  as the failed check propagates an exception.]}
address@hidden
+
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0247-1],ARef=[AI05-0254-1],ARef=[AI05-0262-1],ARef=[AI05-0290-1]}
address@hidden,Text=[Upon successful return from a call of the subprogram
+or entry, prior to copying back any by-copy @key[in out]
+or @key[out] parameters, the postcondition check is performed. This consists of
+the evaluation of any enabled specific and class-wide postcondition 
expressions that
+apply to the subprogram or entry. If any of the postcondition expressions
+evaluate to False, then Assertions.Assertion_Error is raised. The
+postcondition expressions are evaluated in an arbitrary order, and if any
+postcondition expression evaluates to False, it is not specified whether any
+other postcondition expressions are evaluated. The postcondition check, and any
+constraint or predicate checks associated with
address@hidden out] or @key[out] parameters are performed in
+an arbitrary address@hidden address@hidden, language-defined],
+  Sec=[controlled by assertion address@hidden(Assertion_Error),
+  Sec=(raised by failure of run-time check)address@hidden(arbitrary order),
+  Sec=(allowed)address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The class-wide postcondition expressions of the
+  entity itself as well as those of any parent or progenitor operations are
+  evaluated, as these apply to all descendants; in contrast, only the specific
+  postcondition of the entity applies. Postconditions can always be evaluated
+  inside the invoked body.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0032-1]}
address@hidden,Text=[For a call to a task entry, the postcondition check
+is performed before the end of the rendezvous; for a call to a protected
+operation, the postcondition check is performed before the end of the protected
+action of the call. The postcondition check for any call is performed before 
the
+finalization of any implicitly-declared constants associated (as described
+above) with Old @nt{attribute_reference}s but after the finalization of any
+other entities whose accessibility level is that of the execution of the
+callable construct.]}
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0032-1]}
+  @ChgAdded{Version=[4],Text=[If a postcondition references the 
implicitly-declared constant associated
+   with an Old attribute, the postcondition must be evaluated before the
+   constant is finalized. One way to think of this is to imagine
+   declaring a controlled object between any implicit "'Old"
+   constant declarations and any explicit declarations, then
+   performing postcondition checks during the finalization of
+   this object.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0262-1]}
address@hidden,Text=[If a precondition or postcondition check fails, the
+exception is raised at the point of the address@hidden; the exception cannot
+be handled inside the called subprogram or entry]. Similarly, any exception
+raised by the evaluation of a precondition or postcondition expression is
+raised at the point of call.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0247-1],ARef=[AI05-0254-1],ARef=[AI05-0262-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0113-1],ARef=[AI12-0159-1]}
address@hidden,Text=[For address@hidden,New=[ call to a],Old=[]}
+subprogram or entry @Chg{Version=[4],address@hidden<S>],Old=[call]} (including
+dispatching calls), the checks
+that are performed to verify specific precondition expressions and specific
+and class-wide postcondition expressions are determined by those for the 
subprogram
+or entry actually invoked. Note that the class-wide postcondition expressions
+verified by the postcondition check that is part of a call on a primitive
+subprogram of type @i<T> includes all class-wide postcondition expressions
+originating in any progenitor of @i<T>@Redundant[, even if the primitive
+subprogram called is inherited from a type @i<T1> and some of the postcondition
+expressions do not apply to the corresponding primitive subprogram of
address@hidden<T1>address@hidden,New=[ Any operations within a class-wide
+postcondition expression that were resolved as primitive operations of the
+(notional) formal derived type @i<NT>, are in the evaluation of the
+postcondition bound to the corresponding operations of the type identified
+by the controlling tag of the call on @i<S>address@hidden This applies to both
+dispatching and non-dispatching calls on @i<S>.]],Old=[]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This applies to access-to-subprogram calls,
+    dispatching calls, and to statically bound calls. We need this rule to 
cover
+    statically bound calls as well, as specific pre- and postconditions are not
+    inherited, but the subprogram might be.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[For concrete subprograms, we require the original
+    specific postcondition to be evaluated as well as the inherited class-wide
+    postconditions in order that the semantics of an explicitly defined wrapper
+    that does nothing but call the original subprogram is the same as that of
+    an inherited subprogram.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Note that this rule does not apply to class-wide
+    preconditions; they have their own rules mentioned below.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0247-1],ARef=[AI05-0254-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0113-1],ARef=[AI12-0159-1]}
address@hidden,Text=[The class-wide precondition check for a call to a
+subprogram or entry @Chg{Version=[4],address@hidden<S> ],Old=[]}consists 
solely of
+checking the class-wide precondition expressions that apply to the denoted
+callable entity (not necessarily @Chg{Version=[4],New=[to ],Old=[]}the one
+that is invoked)address@hidden,New=[ Any operations within
+such an expression that were resolved as primitive operations of the
+(notional) formal derived type @i<NT> are in the evaluation of the
+precondition bound to the corresponding operations of the type
+identified by the controlling tag of the call on @i<S>address@hidden This
+applies to both dispatching and non-dispatching calls on @i<S>.]],Old=[]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[For a dispatching call, we are talking about the
+    Pre'Class(es) that apply to the subprogram that the dispatching call is
+    resolving to, not the Pre'Class(es) for the subprogram that is ultimately
+    dispatched to. The class-wide precondition of the resolved call is
+    necessarily the same or stronger than that of the invoked call. For a
+    statically bound call, these are the same; for an access-to-subprogram,
+    (which has no class-wide preconditions of its own), we check the
+    class-wide preconditions of the invoked routine.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[These rules imply that logically, class-wide
+    preconditions of routines must be checked at the point of call (other
+    than for access-to-subprogram calls, which must be checked in the body,
+    probably using a wrapper). Specific preconditions that might be called with
+    a dispatching call or via an access-to-subprogram value must be checked
+    inside of the subprogram body. In contrast, the postcondition checks always
+    need to be checked inside the body of the routine. Of course, an
+    implementation can evaluate all of these at the point of call for 
statically
+    bound calls if the implementation uses wrappers for dispatching bodies and
+    for 'Access values.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[There is no requirement for an implementation
+    to generate special code for routines that are imported from outside of
+    the Ada program. That's because there is a requirement on the programmer
+    that the use of interfacing aspects do not violate Ada semantics (see
+    @RefSecNum{Interfacing Aspects}). That includes making pre- and
+    postcondition checks. For instance, if the implementation expects routines
+    to make their own postcondition checks in the body before returning,
+    C code can be assumed to do this
+    (even though that is highly unlikely). That's even though the formal
+    definition of those checks is that they are evaluated at the call site.
+    Note that pre- and postconditions can be very useful for verification
+    tools (even if they aren't checked), because they tell the tool about the
+    expectations on the foreign code that it most likely cannot analyze.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0247-1],ARef=[AI05-0254-1]}
address@hidden,Text=[For a call via an access-to-subprogram value, all
+precondition and postcondition checks performed are determined by the 
subprogram
+or entry denoted by the prefix of the Access attribute reference that produced
+the value.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Text=[A precondition is checked just before the call. 
If
+  another task can change any value that the precondition expression depends 
on,
+  the precondition need not hold within the subprogram or entry body.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0145-2],ARef=[AI05-0230-1],ARef=[AI05-0247-1],ARef=[AI05-0254-1],ARef=[AI05-0262-1],ARef=[AI05-0273-1],ARef=[AI05-0274-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Pre and Post aspects are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0032-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  The Old attribute is defined more carefully. This changes the nominal subtype
+  and place of declaration of the attribute compared to the published Ada 2012
+  Standard. In extreme cases, this could change the runtime behavior of the
+  attribute (for instance, the tag might be different). The changes are most
+  likely going to prevent bugs by being more intuitive, but it is possible that
+  a program that previously worked might fail.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0113-1],ARef=[AI12-0159-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Eliminated unintentional
+  redispatching from class-wide preconditions and postconditions. This means
+  that a different body might be evaluated for a statically bound call to a
+  routine that has a class-wide precondition or postcondition. The change means
+  that the behavior of Pre and Pre'Class will be the same for a particular
+  subprogram, and that the known behavior of the operations can be assumed
+  within the body of that subprogram for Pre'Class. We expect that this change
+  will primarily fix bugs, as it will make Pre'Class and Post'Class work more
+  like expected. In the case where redispatching is desired, an explicit
+  conversion to a class-wide type can be used.]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0045-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Precondition and postcondition aspects cannot be specified on instances of
+  generic subprograms (they should be specified on the generic subprogram
+  instead). This was (unintentionally) allowed by the Ada 2012 standard.
+  These are not be allowed on instances as there is no corresponding way to add
+  preconditions and postconditions to subprograms declared within the instance
+  of a generic package. Therefore, allowing specification on a subprogram
+  instance could present a maintenance problem in the future if the entity
+  needs to be converted to a generic package (a common conversion).]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0131-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Pre'Class is no longer 
allowed
+  to be specified for an overriding primitive subprogram unless there are
+  also inherited class-wide precondittions. This incompatibility prevents
+  cases where the explicit Pre'Class is counterfeited by an implicit
+  class-wide precondition of True. This rule should catch more bugs than it
+  creates; the programmer should have written Pre rather than Pre'Class in
+  this case (or written Pre'Class on the original subprogram, not
+  an overriding). Note that this incompatibility eliminates what otherwise
+  would be an inconsistency with original Ada 2012, where precondition checks
+  that would have previously been made for a statically bound call would no
+  longer be made. That dynamic change was necessary to eliminate cases where
+  the evaluated class-wide precondition on a dispatching call would have been
+  weaker than the class-wide precondition of a statically bound call. (The
+  original Ada 2012 violated the LSP semantics that class-wide preconditions
+  were intended to model.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Parameter Modes}
+
address@hidden
address@hidden @nt{parameter_specification} declares a formal parameter of
+mode @key[in], @key[in out], or @key[out].]
address@hidden
+
address@hidden
address@hidden by copy}
address@hidden copy parameter passing}
address@hidden parameter passing}
address@hidden by reference}
address@hidden reference parameter passing}
address@hidden parameter passing}
+A parameter is passed either @i{by copy} or @i{by reference}.
address@hidden a parameter is passed by copy,
+the formal parameter denotes a separate object from the
+actual parameter, and any information transfer between the two occurs
+only before and after executing the subprogram.
+When a parameter is passed by reference,
+the formal parameter denotes (a view of) the object denoted by the
+actual parameter; reads and updates of the formal parameter directly
+reference the actual parameter object.]
+
address@hidden,Kind=[Revised],ARef=[AI05-0142-4],ARef=[AI05-0262-1]}
address@hidden type}
+A type is a @i(by-copy type) if it is an elementary type,
+or if it is a descendant of a private type whose full type is a
+by-copy type. A parameter of a by-copy type is passed by
address@hidden,New=[, unless the
+formal parameter is explicitly aliased],Old=[]}.
+
address@hidden@address@hidden type}
+A type is a @i(by-reference type) if it
+is a descendant of one of the following:
address@hidden(itemize)
+  a tagged type;
+
+  a task or protected type;
+
address@hidden,Kind=[Revised],ARef=[AI05-0096-1]}
+  @Chg{Version=[3],New=[an explicitly limited record type],Old=[a
+  nonprivate type with the reserved word @key[limited] in its declaration]};
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI05-0096-1]}
+  @ChgDeleted{Version=[3],Text=[A limited private type is by-reference
+  only if it falls under one of the other categories.]}
address@hidden
+
+  a composite type with a subcomponent of a by-reference type;
+
+  a private type
+  whose full type is a by-reference type.
address@hidden(itemize)
+
address@hidden,Kind=[Revised],ARef=[AI05-0142-4],ARef=[AI05-0188-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0027-1]}
+A parameter of a by-reference type is passed by address@hidden,New=[, as is an 
explicitly aliased parameter
+of any type],Old=[]}.
address@hidden object], Sec=(of a value of a by-reference type)}
+Each value of a by-reference type has an associated object.
+For a parenthesized expression, @nt{qualified_expression},
+or @Chg{Version=[4],New=[view conversion],address@hidden, this
+object is the one associated with the address@hidden,New=[ For a value
+conversion, the associated object is the anonymous result object if such an
+object is created (see @RefSecNum{Type Conversions}); otherwise it is the
+associated object of the operand.],address@hidden,New=[ For a
address@hidden, this object is the one associated with the
+evaluated @address@hidden,Old=[]}
+
address@hidden
+By-reference parameter passing makes sense only if there is an
+object to reference; hence, we define such an object for each
+case.
+
+Since tagged types are by-reference types, this implies that every value
+of a tagged type has an associated object. This simplifies things,
+because we can define the tag to be a property of the object, and not of
+the value of the object, which makes it clearer that object tags never
+change.
+
+We considered simplifying things even more by making every value (and
+therefore every expression) have an associated object. After all,
+there is little semantic difference between a constant object and a
+value.
+However, this would cause problems for untagged types.
+In particular, we would have to do a constraint check on every read of a
+type conversion (or a renaming thereof) in certain cases.
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
+We do not want this definition to depend on the view of the type;
+privateness is essentially ignored for this definition.
+Otherwise, things would be confusing (does the rule apply at the call
+site, at the site of the declaration of the subprogram,
+at the site of the
address@hidden,New=[return statement],address@hidden),
+and requiring different calls to use different mechanisms would be an
+implementation burden.
+
address@hidden Variable Control} says that a composite type with an
+atomic or volatile subcomponent is a by-reference type,
+among other things.
+
address@hidden object], Sec=(of a value of a limited type)}
+Every value of a limited by-reference type is the value of
+one and only one limited object.
+The @i{associated object} of a value of a limited by-reference type is
+the object whose value it represents.
address@hidden value], Sec=(for a limited type)}
+Two values of a limited by-reference type are the @i{same}
+if and only if they represent the value of the same object.
+
+We say @lquotes@;address@hidden@; above because
+these statements are not always true for limited private types
+whose underlying type is nonlimited (unfortunately).
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0240-1]}
address@hidden
+For @Chg{Version=[3],New=[other ],address@hidden,New=[],Old=[ of other types]},
+it is unspecified whether the parameter
+is passed by copy or by reference.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+  There is no need to incorporate the discussion of AI83-00178,
+  which requires pass-by-copy for certain kinds of actual parameters,
+  while allowing pass-by-reference for others.
+  This is because we explicitly indicate that a function
+  creates an anonymous constant object for its address@hidden,New=[],Old=[,
+  unless the type is a return-by-reference type]}
+  (see @RefSecNum{Return Statements}).
+  We also provide a special dispensation for
+  instances of Unchecked_Conversion to return by address@hidden,New=[],Old=[, 
even
+  if the result type is not a return-by-reference type]}
+  (see @RefSecNum{Unchecked Type Conversions}).
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0240-1]}
address@hidden access paths}
address@hidden paths],Sec=(distinct)}
address@hidden,See=(distinct access paths)}
address@hidden(bounded error),Sec=(cause)}
+If one @nt<name> denotes a part of a formal parameter,
+and a second @nt<name> denotes a part of
+a distinct formal parameter or an object that is not
+part of a formal parameter, then the two @nt<name>s are
+considered @i(distinct access paths).
+If an object is of a type for which the parameter passing
+mechanism is not address@hidden,New=[ and is not an
+explicitly aliased parameter],Old=[]}, then it is a bounded error to
+assign to the object via one access path,
+and then read the value of the object via a distinct access path,
+unless the first access path denotes a part of a formal parameter that
+no longer exists at the point of the second access
address@hidden(due to leaving the corresponding callable construct).]
address@hidden,Sec=(raised by failure of run-time check)}
+The possible consequences are that Program_Error is raised,
+or the newly assigned value is read, or some old value of the object is read.
address@hidden
+For example, if we call @lquotes@;P(X => Global_Variable, Y => 
Global_Variable)@rquotes@;,
+then within P, the names @lquotes@;address@hidden@;, 
@lquotes@;address@hidden@;, and @lquotes@;address@hidden@;
+are all distinct access paths.
+If Global_Variable's type is neither pass-by-copy nor pass-by-reference,
+then it is a bounded error to assign to Global_Variable and
+then read X or Y, since the language does not specify whether the
+old or the new value would be read. On the other hand, if
+Global_Variable's type is pass-by-copy, then the old value would
+always be read, and there is no error. Similarly, if Global_Variable's
+type is defined by the language to be pass-by-reference, then the
+new value would always be read, and again there is no error.
address@hidden
address@hidden
+We are saying @i(assign) here, not @i(update),
+because updating any subcomponent is considered
+to update the enclosing object.
+
+The @lquotes@;still address@hidden@; part is so that a read after the 
subprogram returns
+is OK.
+
+If the parameter is of a by-copy type,
+then there is no issue here
address@hidden the formal is not a view of the actual.
+If the parameter is of a by-reference type,
+then the programmer may depend on updates through one access path
+being visible through some other access path,
+just as if the parameter were of an access type.
address@hidden
address@hidden
+The implementation can keep a copy in a register of a parameter
+whose parameter-passing mechanism is not specified.
+If a different access path is used to update the object (creating
+a bounded error situation),
+then the implementation can still use the value of the register,
+even though the in-memory version of the object has been changed.
+However, to keep the error properly bounded,
+if the implementation chooses to read the in-memory version,
+it has to be consistent -- it cannot then assume that something it has
+proven about the register is true of the memory location.
+For example, suppose the formal parameter is L,
+the value of L(6) is now in a register, and L(6) is used
+in an @nt{indexed_component} as in @lquotes@;A(L(6)) := 99;@rquotes@;,
+where A has bounds 1..3.
+If the implementation can prove that the value for L(6) in the register is in
+the range 1..3, then it need not perform the constraint check if it
+uses the register value.
+However, if the memory value of L(6) has been changed to 4,
+and the implementation uses that memory value,
+then it had better not alter memory outside of A.
+
+Note that the rule allows the implementation to pass a parameter by
+reference and then keep just part of it in a register, or,
+equivalently, to pass part of the parameter by reference and another
+part by copy.
address@hidden
address@hidden
address@hidden@;We do not want to go so far as to say that the mere presence
+of aliasing is wrong.
+We wish to be able to write the following sorts of things
+in standard Ada:
address@hidden
address@hidden Move ( Source  : @key[in]  String;
+                 Target  : @key[out] String;
+                 Drop    : @key[in]  Truncation := Error;
+                 Justify : @key[in]  Alignment  := Left;
+                 Pad     : @key[in]  Character  := Space);
address@hidden Copies elements from Source to Target (safely if they overlap)}
address@hidden
+
+This is from the standard string handling package.
+It would be embarrassing if this couldn't be written in Ada!
+
+The @lquotes@;address@hidden@; before @lquotes@;address@hidden@; in the rule 
implies that the implementation
+can move a read to an earlier place in the code, but not to a later
+place after a potentially aliased assignment.
+Thus, if the subprogram reads one of its parameters into a local
+variable, and then updates another potentially aliased one,
+the local copy is safe @em it is known to have the old value.
+For example, the above-mentioned Move subprogram can be implemented
+by copying Source into a local variable before assigning into Target.
+
address@hidden@;For an @nt{assignment_statement} assigning one array parameter 
to another,
+the implementation has to check which direction to copy
+at run time, in general, in case the actual parameters are
+overlapping slices.
+For example:
address@hidden
address@hidden Copy(X : @key[in out] String; Y: String) @key[is]
address@hidden
+    X := Y;
address@hidden Copy;
address@hidden
+
+It would be wrong for the compiler to assume that X and Y
+do not overlap (unless, of course, it can prove otherwise).
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI12-0056-1]}
address@hidden,Text=[The mode of a formal parameter describes the
+direction of information transfer to or from the @nt{subprogram_body} (see
address@hidden Declarations}).]}
+
+A formal parameter of mode @key(in) is a constant
+view (see @RefSecNum{Objects and Named Numbers});
+it cannot be updated within the @nt{subprogram_body}.
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0056-1]}
address@hidden,Text=[A formal parameter of mode @key(out)
+might be uninitialized at the start of the @nt{subprogram_body} (see
address@hidden Associations}).]}
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The value of an @key(out) parameter may be read.
+An @key(out) parameter is treated like a declared
+variable without an explicit initial expression.
address@hidden
+
address@hidden
+Discussion of copy-in for parts of out parameters is now
+covered in @RefSec{Parameter Associations}.
+
+The concept of a by-reference type is new to Ada 95.
+
+We now cover in a general way in @RefSecNum{Operations of Discriminated Types}
+the rule regarding erroneous execution when a discriminant
+is changed and one of the parameters depends on the discriminant.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0096-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected so that
+  limited derived types are by-reference only if their parent is.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0142-4]}
+  @ChgAdded{Version=[3],Text=[Defined that explicitly aliased parameters
+  (see @RefSecNum{Subprogram Declarations}) are always passed by reference.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0027-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Corrected so that
+  value conversions that are copies are the @ldquote@;associated address@hidden
+  for parameter passing of by-reference types. This can only happen if the
+  conversion is between unrelated non-limited types, and it is necessary just
+  so the correct object is defined.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Bodies}
+
address@hidden
address@hidden @nt{subprogram_body} specifies the execution of a
+subprogram.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00218-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<subprogram_body>,rhs="@Chg{Version=[2],New=<
+    address@hidden>,Old=<>}
+    @address@hidden,New=<
+       address@hidden>,Old=[]} @key{is}
+       @Syn2{declarative_part}
+    @key{begin}
+        @Syn2{handled_sequence_of_statements}
+    @key{end} address@hidden;"}
+
address@hidden
+If a @nt{designator} appears at the end of a @nt{subprogram_body},
+it shall repeat the @nt{defining_designator} of the 
@nt{subprogram_specification}.
address@hidden
address@hidden
+
address@hidden
address@hidden contrast to other bodies,]
+a @nt{subprogram_body} need not be the completion of a previous
address@hidden,
+in which case the body declares the subprogram].
+If the body is a completion, it shall be the completion of a
address@hidden or @nt{generic_subprogram_declaration}.
+The profile of a @nt{subprogram_body} that completes a declaration
+shall conform fully to that of the declaration.
address@hidden conformance],Sec=(required)}
address@hidden
+
address@hidden
+A @nt{subprogram_body} is considered a declaration.
+It can either complete a previous declaration,
+or itself be the initial declaration of the subprogram.
address@hidden
+
address@hidden
address@hidden, Sec=(nongeneric subprogram_body)}
+The elaboration of a nongeneric
address@hidden has no other effect than to establish
+that the subprogram can from then on be called without
+failing the Elaboration_Check.
address@hidden
+See @RefSecNum{Generic Bodies} for elaboration of a generic body.
+Note that protected @ntf{subprogram_bodies} never get elaborated;
+the elaboration of the containing @nt{protected_body}
+allows them to be called without failing the Elaboration_Check.
address@hidden
+
address@hidden, Sec=(subprogram_body)}
address@hidden execution of a @nt{subprogram_body} is invoked by a
+subprogram call.]
+For this execution the @nt{declarative_part} is elaborated, and the
address@hidden is then executed.
address@hidden
+
address@hidden
address@hidden@address@hidden of procedure body:}
address@hidden
address@hidden Push(E : @key[in] Element_Type; S : @key[in] @key[out] Stack) 
@key[is]
address@hidden
+   @key[if] S.Index = S.Size @key[then]
+      @key[raise] Stack_Overflow;
+   @key[else]
+      S.Index := S.Index + 1;
+      S.Space(S.Index) := E;
+   @key[end] @key[if];
address@hidden Push;
address@hidden
+
address@hidden
address@hidden@address@hidden of a function body:}
address@hidden
address@hidden
address@hidden Dot_Product(Left, Right : Vector) @key[return] Real @key[is]
+   Sum : Real := 0.0;
address@hidden
+   Check(Left'First = Right'First @key[and] Left'Last = Right'Last);
+   @key[for] J @key[in] Left'Range @key[loop]
+      Sum := Sum + Left(J)*Right(J);
+   @key[end] @key[loop];
+   @key[return] Sum;
address@hidden Dot_Product;
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+A @nt{renaming_declaration} may be used instead of a @nt{subprogram_body}.
address@hidden
+
address@hidden
+The syntax rule for @nt{subprogram_body} now uses the syntactic category
address@hidden
+
+The @nt{declarative_part} of a @nt{subprogram_body} is now required;
+that doesn't make any real difference,
+because a @nt{declarative_part} can be empty.
+
+We have incorporated some rules from RM83-6.5 here.
+
+RM83 forgot to restrict the definition of elaboration of a
address@hidden to nongenerics.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00218-03]}
address@hidden,address@hidden is added to
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}An optional
+  @nt{aspect_specification} can be used in a @nt{subprogram_body}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
+
address@hidden Rules}
+
address@hidden
address@hidden
address@hidden,Other=(type conformance)}
address@hidden,Other=(mode conformance)}
address@hidden,Other=(subtype conformance)}
address@hidden,Other=(full conformance)}
address@hidden subprogram profiles are given in more than one place,
+they are required to conform in one of four ways: type conformance, mode
+conformance, subtype conformance, or full conformance.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0011],ARef=[AI95-00117-01]}
address@hidden@Defn{convention}
address@hidden convention}
address@hidden explained in @RefSec{Interfacing Aspects},
+a @i{convention} can be specified for an entity.]
address@hidden this International Standard states otherwise, the default
+convention of an entity is Ada.],Old=[]}
address@hidden a callable entity or access-to-subprogram type,
+the convention is called the @i{calling convention}.]
+The following conventions are defined by the language:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden calling convention}
address@hidden convention], Sec=(Ada)}
+The default calling convention for any subprogram not listed below is
address@hidden
address@hidden@Chg{Version=[3],New=[The],Old=[A @nt{pragma}]}
address@hidden,New=[ aspect],Old=[, Import, or Export]}
+may be @Chg{Version=[3],New=[specified],Old=[used]} to override
+the default calling convention (see @RefSecNum{Interfacing Aspects})].
address@hidden
+See also the rule about renamings-as-body
+in @RefSecNum{Subprogram Renaming Declarations}.
address@hidden
+
address@hidden@Defn{Intrinsic calling convention}
address@hidden convention], Sec=(Intrinsic)}
+The @i{Intrinsic} calling convention represents
+subprograms that are @lquotes@;built address@hidden@; to the compiler.
+The default calling convention is Intrinsic for the following:
address@hidden
+  an enumeration literal;
+
+  a "/=" operator declared implicitly due to
+  the declaration of "=" (see @RefSecNum{Overloading of Operators});
+
+  any other implicitly declared subprogram unless it is
+  a dispatching operation of a tagged type;
+
+  an inherited subprogram of a generic formal tagged type
+  with unknown discriminants;
address@hidden
address@hidden/0011 suggests that the reason for this rule be documented in
+         the AARM.}
address@hidden,Kind=[Added]}
address@hidden:],Old=[]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden@key[package] P @key[is]
+    @key[type] Root @key[is tagged null record];
+    @key[procedure] Proc(X: Root);
address@hidden P;],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden@key[generic]
+    @key[type] Formal(<>) @key[is new] Root @key[with private];
address@hidden G @key[is]
+    ...
address@hidden G;],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden body] G @key[is]
+    ...
+    X: Formal := ...;
+    ...
+    Proc(X); -- @RI[This is a dispatching call in Instance, because]
+             -- @RI[the actual type for Formal is class-wide.]
+    ...
+    -- @RI[Proc'Access would be illegal here, because it is of]
+    -- @RI[convention Intrinsic, by the above rule.]
address@hidden G;]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden Actual @key[is new] Root @key[with] ...;
address@hidden Proc(X: Actual);
address@hidden Instance @key[is new] G(Formal => Actual'Class);
+    -- @RI[It is legal to pass in a class-wide actual, because Formal]
+    -- @RI[has unknown discriminants.]]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden Instance, all calls to Proc will be dispatching calls, so Proc 
doesn't
+really exist in machine code, so we wish to avoid taking 'Access of it.
+This rule applies to those cases where the actual type might be class-wide,
+and makes these Intrinsic, thus forbidding 'Access.],Old=[]}
address@hidden
+
+
+  an attribute that is a subprogram;
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00252-01]}
+  a subprogram declared immediately
+  within a @address@hidden,New=[;],Old=[.]}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00252-01],ARef=[AI95-00407-01]}
+  @ChgRef{Version=[4],Kind=[RevisedAdded],ARef=[AI12-0107-1]}
+  @ChgAdded{Version=[2],Text=[any prefixed view of a subprogram (see
+  @RefSecNum{Selected Components})@Chg{Version=[4],New=[ without
+    synchronization kind (see @RefSecNum{Intertask Communication}) By_Entry or
+    By_Protected_Procedure],Old=[]}.]}
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[The profile of a prefixed view is
+    different than the @lquotes@;address@hidden profile of the subprogram
+    (it doesn't have the first parameter), so we don't want to be able
+    to take 'Access of it, as that would require generating a wrapper of
+    some sort.]}
+
+    @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0107-1]}
+    @ChgAdded{Version=[4],Text=[We except prefixed views that have
+    synchronization kind By_Protected_Procedure so that they can be used
+    with an access-to-protected-procedure type. These don't require special
+    wrappers (this is the normal form for a protected subprogram call). The
+    By_Entry part is just for consistency (there is no access-to-entry type
+    in Ada).]}
+  @end{Reason}
+
address@hidden
+
address@hidden@Redundant[The Access attribute is not allowed
+for Intrinsic subprograms.]
address@hidden
+  The Intrinsic calling convention really represents any number of
+  calling conventions at the machine code level;
+  the compiler might have a different instruction sequence for
+  each intrinsic.
+  That's why the Access attribute is disallowed.
+  We do not wish to require the implementation to generate
+  an out of line body for an intrinsic.
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  Whenever we wish to disallow the Access attribute in order to ease
+  implementation, we make the subprogram Intrinsic.
+  Several language-defined subprograms have
+  @lquotes@;@Chg{Version=[3],address@hidden,address@hidden
+  address@hidden,New=[ => ],Old=[(address@hidden,New=[],Old=[, 
...)]};@rquotes@;.
+  An implementation might actually implement this
+  as @lquotes@;@Chg{Version=[3],address@hidden,address@hidden
+  address@hidden,New=[ => True, Convention
+  => ],Old=[(address@hidden,New=[],Old=[, ...)]};@rquotes@;,
+  if there is really no body, and the implementation of the subprogram
+  is built into the code generator.
+
+  Subprograms declared in @ntf{protected_bodies} will generally have a
+  special calling
+  convention so as to pass along the identification of the
+  current instance of the protected type.
+  The convention is not @i(protected) since such local subprograms
+  need not contain any @lquotes@;address@hidden@; logic since they are
+  not callable via @lquotes@;address@hidden@; calls;
+  this rule prevents an access value designating such a subprogram
+  from being passed outside the protected unit.
+
+  The @lquotes@;implicitly declared address@hidden@; above refers to
+  predefined operators (other than the "=" of a tagged type) and
+  the inherited subprograms of
+  untagged types.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI12-0107-1],ARef=[AI12-0159-1]}
address@hidden calling convention}
address@hidden convention], Sec=(protected)}
+The default calling convention is @i{protected}
+for a protected subprogram,@Chg{Version=[4],New=[ for a
+prefixed view of a subprogram with a synchronization kind of
+By_Protected_Procedure,],Old=[]}
+and for an access-to-subprogram type with
+the reserved word @key(protected) in its definition.
+
address@hidden,Kind=[Revised],ARef=[AI12-0107-1],ARef=[AI12-0159-1]}
address@hidden calling convention}
address@hidden convention], Sec=(entry)}
+The default calling convention is @i{entry} for an
address@hidden,New=[ and for a prefixed view
+of a subprogram with a synchronization kind of By_Entry],Old=[]}.
+
address@hidden,Kind=[Added],ARef=[AI95-00254-01],ARef=[AI95-00409-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0264-1]}
address@hidden,Text=[The calling convention for an
+anonymous access-to-subprogram parameter
+or anonymous access-to-subprogram result is @i<protected> if the reserved
+word @key{protected} appears in its address@hidden,New=[;],Old=[ and]}
address@hidden,New=[, it],Old=[]} is the convention
+of the subprogram that contains the parameter.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The calling convention for other
+  anonymous access-to-subprogram types is Ada.]}
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0011],ARef=[AI95-00117-01]}
address@hidden,address@hidden not specified above as Intrinsic, the calling 
convention for any
+inherited or overriding dispatching operation of a tagged type is that of the
+corresponding subprogram of the parent type.] The default calling convention
+for a new dispatching operation of a tagged type is the convention of the 
type.],
+Old=[]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[The first rule is officially stated in
address@hidden(Dispatching Operations of Tagged Types). The second is intended
+to make interfacing to foreign OOP languages easier, by making the default
+be that the type and operations all have the same convention.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+Of these four conventions, only Ada and Intrinsic are
+allowed as a @address@hidden
+in @Chg{Version=[3],New=[the specification of a],Old=[a @nt{pragma}]}
address@hidden,New=[ aspect],Old=[, Import, or Export]}.
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  The names of the @i{protected} and @i{entry} calling conventions
+  cannot be used in the @Chg{Version=[3],New=[specification of Convention],
+  Old=[interfacing pragmas]}.
+  Note that @key[protected] and @key[entry] are reserved words.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00409-01]}
address@hidden conformance}
address@hidden,Sec=(type conformant)}
+Two profiles
+are @i{type conformant} if they have the same number of parameters,
+and both have a result if either does, and corresponding
+parameter and result types are the same,
+or, for access address@hidden,New=[ or access results],Old=[]},
+corresponding designated types are the address@hidden,New=[, or
+corresponding designated profiles are type conformant],Old=[]}.
address@hidden profile],See=(profile, type conformant)}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00409-01]}
+For @Chg{Version=[2],New=[anonymous access-to-object],Old=[access]}
+parameters, the designated types have to be the same for type
+conformance, not the access types,
+since in general each access parameter has its own anonymous access
+type, created when the subprogram is called.
+Of course, corresponding parameters have to be either both access
+parameters or both not access parameters.
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00409-01]}
address@hidden,Text=[Similarly, for anonymous access-to-subprogram
+parameters, the designated profiles of the types, not the types themselves,
+have to be conformant.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02],ARef=[AI95-00409-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0142-4]}
address@hidden,Type=[Leading],address@hidden for conditional leading.}
address@hidden conformance}
address@hidden,Sec=(mode conformant)}
+Two profiles are @i{mode conformant} address@hidden,New=[:],Old=[ they are
+type-conformant, and
+corresponding parameters have identical
+modes, and, for access
address@hidden,New=[ or access result types],Old=[]}, the
+designated subtypes statically address@hidden,New=[, or the
+designated profiles are subtype conformant.],Old=[]}
address@hidden matching],Sec=(required)}]}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0142-4],ARef=[AI05-0262-1]}
address@hidden,Text=[they are type conformant; and]}
+
address@hidden,Kind=[Added],ARef=[AI05-0142-4]}
address@hidden,Text=[corresponding parameters have identical modes and
+both or neither are explicitly aliased parameters; and]}
+
address@hidden,Kind=[Added],ARef=[AI05-0207-1]}
address@hidden,Text=[for corresponding access parameters and any access
+result type, the designated subtypes statically match and either both or 
neither
+are access-to-constant, or the designated profiles are subtype conformant.
address@hidden matching],Sec=(required)}]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0239-1]}
address@hidden conformance}
address@hidden,Sec=(subtype conformant)}
+Two profiles are @i{subtype conformant} if they are
address@hidden,New=[mode conformant],Old=[mode-conformant]},
+corresponding subtypes of the profile statically match,
+and the associated calling conventions are the same.
+The profile of a generic formal subprogram is not
address@hidden,New=[subtype conformant],Old=[subtype-conformant]}
+with any other profile.
address@hidden matching],Sec=(required)}
+
address@hidden
address@hidden contract issue}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0134-1],ARef=[AI05-0262-1]}
address@hidden,Type=[Leading],address@hidden for conditional leading.}
address@hidden conformance], Sec=(for profiles)}
address@hidden,Sec=(fully conformant)}
+Two profiles are @i{fully conformant} if they
+are @Chg{Version=[3],New=[subtype conformant],Old=[subtype-conformant]},
address@hidden,New=[if they have
+access-to-subprogram results whose designated profiles are fully
+conformant, ],Old=[]}and @Chg{Version=[3],New=[for ],Old=[]}
+corresponding address@hidden,New=[:],
+Old=[ have the same names and have @nt<default_expression>s
+that are fully conformant with one another.]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0262-1]}
address@hidden,Text=[they have the same names; and]}
+
address@hidden,Kind=[Added],ARef=[AI05-0046-1]}
address@hidden,Text=[both or neither have @nt{null_exclusion}s; and]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[neither have @nt{default_expression}s, or they both
+have @nt{default_expression}s that are fully conformant with one another; and]}
+
address@hidden,Kind=[Added],ARef=[AI05-0134-1]}
address@hidden,Text=[for access-to-subprogram parameters, the designated
+profiles are fully conformant.]}
address@hidden
address@hidden
+Full conformance requires subtype conformance,
+which requires the same calling conventions.
+However, the calling convention of the declaration and body of a
+subprogram or entry are always the same by definition.
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0046-1]}
address@hidden,Text=[The part about @nt{null_exclusion}s is
+  necessary to prevent controlling parameters from having different
+  exclusions, as such a parameter is defined to exclude
+  null whether or not an exclusion is given.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0134-1]}
address@hidden,Text=[The parts about access-to-subprogram parameters
+  and results is necessary to prevent such types from having different
+  @nt{default_expression}s in the specification and body of a subprogram.
+  If that was allowed, it would be undefined which @nt{default_expression}
+  was used in a call of an access-to-subprogram parameter.]}
address@hidden
+
address@hidden@Defn2{Term=[full conformance], Sec=(for expressions)}
+Two expressions are @i(fully conformant) if,
address@hidden replacing each use of an operator with the equivalent
address@hidden:]
address@hidden
+each constituent construct of one corresponds to an instance of the
+same syntactic category in the other,
+except that an expanded name may correspond
+to a @nt{direct_name}
+(or @nt{character_literal})
+or to a different expanded name in the other; and
+
address@hidden,Kind=[Added],ARef=[AI12-0050-1]}
address@hidden,Text=[corresponding @nt{defining_identifier}s occurring
+within the two expressions are the same; and]}
+
address@hidden,Kind=[Revised],ARef=[AI12-0050-1]}
+each @nt{direct_name}, @nt{character_literal}, and @nt{selector_name}
+that is not part of the @nt{prefix} of an expanded name in one
+denotes the same declaration as the corresponding
address@hidden, @nt{character_literal},
+or @nt{selector_name} in the address@hidden,New=[, or they denote
+corresponding declarations occurring within the two expressions],Old=[]}; and
address@hidden
+Note that it doesn't say @lquotes@;address@hidden@;
+because a @nt{direct_name} can correspond to a @nt{selector_name},
+and vice-versa, by the previous bullet.
+This rule allows the @nt{prefix} of an expanded name to be removed,
+or replaced with a different @nt{prefix} that denotes a renaming of the
+same entity.
+However, it does not allow a @nt{direct_name} or @nt{selector_name} to
+be replaced with one denoting a distinct renaming
+(except for @nt{direct_name}s and @nt{selector_name}s in @nt{prefix}es
+of expanded names).
+Note that calls using operator notation
+are equivalent to calls using prefix notation.
+
address@hidden@keepnext@;Given the following declarations:
address@hidden
address@hidden A @key[is]
+    @key[function] F(X : Integer := 1) @key[return] Boolean;
address@hidden A;
+
address@hidden,Kind=[Added],ARef=[AI05-0005-1]}
address@hidden A;
address@hidden B @key[is]
+    @key[package] A_View @key[renames] A;
+    @key[function] F_View(X : Integer := 9999) @key[return] Boolean 
@key[renames] @Chg{Version=[3],New=[A.F],Old=[F]};
address@hidden B;
+
address@hidden A, B; @key[use] A, B;
address@hidden Main @key[is] ...
address@hidden
+
+Within Main, the expressions @lquotes@;address@hidden@;, 
@lquotes@;address@hidden@;, @lquotes@;address@hidden@;,
+and @lquotes@;address@hidden@; are all fully conformant with one another.
+However, @lquotes@;address@hidden@; and @lquotes@;address@hidden@; are not 
fully conformant.
+If they were, it would be bad news, since the two denoted views have
+different @nt{default_expression}s.
address@hidden
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0050-1]}
+  @ChgAdded{Version=[4],Text=[We talk about @nt{defining_identifier}s and
+  "corresponding declarations" because of the possibility of
+  @nt{iterator_specification}s occurring within the expressions; each
+  @nt{iterator_specification} is a separate declaration, which we need to
+  allow, but we do want to require that the @nt{defining_identifier}s are
+  the same.]}
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0018],ARef=[AI95-00175-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0092-1]}
address@hidden,Text=[each @nt{attribute_designator} in one
address@hidden,New=[is],Old=[must be]} the same as the
+corresponding @nt{attribute_designator} in the other; and]}
+
+each @nt{primary} that is a literal in one
+has the same value as the corresponding literal in the other.
address@hidden
+The literals may be written differently.
address@hidden
address@hidden
address@hidden
+Note that the above definition makes full conformance a transitive
+relation.
address@hidden
+
address@hidden conformance], Sec=(for @nt{known_discriminant_part}s)}
+Two @nt{known_discriminant_part}s are @i(fully conformant) if they have
+the same number of discriminants, and
+discriminants in the same positions
+have the same names, statically matching subtypes,
+and @nt{default_expression}s that are fully conformant with
+one another.
address@hidden matching],Sec=(required)}
+
address@hidden conformance], Sec=(for @nt{discrete_subtype_definition}s)}
+Two @nt<discrete_subtype_definition>s are @i(fully conformant) if they
+are both @nt<subtype_indication>s or are both @nt<range>s,
+the @nt<subtype_mark>s (if any) denote the same subtype, and
+the corresponding @nt<simple_expression>s of the @nt<range>s (if any)
+fully conform.
address@hidden
+  In the @nt{subtype_indication} case, any ranges have to @i{be}
+  corresponding; that is, two @nt{subtype_indication}s cannot conform
+  unless both or neither has a @nt{range}.
address@hidden
address@hidden
+  This definition is used in @RefSec(Entries and Accept Statements)
+  for the conformance required between the @nt<discrete_subtype_definition>s
+  of an @nt<entry_declaration> for a family of entries and the
+  corresponding @nt<entry_index_specification> of the @nt<entry_body>.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01],ARef=[AI95-00397-01]}
address@hidden,address@hidden view profile}
+The @i<prefixed view profile> of a subprogram is the profile obtained by
+omitting the first parameter of that subprogram. There is no prefixed view
+profile for a parameterless subprogram. For the purposes of defining subtype
+and mode conformance, the convention of a prefixed view profile is considered
+to match that of either an entry or a protected operation.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This definition is used to define how
+  primitive subprograms of interfaces match operations in task and
+  protected type definitions (see @RefSecNum{Task Units and Task Objects} and
+  @RefSecNum{Protected Units and Protected Objects}).]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The weird rule about conventions is pretty much
+  required for synchronized interfaces to make any sense. There will be
+  wrappers all over the place for interfaces anyway. Of course, this doesn't
+  imply that entries have the same convention as protected operations.]}
address@hidden
address@hidden
+
address@hidden
+
+An implementation may declare an operator declared in a language-defined
+library unit to be intrinsic.
+
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The rules for full conformance are relaxed @em they are now based on
+the structure of constructs, rather than the sequence of lexical
+elements. This implies, for example, that "(X, Y: T)"
+conforms fully with "(X: T; Y: T)",
+and "(X: T)" conforms fully with "(X: @key[in] T)".
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0011],ARef=[AI95-00117-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that the default
+  convention is Ada. Also clarified that the convention of a primitive
+  operation of a tagged type is the same as that of the type.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0018],ARef=[AI95-00175-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added wording to ensure 
that two
+  attributes conform only if they have the same @nt{attribute_designator}.]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00252-01],ARef=[AI95-00254-01],ARef=[AI95-00407-01]}
+  @ChgAdded{Version=[2],Text=[Defined the calling convention for anonymous
+  access-to-subprogram types and for prefixed views of subprograms (see
+  @RefSecNum{Selected Components}).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],Text=[Defined the conformance of access result types
+  (see @RefSecNum{Subprogram Declarations}).]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00345-01],ARef=[AI95-00397-01]}
+  @ChgAdded{Version=[2],Text=[Defined the prefixed view profile of subprograms
+  for later use.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00409-01]}
+  @ChgAdded{Version=[2],Text=[Defined the conformance of anonymous
+  access-to-subprogram parameters.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0046-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:> 
Now require
+  @nt{null_exclusion}s to match for full conformance. While this is
+  technically incompatible with Ada 2005 as defined by Amendment 1,
+  it is a new Ada 2005 feature and it is unlikely that users have
+  been intentionally taking advantage of the ability to write mismatching
+  exclusions. In any case, it is easy to fix: add a @nt{null_exclusion}
+  where needed for conformance.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0134-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Now require
+  full conformance of anonymous access-to-subprogram parameters and results
+  for full conformance. This is necessary so that there is no confusion about
+  the default expression that is used for a call. While this is technically
+  incompatible with Ada 2005 as defined by Amendment 1, it is a new Ada 2005
+  feature and it is unlikely that users have been intentionally taking 
advantage
+  and writing different default expressions. In any case, it is
+  easy to fix: change any default expressions that don't conform so that they
+  do conform.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0207-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Now include
+  the presence or absence of @key[constant] in access parameters to be
+  considered when checking mode conformance. This is necessary to prevent
+  modification of constants. While this is technically incompatible with
+  Ada 2005 as defined by Amendment 1, it is a new Ada 2005 feature and it
+  is unlikely that users have been intentionally taking advantage and writing
+  mismatching access types.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0142-4]}
+  @ChgAdded{Version=[3],Text=[Explicitly aliased parameters are included
+  as part of mode conformance (since it affects the parameter passing
+  mechanism).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0107-1],ARef=[AI05-0159-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada address@hidden<Corrigendum:>
+  We now define that a prefixed view of a subprogram with synchronization
+  kind By_Protected_Procedure can be used as the prefix of 'Access for an
+  access-to-protected type. We consider this a correction as it certainly
+  appears that it ought to work, but in original Ada 2012 it would have had
+  a convention mismatch.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0050-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> We now define how two
+  expressions containing quantified expressions can fully conform. This
+  isn't incompatible, as the original Ada 2012 never allowed such expressions
+  to conform (the declarations in each formally being different). Neither is
+  it an extension as one would expect these to conform.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Expansion of Subprograms}
+
address@hidden
address@hidden may be expanded in line at the call site.]
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 2
+through 4 were moved to @RefSec{Obsolescent Features}.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],KeepNext=[T],address@hidden unit pragma], 
Sec=(Inline)}
address@hidden, program unit], Sec=(Inline)}
+The form of a @nt{pragma} Inline,
+which is a program unit pragma (see @RefSecNum{Pragmas and Program Units}),
+is as follows:]}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,InitialVersion=[0],@ChgDeleted{Version=[3],
address@hidden @prag(Inline)(@Syn2{name} {, @Syn2{name}});]}}
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Text=[The @nt{pragma} shall apply to one or more
+callable entities or generic subprograms.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],address@hidden leading}
address@hidden,New=[For],Old=[If a @nt{pragma} Inline applies to]}
+a callable address@hidden,New=[ or],Old=[,
+this indicates that inline expansion is desired for all calls
+to that entity.
+If a @nt{pragma} Inline applies to]} a generic subprogram,
address@hidden,New=[the following language-defined
+representation aspect may be specified:],Old=[this indicates that
+inline expansion is desired for all calls to all instances of that
+generic subprogram.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden type of aspect Inline is Boolean. When
+aspect Inline is True for a callable entity, inline expansion is desired for 
all
+calls to that entity. When aspect Inline is True for a generic subprogram,
+inline expansion is desired for all calls to all instances of that generic
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,NoPrefix=[T],Text=[If directly specified, the
address@hidden shall be a static expression.
address@hidden aspect is never inherited;] if not directly specified,
+the aspect is False.]}
+
address@hidden,Kind=[AddedNormal],Aspect=[Inline],
+  address@hidden,Text=[For efficiency, Inline calls are requested
+    for a subprogram.]}]}
+
address@hidden
+
+
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[Note that inline expansion is
+desired no matter what name is used in the call. This allows one to request
+inlining for only one of several overloaded subprograms as follows:]}
address@hidden
address@hidden,Kind=[Deleted]}
address@hidden,address@hidden IO @key[is]
+   @key[procedure] Put(X : @key[in] Integer);
+   @key[procedure] Put(X : @key[in] String);
+   @key[procedure] Put(X : @key[in] Character);
address@hidden
+   @key[procedure] Character_Put(X : @key[in] Character) @key[renames] Put;
+   @key[pragma] Inline(Character_Put);
address@hidden IO;]}
+
address@hidden,Kind=[Deleted]}
address@hidden,address@hidden IO; @key[use] IO;
address@hidden Main @key[is]
+   I : Integer;
+   C : Character;
address@hidden
+   ...
+   Put(C); address@hidden Inline expansion is desired.}
+   Put(I); address@hidden Inline expansion is NOT desired.}
address@hidden Main;]}
address@hidden
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The meaning of a subprogram can be changed by @Chg{Version=[3],New=[inline
+expansion as requested by aspect],Old=[a @nt{pragma}]} Inline only
+in the presence of failing checks
+(see @RefSecNum{Exceptions and Optimization}).
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+For each call,
+an implementation is free to follow or to ignore the recommendation
address@hidden,New=[determined],Old=[expressed]} by the
address@hidden,New=[Inline aspect],address@hidden
address@hidden
+Note, in particular, that the recommendation
+cannot always be followed for a recursive call,
+and is often infeasible for entries.
+Note also that the implementation can inline calls even
+when no such desire was expressed @Chg{Version=[3],New=[via the
+Inline aspect],Old=[by a pragma]},
+so long as the semantics of the program remains unchanged.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00309-01]}
address@hidden,Kind=[DeletedAddedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[An implementation may allow
+a @nt{pragma} Inline that has an argument which is a @nt{direct_name} denoting 
a
address@hidden of the same @nt{declarative_part}.],Old=[]}]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden,New=[],Old=[This is allowed for
+Ada 83 compatibility. This is only a permission as this usage is considered
+obsolescent.]}]}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden,New=[],Old=[We only need to allow
+this in @nt{declarative_part}s, because a body is only allowed in another body,
+and these all have @nt{declarative_part}s.]}]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Text=[The @nt{name} in a @nt{pragma} Inline can denote
+more than one entity in the case of overloading.
+Such a @nt{pragma} applies to all of the denoted entities.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00309-01]}
+  @ChgRef{Version=[3],Kind=[Deleted],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[2],address@hidden,New=[],address@hidden with Ada 83}
+  A pragma Inline cannot refer to a @nt{subprogram_body} outside of that
+  body. The pragma can be given inside of the subprogram body. Ada 2005
+  adds an @ImplPermName to allow this usage for compatibility (and
+  Ada 95 implementations also can use this permission), but
+  implementations do not have to allow such @nt{pragma}s.]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Deleted],ARef=[AI05-0229-1]}
+  @ChgDeleted{Version=[3],address@hidden to Ada 83}
+  A @nt{pragma} Inline is allowed inside a @nt{subprogram_body} if there
+  is no corresponding @nt{subprogram_declaration}.
+  This is for uniformity with other program unit pragmas.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00309-01]}
+  @ChgRef{Version=[3],Kind=[Deleted],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[2],address@hidden,New=[],address@hidden to Ada 95}
+  @b[Amendment Correction:] Implementations are allowed to let @nt{Pragma}
+  Inline apply to a @nt{subprogram_body}.]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Aspect Inline is new; @nt{pragma} Inline is now obsolescent.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden Calls}
+
address@hidden
address@hidden call}
+A @i{subprogram call} is either a @nt{procedure_call_statement}
+or a @nt{function_call};
address@hidden invokes the execution of the @nt{subprogram_body}.
+The call specifies the association of the actual parameters, if any,
+with formal parameters of the subprogram.]
address@hidden
+
address@hidden
address@hidden<procedure_call_statement>,rhs="
+    @address@hidden;
+  | @address@hidden @Syn2{actual_parameter_part};"}
+
+
address@hidden<function_call>,rhs="
+    @address@hidden
+  | @address@hidden @Syn2{actual_parameter_part}"}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,Text=[For the purpose of non-syntax rules,
+infix operator calls are considered @nt{function_call}s.
+See @RefSecNum{Overloading of Operators}.]}
address@hidden
+
address@hidden<actual_parameter_part>,rhs="
+    (@Syn2{parameter_association} {, @Syn2{parameter_association}})"}
+
address@hidden<parameter_association>,rhs="
+   address@hidden@Syn2{selector_name} =>] @Syn2{explicit_actual_parameter}"}
+
address@hidden<explicit_actual_parameter>,rhs="@Syn2{expression} | 
@address@hidden"}
+
address@hidden
address@hidden association}
address@hidden association}
+A @nt{parameter_association} is @i{named} or @i{positional}
+according to whether or not the
address@hidden@address@hidden@address@hidden is specified.
+Any positional associations shall precede any named associations.
+Named associations are not allowed if the @nt{prefix} in
+a subprogram call is an @address@hidden
address@hidden
+This means that the formal parameter names used in
+describing predefined attributes are
+to aid presentation of their semantics, but are not intended
+for use in actual calls.
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00310-01]}
+The @nt{name} or @nt{prefix} given in a @nt{procedure_call_statement}
+shall resolve to denote
+a callable entity that is a procedure, or an entry renamed
+as (viewed as) a procedure.
+The @nt{name} or @nt{prefix} given in a @nt{function_call}
+shall resolve to denote
+a callable entity that is a
address@hidden,New=[ The @nt{name} or @nt{prefix} shall not
+resolve to denote an abstract subprogram unless it is also a
+dispatching subprogram.],Old=[]}
address@hidden there is an @nt<address@hidden@!part>, the @nt<prefix>
+can be an @nt<address@hidden> of an access-to-subprogram
+value.]
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00310-01]}
address@hidden,Text=[This rule is talking about dispatching operations
+(which is a static concept) and not about dispatching calls (which is a
+dynamic concept).]}
address@hidden
address@hidden
+The function can be an operator,
+enumeration literal, attribute that is a function, etc.
address@hidden
+
+A subprogram call shall contain at most one association for each
+formal parameter.
+Each formal parameter without an association shall have a
address@hidden (in the profile of the view denoted
+by the @nt<name> or @nt<prefix>).
address@hidden rule is an overloading rule
+(see @RefSecNum{The Context of Overload Resolution}).]
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0240-1]}
+  @ChgAdded{Version=[3],Text=[All @ResolutionTitle are overloading rules,
+  see @RefSecNum{The Context of Overload Resolution}.]}
address@hidden
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden, Sec=(subprogram call)}
+For the execution of a subprogram call,
+the @nt{name} or @nt{prefix} of the call is evaluated,
+and each @address@hidden is evaluated
+(see @RefSecNum{Parameter Associations}).
+If a @address@hidden is used,
+an implicit @address@hidden is assumed for this rule.
+These evaluations are done in an arbitrary order.
+The @address@hidden is then address@hidden,New=[, or a call
+on an entry or protected subprogram is performed (see
address@hidden Operations of Tagged Types})],Old=[]}.
+Finally, if the subprogram completes normally, then after it is left,
+any necessary assigning back of formal to actual parameters occurs
+(see @RefSecNum{Parameter Associations})address@hidden order],Sec=[allowed]}
+
address@hidden
+  The implicit association for a default is only for this run-time rule.
+  At compile time, the visibility rules are applied to the default at
+  the place where it occurs, not at the place of a call.
address@hidden
address@hidden
+  If the subprogram is inherited, see @RefSec{Derived Types and Classes}.
+
+  If the subprogram is protected, see @RefSec{Protected Subprograms and 
Protected Actions}.
+
+  If the subprogram is really a renaming of an entry, see @RefSec{Entry Calls}.
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00345-01]}
+  @ChgAdded{Version=[2],Text=[If the subprogram is implemented by an entry or
+  protected subprogram, it will be treated as a dispatching call to the
+  corresponding entry (see @RefSec{Entry Calls}) or protected subprogram (see
+  @RefSec{Protected Subprograms and Protected Actions}).]}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00348-01]}
+  Normally, the @nt{subprogram_body} that is executed by the above rule
+  is the one for the subprogram being called.
+  For an enumeration literal,
+  implicitly declared (but noninherited) subprogram,
+  @Chg{Version=[2],New=[null procedure, ],Old=[]}or an attribute that is
+  a subprogram, an implicit body is assumed.
+  For a dispatching call,
+  @RefSec{Dispatching Operations of Tagged Types}
+  defines which @nt{subprogram_body} is executed.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00407-01]}
address@hidden,Text=[If the @nt{name} or @nt{prefix} of a subprogram
+call denotes a prefixed view (see @RefSecNum{Selected Components}), the
+subprogram call is equivalent to a call on the underlying subprogram, with the
+first actual parameter being provided by the @nt{prefix} of the prefixed view
+(or the Access attribute of this @nt{prefix} if the first formal parameter is
+an access parameter), and the remaining actual parameters given by the
address@hidden, if any.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden,Sec=(raised by failure of run-time check)}
+The exception Program_Error is raised at the point of a
address@hidden if the function
+completes normally without executing a
address@hidden,New=[return statement],address@hidden@!statement}]}.
address@hidden
+We are committing to raising the exception at the point
+of call, for uniformity @em see AI83-00152.
+This happens after the function is left, of course.
+
+Note that there is no name for suppressing this check,
+since the check imposes no time overhead and minimal
+space overhead (since it can usually be statically eliminated
+as dead code).
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01]}
+A @nt{function_call} denotes a constant, as defined in
address@hidden Statements}; the nominal subtype of the constant is
+given by the @Chg{Version=[2],New=[nominal],Old=[result]} subtype of the
address@hidden,New=[ result],Old=[]}.
address@hidden subtype], Sec=(of the result of a @nt<function_call>)}
address@hidden, Sec=(result of a @nt<function_call>)}
address@hidden
+
address@hidden
address@hidden@address@hidden of procedure calls:}
address@hidden
+Traverse_Tree;                                               address@hidden  
see @RefSecNum{Subprogram Declarations}}
+Print_Header(128, Title, True);                              address@hidden  
see @RefSecNum{Subprogram Declarations}}
+
+Switch(From => X, To => Next);                               address@hidden  
see @RefSecNum{Subprogram Declarations}}
+Print_Header(128, Header => Title, Center => True);          address@hidden  
see @RefSecNum{Subprogram Declarations}}
+Print_Header(Header => Title, Center => True, Pages => 128); address@hidden  
see @RefSecNum{Subprogram Declarations}}
address@hidden
+
address@hidden
address@hidden@address@hidden of function calls:}
address@hidden
address@hidden
+Dot_Product(U, V)   address@hidden  see @RefSecNum{Subprogram Declarations} 
and @RefSecNum{Subprogram Bodies}}
+Clock               address@hidden  see @RefSecNum{Delay Statements, Duration, 
and Time}}
address@hidden               address@hidden  presuming F is of an 
access-to-subprogram type @em see @RefSecNum{Access Types}}
address@hidden
+
address@hidden
address@hidden@address@hidden of procedures with default expressions:}
address@hidden
address@hidden
address@hidden Activate(Process : @key[in] Process_Name;
+                   After   : @key[in] Process_Name := No_Process;
+                   Wait    : @key[in] Duration := 0.0;
+                   Prior   : @key[in] Boolean := False);
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden Pair(Left, Right : @key[in] Person_Name := @key[new] 
address@hidden,New=[(M)],Old=[]});   address@hidden  see @RefSecNum{Incomplete 
Type Declarations}}
address@hidden
+
address@hidden
address@hidden@address@hidden of their calls:}
address@hidden
address@hidden
+Activate(X);
+Activate(X, After => Y);
+Activate(X, Wait => 60.0, Prior => True);
+Activate(X, Y, 10.0, False);
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Pair;
+Pair(Left => @key[new] address@hidden,New=[(F)],Old=[]}, Right => @key[new] 
address@hidden,New=[(M)],Old=[]});
address@hidden
address@hidden
+
address@hidden
+If a @nt{default_expression} is used for two or more parameters in a
+multiple @address@hidden, the @address@hidden is
+evaluated once for each omitted parameter. Hence in the above
+examples, the two calls of Pair are equivalent.
address@hidden
+
address@hidden
address@hidden@address@hidden of overloaded subprograms:}
address@hidden
address@hidden Put(X : @key[in] Integer);
address@hidden Put(X : @key[in] String);
+
address@hidden Set(Tint   : @key[in] Color);
address@hidden Set(Signal : @key[in] Light);
address@hidden
+
address@hidden
address@hidden@address@hidden of their calls:}
address@hidden
address@hidden
+Put(28);
+Put("no possible ambiguity here");
+
+Set(Tint   => Red);
+Set(Signal => Red);
+Set(Color'(Red));
+
address@hidden  Set(Red) would be ambiguous since Red may}
address@hidden  denote a value either of type Color or of type Light}
address@hidden
address@hidden
+
address@hidden
+We have gotten rid of parameters @lquotes@;of the form of a type 
address@hidden@;
+(see RM83-6.4.1(3)).
+The new view semantics of @nt{type_conversion}s allows us to use
+normal @nt{type_conversion}s instead.
+
+We have moved wording about run-time semantics of parameter associations
+to @RefSecNum{Parameter Associations}.
+
+We have moved wording about raising Program_Error for a function
+that falls off the end to here from RM83-6.5.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00310-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Nondispatching abstract operations are no longer considered when
+  resolving a subprogram call. That makes it possible to use @key{abstract}
+  to @lquotes@;address@hidden@; a predefined operation for an untagged type.
+  That's especially helpful when defining custom arithmetic packages.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],Text=[Changed the definition of the nominal subtype
+  of a @nt{function_call} to use the nominal subtype wording of
+  @RefSecNum{Subprogram Declarations}, to take into account
+  @nt{null_exclusion}s and access result types.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00345-01]}
+  @ChgAdded{Version=[2],Text=[Added wording to clarify that the meaning of
+  a call on a subprogram @lquotes@;implemented address@hidden an entry or
+  protected operation is defined by
+  @RefSecNum{Dispatching Operations of Tagged Types}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00407-01]}
+  @ChgAdded{Version=[2],Text=[Defined the meaning of a call on a prefixed
+  view of a subprogram (see @RefSecNum{Selected Components}).]}
address@hidden
+
+
address@hidden Associations}
+
address@hidden
address@hidden@Defn{parameter passing}
+A parameter association defines the association between an
+actual parameter and a formal parameter.]
address@hidden
+
address@hidden
+The parameter passing rules for @b(out) parameters
+are designed to ensure that the parts of a type that have
+implicit initial values (see @RefSecNum{Object Declarations})
+don't become @lquotes@;address@hidden@; by
+being passed as an @b(out) parameter.
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0142-4]}
address@hidden,Text=[For explicitly aliased parameters of functions, we
+will ensure at the call site that a part of the parameter can be returned as
+part of the function result without creating a dangling pointer. We do this 
with
+accessibility checks at the call site that all actual objects of explicitly
+aliased parameters live at least as long as the function result; then we can
+allow them to be returned as access discriminants or anonymous access results,
+as those have the master of the function result.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0118-1]}
+The @address@hidden of
address@hidden,New=[ named],Old=[]}
address@hidden@!association} shall resolve to denote a
address@hidden@!specification} of the view being address@hidden,New=[;
address@hidden address@hidden address@hidden parameter address@hidden parameter 
association}this
+is the formal parameter of the association. The formal parameter for a
+positional @address@hidden is the parameter with the corresponding
+position in the formal part of the view being called],Old=[]}.
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0118-1]}
+  @ChgAdded{Version=[3],Text=[For positional parameters, the
+  @ldquote@;corresponding address@hidden is calculated after any
+  transformation of prefixed views.]}
address@hidden
+
address@hidden parameter], Sec=(for a formal parameter)}
+The @i(actual parameter) is either the @nt<explicit_actual_parameter>
+given in a @nt<parameter_association> for a given
+formal parameter, or the corresponding @nt<default_expression>
+if no @nt<parameter_association> is given for the formal parameter.
address@hidden type], Sec=(actual parameter)}
+The expected type for an actual parameter is the
+type of the corresponding formal parameter.
address@hidden
+  The corresponding @nt<default_expression> is the one of the
+  corresponding formal parameter
+  in the profile of the view denoted by the @nt<name> or
+  @nt<prefix> of the call.
address@hidden
+
+If the mode is @key(in),
+the actual is interpreted as an @nt{expression};
+otherwise, the actual is interpreted only as a @nt{name}, if possible.
address@hidden
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0005-1]}
+  This formally resolves the ambiguity present in the syntax rule
+  for @nt<explicit_actual_parameter>.
+  @Chg{Version=[4],New=[This matters as an @nt{expression} that is a
+  @nt{name} is evaluated and represents a value while a @nt{name} by itself
+  can be an object; if the mode is not @key[in], we want the parameter to
+  interpreted as an object.],Old=[]} Note that we don't actually require
+  that the actual be a @nt<name> if the mode is not @key(in);
+  we do that below.
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[4],Text=[This wording uses "interpreted as" rather than
+  "shall be" so that this rule is not used to resolve overloading; it is
+  solely about evaluation as described above. We definitely do not want
+  to allow oddities like the presence of parentheses requiring the selection of
+  an @key[in] formal parameter as opposed to an otherwise matching @key[in out]
+  parameter.]}
address@hidden
address@hidden
+
address@hidden
+If the mode is @key(in out) or @key(out),
+the actual shall be a @nt<name> that denotes a variable.
address@hidden
+  We no longer need @lquotes@;or a
+  @nt{type_conversion} whose argument is the @nt{name} of a variable,@rquotes@;
+  because a @nt{type_conversion} is now a @nt{name}, and a
+  @nt{type_conversion} of a variable is a variable.
address@hidden
address@hidden
+  @leading@;The requirement that the actual be a (variable) @nt<name> is not
+  an overload resolution rule, since
+  we don't want the difference between @nt<expression> and
+  @nt{name} to be used to resolve overloading.
+  For example:
+  @begin{Example}
+procedure Print(X : @key[in] Integer; Y : @key[in] Boolean := True);
+procedure Print(Z : @key[in out] Integer);
+. . .
+Print(3); address@hidden Ambiguous!}
+  @end{Example}
+
+  The above call to Print is ambiguous even though the call is
+  not compatible with the second Print which requires an actual
+  that is a (variable) @nt<name> (@lquotes@;address@hidden@; is an 
@nt<expression>, not
+  a @nt<name>). This requirement is a legality rule, so overload
+  resolution fails before it is considered, meaning that the call
+  is ambiguous.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0074-1],ARef=[AI12-0159-1]}
address@hidden,Text=[If the mode is @key[out], the actual parameter is a
+view conversion, and the type of the formal parameter is an access type or
+a scalar type that has the Default_Value aspect specified, then]}
+  @begin{Itemize}
+    @ChgRef{Version=[4],Kind=[Added]}
+    @ChgAdded{Version=[4],Text=[there shall exist a type (other than a root
+      numeric type) that is an ancestor of both the target type and the operand
+      type; and]}
+
+    @ChgRef{Version=[4],Kind=[Added]}
+    @ChgAdded{Version=[4],Text=[in the case of a scalar type, the type of the
+      operand of the conversion shall have the Default_Value aspect 
specified.]}
+  @end{Itemize}
+
address@hidden,Kind=[Added],ARef=[AI12-0074-1],ARef=[AI12-0159-1]}
address@hidden,address@hidden contract issue}
+In addition to the places where
address@hidden normally apply (see @RefSecNum{Generic Instantiation}),
+these rules also apply in the private part of an instance of a generic unit.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[These rules are needed in order to ensure that a
+    well-defined parameter value is passed.]}
address@hidden
+
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0102-1],ARef=[AI05-0142-4]}
address@hidden@;@Chg{Version=[3],New=[If the formal parameter is an explicitly 
aliased
+parameter, the type of the actual parameter shall be tagged or the actual
+parameter shall be an aliased view of an object. Further, if the formal
+parameter subtype @i{F} is untagged:],
+Old=[The type of the actual parameter associated with an access parameter
+shall be convertible (see @RefSecNum{Type Conversions})
+to its anonymous access type.
address@hidden,Sec=(required)}]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[the subtype @i{F} shall statically match the nominal
+subtype of the actual object; or]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[the subtype @i{F} shall be unconstrained, discriminated
+in its full view, and unconstrained in any partial view.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Tagged objects (and tagged @nt{aggregate}s for 
@key[in]
+  parameters) do not need to be aliased. This matches the behavior of unaliased
+  formal parameters of tagged types, which allow 'Access to be taken of the
+  formal parameter regardless of the form of the actual parameter.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We need the subtype check on untagged actual
+  parameters so that the requirements of 'Access are not lost. 'Access makes 
its
+  checks against the nominal subtype of its prefix, and parameter passing can
+  change that subtype. But we don't want this parameter passing to change the
+  objects that would be allowed as the prefix of 'Access. This is particularly
+  important for arrays, where we don't want to require any additional
+  implementation burden.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0095-1]}
+  @ChgAdded{Version=[4],Text=[We assume the worst in a generic body whether
+  or not a formal subtype has a constrained partial view; specifically, in a
+  generic body a discriminated subtype is considered to have a constrained
+  partial view if it is a descendant of an untagged generic formal private
+  or derived type (see @RefSecNum{Formal Private and Derived Types} for the
+  formal definition of this rule).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0095-1]}
address@hidden,address@hidden contract issue}
+In addition to the places where
address@hidden normally apply (see @RefSecNum{Generic Instantiation}),
+these rules also apply in the private part of an instance of a generic unit.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0142-4],ARef=[AI05-0234-1]}
address@hidden,Text=[In a function call, the accessibility level of the
+actual object for each explicitly aliased parameter shall not be statically
+deeper than the accessibility level of the master of the call
+(see @RefSecNum{Operations of Access Types}).]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Since explicitly aliased parameters are either
+  tagged or required to be objects, there is always an object (possibly
+  anonymous) to talk about. This is discussing the static accessibility level 
of
+  the actual object; it does not depend on any runtime information (for 
instance
+  when the actual object is a formal parameter of another subprogram, it does
+  not depend on the actual parameter of that other subprogram).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0095-1]}
+  @ChgAdded{Version=[3],Text=[This accessibility check (and its dynamic cousin
+  as well) can only fail if the @Chg{Version=[4],New=[master of the function
+  call (which is defined in the Heart of Darkness, or
+  @RefSecNum{Operations of Access Types} if you prefer) is different than
+  the master directly enclosing the call],Old=[function call is used to 
directly initialize a
+  built-in-place object with a master different than that enclosing the call]}.
+  The @Chg{Version=[4],New=[most likely],Old=[only]} place
+  @Chg{Version=[4],New=[where this will occur],Old=[all of those conditions
+  exist]} is in the initializer of an @nt{allocator}; in
+  @Chg{Version=[4],New=[almost ],Old=[]}all other cases this check will always
+  pass.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0144-2]}
address@hidden,Type=[Leading],Text=[Two @nt{name}s are
address@hidden to denote the same object} if:@Defn{known to denote the same 
object}]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[both @nt{name}s statically denote the same
+stand-alone object or parameter; or]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[both @nt{name}s are @nt{selected_component}s,
+their @nt{prefix}es are known to denote the same object, and their
address@hidden denote the same component; or]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[both @nt{name}s are dereferences (implicit or
+explicit) and the dereferenced @nt{name}s are known to denote the same object;
+or]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[both @nt{name}s are @nt{indexed_component}s, their
address@hidden are known to denote the same object, and each of the pairs of
+corresponding index values are either both static expressions with the same
+static value or both @nt{name}s that are known to denote the same object; or]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[both @nt{name}s are @nt{slice}s, their
address@hidden are known to denote the same object, and the two @nt{slice}s have
+statically matching index constraints; or]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[one of the two @nt{name}s statically denotes a
+renaming declaration whose renamed @address@hidden is known to denote
+the same object as the other, the @nt{prefix} of any dereference within
+the renamed @address@hidden is not a variable, and any @nt{expression}
+within the renamed @address@hidden contains no references to variables
+nor calls on nonstatic functions.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[This exposes known renamings of
+  slices, indexing, and so on to this definition. In particular, if we have]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[C : Character @key[renames] S(1);]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[then C and S(1) are known to
+  denote the same object.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[We need the requirement that no
+  variables occur in the @nt{prefix}es of dereferences and in (index)
+  @nt{expression}s of the renamed object in order to avoid problems from later
+  changes to those parts of renamed names. Consider:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[   @key[type] Ref @key[is access] Some_Type;
+   Ptr : Ref := @key[new] Some_Type'(...);
+   X : Some_Type @key[renames] address@hidden;
address@hidden
+   Ptr := @key[new] Some_Type'(...);
+   P (Func_With_Out_Params (address@hidden), X);]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[X and address@hidden should not 
be
+  known to denote the same object, since they denote different allocated 
objects
+  (and this is not an unreasonable thing to do).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The exclusion of variables from
+  renamed object_names is not enough to prevent altering the value of the name
+  or expression by another access path. For instance, both @key[in] parameters
+  passed by reference and access-to-constant values can designate variables. 
For
+  the intended use of "known to be the same object", this is OK; the
+  modification via another access path is very tricky and it is OK to reject
+  code that would be buggy except for the tricky code. Assuming Element is an
+  elementary type, consider the following example:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Global : Tagged_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Foo (Param : @key{in} Tagged_Type := Global) 
@key{is}
+   X : Element @key{renames} Some_Global_Array (Param.C);
address@hidden
+   Global.C := Global.C + 1;
+   Swap (X, Some_Global_Array (Param.C));]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The rules will flag the call of procedure Swap
+  as illegal, since X and Some_Global_Array (Parameter.C) are known to denote
+  the same object (even though they will actually represent different objects 
if
+  Param = Global). But this is only incorrect if the parameter actually is
+  Global and not some other value; the error could exist for some calls. So 
this
+  flagging seems harmless.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Similar examples can be constructed using
+  stand-alone composite constants with controlled or immutably limited
+  components, and (as previously noted) with dereferences of access-to-constant
+  values. Even when these examples flag a call incorrectly, that call depends
+  on very tricky code (modifying the value of a constant); the code is likely
+  to confuse future maintainers as well and thus we do not mind rejecting it.]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Whether or not @nt{name}s or @nt{prefix}es are
+  known to denote the same object is determined statically. If the name
+  contains some dynamic portion other than a dereference, 
@nt{indexed_component}, or
+  @nt{slice}, it is not "known to denote the same object".]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[These rules make no attempt to handle slices of
+  objects that are known to be the same when the slices have dynamic bounds
+  (other than the trivial case of bounds being defined by the same subtype),
+  even when the bounds could be proven to be the same, as it is just too 
complex
+  to get right and these rules are intended to be conservative.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=["Known to denote the same object"
+  is intended to be an equivalence relationship, that is, it is reflexive,
+  symmetric, and transitive. We believe this follows from the rules.
+  For instance, given the following declarations:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[S   : String(1..10);
+ONE : @key[constant] Natural := 1;
+R   : Character @key[renames] S(1);]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[the names R and S(1) are known to
+  denote the same object by the sixth bullet, and S(1) and S(ONE) are known to
+  denote the same object by the fourth bullet, so using the sixth bullet on
+   R and S(ONE), we simply have to test S(1) vs. S(ONE), which we already know
+  denote the same object.]}
address@hidden
+
+
address@hidden,Kind=[Added],ARef=[AI05-0144-2]}
address@hidden,Type=[Leading],Text=[Two @nt{name}s are @i{known to
+refer to the same object} if @Defn{known to refer to the same object}]}
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[The two @nt{name}s are known to denote the same 
object; or]}
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[One of the @nt{name}s is a 
@nt{selected_component},
+  @nt{indexed_component}, or @nt{slice} and its @nt{prefix} is known to refer
+  to the same object as the other @nt{name}; or]}
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[One of the two @nt{name}s statically denotes a
+  renaming declaration whose renamed @address@hidden is known to refer
+  to the same object as the other @nt{name}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This ensures that names Prefix.Comp and Prefix 
are
+  known to refer to the same object for the purposes of the rules below. This
+  intentionally does not include dereferences; we only want to worry about
+  accesses to the same object, and a dereference changes the object in 
question.
+  (There is nothing shared between an access value and the object it
+  designates.)]}
address@hidden
+
+
address@hidden,Kind=[Added],ARef=[AI05-0144-2]}
address@hidden,Type=[Leading],Text=[
+If a call @i<C> has two or more parameters of mode @key[in out] or @key[out] 
that
+are of an elementary type, then the call is legal only if:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[For each @nt{name} @i<N> that is passed as a parameter of 
mode @key[in out] or
address@hidden to the call @i<C>, there is no other @nt{name} among the other
+parameters of mode @key[in out] or @key[out] to @i<C> that is known to denote 
the
+same object.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This means @i{visibly} an elementary type; it 
does
+  not include partial views of elementary types (partial views are always
+  composite). That's necessary to avoid having @LegalityTitle depend on the
+  contents of the private part.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0144-2]}
address@hidden,Type=[Leading],Text=[If a construct @i<C> has two or more
+direct constituents that are @nt{name}s or @nt{expression}s whose evaluation 
may
+occur in an arbitrary order, at least one of which contains a function call 
with
+an @key[in out] or @key[out] parameter, then the construct is legal only if:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[All of the places where the language allows an
+  arbitrary order can be found by looking in the index under "arbitrary order,
+  allowed". Note that this listing includes places that don't involve
+  @nt{name}s or @nt{expression}s (such as checks or finalization).]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[For each name @i<N> that is passed as a parameter of mode 
@key[in out] or
address@hidden to some inner function call @i<C2> (not including the construct 
@i<C>
+itself), there is no other @nt{name} anywhere within a direct constituent of 
the
+construct @i<C> other than the one containing @i<C2>, that is known to refer to
+the same object.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This requirement cannot fail for a procedure
+  or entry call alone; there must be at least one function with an @key[in out]
+  or @key[out] parameter called as part of a parameter expression of the call 
in
+  order for it to fail.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[These rules prevent obvious cases of dependence 
on
+  the order of evaluation of @nt{name}s or @nt{expression}s. Such dependence is
+  usually a bug, and in any case, is not portable to another implementation (or
+  even another optimization setting).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[In the case that the top-level construct C is a
+  call, these rules do not require checks for most @key[in out] parameters, as
+  the rules about evaluation of calls prevent problems. Similarly, we do not
+  need checks for short circuit operations or other operations with a defined
+  order of evaluation. The rules about arbitrary order (see
+  @RefSecNum{Method of Description and Syntax Notation}) allow evaluating
+  parameters and writing parameters back in an arbitrary order, but not
+  interleaving of evaluating
+  parameters of one call with writing parameters back from another @em that
+  would not correspond to any allowed sequential order.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0144-2]}
address@hidden,Type=[Leading],Text=[For the purposes of checking this rule:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[For an array @nt{aggregate}, an @nt{expression}
+associated with a @nt{discrete_choice_list} that has two or more discrete
+choices, or that has a nonstatic range, is considered as two or more separate
+occurrences of the @nt{expression};]}
+
address@hidden,Kind=[Added]}
address@hidden,Type=[Leading],Text=[For a record @nt{aggregate}:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[The @nt{expression} of a
address@hidden is considered to occur once for each
+associated component; and]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The @nt{default_expression} for each
address@hidden
+with <> for which the associated component has a @nt{default_expression}
+is considered part of the @nt{aggregate};]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Text=[For a call, any @nt{default_expression} evaluated as
+part of the call is considered part of the call.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We do not check expressions that are evaluated 
only because
+  of a component initialized by default in an aggregate (via <>).]}
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden, Sec=(parameter_association)}
+For the evaluation of a @nt{parameter_association}:
address@hidden
+The actual parameter is first evaluated.
+
+For an access parameter,
+the @nt{access_definition} is elaborated,
+which creates the anonymous access type.
+
+For a parameter @Redundant[(of any mode)] that is passed by reference
+(see @RefSecNum{Formal Parameter Modes}),
+a view conversion of the actual parameter to the nominal subtype
+of the formal parameter is evaluated,
+and the formal parameter denotes that conversion.
address@hidden subtype conversion],Sec=(parameter passing)}
address@hidden
+We are always allowing sliding, even for address@hidden(in)] @key(out) 
by-reference
+parameters.
address@hidden
+
address@hidden operation], Sec=(during evaluation of a
address@hidden)}
+For an @key(in) or @key(in out) parameter that is passed
+by copy (see @RefSecNum{Formal Parameter Modes}),
+the formal parameter object is created,
+and the value of the actual parameter is converted to the
+nominal subtype of the formal parameter
+and assigned to the formal.
address@hidden subtype conversion],Sec=(parameter passing)}
address@hidden
+The conversion mentioned here is a value conversion.
address@hidden
+
address@hidden@keepnext@;For an @key(out) parameter that is passed by copy,
+the formal parameter object is created, and:
address@hidden(itemize)
address@hidden,Kind=[Revised],ARef=[AI05-0153-3],ARef=[AI05-0196-1]}
+  For an access type, the formal parameter is initialized
+  from the value of the actual, without @Chg{Version=[3],New=[checking that the
+  value satisfies any constraint, any predicate, or any exclusion of the null
+  value],Old=[a constraint check]};
address@hidden
+  This preserves the @MetaRulesName that an object of an access type
+  is always initialized with a @lquotes@;address@hidden@; value.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0153-3],ARef=[AI05-0228-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0074-1],ARef=[AI12-0159-1]}
address@hidden,Type=[Leading],address@hidden add conditional leading}
address@hidden,Text=[For a scalar type that has the Default_Value aspect
+specified, the formal parameter is initialized from the value of the actual,
+without checking that the value satisfies any constraint or any
address@hidden,New=[. Furthermore, if the actual
+parameter is a view conversion and either],Old=[;]}]}
+
+  @begin{Itemize}
+    @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0074-1]}
+    @ChgAdded{Version=[4],Text=[there exists no type (other than a root
+    numeric type) that is an ancestor of both the target type and the type
+    of the operand of the conversion; or]}
+
+    @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0074-1]}
+    @ChgAdded{Version=[4],Text=[the Default_Value aspect is unspecified for
+    the type of the operand of the conversion]}
+  @end{Itemize}
+
address@hidden,Kind=[Added],ARef=[AI12-0074-1]}
address@hidden,NoPrefix=[T],Text=[then Program_Error
+is raised;@Defn2{Term=[Program_Error],Sec=(raised by failure of run-time 
check)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This preserves the @MetaRulesName that all 
objects
+  of a type with an implicit initial value are initialized. This is important 
so
+  that a programmer can guarantee that all objects of a scalar type have a 
valid
+  value with a carefully chosen Default_Value.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This rule means that @b<out> parameters of a
+  subtype @i<T> with a specified Default_Value need to be large enough to
+  support any possible value of the base type of @i<T>. In contrast, a type 
that
+  does not have a Default_Value only need support the size of the subtype 
(since
+  no values are passed in).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[The Program_Error case can only occur in the
+  body of an instance of a generic unit. @LegalityTitle will catch all other
+  cases. Implementations that macro-expand generics
+  can always detect this case when the enclosing instance body is expanded.]}
address@hidden
+
+  For a composite type with discriminants or
+  that has implicit initial values for any subcomponents
+  (see @RefSecNum{Object Declarations}),
+  the behavior is as for an @key[in out] parameter
+  passed by copy.
address@hidden
+  This ensures that no part of an object of such a type
+  can become @lquotes@;address@hidden@; by being part of an @b(out)
+  parameter.
address@hidden
address@hidden
+  This includes an array type whose component type is an access type,
+  and a record type with a component that has a @nt{default_expression},
+  among other things.
address@hidden
+
+  For any other type, the formal parameter is uninitialized.
+  If composite, a view conversion of the actual
+  parameter to the nominal subtype of the formal is evaluated
+  @Redundant[(which might raise Constraint_Error)],
+  and the actual subtype of the formal is that of the
+  view conversion. If elementary, the actual subtype of the formal
+  is given by its nominal subtype.
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0228-1]}
+  This case covers scalar address@hidden,New=[ that do not have
+  Default_Value specified],Old=[]}, and composite types whose
+  subcomponent's subtypes do not have any implicit initial values.
+  The view conversion for composite types ensures that if the lengths
+  don't match between an actual and a formal array parameter,
+  the Constraint_Error is raised before the call, rather than after.
address@hidden
address@hidden(itemize)
+
address@hidden,Kind=[Added],ARef=[AI05-0142-4],ARef=[AI05-0234-1]}
address@hidden,Text=[In a function call, for each explicitly aliased
+parameter, a check is made that the accessibility level of the master of the
+actual object is not deeper than that of the  master of the call
+(see @RefSecNum{Operations of Access Types}).]}
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[If the actual object to a call @i<C> is a formal
+  parameter of some function call @i<F>, no dynamic check against the master of
+  the actual parameter of @i<F> is necessary. Any case which could fail the
+  dynamic check is already statically illegal (either at the call site of 
@i<F>,
+  or at the call site @i<C>). This is important, as it would require nasty
+  distributed overhead to accurately know the dynamic accessibility of a formal
+  parameter (all tagged and explicitly aliased parameters would have to carry
+  accessibility levels).]}
address@hidden
address@hidden
+
address@hidden,Sec=(object)}
address@hidden,Sec=(object)}
+A formal parameter of mode @key[in out] or @key[out] with
+discriminants is constrained if either its nominal subtype
+or the actual parameter is constrained.
+
address@hidden copy back}
address@hidden back of parameters}
address@hidden assigning back}
address@hidden back of parameters}
address@hidden operation], Sec=(during parameter copy back)}
+After normal completion and leaving of a subprogram, for each @key(in out)
+or @key(out) parameter that is passed by copy,
+the value of the formal parameter is converted to
+the subtype of the variable given as the actual parameter
+and assigned to it.
address@hidden subtype conversion],Sec=(parameter passing)}
+These conversions and assignments occur in an arbitrary
address@hidden order],Sec=[allowed]}
address@hidden
+The conversions mentioned above during parameter passing might raise
+Constraint_Error @em (see @RefSecNum{Type Conversions}).
address@hidden
address@hidden
+If any conversion or assignment as part of parameter passing
+propagates an exception, the exception is raised at the place
+of the subprogram call;
+that is, it cannot be handled inside the @nt{subprogram_body}.
address@hidden
address@hidden
+Since these checks happen before or after executing the
address@hidden, the execution of the @nt{subprogram_body} does
+not dynamically enclose them, so it can't handle the exceptions.
address@hidden
address@hidden
+The variable we're talking about is the one denoted by the
address@hidden@nt{name} given as the @nt{explicit_actual_parameter}.
+If this @address@hidden is a @nt{type_conversion},
+then the rules in @RefSecNum{Type Conversions} for assigning to a view
+conversion apply.
+That is, if X is of subtype S1, and the actual is S2(X),
+the above-mentioned conversion will convert to S2,
+and the one mentioned in @RefSecNum{Type Conversions} will convert to
+S1.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0008-1]}
address@hidden,address@hidden(erroneous execution),Sec=(cause)}If
+the nominal subtype of a formal parameter with discriminants is constrained or
+indefinite, and the parameter is passed by reference, then the execution of the
+call is erroneous if the value of any discriminant of the actual is changed
+while the formal parameter exists (that is, before leaving the corresponding
+callable construct).]}
address@hidden
+
address@hidden
address@hidden to Ada 83}
+In Ada 95, a program can rely on the fact that passing an object as
+an @key[out] parameter does not @lquotes@;address@hidden@; any parts of the
+object whose subtypes have implicit initial values.
+(This generalizes the RM83 rule that required copy-in for parts that
+were discriminants or of an access type.)
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+We have eliminated the subclause on Default Parameters,
+as it is subsumed by earlier @Chg{Version=[3],New=[],Old=[clauses and 
]}subclauses.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0196-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  @b<Correction:> Clarified that
+  @key[out] parameters of an access type are not checked for null exclusions
+  when they are passed in (which is similar to the behavior for constraints).
+  This was unspecified in Ada 2005, so a program which depends on the
+  behavior of an implementation which does check the exclusion may
+  malfunction. But a program depending on an exception being raised is 
unlikely.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0144-2]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  Additional rules have been added to make illegal passing the same elementary
+  object to more than one @key[in out] or @key[out] parameters of the same
+  call. In this case, the result in the object could depend on the compiler
+  version, optimization settings, and potentially the phase of the moon, so
+  this check will mostly reject programs that are nonportable and could
+  fail with any change. Even when the result is expected to be the same in both
+  parameters, the code is unnecessarily tricky. Programs which fail this
+  new check should be rare and are easily fixed by adding a temporary object.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0008-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> A missing rule was
+  added to cover cases that were missed in Ada 95 and Ada 2005; specifically,
+  that an @key[in] parameter passed by reference might have its discriminants
+  changed via another path. Such cases are erroneous as requiring compilers
+  to detect such errors would be expensive, and requiring such cases to
+  work would be a major change of the user model (@key[in] parameters
+  with discriminants could no longer be assumed constant). This is not
+  an inconsistency, as compilers are not required to change any current
+  behavior.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0102-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Moved implicit conversion
+  @LegalityName to @RefSecNum{The Context of Overload Resolution}.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0118-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a definition for
+  positional parameters, as this is missing from Ada 95 and later.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0142-4]}
+  @ChgAdded{Version=[3],Text=[Rules have been added defining the legality
+  and dynamic checks needed for explicitly aliased parameters (see
+  @RefSecNum{Subprogram Declarations}).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0144-2]}
+  @ChgAdded{Version=[3],Text=[Additional rules have been added such
+  that passing an object to an @key[in out]
+  or @key[out] parameter of a function is illegal if it is used elsewhere in a
+  construct which allows evaluation in an arbitrary order. Such calls are
+  not portable (since the results may depend on the evaluation order), and
+  the results could even vary because of optimization settings and the like.
+  Thus they've been banned.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0074-1],ARef=[AI12-0159-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Added rules to ensure that the value passed into a @key[out] parameter
+  for elementary types is well-defined in the case of a view conversion.
+  The new rules can be incompatible. For a view conversion to an unrelated type
+  with the Default_Value aspect specified, the aspect is new in Ada 2012 so it
+  should be unlikely to occur in existing code. For a view conversion to an
+  unrelated access type, the incompatibility is possible as this could be
+  written in Ada 95, but such a view conversion is thought to be rare. In both
+  cases, declaring and passing a temporary rather than a view conversion
+  will eliminate the problem.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0095-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Because of a rule added in
+  @RefSecNum{Formal Private and Derived Types}, the checks for the
+  passing of an object to an explicitly aliased parameter in a generic body
+  were strengthened to use an assume the worst rule. This case is rather
+  unlikely as a formal private or derived type with discriminants is required
+  along with an explicitly aliased parameter whose type doesn't statically
+  match the formal type. Such a program is very unlikely, especially as
+  explicitly aliased parameters are a new Ada 2012 feature.]}
address@hidden
+
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Statements}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
+A @Chg{Version=[2],address@hidden@address@hidden or
address@hidden@address@hidden (collectively called a @i<return statement>)
address@hidden statement}],address@hidden is used to
+complete the execution of the
+innermost enclosing @address@hidden,
address@hidden@!body}, or @address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden<@Chg{Version=[2],New=[simple_return_statement],Old=[return_statement]}>,rhs="@key{return}
 address@hidden;"}
+
address@hidden,Kind=[Added],ARef=[AI05-0277-1]}
address@hidden,lhs=<@Chg{Version=[3],New=[extended_return_object_declaration],Old=[]}>,
+rhs="@Chg{Version=[3],New=<
+    @Syn2{defining_identifier} : address@hidden@key{constant}] 
@Syn2{return_subtype_indication} [:= @Syn2{expression}]>,Old=[]}"}
+
address@hidden,Kind=[Added],ARef=[AI95-00318-02]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0015-1],ARef=[AI05-0053-1],ARef=[AI05-0277-1],ARef=[AI05-0299-1]}
address@hidden,lhs=<@Chg{Version=[2],New=[extended_return_statement],Old=[]}>,
+rhs="@Chg{Version=[2],New=<
+    @key{return} 
@Chg{Version=[3],New=<@Syn2{extended_return_object_declaration}>,Old=<@Syn2{defining_identifier}
 : address@hidden,New=<@Key{constant}>,address@hidden 
@Syn2{return_subtype_indication} [:= @Syn2{expression}]>} address@hidden
+        @Syn2{handled_sequence_of_statements}
+    @key{end} @key{return}];>,Old=[]}"}
+
address@hidden,Kind=[Added],ARef=[AI95-00318-02]}
address@hidden,lhs=<@Chg{Version=[2],New=[return_subtype_indication],Old=[]}>,
+rhs="@Chg{Version=[2],New=<@Syn2{subtype_indication} | 
@Syn2{access_definition}>,Old=[]}"}
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden,address@hidden subtype], Sec=(of a function)}
+The @i<result subtype> of a function is the subtype denoted by the
address@hidden<subtype_mark>, or defined by the @nt<access_definition>, after 
the reserved
+word @key<return> in the profile of the address@hidden type],
+Sec=(@nt{expression} of @nt<address@hidden@!statement>)}],address@hidden 
expression}
+The @nt{expression}, if any, of a @nt{return_statement} is called the
address@hidden expression}.
address@hidden subtype], Sec=(of a function)}
+The @i(result subtype) of a function is the subtype denoted by the
address@hidden after the reserved word @key(return) in the profile
+of the address@hidden type], Sec=(return expression)}]}
+The expected type for @Chg{Version=[2],New=[the @nt{expression}, if any, of a
address@hidden@address@hidden,Old=[a return expression]} is the result type of
+the corresponding address@hidden,New=[
address@hidden type], Sec=(@nt{expression} of @nt{extended_return_statement})}
+The expected type for the
address@hidden of an @nt{extended_return_statement} is that of the
address@hidden@address@hidden,Old=[]}
address@hidden
+The same applies to generic functions.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden,address@hidden,
+Sec=(to a callable construct by a return statement)}],
address@hidden, Sec=(to a callable construct by a @nt{return_statement})}]}
+A @Chg{Version=[2],New=[return statement],address@hidden@!statement}]}
+shall be within a callable construct,
+and it @i{applies to} the innermost @Chg{Version=[2],New=[callable construct
+or @nt{extended_return_statement} that contains it],Old=[one]}.
+A @Chg{Version=[2],New=[return statement],address@hidden@!statement}]} shall
+not be within a body that is within the construct to which the
address@hidden,New=[return statement],address@hidden@!statement}]} applies.
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0089-1]}
+  @ChgAdded{Version=[4],Text=[The above also applies to generic subprograms,
+  even though they are not callable constructs. (An instance of a generic
+  subprogram is a callable construct, but not a generic subprogram itself.)]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0015-1]}
+A function body shall contain at least one
address@hidden,New=[return statement],address@hidden@!statement}]} that
+applies to the function body,
+unless the function contains @nt{code_statement}s.
+A @Chg{Version=[2],address@hidden@address@hidden,address@hidden@!statement}]} 
shall
+include @Chg{Version=[2],New=[an @nt{expression}],Old=[a return expression]}
+if and only if it applies to a function
address@hidden,New=[ An @nt<extended_return_statement> shall apply to
+a function body.],address@hidden,New=[ An @nt{extended_return_statement}
+with the reserved word @key[constant] shall include an 
@nt{expression}.],Old=[]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00318-02]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0022-1]}
+  The requirement that a function body has to have at least one
+  @Chg{Version=[2],New=[return statement],address@hidden@!statement}]}
+  is a @lquotes@;address@hidden@; restriction.
+  There @Chg{Version=[2],New=[has],Old=[was]} been some interest in lifting
+  this restriction, or allowing a raise statement to substitute for the
+  @Chg{Version=[2],New=[return statement],address@hidden@!statement}]}.
+  However, there was enough interest in leaving it as is
+  that we decided not to change address@hidden,New=[ Note that for
+  Ada 2012, Corrigendum 1, a return statement whose expression is a
+  @nt{raise_expression} can be given in @i<any> function body (the
+  @nt{raise_expression} will match any type), so there is
+  much less need to eliminate this rule.],Old=[]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],Text=[A return statement can apply to an
+  @nt{extended_return_statement}, so a @address@hidden@!statement} without
+  an @nt{expression} can be given in one. However, neither
+  @address@hidden@!statement} with an @nt{expression} nor an
+  @nt{extended_return_statement} can be given inside an
+  @nt{extended_return_statement}, as they must apply (directly) to a
+  function body.]}
+
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0089-1]}
+  @ChgAdded{Version=[4],Text=[Since a "function body" includes a generic
+  function body, this rule and all of the following @LegalityTitle apply
+  to generic function bodies as well as non-generic function bodies. This is
+  true even though a generic function is not a function.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00318-02]}
address@hidden,Type=[Leading],Text=[For an
address@hidden@address@hidden that applies to a function body:]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00318-02]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0032-1],ARef=[AI05-0103-1]}
address@hidden,Text=[If the result subtype of the function is defined by a
address@hidden, the @address@hidden@!indication} shall be a
address@hidden The type of the @nt{subtype_indication}
+shall address@hidden,New=[ covered by],Old=[]} the
+result type of the function. @Chg{Version=[3],New=[The],Old=[If the result
+subtype of the function is constrained, then the]} subtype defined by the
address@hidden shall @Chg{Version=[3],New=[be statically compatible
+with the result subtype of the function; if the result type of the
+function is elementary, the two subtypes],Old=[also
+be constrained and]} shall statically address@hidden,New=[],Old=[ this
+result address@hidden matching],Sec=(required)}
+If the result subtype of the function is @Chg{Version=[3],New=[indefinite],
+Old=[unconstrained]}, then the subtype
+defined by the @nt{subtype_indication} shall be a definite subtype, or there
+shall be an @nt{expression}.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00318-02]}
address@hidden,Text=[If the result subtype of the function is defined
+by an @nt{access_definition}, the @address@hidden@!indication} shall be an
address@hidden The subtype defined by the @nt{access_definition} shall
+statically match the result subtype of the function. @Redundant[The 
accessibility
+level of this anonymous access subtype is that of the result subtype.]]}
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0070-1]}
+  @ChgAdded{Version=[4],Text=[The accessibility of such anonymous access
+  types is defined in the Heart of Darkness (aka
+  @RefSecnum{Operations of Access Types}).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0032-1]}
address@hidden,Text=[If the result subtype of the function is class-wide,
+the accessibility level of the type of the subtype defined by the
address@hidden
+shall not be statically deeper than that of the master that elaborated
+the function body.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[In this case, the @nt{return_subtype_indication}
+  could be a specific type initialized by default; in that case there is no
+  @nt{expression} to check.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00318-02]}
address@hidden,Kind=[RevisedAdded],address@hidden number only change}
address@hidden,Type=[Leading],Text=[For any return statement
+that applies to a function body:]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00318-02]}
address@hidden,Kind=[RevisedAdded],address@hidden number only change}
address@hidden,address@hidden the result subtype of the function is limited,
+then the @nt{expression} of the return statement (if any) shall 
@Chg{Version=[3],
+New=[meet the restrictions described in @RefSecNum{Limited Types}],Old=[be an
address@hidden, a function call (or equivalent use of an operator), or a
address@hidden or parenthesized expression whose operand is one of
+these]}.]]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Deleted],ARef=[AI05-0188-1]}
+  @ChgDeleted{Version=[3],address@hidden,New=[In other words, if limited, the 
@nt{expression}
+  must produce a @lquotes@;address@hidden@; object, rather than being the name
+  of a preexisting object (which would imply copying).],Old=[]}]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00416-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0032-1],ARef=[AI05-0051-1]}
address@hidden,Text=[If the result subtype of the function is class-wide,
+the accessibility level of the type of the @nt{expression}
address@hidden,New=[(if any) ],Old=[]}of the return
+statement shall not be statically deeper than that of the master that
+elaborated the function address@hidden,New=[],Old=[ If the result subtype
+has one or more
+unconstrained access discriminants, the accessibility level of the anonymous
+access type of each access discriminant, as determined by the
address@hidden of the @address@hidden@!statement} or the
address@hidden@address@hidden, shall not be
+statically deeper than that of the master that elaborated the function 
body.]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0032-1],ARef=[AI05-0051-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[2],address@hidden,New=[If],Old=[We know that if]}
+  the result type is @Chg{Version=[4],New=[class-wide],Old=[class wide]},
+  then there must be an @nt{expression} of the
+  return address@hidden,New=[ unless this is
+  an @nt{extended_return_statement} whose @nt{return_subtype_indication} is
+  a specific type. We have a separate rule to cover that case. Note that
+  if an @nt{extended_return_statement} has an @nt{expression}, then both this
+  rule and the next one must be satisfied],Old=[. Similarly, if
+  the result subtype is unconstrained, then either the
+  @address@hidden@!indication} (if any) is constrained, or
+  there must be an @nt{expression}]}.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0051-1]}
address@hidden,Text=[If the subtype determined by the @nt{expression} of the
address@hidden or by the @nt{return_subtype_indication} has
+one or more access discriminants, the accessibility level of the anonymous
+access type of each access discriminant shall not be statically deeper than 
that
+of the master that elaborated the function body.]}
+
address@hidden
address@hidden,Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[We use the type used by the return statement
+  rather than from the function return type since we want to check whenever
+  the return object has access discriminants, even if the function return type
+  doesn't have any (mostly for a class-wide type).]}
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0277-1]}
address@hidden,Text=[If the keyword @key[aliased] is present in an
address@hidden,
+the type of the extended return object shall be immutably limited.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00318-02]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0015-1],ARef=[AI05-0144-2]}
address@hidden,address@hidden object], Sec=(extended_return_statement)}
+Within an @nt{extended_return_statement}, the @i{return object} is declared
+with the given @nt{defining_identifier}, with the nominal subtype defined by
+the @address@hidden@address@hidden,New=[ An
address@hidden with the reserved word @key[constant]
+is a full constant declaration that declares the return object to be a
+constant object.],Old=[]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00318-02],ARef=[AI95-00416-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0032-1]}
address@hidden,address@hidden, Sec=(extended_return_statement)}
+For the execution of an @nt{extended_return_statement}, the
address@hidden or @nt{access_definition} is elaborated. This creates
+the nominal subtype of the return object. If there is an @nt{expression}, it
+is evaluated and converted to the nominal subtype (which might raise
+Constraint_Error @em see @RefSecNum{Type address@hidden subtype 
conversion],Sec=(function return)});
+the return object is created and the converted value is assigned to
+the return object. Otherwise, the return object is created and initialized
+by default as for a stand-alone object of its nominal subtype (see
address@hidden Declarations}). If the nominal subtype is indefinite, the
+return object is constrained by its initial
address@hidden,Sec=[of a return address@hidden by its initial 
address@hidden,New=[
+A check is made that the value of the return object belongs to the function
+result subtype. Constraint_Error is raised if this
+check address@hidden,
+Sec=(raised by failure of run-time check)}
address@hidden,Old=[]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If the result type is controlled or has a
+  controlled part, appropriate calls on Initialize or Adjust are performed
+  prior to executing the @nt{handled_sequence_of_statements}, except when the
+  initial expression is an @nt{aggregate} (which requires build-in-place
+  with no call on Adjust).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[If the return statement is left without resulting
+  in a return (for example, due to an exception propagated from the
+  @nt{expression} or the @nt{handled_sequence_of_statements}, or a goto out of
+  the @nt{handled_sequence_of_statements}), @Chg{Version=[3],New=[if 
],Old=[]}the
+  return object @Chg{Version=[3],New=[has been created, it ],Old=[]}is
+  finalized prior to leaving the return address@hidden,New=[ If
+  it has not been created when the return statement is left, it is not
+  created or finalized.],Old=[]}]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0032-1]}
+  @ChgAdded{Version=[3],Text=[Other rules ensure that the check required by
+  this rule cannot fail unless the function has a class-wide result subtype
+  where the associated specific subtype is constrained. In other cases,
+  either the subtypes have to match or the function's subtype is
+  unconstrained and needs no checking.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden,address@hidden, Sec=(address@hidden@!statement)}],
address@hidden, Sec=(return_statement)}]}
+For the execution of a @Chg{Version=[2],address@hidden@address@hidden,
address@hidden, the @nt{expression}
+(if any) is first address@hidden,New=[,],Old=[ and]} converted to
+the result address@hidden,
+New=[, and then is assigned to the anonymous @i{return object}.
address@hidden object], Sec=(address@hidden@!statement)}],Old=[.]}
address@hidden subtype conversion],Sec=(function return)}
address@hidden
+The conversion might raise
+Constraint_Error @em (see @RefSecNum{Type Conversions}).
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02],ARef=[AI95-00416-01]}
address@hidden,address@hidden the return object has any parts that are tasks, 
the
+activation of those tasks does not occur until after the function returns (see
address@hidden Execution - Task Activation}).]],
+Old=[If the result type is class-wide, then
+the tag of the result is the tag of the value
+of the @nt<expression>.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is specified by the rules in
+  @RefSecNum{Task Execution - Task Activation}.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Only the caller can know when task activations
+  should take place, as it depends on the context of the call. If the function
+  is being used to initialize the component of some larger object, then that
+  entire object must be initialized before any task activations. Even after the
+  outer object is fully initialized, task activations are still postponed until
+  the @key{begin} at the end of the declarative part if the function is being
+  used to initialize part of a declared object.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02],ARef=[AI95-00344-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0024-1],ARef=[AI05-0032-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0097-1]}
address@hidden,Type=[Leading],Keepnext=[T],address@hidden dummy
+ChgDeleted to get conditional "Leading".}If
+the result type @Chg{Version=[2],New=[of a function ],Old=[]}is a specific
+tagged address@hidden,New=[, the tag of the return object is that
+of the result type. If the result type is class-wide, the tag of the
+return object is that of @Chg{Version=[4],New=[the value of the 
@nt{expression},
+unless the return object is defined by
+an @nt{extended_return_object_declaration} with a @nt{subtype_indication} that
+is specific, in which case it is that of ],address@hidden,New=[the
+type of the @nt{subtype_indication}],address@hidden,New=[],
address@hidden,New=[ if it is
+specific, or otherwise that of ],Old=[]}the
+value of the @Chg{Version=[3],address@hidden,Old=[expression]}]}.
+A check is made that
+the @Chg{Version=[3],New=[master],Old=[accessibility level]} of the type
+identified by the tag of the result @Chg{Version=[3],New=[includes the
+elaboration],Old=[is not deeper than that]} of the master that elaborated
+the function body. If
+this check fails, Program_Error is address@hidden,
+Sec=(raised by failure of run-time check)}
address@hidden,Old=[:]}
+
address@hidden
+  @ChgNote{Moved from after paragraph 10}
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],Text=[The first sentence is true even if the
+  tag of the @nt{expression} is different, which
+  could happen if the @nt{expression} were a view conversion or a
+  dereference of an access value. Note that for a limited type, because
+  of the restriction to @nt{aggregate}s and function calls (and no 
conversions),
+  the tag will already match]}.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],Text=[The first rule ensures
+  that a function whose result type is
+  a specific tagged type always returns an object whose tag is that of the
+  result type. This is important for dispatching on controlling result, and
+  allows the caller to allocate the appropriate amount of space to hold
+  the value being returned (assuming there are no discriminants).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised]}
+  @ChgAdded{Version=[2],Text=[The @Chg{Version=[3],New=[master ],Old=[]}check
+  prevents the returned object
+  from outliving its type. Note that this check cannot fail for a specific
+  tagged type, as the tag represents the function's type, which necessarily
+  must be declared outside of the function.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We can't use the normal accessibility level
+    @lquotes@;deeper address@hidden@; check
+    here because we may have @lquotes@;address@hidden@; levels if
+    the masters belong to two different tasks. This can happen when an
+    accept statement calls a function declared in the enclosing task body, and
+    the function returns an object passed to it from the accept statement, and
+    this object was itself a parameter to the accept statement.]}
address@hidden
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0097-1]}
+  @ChgAdded{Version=[4],Text=[The @nt{expression} here is the return expression
+    if the return statement is a @nt{simple_return_statement}, and the
+    initializing expression of the @nt{extended_return_object_declaration} if 
the
+    return statement is an @nt{extended_return_statement} (ignoring any inner
+    @nt{simple_return_statement}s, which necessarily cannot have an
+    @nt{expression}, and any other @nt{expression}s inside of the
+    @nt{extended_return_statement}).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0073-1]}
address@hidden,address@hidden the result subtype
+of the function is defined by
+an @nt{access_definition} designating a specific tagged type @i<T>, a check
+is made that the result value is null or the tag of the object designated
+by the result value identifies @i<T>.
address@hidden,Sec=(raised by failure of run-time check)}
+Constraint_Error is raised if this check fails.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This check is needed so that dispatching
+  on controlling access results works for tag-indeterminate functions.
+  If it was not made, it would be possible for such functions to return
+  an access to a descendant type, meaning the function could return
+  an object with a tag different than the one assumed by the
+  dispatching rules.]}
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 9
+through 20 were deleted.>address@hidden message should be deleted if the
+paragraphs are ever renumbered.}
address@hidden
+
address@hidden(itemize)
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
+  @ChgDeleted{Version=[2],address@hidden
+  If it is limited, then
+  a check is made that the tag of the value of the return expression
+  identifies the result type.
+  @Defn2{Term=[Constraint_Error],Sec=(raised by failure of run-time check)}
+  Constraint_Error is raised if this check fails.]}
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
+  @ChgDeleted{Version=[2],Text=[If it is nonlimited, then
+  the tag of the result is that of the result type.]}
address@hidden
+  @ChgNote{These two notes were revised and moved up}
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
+  @ChgDeleted{Version=[2],Text=[This is true even if the
+  tag of the return expression is different.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
+  @ChgDeleted{Version=[2],Text=[These rules ensure
+  that a function whose result type is
+  a specific tagged type always returns an object whose tag is that of the
+  result type. This is important for dispatching on controlling result,
+  and, if nonlimited,
+  allows the caller to allocate the appropriate amount of space to hold
+  the value being returned (assuming there are no discriminants).]}
address@hidden
address@hidden(itemize)
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
address@hidden,Type=[Leading],Keepnext=[T],
address@hidden type}
+A type is a @i(return-by-reference) type if it
+is a descendant of one of the following:]}
address@hidden(itemize)
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
+  @ChgDeleted{Version=[2],Text=[a tagged limited type;]}
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
+  @ChgDeleted{Version=[2],Text=[a task or protected type;]}
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
+  @ChgDeleted{Version=[2],Text=[a nonprivate type with the reserved word
+  @b(limited) in its declaration;]}
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
+  @ChgDeleted{Version=[2],Text=[a composite type with a subcomponent
+  of a return-by-reference type;]}
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
+  @ChgDeleted{Version=[2],Text=[a private type
+  whose full type is a return-by-reference type.]}
address@hidden(itemize)
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[
+  The above rules are such that there are no "Ada 83" types other than
+  those containing tasks that are return-by-reference. This helps
+  to minimize upward incompatibilities relating to return-by-reference.]}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
address@hidden,Type=[Leading],address@hidden
+If the result type is a return-by-reference type,
+then a check is made that the return expression is one of the
+following:]}
address@hidden(itemize)
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
+  @ChgDeleted{Version=[2],Text=[a @nt{name} that denotes an object view
+  whose accessibility level is not deeper than that of the master that
+  elaborated the function body; or]}
+  @begin{Discussion}
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00316-01]}
+  @ChgNote{This really wasn't in the previous version, but we don't want it
+  in a version without deletions shown...}
+  @ChgDeleted{Version=[2],Text=[This rule was unnecessarily confusing, and the
+  parenthetical remark "(or a value with an associated object, see 6.2)"
+  was added @em and then the entire concept was deleted.]}
+  @end{Discussion}
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
+  @ChgDeleted{Version=[2],Text=[a parenthesized expression or
+  @nt{qualified_expression} whose operand is one of these kinds of 
expressions.]}
+
address@hidden(itemize)
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00318-02]}
address@hidden,address@hidden,Sec=(raised by failure of run-time check)}
+The exception Program_Error is raised if this check fails.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[Compare the definition of return-by-reference
+  with that of by-reference.]}
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[The return-by-reference types are all limited 
types
+  except those that are limited only because of a limited
+  private type with a nonlimited untagged full type.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],address@hidden contract issue}
+  This check can often be performed at compile time. It is
+  defined to be a run-time check to avoid generic contract model
+  problems. In a future version of the standard, we anticipate
+  that function return of a local variable will be illegal for all
+  limited types, eliminating the need for the run-time check
+  except for dereferences of an access parameter.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02],ARef=[AI95-00402-01],ARef=[AI95-00416-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0051-1]}
address@hidden,
+New=[If @Chg{Version=[3],New=[any part of the specific type of the return 
object],
+Old=[the result subtype]} of a function
address@hidden,New=[(or coextension thereof) ],Old=[]}has one or more
address@hidden,New=[],Old=[unconstrained ]}access
address@hidden,New=[ whose value is not constrained by the
+result subtype of the function],Old=[]},
+a check is made that the accessibility level of the anonymous access type
+of each access discriminant, as determined by the @nt{expression} or the
address@hidden@address@hidden of the @Chg{Version=[3],New=[return
+statement],Old=[function]},
+is not deeper than @Chg{Version=[3],New=[the level of the master of the call
+(see @RefSecNum{Operations of Access Types})],
+Old=[that of the master that elaborated the
+function body]}. If this check fails, Program_Error is raised.
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,
+Old=[For a function with a return-by-reference result type
+the result is returned by reference;
+that is, the function call denotes a constant view of the
+object associated
+with the value of the return expression.
address@hidden operation], Sec=(during execution of a
address@hidden)}
+For any other function, the result is returned by copy;
+that is,
+the converted value is assigned into an anonymous constant created at
+the point of the @nt{return_statement}, and the function call denotes
+that object.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Deleted]}
+  @ChgDeleted{Version=[2],Text=[The assignment operation does the necessary
+  value adjustment, as described in
+  @RefSec{Assignment and Finalization}.
+  @RefSecNum{Completion and Finalization}
+  describes when the anonymous constant is finalized.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The check prevents the returned
+  object (for a nonlimited type) from outliving the object designated by one
+  of its discriminants. The check is made on the values of the discriminants,
+  which may come from the @address@hidden@!indication} (if constrained),
+  or the @nt{expression}, but it is never necessary to check both.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0234-1]}
+  @ChgAdded{Version=[3],Text=[The reason for saying @ldquote@;any part of
+  the specific address@hidden is to simplify implementation. In the case of
+  class-wide result objects, this allows the testing of a simple flag in the
+  tagged type descriptor that indicates whether the specific type has any 
parts with
+  access discriminants. By basing the test on the type of the object rather 
than
+  the object itself, we avoid concerns about whether subcomponents in variant
+  parts and of arrays (which might be empty) are present.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0234-1]}
+  @ChgAdded{Version=[3],Text=[For a function with a class-wide result type, the
+   access values that need to be checked are determined by the tag of the 
return
+   object. In order to implement this accessibility check in the case where the
+   tag of the result is not known statically at the point of the return
+   statement, an implementation may need to somehow associate with the tag of a
+   specific tagged type an indication of whether the type has unconstrained
+   access discriminants (explicit or inherited) or has any subcomponents with
+   such discriminants. If an implementation is already maintaining a statically
+   initialized descriptor of some kind for each specific tagged type, then an
+   additional Boolean could be added to this descriptor.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1],ARef=[AI05-0234-1]}
+  @ChgAdded{Version=[3],Text=[Note that the flag should only be queried in the
+   case where the result object might have access discriminants that might
+   have subtypes with "bad" accessibility levels (as determined by the rules of
+   @RefSecNum{Operations of Access Types} for determining the accessibility
+   level of the type of an access discriminant in the @nt{expression} or
+   @nt{return_subtype_indication} of a return statement).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[Thus, in a case like]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Global @key[is access] T'Class;
address@hidden F (Ptr : Global) @key[return] T'Class @key[is]
address@hidden
+   @key[return] address@hidden;
address@hidden F;]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[there is no need for a run-time
+    accessibility check. While an object of T'Class "might have" access
+    discriminants, the accessibility of those potential discriminants
+    cannot be bad. The setting of the bit doesn't matter and there is no
+    need to query it.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[On the other hand, given]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden F @key[return] T'Class @key[is]
+   Local : T'Class := ... ;
address@hidden
+   @key[return] Local;
address@hidden F;]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[In this case, a check would
+    typically be required.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The need for including
+    subcomponents in this check is illustrated by the following example:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[X : @key[aliased] Integer;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Component_Type (Discrim : @key[access] Integer := 
X'Access)
+   @key[is limited null record];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Undiscriminated @key[is record]
+   Fld : Component_Type;
address@hidden record];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden F @key[return] Undiscriminated @key[is]
+   Local : @key[aliased] Integer;
address@hidden
+   @key[return] X : Undiscriminated := (Fld => (Discrim => Local'Access)) 
@key[do]
+      Foo;
+   @key[end return];
+   address@hidden raises Program_Error after calling Foo.}
address@hidden F;]}
address@hidden
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0234-1]}
+  @ChgAdded{Version=[3],Text=[In the case where the tag of the result is not
+  known statically at the point of the return statement and the run-time
+  accessibility check is needed, discriminant values and array bounds play no
+  role in performing this check. That is, array components are assumed to have
+  nonzero length and components declared within variant parts are assumed to be
+  present. Thus, the check may be implemented simply by testing the
+  aforementioned descriptor bit and conditionally raising Program_Error.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0058-1]}
address@hidden,New=[For the execution of an
address@hidden@address@hidden, the
address@hidden@address@hidden@!statements} is executed. Within this
address@hidden@address@hidden@!statements}, the execution of a
address@hidden@address@hidden that applies to the
address@hidden@address@hidden causes a transfer of control that completes
+the @address@hidden@!statement}. Upon completion
+of a return statement that applies to a callable address@hidden,
+New=[ by the normal completion of a @address@hidden@!statement} or
+by reaching the @key[end return] of an @address@hidden@!statement}],
+Old=[]}],Old=[Finally]}, a
+transfer of control is performed which completes the execution of the callable
address@hidden,New=[], Old=[ to which the @address@hidden
+applies]}, and returns to the caller.
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0058-1]}
+  @ChgAdded{Version=[3],Text=[A transfer of control that completes an
+  @nt{extended_return_statement} (such as an exit or goto) does not cause
+  a return to the caller unless it is caused by @nt{simple_return_statement}
+  (that is, triggers the second sentence of this paragraph). The return to
+  the caller occurs for the @nt{simple_return_statement} that applies to an
+  @nt{extended_return_statement} because the last sentence says
+  @ldquote@;the normal completion of a @address@hidden@;,
+  which includes the one nested in the @nt{extended_return_statement}.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00318-02]}
address@hidden,Text=[In the case of a function, the @nt{function_call}
+denotes a constant view of the return object.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00416-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0050-1]}
address@hidden,Type=[Leading],address@hidden is a fake used to provide a 
conditional leading.}
address@hidden,address@hidden,New=[For a function call used to
+initialize a composite],Old=[If the result subtype of a function is
+unconstrained, and a call on the function is used to provide the initial value
+of an]} object with a constrained nominal address@hidden,New=[ or
+used to initialize a return object that is built in place
+into such an object:],Old=[, Constraint_Error may be raised
+at the point of the call (after abandoning the execution of the function body)
+if, while elaborating the @address@hidden@!indication} or
+evaluating the @nt{expression} of a return statement that applies to the
+function body, it
+is determined that the value of the result will violate the constraint of the
+subtype of this object.]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0050-1]}
+  @ChgAdded{Version=[3],Text=[If the result subtype of the function is
+  constrained, and conversion of an object of this subtype to the subtype of 
the
+  object being initialized would raise Constraint_Error, then Constraint_Error
+  may be raised before calling the function.]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0050-1]}
+  @ChgAdded{Version=[3],Text=[If the result subtype of the function is
+  unconstrained, and a return statement is executed such that the return object
+  is known to be constrained, and conversion of the return object to the 
subtype
+  of the object being initialized would raise Constraint_Error, then
+  Constraint_Error may be raised at the point of the call (after abandoning the
+  execution of the function body).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0050-1]}
+  @ChgAdded{Version=[2],Text=[Without such a permission, it would be very
+  difficult to implement
+  @lquotes@;@Chg{Version=[3],New=[built-in-place],address@hidden semantics.
+  @Chg{Version=[3],New=[The intention is that the exception is raised at the
+  same point that it would have been raised without the permission; it
+  should not change handlers if the implementation switches between
+  return-by-copy and built-in-place. This means that the],Old=[Such an]}
+  exception is not handleable within the function, because in the
+  return-by-copy case, the constraint check to verify that the result satisfies
+  the constraints of the object being initialized happens after the function
+  address@hidden,New=[],Old=[, and we want the semantics to change as
+  little as possible when switching between return-by-copy and 
build-in-place]}.
+  This implies further that upon detecting such a situation, the implementation
+  may need to simulate a goto to a point outside any local exception handlers
+  prior to raising the exception.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0050-1]}
+  @Chg{Version=[3],New=[These permissions do not apply in the case of an 
extended
+  return object with mutable discriminants. That's necessary because in that
+  case a return object can be created with the @ldquote@;address@hidden
+  discriminants and then changed to the @ldquote@;address@hidden discriminants
+  later (but before returning). We don't want this case raising an exception
+  when the canonical semantics will not do so.],address@hidden,New=[This
+  permission is allowed during the evaluation of the @nt{expression} of an
+  @nt{extended_return_statement}, because the @address@hidden@!indication}
+  may be unconstrained and the @nt{expression} then would provide the
+  constraints.],Old=[]}]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0050-1]}
+  @ChgAdded{Version=[3],Text=[It's still possible to write a program that will
+  raise an exception using this permission that would not in the canonical
+  semantics. That could happen if a return statement with the
+  @ldquote@;address@hidden discriminants or bounds is abandoned (via an
+  exception, or for an extended_return_statement, via an exit or goto
+  statement), and then a return statement with the @ldquote@;address@hidden
+  discriminants or bounds is executed. The only solution for this problem is to
+  not have the permission at all, but this is too unusual of a case to worry 
about
+  the effects of the permission, especially given the implementation
+  difficulties for built-in-place objects that this permission is intended to
+  ease.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0050-1]}
+  @ChgAdded{Version=[3],Text=[Note that the mutable-discriminant case only
+  happens when built-in-place initialization is optional. This means that any
+  difficulties associated with implementing built-in-place initialization
+  without these permissions can be sidestepped by not building in place.]}
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden@address@hidden of return statements:}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden;                         address@hidden in a procedure body, 
address@hidden@ExamCom{,address@hidden,New=[
+                                -- @address@hidden, or 
address@hidden,address@hidden or address@hidden
+
address@hidden Key_Value(Last_Index);   address@hidden in a function body}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00318-02]}
address@hidden,New=<@key[return] Node : Cell @key{do}           address@hidden 
in a function body, see @RefSecNum{Incomplete Type Declarations} for Cell}
+   Node.Value := Result;
+   Node.Succ := Next_Node;
address@hidden @key{return};>,Old=<>}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden with Ada 83}
+In Ada 95, if the result type of a function has a part that is a task,
+then an attempt to return a local variable will raise Program_Error.
address@hidden,New=[This is illegal in Ada 2005, see below. ],
+Old=[]}In Ada 83, if a function returns a local variable containing a task,
+execution is erroneous according to AI83-00867. However,
+there are other situations where functions that return tasks
+(or that return a variant record only one of whose variants
+includes a task)
+are correct in Ada 83 but will raise Program_Error according
+to the new rules.
+
+The rule change was made because there will be more types (protected types,
+limited controlled types) in Ada 95 for which
+it will be meaningless to return a local variable, and making
+all of these erroneous is unacceptable.
+The current rule was felt to be the simplest that kept
+upward incompatibilities to situations involving returning tasks,
+which are quite rare.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} has been moved here from
+chapter 5, since it has mainly to do with subprograms.
+
+A function now creates an anonymous object.
+This is necessary so that controlled types
+will work.
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
+We have clarified that a
address@hidden,New=[return statement],address@hidden
+applies to a callable construct, not to a callable entity.
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
+There is no need to mention generics in the rules about where a
address@hidden,New=[return statement],address@hidden
+can appear and what it applies to;
+the phrase @lquotes@;body of a subprogram or generic address@hidden@; is
+syntactic, and refers exactly to @lquotes@;@address@hidden@;.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-0416-1]}
+  
@ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0005-1],ARef=[AI05-0050-1]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  Added an @ImplPermName allowing early raising of Constraint_Error if the
+  result cannot fit in the ultimate object. This gives implementations more
+  flexibility to do built-in-place returns, and is essential for limited types
+  (which cannot be built in a temporary). However, it allows
+  raising @Chg{Version=[3],New=[],Old=[an ]}
+  Constraint_Error in some cases where it would not be raised if the
+  permission was not used. @Chg{Version=[3],New=[See @Inconsistent2005Title for
+  additional changes. ],Old=[]}This case is potentially inconsistent with Ada 
95, but a compiler
+  does not have to take advantage of these permissions for any Ada 95 code, so
+  there should be little practical impact.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95} The entire
+  business about return-by-reference types has been dropped. Instead, the
+  @nt{expression} of a return statement of a limited type can only be an
+  @nt{aggregate} or @nt{function_call} (see @RefSecNum{Limited Types}). This
+  means that returning a global object or @nt{type_conversion}, legal in Ada
+  95, is now illegal. Such functions can be converted to use anonymous access
+  return types by adding @key{access} in the function definition and return
+  statement, adding address@hidden in uses, and adding @key{aliased} in the 
object
+  declarations. This has the advantage of making the reference return semantics
+  much clearer to the casual reader.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We changed these rules so that functions,
+  combined with the new rules for limited types (@RefSecnum{Limited Types}),
+  can be used as build-in-place constructors for limited types. This reduces
+  the differences between limited and nonlimited types, which will
+  make limited types useful in more circumstances.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The @nt{extended_return_statement} is new. This provides a name for
+  the object being returned, which reduces the copying needed to return
+  complex objects (including no copying at all for limited objects). It also
+  allows component-by-component construction of the return object.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],Text=[The wording was updated to support anonymous
+  access return subtypes.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],Text=[The term @lquotes@;return address@hidden@;
+  was dropped because reviewers found it confusing when applied to the default
+  @nt{expression} of an @nt{extended_return_statement}.]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00344-01],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[Added accessibility checks to class-wide
+  return statements. These checks could not fail in Ada 95 (as all of the
+  types had to be declared at the same level, so the tagged type would
+  necessarily have been at the same level as the type of the
+  object).]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00402-01],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[Added accessibility checks to
+  return statements for types with access discriminants. Since such
+  types have to be limited in Ada 95, the @nt{expression} of a return statement
+  would have been illegal in order for this check to fail.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0050-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  @b<Correction:> The @ImplPermName allowing early raising of Constraint_Error 
was modified
+  to remove the most common of these cases from the permission (returning an
+  object with mutable discriminants, where the return object is created with
+  one set of discriminants and then changed to another). (The permission was
+  also widened to allow the early check for constrained functions when that
+  constraint is wrong.) However, there still is an unlikely case where the
+  permission would allow an exception to be raised when none would be raised 
by the canonical
+  semantics (when a return statement is abandoned). These changes can only
+  remove the raising of an exception (or change the place where it is raised)
+  compared to Ada 2005, so programs that depend on the previous behavior should
+  be very rare.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0051-1],ARef=[AI05-0234-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Accessibility checks for
+  access discriminants now depend on the master of the call rather than
+  the point of declaration of the function. This will result in cases
+  that used to raise Program_Error now running without raising any exception.
+  This is technically inconsistent with Ada 2005 (as defined by Amendment 1),
+  but it is unlikely that any real code depends on the raising of this
+  exception.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0073-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:>
+  Added a tag check for functions returning anonymous access-to-tagged types,
+  so that dispatching of tag-indeterminate function works as expected.
+  This is technically inconsistent with Ada 2005 (as defined by Amendment 1),
+  but as the feature in question was newly added to Ada 2005, there should
+  be little code that depends on the behavior that now raises an exception.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0053-1],ARef=[AI05-0277-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  The @key{aliased} keyword can now only appear on extended return objects
+  with an immutably limited type. Other types would provide a way to get
+  an aliased view of an object that is not necessarily aliased, which would be
+  very bad. This is incompatible, but since the feature was added in
+  Ada 2005, the keyword had no defined meaning in Ada 2005
+  (a significant oversight), and most sensible uses involve immutably limited
+  types, it is unlikely that it appears meaningfully in existing programs.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0103-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added wording to require
+  static matching for unconstrained access types in extended return statements.
+  This disallows adding or omitting null exclusions, and adding access
+  constraints, in the declaration of the return object. While this is
+  incompatible, the incompatible cases in question are either useless (access
+  constraints @en the constraint can be given on an @nt{allocator} if 
necessary,
+  and still must be given there even if given on the return object)
+  or wrong (null exclusions @en null could be returned from a
+  function declared to be null excluding), so we expect them to be extremely
+  rare in practice.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0015-1],ARef=[AI05-0144-2]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The return object of an @nt{extended_return_statement} can be declared
+  constant; this works similarly to a constant object declaration.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0032-1]}
+  @ChgAdded{Version=[3],Text=[Added wording to allow
+  the @nt{return_subtype_indication} to have a specific type if the return
+  subtype of the function is class-wide. Specifying the (specific) type of
+  the return object is awkward without this change, and this is consistent
+  with the way @nt{allocator}s work.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0024-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the master check
+  for tags since the masters may be for different tasks and thus 
incomparable.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0058-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the wording
+  defining returns for @nt{extended_return_statement}s, since leaving by
+  an exit or goto is considered @ldquote@;address@hidden completion of the
+  statement.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0205-1],ARef=[AI05-0277-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added the
+  @nt{extended_return_object_declaration} to make other rules easier to write
+  and eliminate the problem described in AI05-0205-1.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0097-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified the wording so 
that
+  it is clear where the tag of the return object comes from. While a literal
+  reading of the original Ada 2012 rule could have caused some weird results
+  (by using some nearby @nt{subtype_indication} to provide the tag in the
+  case of a @nt{simple_return_statement}, such a reading would be so unlike
+  the rest of the language that we do not believe anyone would ever have
+  thought it was intended. As such, we do not believe any implementation
+  ever did this wrong (at least because of the old wording), and thus do not
+  document this as a possible inconsistency.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,InitialVersion=[2],New=[Nonreturning Procedures],Old=[Pragma 
No_Return]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00329-01],ARef=[AI95-00414-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[Specifying aspect],Old=[A @nt{pragma}]}
+No_Return @Chg{Version=[3],New=[to have the value True ],Old=[]}indicates
+that a procedure cannot return address@hidden; it may propagate
+an exception or loop forever].]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,address@hidden,New=[Aspect],address@hidden
address@hidden aspect} will have to wait for
+Ada @Chg{Version=[3],New=[2020],Old=[2017]}. :-)]}
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 2
+and 3 were moved to @RefSec{Obsolescent Features}.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00329-01],ARef=[AI95-00414-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],address@hidden,New=[],Old=[The form
+of a @nt{pragma} No_Return, which is a
+representation pragma (see @RefSecNum{Operational and Representation Aspects}),
+is as follows:]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,InitialVersion=[2],@ChgAdded{Version=[2],
address@hidden,New=[],address@hidden @prag<No_Return>(@address@hidden, 
@address@hidden);]}'}}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[For a procedure or generic procedure, the 
following
+language-defined representation aspect may be specified:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden type of aspect No_Return is Boolean.
+When aspect No_Return is True for an entity, the entity is said to be
address@hidden<nonreturning>address@hidden@AspectDefn{No_Return}]}
+
address@hidden,Kind=[Added]}
address@hidden,NoPrefix=[T],Text=[If directly specified, the
address@hidden shall be a static expression. @Redundant[This aspect is
+never inherited;] if not directly specified, the aspect is False.]}
+
address@hidden,Kind=[AddedNormal],Aspect=[No_Return],
+  address@hidden,Text=[A procedure will not return normally.]}]}
address@hidden
+
address@hidden,Kind=[Added],address@hidden from below}
address@hidden,Text=[If a generic procedure is nonreturning, then so are
+its instances. If a procedure declared within a generic unit is nonreturning,
+then so are the corresponding copies of that procedure in instances.]}
+
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00329-01],ARef=[AI95-00414-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[Aspect No_Return],
address@hidden @address@hidden shall denote one
+or more procedures or generic procedures; the denoted entities are
address@hidden<nonreturning>. The @address@hidden shall not
address@hidden,New=[be specified for],Old=[denote]} a
+null procedure nor an instance of a generic unit.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[A null procedure cannot have the appropriate
+  nonreturning semantics, as it does not raise an exception or loop forever.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[2],Text=[The procedure can be address@hidden,New=[],
+  Old=[ The denoted declaration can be a @nt{renaming_declaration} if it obeys 
the usual rules
+  for representation pragmas: the renaming has to occur immediately within the
+  same declarative region as the renamed subprogram.]} If a nonreturning
+  procedure is renamed (anywhere) calls through the new name still have the
+  nonreturning semantics.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00329-01],ARef=[AI95-00414-01]}
address@hidden,Text=[A return statement shall not apply to a
+nonreturning procedure or generic procedure.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00414-01]}
address@hidden,Text=[A procedure shall be nonreturning if it overrides
+a dispatching nonreturning procedure.
address@hidden contract issue}
+In addition to the places where
address@hidden normally apply (see @RefSecNum{Generic Instantiation}),
+this rule applies also in the private part of an instance of a generic unit.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This ensures that dispatching calls to
+  nonreturning procedures will, in fact, not return.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00414-01]}
address@hidden,Text=[If a renaming-as-body completes a nonreturning
+procedure declaration, then the renamed procedure shall be nonreturning.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This ensures that no extra code is needed to
+  implement the renames (that is, no wrapper is needed) as the body has
+  the same property.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraph 8
+was deleted.>address@hidden message should be deleted if the paragraphs
+are ever address@hidden special message is needed to get rid of
+the old, now unused, subheader}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00329-01],ARef=[AI95-00414-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[],Old=[If a generic procedure
+is nonreturning, then so are its instances. If a procedure declared within
+a generic unit is nonreturning, then so are the corresponding copies of
+that procedure in instances.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00329-01],ARef=[AI95-00414-01]}
address@hidden,Text=[If the body of a nonreturning procedure completes
+normally, Program_Error is raised at the point of the call.
address@hidden,Sec=(raised by failure of run-time check)}]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Note that there is no name for suppressing
+  this check, since the check represents a bug, imposes no time overhead,
+  and minimal space overhead (since it can usually be statically eliminated
+  as dead code).]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If a nonreturning procedure tries to return, we
+  raise Program_Error. This is stated as happening at the call site, because we
+  do not wish to allow the procedure to handle the exception (and then,
+  perhaps, try to return again!). However, the expected run-time model is that
+  the compiler will generate @key{raise} Program_Error at the end of the
+  procedure body (but not handleable by the procedure itself), as opposed to
+  doing it at the call site. (This is just like the typical run-time model for
+  functions that fall off the end without returning a value). The reason is
+  indirect calls: in address@hidden(...);, the compiler cannot know whether P
+  designates a nonreturning procedure or a normal one. Putting the @key{raise}
+  Program_Error in the procedure's generated code solves this problem neatly.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Similarly, if one passes a nonreturning
+  procedure to a generic formal parameter, the compiler cannot know this at
+  call sites (in shared code implementations); the raise-in-body solution
+  deals with this neatly.]}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,address@hidden(procedure) Fail(Msg : 
String)@Chg{Version=[3],New=[],Old=[;]}  address@hidden raises Fatal_Error 
exception]
address@hidden,New=[   @key(with)],address@hidden(pragma)]} 
address@hidden,New=[],Old=[(Fail)]};
+   address@hidden Inform compiler and reader that procedure never returns 
normally]]}
address@hidden
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00329-01],ARef=[AI95-00414-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @nt{Pragma} No_Return is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Aspect No_Return is new; @nt{pragma} No_Return is now obsolescent.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden of Operators}
+
address@hidden
address@hidden
address@hidden operator}
address@hidden, Sec=(user-defined)}
+An @i{operator} is a function whose @nt{designator} is an
address@hidden<operator_symbol>.
address@hidden, like other functions, may be overloaded.]
address@hidden
+
address@hidden
+Each use of a unary or binary operator is equivalent to a
address@hidden with @address@hidden being the
+corresponding @nt{operator_symbol}, and with (respectively) one or
+two positional actual parameters being the operand(s) of the operator
+(in order).
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+We also use the term operator
+(in @Chg{Version=[3],New=[Clause],Old=[Section]} 4 and in
address@hidden Declarations})
+to refer to one of the syntactic categories
+defined in @RefSec{Operators and Expression Evaluation}
+whose names end with @lquotes@;_operator:@rquotes@;
address@hidden<address@hidden>,
address@hidden<address@hidden>,
address@hidden<address@hidden@!operator>,
address@hidden<address@hidden@!operator>,
address@hidden<address@hidden>, and
address@hidden<address@hidden@!operator>.
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,Text=[This equivalence extends to uses of
address@hidden in most other language rules. However, as
+often happens, the equivalence is not perfect, as operator
+calls are not a @nt{name}, while a @nt{function_call} is a
address@hidden Thus, operator calls cannot be used in contexts
+that require a @nt{name} (such as a rename of an object).
+A direct fix for this problem would be very disruptive, and thus
+we have not done that. However, qualifying an operator call
+can be used as a workaround in contexts that require a @nt{name}.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0143-1]}
+The @nt{subprogram_specification} of a unary or binary operator shall have
+one or two parameters, address@hidden,New=[ The parameters
+shall be of mode @key[in].],Old=[]}
+A generic function instantiation whose @nt{designator} is an
address@hidden is only allowed if the specification of the
+generic function has the corresponding number of
address@hidden,New=[, and they are all of mode @key[in]],Old=[]}.
+
address@hidden are not allowed for the parameters of an operator
+(whether the operator is declared with an explicit
address@hidden or by a @nt{generic_instantiation}).
+
+An explicit declaration of "/=" shall not have a result
+type of the predefined type Boolean.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0128-1]}
address@hidden,New=[An explicit],Old=[A]} declaration of "="
+whose result type is Boolean implicitly declares
address@hidden,New=[an operator],Old=[a declaration of]} "/=" that
+gives the complementary address@hidden/= operator}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0128-1]}
address@hidden,Text=[A "/=" defined by this rule is considered
+user-defined, which means that it will be inherited by a derived type.
address@hidden@;address@hidden means @ldquote@;not address@hidden for
+the purposes of inheritance, that is anything other than predefined operators.
address@hidden of the address@hidden is 6.6(6) :-)}]}
address@hidden
address@hidden
+
address@hidden
+The operators "+" and "@en@;" are both unary and binary operators,
+and hence may be overloaded with both one- and two-parameter functions.
address@hidden
+
address@hidden
address@hidden@address@hidden of user-defined operators:}
address@hidden
address@hidden "+" (Left, Right : Matrix) @key[return] Matrix;
address@hidden "+" (Left, Right : Vector) @key[return] Vector;
address@hidden line}
address@hidden  assuming that A, B, and C are of the type Vector}
address@hidden  the following two statements are equivalent:}
address@hidden line}
+A := B + C;
+A := "+"(B, C);
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Explicit declarations of "=" are now permitted for any
+combination of parameter and result types.
+
+Explicit declarations of "/=" are now permitted, so long
+as the result type is not Boolean.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0128-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the wording
+  so that only explicit declarations of "=" cause an implicit declaration
+  of "/="; otherwise, we could get multiple implicit definitions of "/="
+  without an obvious way to chose between them.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0143-1]}
+  @ChgAdded{Version=[3],Text=[Added wording so that operators only allow
+  parameters of mode @key[in]. This was made necessary by the elimination
+  elsewhere of the restriction that function parameters be only of
+  mode @key[in].]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,Name=[Null Procedures]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00348-01]}
address@hidden,Text=[A @nt<null_procedure_declaration> provides a shorthand
+to declare a procedure with an empty body.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00348-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden,lhs=<@Chg{Version=[2],New=<null_procedure_declaration>,Old=<>}>,
+rhs="@Chg{Version=[2],New=<
+   address@hidden
+   @Syn2{procedure_specification} @key{is} @address@hidden,New=<
+       address@hidden>,Old=[]};>,Old=<>}"}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0177-1]}
address@hidden,Text=[If a @nt{null_procedure_declaration} is a completion,
+it shall be the completion of a @nt{subprogram_declaration} or
address@hidden The profile of a
address@hidden that completes a declaration shall
+conform fully to that of the address@hidden conformance],Sec=(required)}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00348-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0177-1],ARef=[AI05-0264-1]}
address@hidden,Text=[A @nt<null_procedure_declaration> declares a @i<null
+procedure>address@hidden address@hidden,Sec=[null]}
+A completion is not allowed for a 
@nt<null_procedure_declaration>@Chg{Version=[3],New=[;
+however, a @nt{null_procedure_declaration} can complete a previous 
declaration],Old=[]}.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[There are no null functions because the return
+value has to be constructed somehow; a function that always raises
+Program_Error doesn't seem very useful or worth the complication.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00348-01]}
address@hidden,Text=[The execution of a null procedure is invoked by a 
subprogram call.
+For the execution of a subprogram call on a null procedure, the execution of
+the @nt<subprogram_body> has no effect.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Thus, a null procedure is equivalent to the body]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key{null};
address@hidden;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[with the exception that a null procedure can be used in
+place of a procedure specification.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00348-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0177-1]}
address@hidden,address@hidden, Sec=(null_procedure_declaration)}
+The elaboration of a @nt{null_procedure_declaration} has no
address@hidden,New=[other ],address@hidden,New=[ than to
+establish that the null procedure can be called without failing the
+Elaboration_Check],Old=[]}.]}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,address@hidden(procedure) Simplify(Expr : @key(in out) 
Expression) @key(is null); address@hidden see @RefSecNum{Tagged Types and Type 
Extensions}]
address@hidden By default, Simplify does nothing, but it may be overridden in 
extensions of Expression]]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00348-01]}
address@hidden,address@hidden to Ada 95}
+Null procedures are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0177-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  A @nt{null_procedure_declaration} can now be a completion.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],Text=[An optional @nt{aspect_specification}
+  can be used in a @nt{null_procedure_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,Name=[Expression Functions]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0177-1]}
address@hidden,Text=[An @nt{expression_function_declaration} provides a
+shorthand to declare a function whose body consists of a single return
+statement.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-0177-1]}
address@hidden,Kind=[Revised],ARef=[AI95-0147-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<expression_function_declaration>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<
+   address@hidden
+   @Syn2{function_specification} @key{is}
+       (@Syn2{expression})
+       address@hidden;@Chg{Version=[4],New=<
+ | address@hidden
+   @Syn2{function_specification} @key{is}
+       @Syn2{aggregate}
+       address@hidden;>,Old=<>}>,Old=<>}"}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0177-1]}
address@hidden,Kind=[Revised],ARef=[AI95-0147-1]}
address@hidden,Text=[The expected type for the @nt{expression}
address@hidden,New=[or @nt{aggregate} ],Old=[]}of an
address@hidden@address@hidden is the result type (see
address@hidden Statements}) of the address@hidden type],
+Sec=(expression of expression function)}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0177-1]}
address@hidden,Text=[If an @address@hidden@!declaration} is a
+completion, it shall be the completion of a @nt{subprogram_declaration} or
address@hidden The profile of an
address@hidden@address@hidden that completes a declaration
+shall conform fully to that of the address@hidden 
conformance],Sec=(required)}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0177-1]}
address@hidden,Kind=[Revised],ARef=[AI95-0147-1]}
address@hidden,Text=[If the result subtype has one or more unconstrained
+access discriminants, the accessibility level of the anonymous access type of
+each access discriminant, as determined by the @nt{expression}
address@hidden,New=[or @nt{aggregate} ],Old=[]}of the
address@hidden,address@hidden@address@hidden,Old=[expression
+function]}, shall not be statically deeper than that of the master that
+elaborated the @address@hidden@!declaration}.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This can only fail if the discriminant is an
+  access to a part of a non-aliased parameter, as there can be no local
+  declarations here.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[3],Text=[We don't need to repeat any of the other
+  @LegalityTitle for return statements since none of them can fail here: the
+  implicit return statement has to apply to this function (and isn't nested in
+  something), there clearly is a return statement in this function, and the
+  static @Chg{Version=[4],New=[class-wide],Old=[classwide]} accessibility check
+  cannot fail as a tagged type cannot be
+  declared locally in an expression function.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0177-1],ARef=[AI05-0264-1]}
address@hidden,Kind=[Revised],ARef=[AI95-0147-1]}
address@hidden,Text=[An @address@hidden@!declaration} declares
+an @i{expression address@hidden address@hidden,Sec=[expression]}
address@hidden,New=[The @i<return expression>@Defn2{Term=[return 
expression],Sec=[of expression function]}
+of an expression function is the @nt{expression} or @nt{aggregate} of the
address@hidden ],Old=[]}A completion
+is not allowed for an @address@hidden@!declaration}; however, an
address@hidden@address@hidden can complete a previous declaration.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0177-1],ARef=[AI05-0262-1]}
address@hidden,Kind=[Revised],ARef=[AI95-0147-1]}
address@hidden,Text=[ The execution of an expression function is invoked
+by a subprogram call. For the execution of a subprogram call on an expression
+function, the execution of the @nt{subprogram_body} executes an implicit
+function body containing only a @nt{simple_return_statement} whose
address@hidden is @Chg{Version=[4],New=[the return expression],Old=[that]}
+of the expression function.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The last sentence effectively means that all of
+  the dynamic wording in @RefSecNum{Return Statements} applies as needed, and 
we
+  don't have to repeat it here.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0177-1]}
address@hidden,address@hidden,
+Sec=(expression_function_declaration)}The elaboration of an
address@hidden@address@hidden has no other effect than to establish
+that the expression function can be called without failing the
+Elaboration_Check.]}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0177-1]}
address@hidden,address@hidden(function) Is_Origin (P : @key[in] Point) 
@key[return] Boolean @key[is] -- @Examcom[see @RefSecNum{Tagged Types and Type 
Extensions}]
+   (P.X = 0.0 @key[and] P.Y = 0.0);]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0177-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Expression functions are new in Ada 2012.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0157-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada 2012}
+  A @nt{aggregate} can directly be the return expression of an expression
+  function. This eliminates the double parentheses that otherwise would be
+  necessary.]}
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/07.mss 
b/packages/ada-ref-man/source_2012/07.mss
new file mode 100755
index 0000000..91f4f6e
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/07.mss
@@ -0,0 +1,4924 @@
address@hidden(07, Root="ada.mss")
+
address@hidden: 2015/04/03 04:12:41 $}
address@hidden
+
address@hidden: e:\\cvsroot/ARM/Source/07.mss,v $}
address@hidden: 1.138 $}
+
address@hidden
address@hidden@ToGlossaryAlso{Term=<Package>,
+  Text=<Packages are program units that allow the specification of groups of
+  logically related entities.
+  Typically, a package contains the declaration of a type
+  (often a private type or private extension) along with
+  the declarations of primitive subprograms of the type,
+  which can be called from outside the package,
+  while their inner workings remain hidden from outside users.>}
address@hidden hiding],See=(package)}
address@hidden,See=(package)}
address@hidden,See=(package)}
address@hidden,See=(package)}]
address@hidden
+
address@hidden Specifications and Declarations}
+
address@hidden
address@hidden package is generally provided in two parts: a
address@hidden and a @nt{package_body}.
+Every package has a @nt{package_specification}, but not all packages
+have a @nt{package_body}.]
address@hidden
+
address@hidden
address@hidden<package_declaration>,rhs="@Syn2{package_specification};"}
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<package_specification>,rhs="
+    @key{package} @address@hidden,New=<
+        address@hidden>,Old=[]} @key{is}
+      address@hidden
+   address@hidden
+      address@hidden
+    @key{end} address@hidden@Syn2{identifier}]"}
+
address@hidden
+If an @nt{identifier} or @address@hidden
+appears at the end of a @nt{package_specification},
+then this sequence of lexical elements shall repeat the
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
address@hidden a completion], Sec=(@nt{package_declaration})}
address@hidden a completion], Sec=(@nt{generic_package_declaration})}
+A @nt{package_declaration} or @nt{generic_package_declaration}
+requires a completion @Redundant[(a body)]
+if it contains any @Chg{Version=[2],address@hidden,
address@hidden<declarative_item>]} that requires a completion,
+but whose completion is not in its @nt{package_specification}.
address@hidden(Honest)
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  If an implementation supports it,@Chg{Version=[3],New=[],Old=[ a
+  @nt{pragma} Import may substitute
+  for]} the body of a package or generic address@hidden,New=[
+  may be imported (using aspect Import, see @RefSecNum{Interfacing Aspects}),
+  in which case no explicit body is allowed],Old=[]}.
address@hidden(Honest)
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00420-01],ARef=[AI95-00434-01]}
address@hidden part], Sec=<of a package
+(other than a generic formal package)>}
+The first list of @Chg{Version=[2],address@hidden,
address@hidden of a
address@hidden of a package other than a generic formal package
+is called the @i{visible part} of the package.
address@hidden@PDefn2{Term=[private part], Sec=(of a package)}
+The optional list of @Chg{Version=[2],address@hidden,
address@hidden after the reserved word
address@hidden (of any @nt{package_specification}) is called the
address@hidden part} of the package.
+If the reserved
+word @key{private} does not appear, the package has an implicit empty
+private address@hidden,New=[ Each list of @nt{basic_declarative_item}s
+of a @nt{package_specification} forms a @i{declaration list} of the
address@hidden list],Sec=(package_specification)}],Old=[]}
+
address@hidden
+This definition of visible part does not apply to generic formal
+packages @em @RefSecNum{Formal Packages} defines
+the visible part of a generic formal package.
+
+The implicit empty private part is important because certain
+implicit declarations occur there if the package is a child package,
+and it defines types in its visible part that are derived from,
+or contain as components, private types declared within the
+parent package. These implicit declarations are visible
+in children of the child package.
+See @RefSecNum(Compilation Units - Library Units).
address@hidden
+
address@hidden entity declared in the private part of a package is visible
+only within the declarative region of the package itself
+(including any child units @em
+see @RefSecNum{Compilation Units - Library Units}).
+In contrast, expanded names denoting
+entities declared in the visible part can be used even outside the
+package; furthermore, direct visibility of such entities can be
+achieved by means of @nt{use_clause}s
+(see @RefSecNum{Selected Components} and @RefSecNum{Use Clauses}).]
address@hidden
+
address@hidden
address@hidden, Sec=(package_declaration)}
+The elaboration of a @nt{package_declaration} consists of the elaboration of
+its @nt{basic_declarative_item}s in the given order.
address@hidden
+
address@hidden
+The visible part of a package contains all the information that
+another program unit is able to know about the package.
+
+If a declaration occurs immediately within the specification
+of a package, and the declaration has a corresponding completion that
+is a body,
+then that body has to occur immediately within the body of
+the package.
address@hidden
+This follows from the fact that the declaration and completion are
+required to occur
+immediately within the same declarative region,
+and the fact that @ntf{bodies} are disallowed (by the @SyntaxName@;s)
+in @nt{package_specification}s.
+This does not apply to instances of generic units,
+whose bodies can occur in @nt{package_specification}s.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of a package declaration:}
address@hidden
address@hidden Rational_Numbers @key[is]
+
+   @key[type] Rational @key[is]
+      @key[record]
+         Numerator   : Integer;
+         Denominator : Positive;
+      @key[end] @key[record];
+
+   @key[function] "="(X,Y : Rational) @key[return] Boolean;
+
+   @key[function] "/"  (X,Y : Integer)  @key[return] Rational;  address@hidden 
 to construct a rational number}
+
+   @key[function] "+"  (X,Y : Rational) @key[return] Rational;
+   @key[function] "-"  (X,Y : Rational) @key[return] Rational;
+   @key[function] "*"  (X,Y : Rational) @key[return] Rational;
+   @key[function] "/"  (X,Y : Rational) @key[return] Rational;
address@hidden Rational_Numbers;
address@hidden
+
+There are also many examples of package declarations in the predefined
+language environment
+(see @RefSecNum{Predefined Language Environment}).
address@hidden
+
address@hidden
address@hidden with Ada 83}
+In Ada 83, a library package is allowed to have a body even if
+it doesn't need one.
+In Ada 95, a library package body is either
+required or forbidden @em never optional.
+The workaround is to add @key[pragma] Elaborate_Body,
+or something else requiring a body,
+to each library package that has a body that isn't otherwise
+required.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+We have moved the syntax into this 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+and the next @Chg{Version=[3],New=[subclause],Old=[clause]} from
+RM83-7.1, @lquotes@;Package address@hidden@;, which we have removed.
+
+RM83 was unclear on the rules about when a package requires a body.
+For example, RM83-7.1(4) and RM83-7.1(8) clearly forgot about the
+case of an incomplete type declared in a @nt{package_declaration} but
+completed in the body.
+In addition,
+RM83 forgot to make this rule apply to a generic package.
+We have corrected these rules.
+Finally, since we now allow a @nt{pragma} Import for any explicit
+declaration, the completion rules need to take this into account as
+well.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00420-01]}
+  @ChgAdded{Version=[2],Text=[Defined @lquotes@;declaration address@hidden
+  to avoid ambiguity in other rules as to whether packages are included.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a 
@nt{package_specification}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
address@hidden Bodies}
+
address@hidden
address@hidden contrast to the entities declared in the visible part of a
+package, the entities declared in the @nt{package_body} are
+visible only
+within the @nt{package_body} itself.
+As a consequence, a
+package with a @nt{package_body} can be used for the construction of
+a group of related subprograms in
+which the logical operations available to clients are clearly
+isolated from the internal entities.]
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0267-1]}
address@hidden<package_body>,rhs="
+    @key{package} @key{body} @address@hidden,New=<
+        address@hidden>,Old=[]} @key{is}
+       @Syn2{declarative_part}
+   address@hidden
+        @Syn2{handled_sequence_of_statements}]
+    @key{end} address@hidden@Syn2{identifier}];"}
+
address@hidden
+If an @nt{identifier} or @address@hidden
+appears at the end of a @nt{package_body},
+then this sequence of lexical elements shall repeat the
address@hidden
address@hidden
address@hidden
+
address@hidden
+A @nt{package_body} shall be the completion of a previous
address@hidden@!declaration} or @address@hidden@!declaration}.
+A library @address@hidden or
+library @address@hidden@!declaration}
+shall not have a body
+unless it requires a address@hidden;
address@hidden<pragma> Elaborate_Body can be used to require
+a @nt<address@hidden@!declaration> to have a body
+(see @RefSecNum{Elaboration Control})
+if it would not otherwise require one].
address@hidden
+The first part of the rule forbids a @nt{package_body} from
+standing alone @em it has to belong to some previous
address@hidden or @nt{generic_package_declaration}.
+
+A nonlibrary @nt{package_declaration} or
+nonlibrary @nt<generic_package_declaration>
+that does not require a completion may
+have a corresponding body anyway.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+In any @nt{package_body} without @nt{statement}s
+there is an implicit @address@hidden
+For any @address@hidden without an explicit completion,
+there is an implicit @address@hidden containing a single
address@hidden
+For a noninstance, nonlibrary package,
+this body occurs at the end of the
address@hidden@!part} of the innermost enclosing program unit or
address@hidden@!statement};
+if there are several such packages,
+the order of the implicit @address@hidden is unspecified.
address@hidden
address@hidden(For an instance, the implicit @address@hidden
+occurs at the place of the instantiation
+(see @RefSecNum{Generic Instantiation}).
+For a library package, the place is partially determined by the
+elaboration dependences (see @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden Structure and Compilation Issues}).)]
address@hidden
+Thus, for example, we can refer to something happening just
+after the @key{begin} of a @nt{package_body},
+and we can refer to the @nt{handled_sequence_of_statements}
+of a @nt{package_body},
+without worrying about all the optional pieces.
+The place of the implicit body makes a difference for tasks
+activated by the package.
+See also RM83-9.3(5).
+
+The implicit body would be illegal if explicit in the case of a library
+package that does not require (and therefore does not allow)
+a body.
+This is a bit strange, but not harmful.
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(nongeneric package_body)}
+For the elaboration of a nongeneric @nt{package_body},
+its @address@hidden is first
+elaborated, and its @address@hidden@!statements} is then executed.
address@hidden
+
address@hidden
+A variable declared in the body of a package is only visible
+within this body and, consequently, its value can only be
+changed within the @nt{package_body}. In the absence of local tasks,
+the value of such a variable remains unchanged between calls issued
+from outside the package to subprograms declared in the visible part.
+The properties of such a variable are similar to those of a 
@lquotes@;address@hidden@;
+variable of C.
+
+The elaboration of the body of a subprogram explicitly declared
+in the visible part of a package is caused by the elaboration of the
+body of the package. Hence a call of such a subprogram by an
+outside program unit raises the exception Program_Error if the call
+takes place before the elaboration of the
address@hidden (see @RefSecNum{Declarative Parts}).
address@hidden
+
address@hidden
address@hidden@address@hidden of a package body
+(see @RefSecNum{Package Specifications and Declarations}):}
address@hidden
address@hidden @key[body] Rational_Numbers @key[is]
+
+   @key[procedure] Same_Denominator (X,Y : @key[in] @key[out] Rational) 
@key[is]
+   @key[begin]
+      address@hidden  reduces X and Y to the same denominator:}
+      ...
+   @key[end] Same_Denominator;
+
+   @key[function] "="(X,Y : Rational) @key[return] Boolean @key[is]
+      U : Rational := X;
+      V : Rational := Y;
+   @key[begin]
+      Same_Denominator (U,V);
+      @key[return] U.Numerator = V.Numerator;
+   @key[end] "=";
+
+   @key[function] "/" (X,Y : Integer) @key[return] Rational @key[is]
+   @key[begin]
+      @key[if] Y > 0 @key[then]
+         @key[return] (Numerator => X,  Denominator => Y);
+      @key[else]
+         @key[return] (Numerator => -X, Denominator => -Y);
+      @key[end] @key[if];
+   @key[end] "/";
+
+   @key[function] "+" (X,Y : Rational) @key[return] Rational @key[is] ... 
@key[end] "+";
+   @key[function] "-" (X,Y : Rational) @key[return] Rational @key[is] ... 
@key[end] "-";
+   @key[function] "*" (X,Y : Rational) @key[return] Rational @key[is] ... 
@key[end] "*";
+   @key[function] "/" (X,Y : Rational) @key[return] Rational @key[is] ... 
@key[end] "/";
+
address@hidden Rational_Numbers;
address@hidden
address@hidden
+
address@hidden
+The syntax rule for @nt{package_body} now uses the syntactic category
address@hidden
+
+The @nt{declarative_part} of a @nt{package_body} is now required;
+that doesn't make any real difference,
+since a @nt{declarative_part} can be empty.
+
+RM83 seems to have forgotten to say that a @nt{package_body} can't
+stand alone, without a previous declaration.
+We state that rule here.
+
+RM83 forgot to restrict the definition of elaboration of
address@hidden to nongeneric ones.
+We have corrected that omission.
+
+The rule about implicit bodies (from RM83-9.3(5))
+is moved here, since it is more generally applicable.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0267-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a @nt{package_body}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
address@hidden Types and Private Extensions}
+
address@hidden
address@hidden declaration (in the visible part of a
+package) of a type as a private type or private extension
+serves to separate the characteristics that can be used
+directly by outside program units (that is, the logical properties)
+from other characteristics whose direct use is confined to the
+package (the details of the definition of the type itself).
+See @RefSecNum(Type Extensions) for an overview of type extensions.
address@hidden types and private extensions}
address@hidden hiding],See=(private types and private extensions)}
address@hidden type],See=(private types and private extensions)}
address@hidden data type (ADT)],See=(private types and private extensions)}
address@hidden (abstract data type)],See=(private types and private 
extensions)}]
address@hidden
+
address@hidden
+A private (untagged) type can be thought of as a record type
+with the type of its single (hidden) component being the full view.
+
+A private tagged type can be thought of as a private extension
+of an anonymous parent with no components. The only
+dispatching operation of the parent is equality
+(although the Size attribute, and, if nonlimited, assignment are allowed,
+and those will presumably be implemented in terms of dispatching).
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<private_type_declaration>,rhs="
+   @key{type} @Syn2{defining_identifier} address@hidden @key{is} 
address@hidden @key{tagged}] address@hidden @address@hidden,New=<
+      address@hidden>,Old=[]};"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00251-01],ARef=[AI95-00419-01],ARef=[AI95-00443-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<private_extension_declaration>,rhs="
+   @key{type} @Syn2{defining_identifier} address@hidden @key{is}
+     address@hidden @Chg{Version=[2],New=<address@hidden | 
@key{synchronized}]>,Old=[]} @key{new} @SynI(ancestor_)@address@hidden,New=<
+     address@hidden @Syn2[interface_list]]>,Old=<>} @key{with 
address@hidden,New=<
+       address@hidden>,Old=[]};"}
address@hidden
+
address@hidden
address@hidden don't mark this as a change, since it only involves the AARM}
address@hidden view], Sec=(of a type)}
address@hidden a completion], Sec=(declaration of a partial view)}
+A @nt<private_type_declaration>
+or @nt<private_extension_declaration>
+declares a @i{partial view} of the type;
+such a declaration is allowed only as a
address@hidden of the visible part of a package,
+and it requires a completion,
+which shall be a @nt{full_type_declaration} that occurs as
+a @nt{declarative_item} of the private part of the package.
address@hidden,New=[],address@hidden view], Sec=(of a type)}]}
address@hidden@ChgNote{This really should be a change, but that's too hard.}
+The view of the type declared by the @nt<full_type_declaration>
+is called the @i(full view).]
+A generic formal private type or a
+generic formal private extension is also a partial view.
address@hidden(Honest)
+  A private type can also address@hidden,New=[
+  imported (using aspect Import, see @RefSecNum{Interfacing Aspects}),
+  in which case no completion is allowed],Old=[completed by a @nt{pragma}
+  Import]}, if supported by an implementation.
address@hidden(Honest)
address@hidden
+  We originally used the term @lquotes@;private view,@rquotes@; but this was
+  easily confused with the view provided @i(from) the private part, namely the
+  full view.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00326-01]}
+  @ChgAdded{Version=[2],Text=[Full view is now defined in
+  @RefSec{Type Declarations}, as all types now have them.]}
address@hidden
+
address@hidden type shall be completely defined before it is frozen
+(see @RefSecNum{Completions of Declarations} and
address@hidden Rules}).
+Thus, neither the declaration
+of a variable of a partial view of a type, nor the creation by an
address@hidden of an object of the partial view are allowed before
+the full declaration of the type.
+Similarly, before the full declaration, the name of the partial view
+cannot be used in a @nt{generic_instantiation} or in a
+representation item.]
address@hidden
+  This rule is stated officially in
+  @RefSec{Completions of Declarations}.
address@hidden
+
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00419-01],ARef=[AI95-00443-01]}
address@hidden private type is limited if its declaration includes
+the reserved word @key[limited];
+a private extension is limited if its ancestor type is @Chg{Version=[2],
+New=[a limited type that is not an interface type, or if the reserved word
address@hidden or @key{synchronized} appears in its
+definition],Old=[limited]}.]
+If the partial view is nonlimited, then
+the full view shall be nonlimited.
+If a tagged partial view is limited,
+then the full view shall be limited.
address@hidden the other hand,
+if an untagged partial view is limited,
+the full view may be limited or nonlimited.]
+
+If the partial view is tagged,
+then the full view shall be tagged.
address@hidden the other hand, if the partial view is untagged,
+then the full view may be tagged or untagged.]
+In the case where the partial view is untagged and the full view is
+tagged,
+no derivatives of the partial view are allowed within the immediate
+scope of the partial view;
address@hidden of the full view are allowed.]
address@hidden
+Note that deriving from a partial view within its immediate scope
+can only occur in a package that is a child of the one where the partial
+view is declared.
+The rule implies that in the visible part of a public child package,
+it is impossible to derive from an untagged private type declared in the
+visible part of the parent package in the case where the full
+view of the parent type turns out to be tagged.
+We considered a model in which the derived type was implicitly
+redeclared at the earliest place within its immediate scope where
+characteristics needed to be added.
+However, we rejected that model, because (1) it would imply that (for an
+untagged type) subprograms explicitly declared after the derived type
+could be inherited, and (2) to make this model work for composite types
+as well, several implicit redeclarations would be
+needed, since new characteristics can become visible one by one;
+that seemed like too much mechanism.
address@hidden
address@hidden
+  The rule for tagged partial views
+  is redundant for partial views that are private extensions,
+  since all extensions of a given ancestor tagged type are tagged,
+  and limited if the ancestor is limited.
+  We phrase this rule partially redundantly to keep its structure parallel
+  with the other rules.
address@hidden
address@hidden
+  This rule is checked in a generic unit,
+  rather than using the @lquotes@;assume the address@hidden@; or 
@lquotes@;assume the address@hidden@;
+  method.
address@hidden
address@hidden
+  @leading@;@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00230-01]}Tagged
+  limited private types have certain capabilities that are
+  incompatible with having assignment for the full view of the type.
+  In particular, tagged limited private types can be extended
+  with @Chg{Version=[2],New=[],Old=[access discriminants and ]}components
+  of a limited type, which works only because assignment is not allowed.
+  Consider the following example:
+  @begin{Example}
address@hidden P1 @key[is]
+    @key[type] T1 @key[is] @key[tagged] @key[limited] @key[private];
+    @key[procedure] Foo(X : @key[in] T1'Class);
address@hidden
+    @key[type] T1 @key[is] @key[tagged] @key[null] @key[record]; 
address@hidden Illegal!}
+        address@hidden This should say @lquotes@;@key[tagged limited null 
address@hidden@;.}
address@hidden P1;
+
address@hidden,address@hidden AI-00114}
address@hidden @key[body] P1 @key[is]
+    @key[type] A @key[is] @key[access] T1'Class;
+    Global : A;
+    @key[procedure] Foo(X : @key[in] T1'Class) @key[is]
+    @key[begin]
+        Global := @key[new] T1'Class'(X);
+            address@hidden This would be illegal if the full view of}
+            address@hidden T1 were limited, like it's supposed to be.}
+    @key[end] @Chg{New=[Foo],Old=[A]};
address@hidden P1;
+
address@hidden,Kind=[Revised],address@hidden P1;
address@hidden P2 @key[is]
+    @key[type] T2(D : @key[access] Integer)@Chg{Version=[2],New=[],Old=[ 
address@hidden Trouble!}]}
+            @key[is] @key[new] P1.T1 @key[with]
+        @key[record]
+            My_Task : Some_Task_Type; address@hidden 
@Chg{Version=[2],New=[Trouble],Old=[More trouble]}!}
+        @key[end] @key[record];
address@hidden P2;
+
address@hidden,address@hidden AI-00114}
address@hidden P1;
address@hidden P2;
address@hidden Main @key[is]
+    Local : @key[aliased] Integer;
+    Y : P2.T2(@Chg{New=[D],Old=[A]} => Local'Access);
address@hidden
+    P1.Foo(Y);
address@hidden Main;
+  @end{Example}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00230-01]}
+  If the above example were legal,
+  we would have succeeded in @Chg{Version=[2],New=[],Old=[making an access
+  value that points to Main.Local after Main has been left,
+  and we would also have succeeded in ]}doing an assignment of a task
+  object, @Chg{Version=[2],New=[],Old=[both of ]}which 
@Chg{Version=[2],New=[is],
+  Old=[are]} supposed to be @Chg{Version=[2],New=[a no-no],Old=[no-no's]}.
+  @ChgNote{A runtime check prevents the first from being a problem in Ada 
2005.}
+
+  This rule is not needed for private extensions,
+  because they inherit their limitedness from their ancestor,
+  and there is a separate rule forbidding limited components of the
+  corresponding record extension if the parent is nonlimited.
address@hidden
address@hidden
address@hidden@;A type derived from an untagged private type is untagged,
+even if the full view of the parent is tagged,
+and even at places that can see the parent:
address@hidden
address@hidden P @key[is]
+    @key[type] Parent @key[is] @key[private];
address@hidden
+    @key[type] Parent @key[is] @key[tagged]
+        @key[record]
+            X: Integer;
+        @key[end] @key[record];
address@hidden P;
+
address@hidden,address@hidden AI-00114}
address@hidden@key[with] P;
+],address@hidden Q @key[is]
+    @key[type] T @key[is] @key[new] @Chg{New=[P.],Old=[]}Parent;
address@hidden Q;
+
address@hidden Q; @key[use] Q;
address@hidden @key[body] P @key[is]
+    ... T'Class ... address@hidden Illegal!}
+    Object: T;
+    ... Object.X ... address@hidden Illegal!}
+    ... Parent(Object).X ... address@hidden OK.}
address@hidden P;
address@hidden
+
+The declaration of T declares an untagged view.
+This view is always untagged, so T'Class is illegal,
+it would be illegal to extend T, and so forth.
+The component name X is never visible for this view,
+although the component is still there @em one
+can get one's hands on it via a @nt{type_conversion}.
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00396-01]}
address@hidden,Type=[Leading],Text=[If a full type has a partial view
+that is tagged, then:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[the partial view shall be a synchronized tagged
+type (see @RefSecNum{Interface Types}) if and only if the full type is a
+synchronized tagged type;]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[ Since we do not allow record extensions of
+  synchronized tagged types, this property has to be visible in the partial
+  view to avoid privacy breaking. Generic formals do not need a similar rule as
+  any extensions are rechecked for legality in the specification, and
+  extensions of tagged formals are always illegal in a generic body.]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Text=[the partial view shall be a descendant of an
+interface type (see 3.9.4) if and only if the full type is a descendant of the
+interface type.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],KeepNext=[T],Type=[Leading],Text=[Consider the 
following example:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden P @key{is}
+   @key{package} Pkg @key{is}
+      @key{type} Ifc @key{is interface};
+      @key{procedure} Foo (X : Ifc) @key{is abstract};
+   @key{end} Pkg;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} Parent_1 @key{is tagged null record};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} T1 @key{is new} Parent_1 @key{with private};
address@hidden
+   @key{type} Parent_2 @key{is new} Parent_1 @key{and} Pkg.Ifc @key{with null 
record};
+   @key{procedure} Foo (X : Parent_2); -- @RI[Foo #1]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} T1 @key{is new} Parent_2 @key{with null 
record}; -- @RI[Illegal.]
address@hidden P;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden P;
address@hidden P_Client @key{is}
+   @key{type} T2 @key{is new} P.T1 @key{and} P.Pkg.Ifc @key{with null record};
+   @key{procedure} Foo (X : T2); -- @RI[Foo #2]
+   X : T2;
address@hidden P_Client;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden P_Client;
address@hidden body} P @key{is}
+   ...]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} Bar (X : T1'Class) @key{is}
+   @key{begin}
+      Pkg.Foo (X); -- @RI[should call Foo #1 or an override thereof]
+   @key{end};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   Pkg.Foo (Pkg.Ifc'Class (P_Client.X));      -- @RI[should call Foo #2]
+   Bar (T1'Class (P_Client.X));
address@hidden P;]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This example is illegal because the completion
+    of T1 is descended from an interface that the partial view is not descended
+    from. If it were legal, T2 would implement Ifc twice, once in the visible
+    part of P, and once in the visible part of P_Client. We would need to
+    decide how Foo #1 and Foo #2 relate to each other. There are two options:
+    either Foo #2 overrides Foo #1, or it doesn't.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If Foo #2 overrides Foo #1,
+    we have a problem because the client redefines a behavior that it doesn't
+    know about, and we try to avoid this at all costs, as it would lead to a
+    breakdown of whatever abstraction was implemented. If the abstraction
+    didn't expose that it implements Ifc, there must be a reason, and it should
+    be able to depend on the fact that no overriding takes place in clients.
+    Also, during maintenance, things may change and the full view might
+    implement a different set of interfaces. Furthermore, the situation is even
+    worse if the full type implements another interface Ifc2 that happens to
+    have a conforming Foo (otherwise unrelated, except for its name and
+    profile).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If Foo #2 doesn't override Foo #1,
+    there is some similarity with the case of normal tagged private types,
+    where a client can declare an operation that happens to conform to some
+    private operation, and that's OK, it gets a different slot in the type
+    descriptor. The problem here is that T2 would implement Ifc in two
+    different ways, and through conversions to Ifc'Class we could end up with
+    visibility on both of these two different implementations. This is the
+    @lquotes@;diamond address@hidden problem of C++ all over again, and we
+    would need some kind of a preference rule to pick one implementation. We
+    don't want to go there (if we did, we might as well provide full-fledged
+    multiple inheritance).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Note that there wouldn't be any difficulty to
+    implement the first option, so the restriction is essentially
+    methodological. The second option might be harder to implement, depending
+    on the language rules that we would choose.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[This rule also prevents completing a private type
+  with an interface. @Chg{Version=[3],New=[An],Old=[A]} interface, like all
+  types, is a descendant of itself,
+  and thus this rule is triggered. One reason this is necessary is that
+  a client of a private extension should be able to inherit limitedness
+  without having to look in the private part to see if the type is an
+  interface (remember that limitedness of interfaces is never inherited, while
+  it is inherited from other types).]}
address@hidden
+
address@hidden
+
address@hidden subtype], Sec=(of a @nt<private_extension_declaration>)}
+The @i(ancestor subtype) of a @nt<private_extension_declaration>
+is the subtype defined by the @i(ancestor_)@address@hidden<address@hidden>;
+the ancestor type shall be a specific tagged type.
+The full view of a private extension shall be derived
+(directly or indirectly) from the ancestor type.
+In addition to the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}),
+the requirement that the ancestor be specific applies also in the
+private part of an instance of a generic address@hidden contract issue}
address@hidden
+  This rule allows the full view to be defined
+  through several intermediate derivations,
+  possibly from a series of types produced by
+  @nt{generic_instantiation}s.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00419-01],ARef=[AI95-00443-01]}
address@hidden,Text=[If the reserved word @key{limited} appears in a
address@hidden, the ancestor type shall be a limited type.
+If the reserved word @key{synchronized} appears in a
address@hidden, the ancestor type shall be a limited
+interface.]}
+
+If the declaration of a partial view includes
+a @nt{known_discriminant_part}, then
+the @nt{full_type_declaration} shall have a fully conforming
address@hidden(explicit)]
address@hidden
address@hidden(see @RefSec(Conformance Rules))].
address@hidden conformance],Sec=(required)}
address@hidden ancestor subtype may be unconstrained;
+the parent subtype of the full view is required to be constrained
+(see @RefSecNum{Discriminants}).]
address@hidden
+  If the ancestor subtype has discriminants,
+  then it is usually best to make it unconstrained.
address@hidden
+
address@hidden
+  If the partial view has a @nt<known_discriminant_part>,
+  then the full view has to be a composite, non-array type,
+  since only such types may have known discriminants.
+  Also, the full view cannot inherit the discriminants in this case;
+  the @nt{known_discriminant_part} has to be explicit.
+
+  @address@hidden@;That is, the following is illegal:
+  @begin{Example}
address@hidden P @key[is]
+    @key[type] T(D : Integer) @key[is] @key[private];
address@hidden
+    @key[type] T @key[is] @key[new] Some_Other_Type; address@hidden Illegal!}
address@hidden P;
+  @end{Example}
+  even if Some_Other_Type has an integer discriminant called D.
+
+  It is a ramification of this and other rules that in order for
+  a tagged type to privately inherit unconstrained discriminants,
+  the private type declaration has to have an
+  @nt{unknown_discriminant_part}.
address@hidden
+
+
+If a private extension inherits known discriminants from the ancestor subtype,
+then the full view shall also inherit its discriminants from the
+ancestor subtype,
+and the parent subtype of the full view shall be constrained
+if and only if the ancestor subtype is constrained.
address@hidden
+  The first part ensures that the full view has the same discriminants
+  as the partial view.
+  The second part ensures that if the partial view is unconstrained,
+  then the full view is also unconstrained;
+  otherwise, a client might constrain the partial view in a way that
+  conflicts with the constraint on the full view.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00419-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0004-1]}
address@hidden,Text=[If the @nt{full_type_declaration} for a private
+extension @Chg{Version=[3],New=[includes],Old=[is]} a
address@hidden,address@hidden,address@hidden,
+then the reserved word
address@hidden shall appear in the @nt{full_type_declaration} if and only if it
+also appears in the @nt{private_extension_declaration}.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0004-1]}
+  @ChgAdded{Version=[2],Text=[The word @key{limited} is optional (unless the
+  ancestor is an interface), but it should be used consistently. Otherwise
+  things would be too confusing for the reader. Of course, we only require
+  that if the full type @Chg{Version=[3],New=[includes],Old=[is defined by]}
+  a @nt{derived_type_definition}, as we
+  want to allow task and protected types to complete extensions of synchronized
+  interfaces.]}
address@hidden
+
address@hidden a partial view has unknown discriminants,
+then the @nt{full_type_declaration} may define
+a definite or an indefinite subtype, with or without discriminants.]
+
+If a partial view has neither known nor unknown discriminants,
+then the @nt{full_type_declaration} shall define a definite subtype.
+
+If the ancestor subtype of a private extension has constrained
+discriminants,
+then the parent subtype of the full view shall impose a statically
+matching constraint on those discriminants.
address@hidden matching],Sec=(required)}
address@hidden
+  If the parent type of the full view is not the ancestor type,
+  but is rather some descendant thereof, the constraint on
+  the discriminants of the parent type might come from
+  the declaration of some intermediate type in the derivation
+  chain between the ancestor type and the parent type.
address@hidden
address@hidden
address@hidden@keepnext@;This prevents the following:
address@hidden
address@hidden P @key[is]
+    @key[type] T2 @key[is] @key[new] T1(Discrim => 3) @key[with] @key[private];
address@hidden
+    @key[type] T2 @key[is] @key[new] T1(Discrim => 999) address@hidden 
Illegal!}
+        @key[with] @key[record] ...;
address@hidden P;
address@hidden
+
+The constraints in this example do not statically match.
+
address@hidden@;If the constraint on the parent subtype of the full view 
depends on
+discriminants of the full view, then the ancestor subtype has to be
+unconstrained:
address@hidden
address@hidden One_Discrim(A: Integer) @key[is] @key[tagged] ...;
+...
address@hidden P @key[is]
+    @key[type] Two_Discrims(B: Boolean; C: Integer) @key[is] @key[new] 
One_Discrim @key[with] @key[private];
address@hidden
+    @key[type] Two_Discrims(B: Boolean; C: Integer) @key[is] @key[new] 
One_Discrim(A => C) @key[with]
+        @key[record]
+            ...
+        @key[end] @key[record];
address@hidden P;
address@hidden
+
+The above example would be illegal if the private extension said
address@hidden@;is new One_Discrim(A => C);@rquotes@;,
+because then the constraints would not statically match.
+(Constraints that depend on discriminants are not static.)
+
address@hidden
address@hidden
+
address@hidden
address@hidden type}
+A @nt{private_type_declaration} declares a private type
+and its first subtype.
address@hidden extension}
+Similarly, a @address@hidden@!declaration} declares a private
+extension and its first subtype.
address@hidden
address@hidden type}
+A @i(package-private type) is one
+declared by a @nt<private_type_declaration>;
+that is,
+a private type other than a generic formal private type.
address@hidden extension}
+Similarly, a @i(package-private extension) is one
+declared by a @nt<private_extension_declaration>.
+These terms are not used in the RM95 version of this document.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0269-1]}
+A declaration of a partial view and the corresponding
address@hidden define two views of a single type.
+The declaration of a partial view
+together with the visible part define the operations that are
+available to outside program units;
+the declaration of the full view together with
+the private part define other operations whose direct use is
+possible only within the declarative region of the package itself.
address@hidden,New=[],address@hidden,
+within the scope of the declaration of the full view, the
address@hidden,New=[characteristics (see
address@hidden Types and Classes})],address@hidden
+of the type are determined by the full view;
+in particular, within its scope, the full view determines
+the classes that include the type,
+which components, entries, and protected subprograms are visible,
+what attributes and other predefined operations are allowed,
+and whether the first subtype is static.
+See @RefSecNum{Private Operations}.
+
address@hidden,Kind=[Revised],ARef=[AI95-00401-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0110-1]}
address@hidden,New=[For a],Old=[A]}
+private address@hidden,New=[, the characteristics],
+Old=[inherits components]} (including
address@hidden,New=[components, but excluding ],Old=[]}discriminants
address@hidden,New=[if],Old=[unless]} there is a new @nt<discriminant_part>
+specified)@Chg{Version=[3],New=[, predefined operators,],Old=[]} and
address@hidden,New=[inherited ],Old=[]}user-defined primitive
+subprograms @Chg{Version=[3],New=[are determined
+by],Old=[from]} its ancestor address@hidden,New=[ and its progenitor
+types (if any)],Old=[]}, in the same way address@hidden,New=[ those
+of],Old=[]} a record extension @Chg{Version=[3],New=[are determined
+by those of],Old=[inherits components and user-defined primitive
+subprograms from]} its parent address@hidden,New=[ and its progenitor
+types],Old=[]}
+(see @RefSecNum{Derived Types and address@hidden,New=[ and
address@hidden Operations}],Old=[]}).
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0110-1]}
+If an operation of the @Chg{Version=[3],New=[ancestor or],Old=[]} parent type
+is abstract, then the abstractness of the inherited operation
+is different for nonabstract record extensions
+than for nonabstract private extensions
+(see @RefSecNum{Abstract Types and Subprograms}).
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(private_type_declaration)}
+The elaboration of a @nt{private_type_declaration} creates a partial
+view of a type.
address@hidden, Sec=(private_extension_declaration)}
+The elaboration of a @nt{private_extension_declaration} elaborates
+the @i(ancestor_)@nt<subtype_indication>, and creates a
+partial view of a type.
address@hidden
+
address@hidden
+The partial view of a type as declared by a @nt<private_type_declaration>
+is defined to be a composite view (in @RefSecNum{Types and Subtypes}).
+The full view of the type might or might not be composite.
+A private extension is also composite,
+as is its full view.
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
+Declaring a private type with an @nt{unknown_discriminant_part} is a
+way of preventing clients from creating uninitialized objects of the
+type; they are then forced to initialize each object by calling some
+operation declared in the visible part of the package.
address@hidden,New=[],Old=[If such a type is also limited, then no objects
+of the type can be declared outside the scope of the 
@nt{full_type_declaration},
+restricting all object creation to the package defining the type. This
+allows complete control over all storage allocation for the type.
+Objects of such a type can still be passed as parameters, however.]}
address@hidden
address@hidden contract/private type contract analogy}
+Packages with private types are analogous to generic packages with
+formal private types,
+as follows:
+The declaration of a package-private type is like the declaration of
+a formal private type.
+The visible part of the package is like the generic formal part;
+these both specify a contract (that is, a set of operations and other
+things available for the private type).
+The private part of the package is like an instantiation of the generic;
+they both give a @nt{full_type_declaration} that specifies implementation
+details of the private type.
+The clients of the package are like the body of the generic;
+usage of the private type in these places is restricted to the
+operations defined by the contract.
+
+In other words, being inside the package is like being outside the
+generic, and being outside the package is like being inside the
+generic;
+a generic is like an @lquotes@;address@hidden@; package.
+
+This analogy also works for private extensions
+in the same inside-out way.
+
+Many of the legality rules are defined with this analogy in mind.
+See, for example, the rules relating to operations of [formal]
+derived types.
+
+The completion rules for a private
+type are intentionally quite similar to the matching rules for a
+generic formal private type.
+
+This analogy breaks down in one respect:
+a generic actual subtype is a subtype,
+whereas the full view for a private type is always a new type.
+(We considered allowing the completion of a @nt{private_type_declaration}
+to be a @nt{subtype_declaration},
+but the semantics just won't work.)
+This difference is behind the fact that a generic actual type can be
+class-wide, whereas the completion of a private type always declares
+a specific type.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00401]}
+The ancestor type specified in a @nt<private_extension_declaration>
+and the parent type specified in the corresponding declaration
+of a record extension given in the private part need not be the
address@hidden,New=[. If the ancestor
+type is not an interface type,],Old=[ @em]} the parent type of the full view
+can be any descendant of the ancestor type.
+In this case, for a primitive subprogram that is inherited from the
+ancestor type and
+not overridden, the formal parameter names and default expressions (if any)
+come from the corresponding primitive subprogram of the specified ancestor
+type, while the body comes from the corresponding primitive subprogram
+of the parent type of the full view.
+See @RefSecNum{Dispatching Operations of Tagged Types}.
+
address@hidden,Kind=[Added],ARef=[AI95-00401]}
address@hidden,Text=[If the ancestor type specified in a
address@hidden is an
+interface type, the parent type can be any type so long as the full view is a
+descendant of the ancestor type. The progenitor types specified in a
address@hidden and the progenitor types specified in the
+corresponding declaration of a record extension given in the private part need
+not be the same @em the only requirement is that the private extension and the
+record extension be descended from the same set of interfaces.]}
address@hidden
+
address@hidden
address@hidden@address@hidden of private type declarations:}
address@hidden
address@hidden Key @key[is] @key[private];
address@hidden File_Name @key[is] @key[limited] @key[private];
address@hidden
+
address@hidden
address@hidden@address@hidden of a private extension declaration:}
address@hidden
address@hidden
address@hidden List @key[is] @key[new] Ada.Finalization.Controlled @key[with] 
@key[private];
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax for a @nt{private_type_declaration} is augmented to
+allow the reserved word @key{tagged}.
+
+In Ada 83, a private type without discriminants cannot be completed
+with a type with discriminants.
+Ada 95 allows the full view to have discriminants,
+so long as they have defaults
+(that is, so long as the first subtype is definite).
+This change is made for uniformity with generics,
+and because the rule as stated is simpler and easier to remember
+than the Ada 83 rule.
+In the original version of Ada 83, the same restriction applied
+to generic formal private types.
+However, the restriction was removed by the ARG for generics.
+In order to maintain the @lquotes@;generic contract/private type contract 
address@hidden@;
+discussed above, we have to apply the same rule to
+package-private types.
+Note that a private untagged type without discriminants can be
+completed with a tagged type with discriminants only if the
+full view is constrained, because discriminants of tagged types
+cannot have defaults.
address@hidden
+
address@hidden
+RM83-7.4.1(4),
address@hidden@;Within the specification of the package that declares a private 
type
+and before the end of the corresponding full type declaration, a
+restriction address@hidden@;,
+is subsumed (and corrected) by the rule that
+a type shall be completely defined before it is frozen,
+and the rule that the parent type of a derived type declaration shall be
+completely defined, unless the derived type is a private extension.
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01],ARef=[AI95-00396-01],ARef=[AI95-00401-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Added @nt{interface_list} to private extensions to
+  support interfaces and multiple inheritance
+  (see @RefSecNum{Interface Types}).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00419-01]}
+  @ChgAdded{Version=[2],Text=[A private extension may specify that it is a
+  limited type. This is required for interface ancestors (from which
+  limitedness is not inherited), but it is generally useful as documentation of
+  limitedness.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00443-01]}
+  @ChgAdded{Version=[2],Text=[A private extension may specify that it is a
+  synchronized type. This is required in order so that a regular limited
+  interface can be used as the ancestor of a synchronized type (we do not
+  allow hiding of synchronization).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a 
@nt{private_type_declaration} and
+  a @nt{private_extension_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0110-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> The description of how a
+  private extension inherits characteristics was made consistent with the
+  way formal derived types inherit characteristics (see
+  @RefSecNum{Formal Private and Derived Types}).]}
address@hidden
+
+
+
address@hidden Operations}
+
address@hidden
address@hidden a type declared in the visible part of a package
+or generic package, certain operations on the type
+do not become visible until later in the package @em
+either in the private part or the body.
address@hidden operations}
+Such @i{private operations} are available only inside the declarative
+region of the package or generic package.]
address@hidden
+
address@hidden
+The predefined operators that exist for a given type are determined by
+the classes to which the type belongs.
+For example, an integer type has a predefined "+" operator.
+In most cases, the predefined operators of a type are declared
+immediately after the definition of the type;
+the exceptions are explained below.
+Inherited subprograms are also implicitly declared
+immediately after the definition of the type,
+except as stated below.
+
address@hidden,Kind=[Revised],Ref=[8652/0019],ARef=[AI95-00033-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0029-1]}
+For a composite type, the characteristics
+(see @RefSecNum{Private Types and Private Extensions})
+of the type are determined in part by the
+characteristics of its component types.
+At the place where the composite type is declared,
+the only characteristics of component types used are those
+characteristics visible at that place.
+If later @Chg{New=[immediately within the declarative region in which the
+composite type is declared],
+Old=[within the immediate scope of the composite type]} additional
+characteristics become visible for a component type,
+then any corresponding characteristics become visible for the composite
+type.
+Any additional predefined operators are implicitly declared at that
address@hidden,New=[ If there is no such place, then additional
+predefined operators are not declared at all, but they still exist.],Old=[]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0029-1]}
+  @ChgAdded{Version=[3],Text=[We say that the predefined operators exist
+  because they can emerge in some unusual generic instantiations. See
+  @RefSecNum{Formal Types}.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0029-1]}
+  @ChgAdded{Version=[3],Text=[The predefined operators for the underlying class
+  of a type always exist, even if there is no visibility on that underlying
+  class. This rule is simply about where (if ever) those operators are
+  declared (and thus become usable). The @ldquote@;additional predefined
+  address@hidden defined by this rule are any that are not declared at the
+  point of the original type declaration. For instance, a type derived from a
+  private type whose full type is type String always will have a ">"
+  operator, but where that operator is declared (and thus whether it is
+  visible) will depend on the visibility of the full type of the parent type.]}
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0019],ARef=[AI95-00033-01]}
+The corresponding rule applies to a type defined by a
address@hidden,
+if there is a place @Chg{New=[immediately within the declarative region in 
which
+the type is declared],
+Old=[within its immediate scope]} where additional
+characteristics of its parent type become visible.
+
address@hidden,Kind=[Revised],Ref=[8652/0019],ARef=[AI95-00033-01]}
address@hidden nonlimited}
address@hidden type],Sec=(becoming nonlimited)}
address@hidden type],Sec=(becoming nonlimited)}
address@hidden example, an array type whose component type is limited
+private becomes nonlimited if the full view of the component type is
+nonlimited and visible at some later place @Chg{New=[immediately within the 
declarative region in which
+the array type is declared.],
+Old=[within the immediate scope of the array type.]}
+In such a case, the predefined "=" operator is implicitly declared at
+that place, and assignment is allowed after that place.]
+
address@hidden,Kind=[Added],ARef=[AI05-0115-1],ARef=[AI05-0269-1]}
address@hidden,Text=[A type is a @i<descendant>@Defn2{Term=[descendant],
+Sec=[of the full view of a type]} of the full view of some ancestor
+of its parent type only if the current view it has of its parent is a
+descendant of the full view of that ancestor. More generally, at any given
+place, a type is descended from the same view of an ancestor as that from which
+the current view of its parent is descended. This view determines what
+characteristics are inherited from the address@hidden, and, for example,
+whether the type is considered to be a descendant of a record type, or a
+descendant only through record extensions of a more distant ancestor].]}
+
address@hidden,Kind=[Added],ARef=[AI05-0115-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0065-1]}
address@hidden,address@hidden@Chg{Version=[4],New=[Furthermore,
+it],Old=[It]} is possible for there to be places
+where a derived type is @Chg{Version=[4],New=[known to be derived
+indirectly from],Old=[visibly a descendant of]} an ancestor type, but
address@hidden,New=[is ],Old=[]}not a
+descendant of even a partial view of the ancestor type, because the parent
+of the derived type is not visibly a descendant of the ancestor.  In
+this case, the derived type inherits no characteristics from that
+ancestor, but nevertheless is within the derivation class of the
+ancestor for the purposes of type conversion, the "covers"
+relationship, and matching against a formal derived type. In this
+case the derived type is @Chg{Version=[4],New=[effectively],Old=[considered
+to be]} a @i<descendant> of an incomplete view of the 
address@hidden,New=[],address@hidden,
+Sec=[of an incomplete view]}]}]]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[Here is an example of this 
situation:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden P @key[is]
+   @key[type] T @key[is] @key[private];
+   C : @key[constant] T;
address@hidden
+   @key[type] T @key[is new] Integer;
+   C : @key[constant] T := 42;
address@hidden P;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0065-1]}
address@hidden,address@hidden P;
address@hidden Q @key[is]
+    @key[type] T2 @key[is new] P.T;@Chg{Version=[4],New=[  -- @Examcom{T2 is 
@b<not> a descendant of Integer}],Old=[]}
address@hidden Q;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0065-1]}
address@hidden,address@hidden Q;
address@hidden P.Child @key[is]
+    @key[type] T3 @key[is new] Q.T2;
address@hidden
+    @Chg{Version=[4],New=[-- @Examcom{Here T3 is known to be indirectly 
derived from Integer, but inherits}
+    -- @address@hidden<no> characteristics from Integer, since T2 inherits no 
characteristics}
+    -- @Examcom{from Integer.}
+    -- @Examcom{However, we allow an explicit conversion of T3 to/from 
Integer.}
+    -- @Examcom{Hence, T3 is effectively a descendant of an "incomplete" view 
of Integer.}
+    ],Old=[]}Int : Integer := 52;
+    V : T3 := T3(P.C);  -- @Examcom{Legal: conversion allowed}
+    W : T3 := T3(Int);  -- @Examcom{Legal: conversion allowed}
+    X : T3 := T3(42);   -- @Examcom{Error: T3 is not a numeric type}
+    Y : T3 := X + 1;    -- @Examcom{Error: no visible "+" operator}
+    Z : T3 := T3(Integer(W) + 1);   -- @Examcom{Legal: convert to Integer 
first}
address@hidden P.Child;]}
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0019],ARef=[AI95-00033-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0029-1]}
+Inherited primitive subprograms follow a different rule.
+For a @nt{derived_type_definition},
+each inherited primitive subprogram
+is implicitly declared at the earliest place, if any,
address@hidden within the declarative region in which],
+Old=[within the immediate scope of]} the @address@hidden occurs],Old=[]},
+but after the @nt{type_declaration},
+where the corresponding declaration from the parent is
+visible.
+If there is no such place, then the inherited subprogram
+is not declared at address@hidden,New=[, but it still exists],Old=[]}.
address@hidden@Chg{Version=[3],New=[For a tagged type, it is possible to
+dispatch to an],Old=[An]} inherited subprogram that is not declared at
address@hidden,New=[],Old=[cannot be named in a call and cannot be
+overridden, but for a tagged type, it is possible to dispatch to it]}.]
+
+For a @nt{private_extension_declaration}, each inherited subprogram is
+declared immediately after the @nt{private_extension_declaration}
+if the corresponding declaration from the ancestor is visible at that
+place.
+Otherwise, the inherited subprogram is not declared for the private
+extension, @Redundant[though it might be for the full type].
address@hidden
+  @ChgRef{Version=[1],Kind=[Revised]}
+  There is no need for the @lquotes@;earliest place
+  @Chg{New=[immediately within the declarative region],
+  Old=[within the immediate address@hidden@;
+  business here, because a @nt{private_extension_declaration} will be
+  completed with a @nt{full_type_declaration}, so we can hang the
+  necessary private implicit declarations on the @nt{full_type_declaration}.
address@hidden
address@hidden
+The above rules matter only when the component type (or parent type) is
+declared in the visible part of a package, and the composite type (or
+derived type) is declared within the declarative region of that package
+(possibly in a nested package or a child package).
+
address@hidden@keepnext@;Consider:
address@hidden
address@hidden Parent @key[is]
+    @key[type] Root @key[is] @key[tagged] @key[null] @key[record];
+    @key[procedure] Op1(X : Root);
+
+    @key[type] My_Int @key[is] @key[range] 1..10;
address@hidden
+    @key[procedure] Op2(X : Root);
+
+    @key[type] Another_Int @key[is] @key[new] My_Int;
+    @key[procedure] Int_Op(X : My_Int);
address@hidden Parent;
+
address@hidden Parent; @key[use] Parent;
address@hidden Unrelated @key[is]
+    @key[type] T2 @key[is] @key[new] Root @key[with] @key[null] @key[record];
+    @key[procedure] Op2(X : T2);
address@hidden Unrelated;
+
address@hidden Parent.Child @key[is]
+    @key[type] T3 @key[is] @key[new] Root @key[with] @key[null] @key[record];
+    address@hidden Op1(T3) implicitly declared here.}
+
+    @key[package] Nested @key[is]
+        @key[type] T4 @key[is] @key[new] Root @key[with] @key[null] 
@key[record];
+    @key[private]
+        ...
+    @key[end] Nested;
address@hidden
+    address@hidden Op2(T3) implicitly declared here.}
+    ...
address@hidden Parent.Child;
+
address@hidden Unrelated; @key[use] Unrelated;
address@hidden @key[body] Parent.Child @key[is]
+    @key[package] @key[body] Nested @key[is]
+        address@hidden Op2(T4) implicitly declared here.}
+    @key[end] Nested;
+
+    @key[type] T5 @key[is] @key[new] T2 @key[with] @key[null] @key[record];
address@hidden Parent.Child;
address@hidden
+
+Another_Int does not inherit Int_Op,
+because Int_Op does not @lquotes@;address@hidden@; at the place
+where Another_Int is declared.
+
address@hidden,Kind=[Revised]}
+Type T2 inherits Op1 and Op2 from Root.
+However, the inherited Op2 is never declared,
+because Parent.Op2 is never visible @Chg{New=[immediately within the 
declarative region],
+Old=[within the immediate scope]} of T2.
+T2 explicitly declares its own Op2,
+but this is unrelated to the inherited one @em it
+does not override the inherited one,
+and occupies a different slot in the type descriptor.
+
+T3 inherits both Op1 and Op2. Op1 is implicitly declared immediately
+after the type declaration,
+whereas Op2 is declared at the beginning of the private part.
+Note that if Child were a private child of Parent,
+then Op1 and Op2 would both be implicitly declared immediately after the
+type declaration.
+
address@hidden,Kind=[Revised]}
+T4 is similar to T3, except that the earliest place
address@hidden within the declarative region containing T4],
+Old=[within T4's immediate scope]}
+where Root's Op2 is visible is in the body of Nested.
+
+If T3 or T4 were to declare a type-conformant Op2,
+this would override the one inherited from Root.
+This is different from the situation with T2.
+
+
+T5 inherits Op1 and two Op2's from T2.
+Op1 is implicitly declared immediately after the declaration of T5,
+as is the Op2 that came from Unrelated.Op2.
+However, the Op2 that originally came from Parent.Op2 is never
+implicitly declared for T5,
+since T2's version of that Op2 is never visible (anywhere @em it never
+got declared either).
+
+For all of these rules, implicit private parts and bodies are assumed as
+needed.
+
address@hidden@keepnext@;It is possible for characteristics of a type to be 
revealed
+in more than one place:
+
address@hidden
address@hidden P @key[is]
+    @key[type] Comp1 @key[is] @key[private];
address@hidden
+    @key[type] Comp1 @key[is] @key[new] Boolean;
address@hidden P;
+
address@hidden P.Q @key[is]
+    @key[package] R @key[is]
+        @key[type] Comp2 @key[is] @key[limited] @key[private];
+        @key[type] A @key[is] @key[array](Integer @key[range] <>) @key[of] 
Comp2;
+    @key[private]
+        @key[type] Comp2 @key[is] @key[new] Comp1;
+        address@hidden A becomes nonlimited here.}
+        address@hidden "="(A, A) return Boolean is implicitly declared here.}
+        ...
+    @key[end] R;
address@hidden
+    address@hidden Now we find out what Comp1 really is, which reveals}
+    address@hidden more information about Comp2, but we're not within}
+    address@hidden the immediate scope of Comp2, so we don't do anything}
+    address@hidden about it yet.}
address@hidden P.Q;
+
address@hidden @key[body] P.Q @key[is]
+    @key[package] @key[body] R @key[is]
+        address@hidden Things like "@key[xor]"(A,A) return A are implicitly}
+        address@hidden declared here.}
+    @key[end] R;
address@hidden P.Q;
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0019],ARef=[AI95-00033-01]}
address@hidden,Type=[Leading],Text=[We say @i<immediately> within
+the declarative region in order that
+types do not gain operations within a nested scope. Consider:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden@Key[package] Outer @key[is]
+    @key[package] Inner @key[is]
+        @key[type] Inner_Type @key[is] @key[private];
+    @key[private]
+        @key[type] Inner_Type @key[is] @key[new] Boolean;
+    @key[end] Inner;
+    @key[type] Outer_Type @key[is] @key[array](Natural @key[range] <>) 
@key[of] Inner.Inner_Type;
address@hidden Outer;],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden@key[package] @key[body] Outer @key[is]
+    @key[package] @key[body] Inner @key[is]
+        -- At this point, we can see that Inner_Type is a Boolean type.
+        -- But we don't want Outer_Type to gain an "and" operator here.
+    @key[end] Inner;
address@hidden Outer;],Old=[]}
address@hidden
address@hidden
+
address@hidden@Redundant[The Class attribute is defined for tagged subtypes in
address@hidden Types and Type Extensions}.
+In addition,] for
address@hidden subtype S of an untagged private type
+whose full view is tagged},
+the following attribute is defined:
address@hidden(description)
address@hidden<S>, AttrName=<Class>,
+  Text=<Denotes the class-wide subtype corresponding to the full
+  view of S.
+  This attribute is allowed only from the beginning of the private part
+  in which the full view is declared, until the declaration of the full
+  view.
+  @Redundant[After the full view,
+  the Class attribute of the full view can be used.]>}
address@hidden(description)
address@hidden
address@hidden
+
address@hidden
+Because a partial view and a full view
+are two different views of one and the same type,
+outside of the defining package the characteristics of the type are
+those defined by the visible part.
+Within these outside program units the type is just a private type
+or private extension,
+and any language rule that applies only to another class of types
+does not apply. The fact that the full declaration might implement
+a private type with a type of a particular class (for example, as
+an array type) is relevant only
+within the declarative region of the package itself
+including any child units.
+
address@hidden@;The consequences of this actual implementation are, however, 
valid
+everywhere. For example: any default initialization of components
+takes place; the attribute Size provides the size of the full view;
+finalization is still done for controlled components of the full view;
+task dependence rules still apply to components that are task
+objects.
+
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
+Partial views provide @Chg{Version=[2],New=[initialization],
+Old=[assignment (unless the view is limited)]},
+membership tests, selected components for the selection of
+discriminants and inherited components, qualification,
+and explicit address@hidden,New=[ Nonlimited partial views
+also allow use of @nt{assignment_statement}s.],Old=[]}
+
+For a subtype S of a partial view, S'Size is defined
+(see @RefSecNum{Operational and Representation Attributes}).
+For an object A of a partial view,
+the attributes A'Size and A'Address are defined
+(see @RefSecNum{Operational and Representation Attributes}).
+The Position, First_Bit, and Last_Bit attributes
+are also defined for discriminants and inherited components.
address@hidden
+
address@hidden
address@hidden@address@hidden of a type with private operations:}
address@hidden
address@hidden Key_Manager @key[is]
+   @key[type] Key @key[is] @key[private];
+   Null_Key : @key[constant] Key; address@hidden a deferred constant 
declaration (see @RefSecNum{Deferred Constants})}
+   @key[procedure] Get_Key(K : @key[out] Key);
+   @key[function] "<" (X, Y : Key) @key[return] Boolean;
address@hidden
+   @key[type] Key @key[is] @key[new] Natural;
+   Null_Key : @key[constant] Key := Key'First;
address@hidden Key_Manager;
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden @key[body] Key_Manager @key[is]
+   Last_Key : Key := Null_Key;
+   @key[procedure] Get_Key(K : @key[out] Key) @key[is]
+   @key[begin]
+      Last_Key := Last_Key + 1;
+      K := Last_Key;
+   @key[end] Get_Key;
+
+   @key[function] "<" (X, Y : Key) @key[return] Boolean @key[is]
+   @key[begin]
+      @key[return] Natural(X) < Natural(Y);
+   @key[end] "<";
address@hidden Key_Manager;
address@hidden
address@hidden
+
address@hidden
address@hidden on the example:}
+Outside of the package Key_Manager, the operations available for
+objects of type Key include assignment, the comparison for equality
+or inequality, the procedure Get_Key and the operator "<"; they do
+not include other relational operators such as ">=", or arithmetic
+operators.
+
address@hidden@;The explicitly declared operator "<" hides the predefined 
operator
+"<" implicitly declared by the @nt{full_type_declaration}. Within the
+body of the function, an explicit conversion of X and Y to the
+subtype Natural is necessary to invoke the "<" operator of the parent
+type.
+Alternatively, the result of the function could be written as not (X
+>= Y), since the operator ">=" is not redefined.
+
address@hidden@;The value of the variable Last_Key, declared in the package 
body,
+remains unchanged between calls of the procedure Get_Key. (See also
+the NOTES of @RefSecNum{Package Bodies}.)
address@hidden
+
address@hidden
+The phrase in RM83-7.4.2(7), @lquotes@;...after the full type address@hidden@;,
+doesn't work in the presence of child units, so we define that rule in
+terms of visibility.
+
+The definition of the Constrained attribute for private types
+has been moved to @lquotes@;Obsolescent address@hidden@;
+(The Constrained attribute of an object has not been moved there.)
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0018],ARef=[AI95-00033-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified when additional
+  operations are declared.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],Text=[Revised the note on operations of partial views
+  to reflect that limited types do have an assignment operation, but not
+  @nt{assignment_statement}s.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0029-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Revised the wording to say
+  that predefined operations still exist even if they are never declared,
+  because it is possible to reference them in a generic unit.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0115-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified that the 
characteristics
+  of a descendant of a private type depend on the visibility of the full
+  view of the direct ancestor. This has to be the case (so that privacy is not
+  violated), but it wasn't spelled out in earlier versions of Ada.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0065-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified the 
clarification added
+  by AI05-0115-1, as it turned out to not be that clear. Hopefully this version
+  is better.]}
address@hidden
+
+
address@hidden,Name=[Type Invariants]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0146-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0041-1]}
address@hidden,Type=[Leading],Text=[For a private address@hidden,New=[,],Old=[ 
or]} private
address@hidden,New=[, or interface],Old=[]}, the following
+language-defined aspects may be specified with an
address@hidden (see @RefSecNum{Aspect Specifications}):]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0146-1],ARef=[AI05-0250-1]}
address@hidden,address@hidden aspect
+   shall be specified by an @nt{expression}, called an @i<invariant
+   expression>address@hidden expression}
+   Type_Invariant may be specified on a @address@hidden@!declaration}, on a
+   @address@hidden@!declaration}, or on a @address@hidden@!declaration} that
+   declares the completion of a private type or private
+   address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Type_Invariant],
+    address@hidden,Text=[A condition that must hold true for all
+      objects of a type.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0146-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0041-1],ARef=[AI12-0150-1]}
address@hidden,Text=[Type_Invariant'address@hidden aspect
+   shall be specified by an @nt{expression}, called an @i<invariant
+   expression>.
+   Type_Invariant'Class may be specified on a
+   @address@hidden@address@hidden,New=[,],Old=[ or]} a
+   @address@hidden@address@hidden,New=[, or a
+   @address@hidden@!declaration} for an
+   interface type],address@hidden'address@hidden,New=[
+   Type_Invariant'Class determines a @i{class-wide type invariant}
+   for a tagged address@hidden type address@hidden invariant],
+   address@hidden,Sec=[class-wide]}],Old=[]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0254-1]}
+  @ChgAdded{Version=[3],Text=[A class-wide type invariant cannot be hidden
+  in the private part, as the creator of an extension needs to know about it
+  in order to conform to it in any new or overriding operations. On the other
+  hand, a specific type invariant is not inherited, so that no operation
+  outside of the original package needs to conform to it; thus there is no
+  need for it to be visible.]}
address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Type_Invariant'Class],
+    address@hidden,Text=[A condition that must hold true for all
+      objects in a class of types.]}]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0146-1]}
address@hidden,Text=[The expected type for an invariant expression
+is any boolean address@hidden type],
+Sec=(invariant expression)}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0146-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0150-1],ARef=[AI12-0159-1]}
address@hidden,address@hidden an invariant expression, the
+identifier of the first subtype of the associated type denotes the current
+instance of the type.] Within an invariant expression
address@hidden,New=[for the Type_Invariant aspect of a],Old=[associated
+with]} type @i<T>, the type of @Chg{Version=[4],New=[this],Old=[the]}
+current instance is @i<T>@Chg{Version=[4],New=[. Within an invariant
+expression],Old=[for the Type_Invariant aspect and @i<T>'Class]}
+for the Type_Invariant'Class address@hidden,New=[ of a
+type @i<T>, the type of this current instance is interpreted as though it
+had a (notional) type @i<NT> that is a visible formal derived type whose
+ancestor type is @i<T>address@hidden The effect of this
+interpretation is that the only operations that can be applied to this
+current instance are those defined for such a formal derived type.]],Old=[.]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The first sentence is given formally in
+  @RefSecNum{Aspect Specifications}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0159-1]}
+  @ChgAdded{Version=[4],Text=[The rules for Type_Invariant'Class ensure
+  that the invariant expression is well-defined for any type descended
+  from @i<T>.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0146-1]}
address@hidden,address@hidden Type_Invariant'Class aspect shall not be
+specified for an untagged type.] The Type_Invariant aspect shall not be 
specified
+for an abstract type.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The first sentence is given formally in
+  @RefSecNum{Aspect Specifications}.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0042-1]}
address@hidden,Text=[If a type extension occurs at a point where a
+private operation of some ancestor is visible and inherited, and a
+Type_Invariant'Class expression applies to that ancestor, then the inherited
+operation shall be abstract or shall be overridden.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0250-1]}
address@hidden,address@hidden the Type_Invariant aspect is
+specified for a type @i<T>, then the invariant expression applies to @i<T>.]]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0146-1]}
address@hidden,address@hidden the Type_Invariant'Class aspect is
+specified for a tagged type @i<T>, then the invariant expression applies to all
+descendants of @i<T>.]]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=["Applies" is formally defined in
+  @RefSecNum{Aspect Specifications}.]}
address@hidden
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0146-1],ARef=[AI05-0247-1],ARef=[AI05-0290-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0150-1]}
address@hidden,Type=[Leading],Text=[If one or more invariant expressions
+apply to a @Chg{Version=[4],New=[nonabstract ],Old=[]}type @i<T>, then an
+invariant check is performed at the following places,
+on the specified object(s):@Defn{invariant address@hidden, language-defined],
+  Sec=[controlled by assertion policy]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0133-1]}
+  @ChgAdded{Version=[3],Text=[After successful
+    @Chg{Version=[4],New=[],Old=[default ]}initialization of an
+    object of type @i<T>@Chg{Version=[4],New=[ by default (see
+    @RefSecNum{Object Declarations})],Old=[]}, the check is performed on the
+    new address@hidden,New=[ unless the partial
+    view of @i<T> has unknown discriminants],Old=[]};]}
+
+  @begin{Reason}
+    @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0133-1]}
+    @ChgAdded{Version=[4],Text=[The check applies everywhere, even in the
+    package body, because default initialization has to work the same for
+    clients as it does within the package. As such, checks within the package
+    are either harmless or will uncover a bug that could also happen to a
+    client. However, if the partial view of the type has unknown discriminants,
+    no client of the package can declare a default-initialized object.
+    Therefore, no invariant check is needed, as all default initialized objects
+    are necessarily inside the package.]}
+  @end{Reason}
+
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0049-1]}
+  @ChgAdded{Version=[4],Text=[After successful explicit initialization of the
+  completion of a deferred constant with a part of type @i<T>, if the 
completion
+  is inside the immediate scope of the full view of @i<T>, and the deferred
+  constant is visible outside the immediate scope of @i<T>, the check is
+  performed on the part(s) of type @i<T>;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[After successful conversion to type @i<T>, the
+    check is performed on the result of the conversion;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0146-1],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],Text=[For a view conversion, outside the immediate 
scope
+  of @i<T>, that converts from a descendant of @i<T> (including @i<T> itself) 
to
+  an ancestor of type @i<T> (other than @i<T> itself), a check is performed on
+  the part of the object that is of type @i<T>:]}
+
+  @begin{InnerItemize}
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[after assigning to the view conversion; and]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[after successful return from a call that 
passes the view conversion
+    as an @key[in out] or @key[out] parameter.]}
+  @end{InnerItemize}
+
+  @begin{Ramification}
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[For a single view conversion that converts
+    between distantly related types, this rule could be triggered for
+    multiple types and thus multiple invariant checks may be needed.]}
+  @end{Ramification}
+  @begin{ImplNote}
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0299-1]}
+    @ChgAdded{Version=[3],Text=[For calls to inherited subprograms (including
+    dispatching calls), the implied view conversions mean that a wrapper is
+    probably needed. (See the Note at the bottom of this subclause for more
+    on the model of checks for inherited subprograms.)]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[For view conversions involving class-wide
+    types, the exact checks needed may not be known at compile-time. One
+    way to deal with this is to have an implicit dispatching operation
+    that is given the object to check and the tag of the target of the
+    conversion, and which first checks if the passed tag is not for itself,
+    and if not, checks the its invariant on the object and then calls
+    the operation of its parent type. If the tag is for itself, the
+    operation is complete.]}
+  @end{ImplNote}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0146-1]}
+  @ChgAdded{Version=[3],Text=[After a successful call on the Read or Input
+    @Chg{Version=[4],New=[stream-oriented],Old=[stream]} attribute of the
+    type @i<T>, the check is performed on the object
+    initialized by the @Chg{Version=[4],New=[],Old=[stream ]}attribute;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0146-1],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[An invariant is checked upon 
successful return from a call
+  on any subprogram or entry that:]}
+  @begin{Itemize}
+    
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0146-1],ARef=[AI05-0269-1]}
+    @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0042-1]}
+    @ChgAdded{Version=[3],Text=[is declared within the immediate
+      scope of type @i<T> (or by an instance of a generic unit, and the generic
+      is declared within the immediate scope of type 
@i<T>),@Chg{Version=[4],New=[],Old=[ and]}]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgRef{Version=[4],Kind=[Deleted],ARef=[AI12-0042-1]}
+    @ChgAdded{Version=[3],address@hidden,New=[],Old=[is visible outside the
+      immediate scope of type @i<T> or overrides an operation that is visible 
outside
+      the immediate scope of @i<T>, and]}]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0289-1]}
+    @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0042-1],ARef=[AI12-0044-1]}
+    @ChgAdded{Version=[4],Type=[Leading],address@hidden get conditional 
Leading}
+    @Chg{Version=[3],address@hidden,New=[and either:],
+      Old=[has a result with a part of type @i<T>, or one or more parameters
+      with a part of type @i<T>, or an access to variable
+      parameter whose designated type has a part of type @i<T>.]}],Old=[]}
+
address@hidden
+      @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0044-1]}
+      @ChgAdded{Version=[4],Text=[has a result with a part of type @i<T>, or]}
+
+      @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0044-1]}
+      @ChgAdded{Version=[4],Text=[has one or more @key[out] or @key[in out]
+        parameters with a part of type @i<T>, or]}
+
+      @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0044-1],ARef=[AI12-0149-1]}
+      @ChgAdded{Version=[4],Text=[has an access-to-object parameter or result
+        whose designated type has a part of type @i<T>, or]}
+
+      @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0042-1],ARef=[AI12-0044-1]}
+      @ChgAdded{Version=[4],Text=[is a procedure or entry that has an @key[in]
+        parameter with a part of type @i<T>,]}
+
address@hidden
+      @ChgRef{Version=[4],Kind=[AddedNormal]}
+      @ChgAdded{Version=[4],Text=[We don't check @key[in] parameters for
+        functions to avoid infinite recursion for calls to public functions
+        appearing in invariant expressions. Such function calls are unavoidable
+        for class-wide invariants and likely for other invariants. This is the
+        simplest rule that avoids trouble, and functions are much more likely 
to
+        be queries that don't modify their parameters than other callable
+        entities.]}
address@hidden
address@hidden
+
+    @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0042-1]}
+    @ChgAdded{Version=[4],Type=[Leading],Text=[and either:]}
+
+    @begin{Itemize}
+      @ChgRef{Version=[4],Kind=[Added]}
+      @ChgAdded{Version=[4],address@hidden<T> is a private type or a private 
extension
+        and the subprogram or entry is visible outside the immediate scope of
+        type @i<T> or overrides an inherited operation that is visible outside
+        the immediate scope of @i<T>, or]}
+
+      @ChgRef{Version=[4],Kind=[Added]}
+      @ChgAdded{Version=[4],address@hidden<T> is a record extension, and the
+        subprogram or entry is a primitive operation visible outside the
+        immediate scope of type @i<T> or overrides an inherited operation that
+        is visible outside the immediate scope of @i<T>.]}
+    @end{Itemize}
+  @end{Itemize}
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0146-1],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],NoPrefix=[T],Text=[The check is performed on each such
+  part of type @i<T>.]}
+
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0042-1]}
+  @ChgAdded{Version=[4],Text=[For a view conversion to a class-wide type
+  occurring within the immediate scope of @i<T>, from a specific type that is
+  a descendant of @i<T> (including @i<T> itself), a check is performed
+  on the part of the object that is of type @i<T>.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[Class-wide objects are treated as though they
+    exist outside the scope of every type, and may be passed across package
+    "boundaries" freely without further invariant checks.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0290-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0080-1],ARef=[AI12-0159-1]}
address@hidden,Text=[If performing checks is required by the
address@hidden,New=[Type_Invariant],Old=[Invariant]} or
address@hidden,New=[Type_Invariant'Class],Old=[Invariant'Class]} assertion
+policies (see
address@hidden Assert and Assertion_Policy}) in effect at the point of
address@hidden,New=[the ],Old=[]}corresponding aspect specification
+applicable to a given type, then the respective invariant expression is
+considered @i(enabled)address@hidden,Sec=[invariant expression]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If a class-wide invariant expression is enabled
+  for a type, it remains enabled when inherited by descendants of that type,
+  even if the policy in effect is Ignore for the inheriting type.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0146-1],ARef=[AI05-0250-1],ARef=[AI05-0289-1],ARef=[AI05-0290-1]}
address@hidden,Text=[The invariant check consists of the evaluation of
+each enabled invariant expression that applies to @i<T>, on each of the objects
+specified above. If any of these evaluate to False,
+Assertions.Assertion_Error is raised at the point of the object
+initialization, conversion, or address@hidden(Assertion_Error),
+Sec=(raised by failure of run-time check)} If a given call requires more than 
one
+evaluation of an invariant expression, either for multiple objects of a single
+type or for multiple types with invariants, the evaluations are performed in
+an arbitrary order, and if one of them evaluates to False, it is not specified 
whether
+the others are evaluated. Any invariant check is performed prior to copying 
back
+any by-copy @key[in out] or @key[out] parameters. Invariant checks,
+any postcondition check, and any
+constraint or predicate checks associated with @key[in out] or @key[out]
+parameters are performed in an arbitrary order.]}
+
address@hidden,Kind=[Added],ARef=[AI12-0150-1],ARef=[AI12-0159-1]}
address@hidden,Text=[For an invariant check on a value of type @i<T1>
+based on a class-wide invariant expression inherited from an ancestor type
address@hidden<T>, any operations within the invariant expression that were 
resolved as
+primitive operations of the (notional) formal derived type @i<NT> are
+bound to the corresponding operations of type @i<T1> in the
+evaluation of the invariant expression for the check on @i<T1>.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0146-1],ARef=[AI05-0247-1],ARef=[AI05-0250-1]}
address@hidden,Text=[The invariant checks performed on a call are
+determined by the subprogram or entry actually invoked, whether directly, as
+part of a dispatching call, or as part of a call through an 
access-to-subprogram
+value.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0149-1]}
+  @ChgAdded{Version=[3],Text=[Invariant checks on subprogram return are not
+  performed on objects that are accessible only through access
+  address@hidden,New=[ that are subcomponents of some other object],Old=[]}.
+  It is also possible to call through an access-to-subprogram value and reach a
+  subprogram body that has visibility on the full declaration of a type, from
+  outside the immediate scope of the type. No invariant checks will be 
performed
+  if the designated subprogram is not itself externally visible. These cases
+  represent "holes" in the protection provided by invariant checks; but note
+  that these holes cannot be caused by clients of the type @i<T> with the
+  address@hidden,New=[. The designer of the package has to declare
+  a visible type with an address@hidden<T> subcomponent and use it as a 
parameter
+  or result to subprograms in the package, or pass the client an
+  access-to-subprogram value representing a private operation of the package.
+  In the absence of such things, all values that the client can see will be
+  checked for a private type or extension],Old=[ without help for the
+  designer of the package containing @i<T>]}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The implementation might want to produce a 
warning
+  if a private extension has an ancestor type that is a visible extension, and
+  an invariant expression depends on the value of one of the components from a
+  visible extension part.]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0250-1],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],Text=[For a call of a primitive subprogram of type
+  @i<NT> that is inherited from type @i<T>, the specified checks of the 
specific
+  invariants of both the types @i<NT> and @i<T> are performed. For a call of a
+  primitive subprogram of type @i<NT> that is overridden for type @i<NT>, the
+  specified checks of the specific invariants of only type @i<NT> are
+  performed.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This follows from the definition of a call on
+  an inherited subprogram as view conversions of the parameters of the type
+  and a call to the original subprogram
+  (see @RefSecNum{Derived Types and Classes}), along with the normal invariant
+  checking rules. In particular, the call to the original subprogram takes
+  care of any checks needed on type @i<T>, and the checks required
+  on view conversions take care of any checks needed on type @i<NT>,
+  specifically on @key[in out] and @key[out] parameters. We require this in
+  order that the semantics of an explicitly defined wrapper that does nothing
+  but call the original subprogram is the same as that of an inherited
+  subprogram.]}
address@hidden
+
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0146-1],ARef=[AI05-0247-1],ARef=[AI05-0250-1],ARef=[AI05-0289-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Type_Invariant aspects are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0042-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada 2012}
+  @b<Corrigendum:> Clarified the definition of when invariant checks occur
+  for inherited subprograms. This might cause checks to be added or removed
+  in some cases. These are all rare cases involving class-wide type
+  invariants and either record extensions or multiple levels of derivation.
+  Additionally, implementations probably make the checks as the intent seems
+  clear, even though the formal language did not include them. So we do not
+  expect this to be a problem in practice.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0042-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Added invariant checks for
+  conversions to class-wide types. This might cause an invariant check to
+  fail in some cases where they would not be made in the original definition
+  of Ada 2012. Such cases represent a hole where a value that fails an
+  invariant could "leak out" of a package, and as such will detect far more
+  bugs than it causes.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0044-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Removed the invariant 
check
+  for @key[in] parameters of
+  functions, so that typical invariants don't cause infinite recursion.
+  This is strictly inconsistent, as the Ada 2012 definition has this check;
+  therefore, programs could depend on Assertion_Error being raised upon the
+  return from some call on a public function. However, as the intent of
+  assertion checking is to uncover bugs, a program that depends on a bug
+  occurring seems very unlikely.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0049-1],ARef=[AI12-0149-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Added an invariant check 
for
+  deferred constants and for access values returned from functions, so they
+  cannot be used to @ldquote@;address@hidden values that violate the invariant
+  from a package. This is strictly inconsistent, as the Ada 2012 definition
+  is missing these checks; therefore, programs could depend on using values
+  that violate an invariant outside of the package of definition. These will
+  not raise Assertion_Error in Ada 2012 as defined in the Ada 2012 Standard,
+  but ought to do so (as noted by this change). As these are a violation of
+  the intent of invariants, we think that this change will mainly reveal bugs
+  rather than cause them.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0150-1],ARef=[AI12-0159-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Eliminated unintentional
+  redispatching from class-wide type invariants. This means that a different
+  body might be evaluated for a type invariant check where the value
+  has a different tag than that of the type. The change means that the behavior
+  of Type_Invariant and Type_Invariant'Class will be the same for a particular
+  subprogram, and that the known behavior of the operations can be assumed.
+  We expect that this change will primarily fix bugs, as it will make
+  class-wide type invariants work more like expected. In the case where
+  redispatching is desired, an explicit conversion to a class-wide type can be
+  used.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0042-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada 2012}
+  @b<Corrigendum:> A private operation that is inherited in the visible
+  part of a package to which a class-wide invariant applies now requires
+  overriding. This is a very unlikely situation, and will prevent problems
+  with invariant checks being added to routines that assume that they don't
+  need them.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0041-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada 2012}
+  @b<Corrigendum:> Class-wide type invariants can now be specified on
+  interfaces as well as private types.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0133-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that all objects
+  that are initialized by default should have an invariant check, and
+  added an exception for types with unknown discriminants, as in that
+  case the client cannot declare a default-initialized object. This
+  exception to the check is formally inconsistent, but since it is only
+  removing an assertion failure that occurs where no assertion should be
+  checked anyway (meaning it's more likely to fix a bug than cause one),
+  and programs depending on assertion failure should be very rare outside of
+  test cases, we don't document this as inconsistent.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Constants}
+
address@hidden
address@hidden constant declarations may be used to declare constants
+in the visible part of a package,
+but with the value of the constant given in the private part.
+They may also be used to declare constants imported from other
+languages (see @RefSecNum{Interface to Other Languages}).]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1],ARef=[AI05-0269-1]}
address@hidden@Defn{deferred constant declaration}
+A @i(deferred constant declaration) is an @nt<object_declaration>
+with the reserved word @key(constant) but no initialization expression.]
address@hidden constant}
+The constant declared by a deferred constant declaration is called
+a @i{deferred constant}.
address@hidden a completion], Sec=(deferred constant declaration)}
address@hidden,address@hidden the Import aspect
+(see @RefSecNum{Interfacing Aspects}) is True for a deferred constant
+declaration, the ]],Old=[A]} deferred constant declaration requires a 
completion,
+which shall be a full constant declaration
+(called the @i{full declaration} of the deferred
+constant)@Chg{Version=[3],New=[],Old=[,
+or a @nt{pragma} Import (see @RefSecNum(Interface to Other Languages))]}.
address@hidden declaration}
address@hidden
+The first sentence is redundant, as it is stated officially in
address@hidden(Object Declarations).
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0269-1]}
address@hidden,Text=[The first part of the last sentence is redundant,
+as no imported entity may have a completion, as stated in
address@hidden Aspects}.]}
address@hidden
+
address@hidden@;A deferred constant declaration that is completed
+by a full constant declaration shall occur immediately
+within the visible part of a @nt<package_specification>.
+For this case, the following additional rules apply to the
+corresponding full declaration:
address@hidden(itemize)
+  The full declaration shall occur immediately
+  within the private part of the same package;
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00385-01]}
+  The deferred and full constants shall have the same address@hidden,
+  New=[, or shall have statically matching anonymous access subtypes],Old=[]};
+  @begin{Ramification}
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00385-01]}
+  This implies that
+  both the deferred declaration and the full declaration
+  have to have a @nt<subtype_indication>@Chg{Version=[2],New=[ or
+  @nt{access_definition}],Old=[]} rather than an
+  @nt<array_type_definition>, because each @nt{array_type_definition}
+  would define a new type.
+  @end{Ramification}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00385-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0062-1],ARef=[AI05-0262-1]}
+  If the @Chg{Version=[2],New=[deferred constant declaration includes
+  a],Old=[subtype defined by the]} @nt<subtype_indication>
+  @Chg{Version=[3],address@hidden<S> ],address@hidden,
+  New=[that defines a],Old=[in the deferred declaration is]}
+  address@hidden,New=[ subtype],Old=[]}, then the
+  @Chg{Version=[3],New=[constraint],Old=[subtype]} defined
+  by the @nt<subtype_indication> in the full declaration shall match
+  @Chg{Version=[3],New=[the constraint defined by @i<S>],Old=[it]}
+  address@hidden On the other hand,
+  if the subtype of the deferred constant is unconstrained,
+  then the full declaration is still allowed to impose a constraint.
+  The constant itself will be constrained, like all constants;]
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00231-01]}
+  If the deferred constant declaration
+  includes the reserved word @key(aliased), then the
+  full declaration shall address@hidden,New=[;],Old=[.]}
+  @begin{Ramification}
+    On the other hand, the full constant can be aliased
+    even if the deferred constant is not.
+  @end{Ramification}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],Text=[If the subtype of the deferred constant
+  declaration excludes null, the subtype of the full declaration shall also
+  exclude null.]}
+  @begin{Ramification}
+    @ChgRef{Version=[2],Kind=[Added]}
+    @ChgAdded{Version=[2],Text=[On the other hand, the full constant can
+    exclude null even if the deferred constant does not. But that can only
+    happen for a @nt{subtype_indication}, as anonymous access types are
+    required to statically match (which includes any @nt{null_exclusion}).]}
+  @end{Ramification}
address@hidden(itemize)
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden deferred constant declaration
+  @Chg{Version=[3],New=[for which the],Old=[that is completed by
+  a @nt{pragma}]} Import @Chg{Version=[3],New=[aspect is True ],Old=[]}need
+  not appear in the visible part of a @nt{package_specification},
+  and has no full constant declaration.]
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00256-01]}
+The completion of a deferred constant declaration shall occur
+before the constant is frozen
+(see @Chg{Version=[2],address@hidden Rules}],
address@hidden Constants}]}).
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0004-1]}
address@hidden, Sec=(deferred constant declaration)}
+The elaboration of a deferred constant declaration
+elaborates the @nt<subtype_indication>@Chg{Version=[3],New=[,
address@hidden<access_definition>,],Old=[]} or (only allowed in the case of an
+imported constant) the @nt<array_type_definition>.
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0004-1]}
+  @ChgAdded{Version=[3],Text=[For nonimported constants, these elaborations
+  cannot require any code or checks for a legal program, because the given
+  @nt<subtype_indication> has to be indefinite or statically match that of
+  the full constant, meaning that either it is a @nt<subtype_mark> or it has
+  static constraints. If the deferred constant instead has an
+  @nt<access_definition>, the designated subtype must be a @nt<subtype_mark>.
+  We still say that these are elaborated, however, because part of elaboration
+  is creating the type, which is clearly needed for @nt<access_definition>s.
+  (A deferred constant and its full constant have different types when
+  they are specified by an @nt<access_definition>, although there is no
+  visible effect of these types being different as neither can be named.)]}
address@hidden
address@hidden
+
address@hidden
+The full constant declaration for a deferred constant that is of a given
+private type or private extension is not allowed before the corresponding
address@hidden This is a consequence of the freezing
+rules for types
+(see @RefSecNum{Freezing Rules}).
address@hidden
+Multiple or single declarations are allowed for the
+deferred and the full declarations, provided that the
+equivalent single declarations would be allowed.
+
+Deferred constant declarations are useful for declaring constants of
+private views, and types with components of private views.
+They are also useful for declaring
+access-to-constant objects that designate
+variables declared in the private part of a package.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of deferred constant declarations:}
address@hidden
+Null_Key : @key[constant] Key;      address@hidden see @RefSecNum{Private 
Operations}]
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+CPU_Identifier : @key[constant] String(1..8)@Chg{Version=[3],New=[],Old=[;]}
address@hidden,New=[   @key[with]],address@hidden address@hidden,New=[ => True, 
Convention => ],Old=[(]}Assembler, @Chg{Version=[3],New=[],Old=[CPU_Identifier, 
]}Link_Name => "CPU_ID"@Chg{Version=[3],New=[],Old=[)]};
+                              address@hidden see @RefSecNum{Interfacing 
Aspects}]
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+In Ada 83, a deferred constant is required to be of a private type
+declared in the same visible part.
+This restriction is removed for Ada 95;
+deferred constants can be of any type.
+
+In Ada 83, a deferred constant declaration was not permitted to
+include a constraint, nor the reserved word @key(aliased).
+
+In Ada 83, the rules required conformance of type marks; here
+we require static matching of subtypes if the deferred constant
+is constrained.
+
+A deferred constant declaration can be completed with a @nt{pragma}
+Import. Such a deferred constant declaration need not be within a
address@hidden
+
+The rules for too-early uses of deferred constants are modified in
+Ada 95 to allow more cases, and catch all errors at compile time.
+This change is necessary in order to allow deferred constants of a
+tagged type without violating the principle that for a dispatching call,
+there is always an implementation to dispatch to.
+It has the beneficial side effect of catching some Ada-83-erroneous
+programs at compile time.
+The new rule fits in well with the new freezing-point rules.
+Furthermore, we are trying to convert undefined-value problems into
+bounded errors, and we were having trouble for the case of deferred
+constants.
+Furthermore, uninitialized deferred constants cause trouble for the
+shared variable / tasking rules, since they are really variable, even
+though they purport to be constant.
+In Ada 95, they cannot be touched until they become constant.
+
+Note that we do not consider this change to be an upward
+incompatibility, because it merely changes an erroneous execution in Ada
+83 into a compile-time error.
+
+The Ada 83 semantics are unclear in the case where
+the full view turns out to be an access type.
+It is a goal of the language design to prevent uninitialized access
+objects.
+One wonders if the implementation is required to initialize the
+deferred constant to null, and then initialize it (again!) to its
+real value.
+In Ada 95, the problem goes away.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Since deferred constants can now be of a nonprivate type,
+we have made this a stand-alone @Chg{Version=[3],New=[subclause],Old=[clause]},
+rather than a subclause of @RefSec{Private Types and Private Extensions}.
+
+Deferred constant declarations used to have their own syntax, but now
+they are simply a special case of @nt<object_declaration>s.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00385-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Deferred constants were enhanced to allow
+  the use of anonymous access types in them.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],Text=[Added matching rules for subtypes that
+  exclude null.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0062-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected rules so
+  that the intent that a full constant may have a null exclusion even
+  if the deferred constant does not is actually met.]}
address@hidden
+
+
address@hidden Types}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
address@hidden limited type is (a view of) a type for which
+  @Chg{Version=[2],New=[copying (such as for an @nt{assignment_statement})],
+    Old=[the assignment operation]} is not allowed.
+  A nonlimited type is a (view of a) type for which
+  @Chg{Version=[2],New=[copying], Old=[the assignment operation]} is allowed.]
address@hidden
+The concept of the @i(value) of a limited type is difficult
+to define, since the abstract value of a limited type often
+extends beyond its physical representation. In some
+sense, values of a limited type cannot be divorced from
+their object. The value @i(is) the object.
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
+In Ada 83, in the two places where limited types were defined
+by the language, namely tasks and files, an implicit
+level of indirection was implied by the semantics to
+avoid the separation of the value from an associated
+object.
+In Ada 95, most limited types are passed by reference,
+and even return-ed by address@hidden,New=[ In Ada 2005,
+most limited types are built-in-place upon return, rather than returned
+by reference. Thus the object @lquotes@;address@hidden is part of the
+logical value of most limited types.],Old=[]}
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00287-01],ARef=[AI95-00419-01]}
+For a limited partial view whose full view is nonlimited,
address@hidden,New=[copying],Old=[assignment]} is possible on parameter
+passing and function return. To prevent any copying whatsoever, one should
+make both the partial @i{and} full views limited.
address@hidden
address@hidden below was moved from a ChgToGlossaryAlso.}
address@hidden,Kind=[Revised],Term=<Limited type>,
+  Text=<A limited type is @Chg{Version=[2],New=[],Old=[(a view of) ]}a type
+  for which
+  @Chg{Version=[2],New=[copying (such as in an @nt{assignment_statement})],
+    Old=[the assignment operation]} is not allowed.
+  A nonlimited type is a @Chg{Version=[2],New=[],Old=[(view of a) ]}type for
+  which
+  @Chg{Version=[2],New=[copying], Old=[the assignment operation]} is allowed.>}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00419-01]}
+If a tagged record type has any limited components,
+then the reserved word @key[limited] shall
+appear in its @nt<record_type_definition>address@hidden,New=[ @Redundant[If
+the reserved word @key[limited] appears in the definition of a
address@hidden, its parent type and any progenitor interfaces
+shall be limited.]],Old=[]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00419-01]}
+  @ChgAdded{Version=[2],Text=[The rule about the parent type being required
+  to be limited can be found in @RefSecNum{Derived Types and Classes}. Rules
+  about progenitor interfaces can be found in
+  @RefSecNum{Interface Types}, specifically, a nonlimited interface can appear
+  only on a nonlimited type. We repeat these rules here to gather these
+  scattered rules in one obvious place.]}
address@hidden
address@hidden
address@hidden@;This prevents tagged limited types from becoming nonlimited.
+Otherwise, the following could happen:
address@hidden
address@hidden P @key[is]
+    @key[type] T @key[is] @key[limited] @key[private];
+    @key[type] R @key[is] @key[tagged]
+        @key[record] address@hidden Illegal!}
+               address@hidden This should say @lquotes@;@key[limited 
address@hidden@;.}
+            X : T;
+        @key[end] @key[record];
address@hidden
+    @key[type] T @key[is] @key[new] Integer; address@hidden R becomes 
nonlimited here.}
address@hidden P;
+
address@hidden,Kind=[Revised]}
address@hidden Q @key[is]
+    @key[type] address@hidden,New=[],Old=[(Access_Discrim : @key[access] 
...)]} @key[is] @key[new] R @key[with]
+        @key[record]
+            Y : Some_Task_Type;
+        @key[end] @key[record];
address@hidden Q;
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01]}
+If the above were legal,
+then assignment would be defined for R'Class in the body of P,
+which is bad news, given @Chg{Version=[2],New=[],Old=[the access discriminant
+and ]}the task.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00287-01],ARef=[AI95-00318-02]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0147-1]}
address@hidden,Type=[Leading],Text=[In the following contexts,
+an @nt{expression} of a limited
+type is not permitted unless it is an @nt{aggregate}, a @nt{function_call},
address@hidden,New=[],Old=[or ]}a parenthesized @nt{expression} or
address@hidden whose operand
+is permitted by this address@hidden,New=[, or a @nt{conditional_expression}
+all of whose @address@hidden are permitted by this
+rule],Old=[]}:]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,New=[the initialization @nt{expression} of an
address@hidden (see @RefSecNum{Object Declarations})],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,New=[the @nt{default_expression} of a
address@hidden (see @RefSecNum{Record Types})],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,New=[the @nt{expression} of a @nt{record_component_association} 
(see @RefSecNum{Record Aggregates})],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,New=[the @nt{expression} for an @nt{ancestor_part} of an
address@hidden (see @RefSecNum{Extension Aggregates})],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,New=[an @nt{expression} of a @nt{positional_array_aggregate}
+or the @nt{expression} of an @nt{array_component_association} (see
address@hidden Aggregates})],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,New=[the @nt{qualified_expression} of an initialized allocator
+(see @RefSecNum{Allocators})],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,New=[the @nt{expression} of a return statement (see
address@hidden Statements})],Old=[]}
+
address@hidden,Kind=[Added],ARef=[AI05-0177-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0157-1]}
address@hidden,New=[the
address@hidden,New=[return expression],address@hidden of an
address@hidden,New=[expression function],address@hidden
+(see @RefSecNum{Expression Functions})],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden because the paragraph number has changed}
address@hidden,New=[the @nt{default_expression} or actual parameter for a
+formal object of mode @b{in} (see @RefSecNum{Formal Objects})],Old=[]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[All of these contexts normally require copying; by
+restricting the uses as above, we can require the new object to be
+built-in-place.]}
address@hidden
address@hidden
+
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00419-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0178-1]}
address@hidden@address@hidden type}
+A @Chg{Version=[3],New=[view of a ],Old=[]}type is @i{limited} if it
+is @Chg{Version=[2],New=[],Old=[a descendant of ]}one of the following:
address@hidden(itemize)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00411-01],ARef=[AI95-00419-01]}
+  a type with the reserved word @key(limited)@Chg{Version=[2],New=[,
+  @key(synchronized), @key(task), or @key(protected) ],Old=[]}
+  in its definition;
+  @begin{Ramification}
+  Note that there is always a @lquotes@;definition,@rquotes@; conceptually,
+  even if there is no syntactic category called @lquotes@;address@hidden@;.
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00419-01]}
+  @ChgAdded{Version=[2],Text=[This includes interfaces of the above kinds,
+  derived types with the reserved word @key{limited}, as well as task and
+  protected types.]}
+  @end{Ramification}
+
+  @ChgNote{This should really be deleted in Version 2, but we want to
+  reuse the paragraph number, and that is hard, so we add the message 
manually.}
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00419-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0087-1]}
+  @Chg{Version=[3],New=[a class-wide type whose specific type is limited;],
+  address@hidden,address@hidden@i<This paragraph was deleted.>}],
+  Old=[a task or protected type;]}]}
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00419-01]}
+  a composite type with a limited address@hidden,New=[;],Old=[.]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0178-1]}
+  @ChgAdded{Version=[3],Text=[an incomplete view;]}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00419-01]}
+  @ChgAdded{Version=[2],Text=[a derived type whose parent is limited and is 
not an
+  interface.]}
+
+  @begin{Ramification}
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00419-01]}
+  @ChgAdded{Version=[2],Text=[Limitedness is not inherited from interfaces;
+  it must be explicitly specified when the parent is an interface.]}
+  @end{Ramification}
+
address@hidden(itemize)
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00419-01]}
+  @ChgAdded{Version=[2],Text=[A derived type can become nonlimited if
+  @key{limited} does not appear and the derivation
+  takes place in the visible part of a child package,
+  and the parent type is nonlimited as viewed from the
+  private part or body of the child package.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00419-01]}
+  @ChgAdded{Version=[2],Text=[We considered a rule where limitedness was always
+  inherited from the parent for derived types, but in the case of a type whose
+  parent is an interface, this meant that the first interface is treated
+  differently than other interfaces. It also would have forced users to declare
+  dummy nonlimited interfaces just to get the limitedness right. We also
+  considered a syntax like @key{not limited} to specify nonlimitedness when the
+  parent was limited, but that was unsavory. The rule given is more uniform and
+  simpler to understand.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00419-01]}
+  @ChgAdded{Version=[2],Text=[The rules for interfaces are asymmetrical, but
+  the language is not: if the parent interface is limited, the presence of the
+  word @key{limited} determines the limitedness, and nonlimited progenitors are
+  illegal by the rules in @RefSecNum{Interface Types} if @key{limited} is
+  present. If the parent interface
+  is nonlimited, the word @key{limited} is illegal by the rules in
+  @RefSecNum{Derived Types and Classes}. The net effect is that the order of
+  the interfaces doesn't matter.]}
address@hidden
+
+
address@hidden type}
+Otherwise, the type is nonlimited.
+
address@hidden are no predefined equality operators for
+a limited type.]
+
address@hidden,Kind=[Added],ARef=[AI05-0052-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[A type is
address@hidden limited} if it is one of the
+following:@Defn{immutably address@hidden type],Sec=[immutably]}]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[An explicitly limited record type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0217-1]}
address@hidden,Text=[A record extension with the reserved word
address@hidden;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[A nonformal limited private type that is
+tagged or has at least one access discriminant with a 
@nt{default_expression};]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The full type in both of these cases must
+  necessarily be immutably limited. We need to include private types
+  as much as possible so that we aren't unintentionally discouraging the
+  use of private types.]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Text=[A task type, a protected type, or a
+synchronized interface;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[A type derived from an immutably limited type.]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[An immutably limited type is a type that cannot
+  become nonlimited subsequently in a private part or in a child unit.
+  If a view of the type makes it immutably limited, then no copying 
(assignment)
+  operations are ever available for objects of the type. This allows other
+  properties; for instance, it is safe for such objects to have
+  access discriminants that have defaults or designate other limited objects.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[A nonsynchronized limited interface type is
+  not immutably limited; a type derived from it can be nonlimited.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0052-1]}
address@hidden,Text=[A descendant of a generic formal
+limited private type is
+presumed to be immutably limited except within the body
+of a generic unit or a body declared within the declarative
+region of a generic unit, if the formal type is declared
+within the formal part of the generic unit.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[In an instance, a type is descended from
+  the actual type corresponding to the formal, and all rules are rechecked
+  in the specification. Bodies are excepted so that we assume the worst there;
+  the complex wording is required to handle children of generics and
+  unrelated bodies properly.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00287-01],ARef=[AI95-00318-02]}
address@hidden,Kind=[DeletedAddedNoDelMsg],ARef=[AI05-0067-1]}
address@hidden,address@hidden,New=[
+For an @nt{aggregate} of a limited type used to initialize an object as allowed
+above, the implementation shall not create a separate anonymous object for the
address@hidden For a @nt{function_call} of a type with a part that is of a
+task, protected, or explicitly limited record type that is used to initialize
+an object as allowed above, the implementation shall not create a separate
+return object (see 6.5) for the @nt{function_call}. The @nt{aggregate} or
address@hidden shall be constructed directly in the new object.],Old=[]}]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00318-02]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0067-1]}
address@hidden,address@hidden,New=[For a
address@hidden, we only require @address@hidden
+for a limited type that would have
+been a return-by-reference type in Ada 95. We do this because
+we want to minimize disruption to Ada 95 implementations and users.],Old=[]}]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00287-01],ARef=[AI95-00318-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0067-1]}
address@hidden,New=[While it is allowed to write initializations of limited
+objects, such initializations never copy a limited object. The source of such 
an
+assignment operation must be an @nt<aggregate> or @nt<function_call>, and such
address@hidden<aggregate>s and @nt<function_call>s must be built directly in 
the target
address@hidden,New=[ (see @RefSecNum{Assignment and Finalization})],Old=[]}.],
address@hidden@keepnext@;The following are consequences of the rules for 
limited types:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This isn't quite true if the type can become
+nonlimited (see below); @nt{function_call}s only are required to be
+build-in-place for @lquotes@;address@hidden@; limited types.]}
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 10
+through 15 were deleted.>address@hidden message should be deleted if the
+paragraphs are ever renumbered.}
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00287-01]}
address@hidden,Text=[An initialization expression is not allowed in an
address@hidden if the type of the object is limited.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00287-01]}
address@hidden,Text=[A default expression is not allowed in a
address@hidden if the type of the record component is limited.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00287-01]}
address@hidden,Text=[An initialized allocator is not allowed if the
+designated type is limited.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00287-01]}
address@hidden,Text=[A generic formal parameter of mode @key[in] must
+not be of a limited type.]}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00287-01]}
address@hidden,address@hidden are not available for a limited
+composite type. Concatenation is not available for a limited array type.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00287-01]}
address@hidden,Text=[The rules do not exclude a @nt{default_expression}
+for a formal parameter of a limited type; they do not exclude a deferred
+constant of a limited type if the full declaration of the constant is of a
+nonlimited type.]}
+
address@hidden nonlimited}
address@hidden type],Sec=(becoming nonlimited)}
address@hidden type],Sec=(becoming nonlimited)}
+As illustrated in @RefSecNum{Private Operations},
+an untagged limited type can become nonlimited under certain
+circumstances.
address@hidden
+  Limited private types do not become nonlimited;
+  instead, their full view can be nonlimited,
+  which has a similar effect.
+
+  It is important to remember
+  that a single nonprivate type can be both limited and nonlimited
+  in different parts of its scope. In other words, @lquotes@;address@hidden@; 
is a property
+  that depends on where you are in the scope of the type.
+  We don't call this a @lquotes@;view address@hidden@; because there is no 
particular
+  declaration to declare the nonlimited view.
+
+  Tagged types never become nonlimited.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of a package with a limited type:}
address@hidden
address@hidden IO_Package @key[is]
+   @key[type] File_Name @key[is] @key[limited] @key[private];
+
+   @key[procedure] Open (F : @key[in] @key[out] File_Name);
+   @key[procedure] Close(F : @key[in] @key[out] File_Name);
+   @key[procedure] Read (F : @key[in] File_Name; Item : @key[out] Integer);
+   @key[procedure] Write(F : @key[in] File_Name; Item : @key[in]  Integer);
address@hidden
+   @key[type] File_Name @key[is]
+      @key[limited] @key[record]
+         Internal_Name : Integer := 0;
+      @key[end] @key[record];
address@hidden IO_Package;
+
+
address@hidden @key[body] IO_Package @key[is]
+   Limit : @key[constant] := 200;
+   @key[type] File_Descriptor @key[is] @key[record]  ...  @key[end] 
@key[record];
+   Directory : @key[array] (1 .. Limit) @key[of] File_Descriptor;
+   ...
+   @key[procedure] Open (F : @key[in] @key[out] File_Name) @key[is]  ...  
@key[end];
+   @key[procedure] Close(F : @key[in] @key[out] File_Name) @key[is]  ...  
@key[end];
+   @key[procedure] Read (F : @key[in] File_Name; Item : @key[out] Integer) 
@key[is] ... @key[end];
+   @key[procedure] Write(F : @key[in] File_Name; Item : @key[in]  Integer) 
@key[is] ... @key[end];
address@hidden
+   ...
address@hidden IO_Package;
address@hidden
address@hidden
+
address@hidden
address@hidden on the example:}
+In the example above, an outside subprogram making use of IO_Package
+may obtain a file name by calling Open and later use it in calls to
+Read and Write. Thus, outside the package, a file name obtained from
+Open acts as a kind of password; its internal properties (such as
+containing a numeric value) are not known and no other operations
+(such as addition or comparison of internal names) can be performed
+on a file name.
+Most importantly, clients of the package cannot make copies
+of objects of type File_Name.
+
address@hidden@;This example is characteristic of any case where complete 
control
+over the operations of a type is desired. Such packages serve a dual
+purpose. They prevent a user from making use of the internal
+structure of the type. They also implement the notion of an
+encapsulated data type where the only operations on the type are
+those given in the package specification.
+
address@hidden@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00318-02]}
+The fact that the full view of File_Name is explicitly declared
address@hidden means that parameter passing @Chg{Version=[2],New=[],
+Old=[and function return ]}will always be by address@hidden,New=[
+and function results will always be built directly in the result 
object],Old=[]}
+(see @RefSecNum{Formal Parameter Modes} and @RefSecNum{Return Statements}).
+
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The restrictions in RM83-7.4.4(4),
+which disallowed @key[out] parameters of limited types in certain
+cases, are removed.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Since limitedness and privateness are orthogonal in Ada 95 (and
+to some extent in Ada 83), this is now its own 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+rather than being a subclause of
address@hidden Types and Private Extensions}.
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Limited types now have an assignment operation, but its use is restricted
+  such that all uses are build-in-place. This is
+  accomplished by restricting uses to @nt{aggregate}s and @nt{function_call}s.
+  @nt{Aggregate}s were not allowed to have a limited type in Ada 95, which
+  causes a compatibility issue discussed in @RefSec{Aggregates}.
+  Compatibility issues with return statements for limited
+  @nt{function_call}s are discussed
+  in @RefSec{Return Statements}.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00411-01],ARef=[AI95-00419-01]}
+  @ChgAdded{Version=[2],Text=[Rewrote the definition of limited to ensure that
+  interfaces are covered, but that limitedness is not inherited from 
interfaces.
+  Derived types that explicitly include @key{limited} are now also covered.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0052-1],ARef=[AI05-0217-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a definition for
+  immutably limited types, so that the fairly complex definition does
+  not need to be repeated in rules elsewhere in the Standard.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0067-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> The built-in-place rules
+  are consolidated in @RefSecNum{Assignment and Finalization}, and thus
+  they are removed from this subclause.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0087-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Fixed an oversight: 
class-wide
+  types were never defined to be limited, even if their associated specific
+  type is. It is thought that this oversight was never implemented incorrectly
+  by any compiler, thus we have not classified it as an incompatibility.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0147-1]}
+  @ChgAdded{Version=[3],Text=[Allowed @nt{conditional_expression}s in limited
+  constructor contexts @em we want to treat these as closely to parentheses as
+  possible.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0177-1]}
+  @ChgAdded{Version=[3],Text=[Added wording so that expression functions can
+  return limited entities.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0178-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added incomplete views
+  to the list of reasons for a view of a type to be limited. This is not
+  a change as the definition already was in
+  @RefSecNum{Incomplete Type Declarations}. But it is much better to have
+  all of the reasons for limitedness together.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,New=[Assignment and Finalization],Old=[User-Defined Assignment 
and Finalization]}
+
address@hidden
address@hidden@Defn{user-defined assignment}
address@hidden, Sec=(user-defined)}
+Three kinds of actions are
+fundamental to the manipulation of objects:
+initialization, finalization, and assignment.
+Every object is initialized, either explicitly
+or by default, after being created
+(for example, by an @nt{object_declaration} or @nt{allocator}).
+Every object is finalized before being destroyed
+(for example, by leaving a @nt{subprogram_body} containing an
address@hidden, or by a call to an instance of
+Unchecked_Deallocation).
+An assignment operation is used as part of @nt{assignment_statement}s,
+explicit initialization, parameter passing, and other operations.
address@hidden,See=[initialization]}
address@hidden,See=[Initialize]}
address@hidden,See=[finalization]}
+
+Default definitions for these three fundamental
+operations are provided by the
+language, but
address@hidden type}
+a @i{controlled} type gives the user additional
+control over parts of these operations.
address@hidden@address@hidden
+In particular, the user can define, for a controlled type,
+an Initialize procedure which is invoked immediately after
+the normal default initialization of a controlled object, a Finalize procedure
+which is invoked immediately before finalization of any of the
+components of a controlled object, and an Adjust
+procedure which is invoked as the last step of an assignment to
+a (nonlimited) controlled object.]
address@hidden<Controlled type>,
+  Text=<A controlled type supports user-defined assignment and
+  finalization.
+  Objects are always finalized before being destroyed.>}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01],ARef=[AI95-00287-01]}
+Here's the basic idea of initialization, value adjustment, and finalization,
+whether or not user defined:
+When an object is created,
+if it is explicitly assigned an initial value,
address@hidden,New=[the object is either built-in-place from an @nt{aggregate}
+or function call (in which case neither Adjust nor Initialize is applied), or 
],Old=[]}
+the assignment copies and
+adjusts the initial value. Otherwise, Initialize is applied to it
+(except in the case of an @nt{aggregate} as a whole).
+An @nt{assignment_statement} finalizes the target before
+copying in and adjusting the new value.
+Whenever an object goes away, it is finalized.
+Calls on Initialize and Adjust happen bottom-up; that is,
+components first, followed by the containing object.
+Calls on Finalize @Chg{Version=[2],New=[happen],Old=[happens]} top-down; that 
is,
+first the containing object, and then its components.
+These ordering rules ensure that any components will be in a
+well-defined state when Initialize, Adjust,
+or Finalize is applied to the containing object.
address@hidden
address@hidden
+
address@hidden
address@hidden@keepnext@;The following language-defined library package exists:
address@hidden@ChgRef{Version=[1],Kind=[Revised],Ref=[8652/0020],ARef=[AI95-00126-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0212-1]}
address@hidden Ada.Finalization @address@hidden,Child=[Finalization]}
+    @key[pragma] 
@Chg{Version=[3],New=[Pure],Old=[Preelaborate]}(Finalization);@Chg{Version=[3],New=[],address@hidden
+    @key[pragma] Remote_Types(Finalization);],Old=[]}]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00161-01]}
+    @key[type] @AdaTypeDefn{Controlled} @key[is abstract tagged 
private];@Chg{Version=[2],New=[
+    @key{pragma} Preelaborable_Initialization(Controlled);],Old=[]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00348-01]}
+    @key(procedure) @AdaSubDefn{Initialize} (Object : @key(in out) 
Controlled)@Chg{Version=[2],New=[ @key{is null}],Old=[]};
+    @key(procedure) @AdaSubDefn{Adjust}     (Object : @key(in out) 
Controlled)@Chg{Version=[2],New=[ @key{is null}],Old=[]};
+    @key(procedure) @AdaSubDefn{Finalize}   (Object : @key(in out) 
Controlled)@Chg{Version=[2],New=[ @key{is null}],Old=[]};
+
address@hidden,Kind=[Revised],ARef=[AI95-00161-01]}
+    @key[type] @AdaTypeDefn{Limited_Controlled} @key[is abstract tagged 
limited private];@Chg{Version=[2],New=[
+    @key{pragma} Preelaborable_Initialization(Limited_Controlled);],Old=[]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00348-01]}
+    @key(procedure) @AdaSubDefn{Initialize} (Object : @key(in out) 
Limited_Controlled)@Chg{Version=[2],New=[ @key{is null}],Old=[]};
+    @key(procedure) @AdaSubDefn{Finalize}   (Object : @key(in out) 
Limited_Controlled)@Chg{Version=[2],New=[ @key{is null}],Old=[]};
address@hidden(private)
+    ... -- @RI{not specified by the language}
address@hidden Ada.Finalization;
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00348-01]}
address@hidden type}
+A controlled type is a descendant of Controlled or Limited_Controlled.
address@hidden,New=[],Old=[The (default) implementations of
+Initialize, Adjust, and Finalize have no effect. ]}The predefined
+"=" operator of type Controlled always returns True,
address@hidden this operator is incorporated into
+the implementation of the predefined equality operator of types derived
+from Controlled, as explained in
address@hidden(Relational Operators and Membership Tests).]
+The type Limited_Controlled is like Controlled, except
+that it is limited and it lacks the primitive subprogram Adjust.
address@hidden
+We say @lquotes@;nonlimited controlled address@hidden@ (rather than just
address@hidden@;controlled address@hidden@;;) when we want to talk about 
descendants
+of Controlled only.
address@hidden
address@hidden
+  We considered making Adjust and Finalize abstract.
+  However, a reasonable coding convention is e.g. for Finalize to
+  always call the parent's Finalize after doing whatever work is needed
+  for the extension part.
+  (Unlike CLOS, we have no way to do that automatically in Ada 95.)
+  For this to work, Finalize cannot be abstract.
+  In a generic unit, for a generic formal abstract derived type whose
+  ancestor is Controlled or Limited_Controlled, calling the ancestor's
+  Finalize would be illegal if it were abstract, even though the actual
+  type might have a concrete version.
+
+  Types Controlled and Limited_Controlled are abstract, even though
+  they have no abstract primitive subprograms.
+  It is not clear that they need to be abstract, but there seems to be
+  no harm in it, and it might make an implementation's life easier to
+  know that there are no objects of these types @em in case the
+  implementation wishes to make them @lquotes@;address@hidden@; in some way.
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Text=[For Ada 2005, we considered making these types
+  interfaces. That would have the advantage of allowing them to be added
+  to existing trees. But that was rejected both because it would cause
+  massive disruptions to existing implementations, and because it would be
+  very incompatible due to the "no hidden interfaces" rule. The latter rule
+  would prevent a tagged private type from being completed with a derivation
+  from Controlled or Limited_Controlled @em a very common idiom.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00360-01]}
address@hidden,Type=[Leading],Text=[A type is said to
address@hidden finalization} if:@Defn{needs address@hidden,Sec=[needs 
finalization]}]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[it is a controlled type, a task type or
+a protected type; or]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0092-1]}
address@hidden,Text=[it has a component
address@hidden,New=[whose type ],Old=[that ]} needs finalization; or]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0013-1]}
address@hidden,New=[it is a class-wide type; or],
address@hidden,New=[it is a limited type that
+has an access discriminant whose designated type needs finalization; 
or],Old=[]}]}
+
address@hidden,Kind=[Added],ARef=[AI05-0026-1]}
address@hidden,Text=[it is a partial view whose full view needs finalization; 
or]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[it is one of a number of language-defined types
+that are explicitly defined to need finalization.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The fact that a type needs finalization
+  does not require it to be implemented with a controlled type. It just has to
+  be recognized by the No_Nested_Finalization restriction.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This property is defined for the type, not
+  for a particular view. That's necessary as restrictions look in private parts
+  to enforce their restrictions; the point is to eliminate all controlled
+  parts, not just ones that are visible.]}
address@hidden
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00373-01]}
address@hidden,New=[],address@hidden,
+Sec=(object_declaration)}]}During
+the elaboration @Chg{Version=[2],New=[or evaluation of a construct that
+causes an object to be initialized by default],Old=[of
+an @nt{object_declaration}]},
+for every controlled subcomponent of
+the object that is not assigned an initial value
+(as defined in @RefSecNum{Object Declarations}),
+Initialize is called on that subcomponent.
+Similarly, if the object @Chg{Version=[2],New=[that is initialized by
+default ],Old=[]}as a whole is address@hidden,New=[],Old=[ and
+is not assigned an initial value]}, Initialize is called on the address@hidden,
+New=[],Old=[ The same applies to the evaluation of an @nt{allocator},
+as explained in @RefSecNum{Allocators}.]}
+
address@hidden,Kind=[Revised],Ref=[8652/0021],ARef=[AI95-00182-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00373-01]}
+For an @nt{extension_aggregate} whose @nt{ancestor_part} is a
address@hidden@Chg{Version=[2],New=[ denoting a],
+Old=[, @Chg{New=[for each controlled subcomponent of the ancestor part, either
+Initialize is called, or its initial value is assigned, as appropriate],
+Old=[Initialize is called on all controlled subcomponents of the
+ancestor part]}; if the type of the ancestor part is itself]}
address@hidden,New=[ subtype],Old=[]},
+the Initialize procedure of the ancestor type is called,
+unless that Initialize procedure is abstract.
address@hidden
address@hidden@keepnext@;Example:
address@hidden
address@hidden T1 @key[is] @key[new] Controlled @key[with]
+    @key[record]
+        ... address@hidden some components might have defaults}
+    @key[end] @key[record];
+
address@hidden T2 @key[is] @key[new] Controlled @key[with]
+    @key[record]
+        X : T1; address@hidden no default}
+        Y : T1 := ...; address@hidden default}
+    @key[end] @key[record];
+
+A : T2;
+B : T2 := ...;
address@hidden
+
+As part of the elaboration of A's declaration, A.Y is assigned a
+value; therefore Initialize is not applied to A.Y.
+Instead, Adjust is applied to A.Y as part of the assignment operation.
+Initialize is applied to A.X and to A, since those objects are not
+assigned an initial value.
+The assignment to A.Y is not considered an assignment to A.
+
+For the elaboration of B's declaration, Initialize is not called at
+all. Instead the assignment adjusts B's value;
+that is, it applies Adjust to B.X, B.Y, and B.
+
address@hidden,Kind=[Added],Ref=[8652/0021],ARef=[AI95-00182-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00373-01]}
address@hidden,Text=[The @nt{ancestor_part} of an
address@hidden@Chg{Version=[2],New=[, <> in aggregates, and the
+return object of an @nt{extended_return_statement} are],Old=[ is]} handled
+similarly.]}
address@hidden
+
+Initialize and other initialization
+operations are done in an arbitrary order,
+except as address@hidden order],Sec=[allowed]}
+Initialize is applied to an object after initialization
+of its subcomponents, if any
address@hidden(including both implicit initialization and Initialize calls)].
+If an object has a component with an access discriminant
+constrained by a per-object expression,
+Initialize is applied to this component after any components that do not
+have such discriminants.
+For an object with several components with such a discriminant,
+Initialize is applied to them in order
+of their @nt{component_declaration}s.
+For an @nt<allocator>,
+any task activations follow all calls
+on Initialize.
address@hidden
+  The fact that Initialize is done for subcomponents
+  first allows Initialize for a composite
+  object to refer to its subcomponents knowing
+  they have been properly initialized.
+
+  The fact that Initialize is done for components with access
+  discriminants after other components
+  allows the Initialize operation for a component
+  with a self-referential access discriminant to assume
+  that other components of the enclosing object have already been
+  properly initialized.
+  For multiple such components, it allows some predictability.
address@hidden
+
address@hidden@address@hidden operation}
+When a target object with any controlled parts is assigned a value,
address@hidden when created or in a subsequent
address@hidden,]
+the @i{assignment operation} proceeds as follows:
address@hidden(itemize)
+  The value of the target becomes the assigned value.
+
+  @Defn{adjusting the value of an object}
+  @Defn{adjustment}
+  The value of the target is @i{adjusted.}
address@hidden(itemize)
address@hidden
+    If any parts of the object are controlled,
+    abort is deferred during the assignment operation.
address@hidden
+
address@hidden,Kind=[Revised],address@hidden need future changes.}
address@hidden the value of an object}
address@hidden
+To adjust the value of a
address@hidden,New=[],address@hidden(nonlimited)] ]}composite object,
+the values of the components of the object are first
+adjusted in an arbitrary order,
+and then, if the object is
address@hidden,New=[nonlimited ],Old=[]}controlled,
+Adjust is address@hidden order],Sec=[allowed]}
+Adjusting the value of an elementary object has no address@hidden,
+nor does adjusting the value of a composite object with no
+controlled parts.]
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0067-1]}
+  Adjustment is never @Chg{Version=[3],New=[actually ],Old=[]}performed for
+  values of @Chg{Version=[3],New=[an immutably],Old=[a by-reference]} limited 
type,
+  since @Chg{Version=[3],New=[all
+  assignment operations for such types are required to be built-in-place.
+  Even so, we still define adjustment for all types in order that the
+  canonical semantics is well-defined],Old=[these
+  types do not support copying]}.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+  The verbiage in the Initialize rule about access discriminants
+  constrained by per-object expressions is not necessary here,
+  since such types are
+  @Chg{Version=[3],New=[either ],address@hidden,New=[ or
+  do not have defaults, so the discriminant can only be changed by
+  an assignment to an outer object. Such an assignment could
+  happen only before any adjustments or (if part of an outer Adjust)
+  only after any inner (component) adjustments have completed.],
+  Old=[, and therefore are never adjusted.]}
address@hidden
+
address@hidden, Sec=(assignment_statement)}
+For an @nt{assignment_statement},
address@hidden after the @nt{name} and
address@hidden have been evaluated,
+and any conversion (including constraint checking) has been done,]
+an anonymous object is created, and
+the value is assigned into it;
address@hidden is, the assignment operation is applied].
address@hidden(Assignment includes value adjustment.)]
+The target of the @nt{assignment_statement} is then finalized.
+The value of the anonymous object is then assigned into the target of
+the @nt{assignment_statement}.
+Finally, the anonymous object is finalized.
address@hidden explained below,
+the implementation may eliminate the intermediate anonymous object,
+so this description subsumes the one given in
address@hidden Statements}.]
address@hidden
address@hidden@;An alternative design for user-defined assignment might involve 
an
+Assign operation instead of Adjust:
address@hidden
address@hidden Assign(Target : @key[in] @key[out] Controlled; Source : @key[in] 
@key[out] Controlled);
address@hidden
+
address@hidden@keepnext@;Or perhaps even a syntax like this:
address@hidden
address@hidden ":="(Target : @key[in] @key[out] Controlled; Source : @key[in] 
@key[out] Controlled);
address@hidden
+
address@hidden@;Assign (or ":=") would have the responsibility of doing the 
copy,
+as well as whatever else is necessary.
+This would have the advantage that the Assign operation knows about both
+the target and the source at the same time @em it would be possible to
+do things like reuse storage belonging to the target, for example,
+which Adjust cannot do.
+However, this sort of design would not work in the case of unconstrained
+discriminated variables, because there is no way to change the
+discriminants individually.
+For example:
address@hidden
address@hidden Mutable(D : Integer := 0) @key[is]
+    @key[record]
+        X : Array_Of_Controlled_Things(1..D);
+        @key[case] D @key[is]
+            @key[when] 17 => Y : Controlled_Thing;
+            @key[when] @key[others] => @key[null];
+        @key[end] D;
+    @key[end] @key[record];
address@hidden
+
+An assignment to an unconstrained variable of type Mutable can cause
+some of the components of X, and the component Y, to appear and/or
+disappear.
+There is no way to write the Assign operation to handle this sort of
+case.
+
+Forbidding such cases is not an option @em it would cause generic
+contract model violations.
address@hidden
+
+
address@hidden,Kind=[Added],ARef=[AI05-0067-1]}
address@hidden,Type=[Leading],Text=[When a function call
+or @nt{aggregate} is used to initialize an object, the
+result of the function call or @nt{aggregate} is an anonymous object, which
+is assigned into the newly-created object. For such an assignment,
+the anonymous object might be @i<built in place>,@Defn{built in 
address@hidden,Other=[built in place]}
+in which case the assignment does not involve any copying.
+Under certain circumstances, the anonymous object is required to be built in
+place. In particular:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0067-1]}
+  @ChgAdded{Version=[3],Text=[We say assignment to built-in-place objects does 
not
+  involve copying, which matches the intended implementation (see below). Of
+  course, the implementation can do any copying it likes, if it can make such
+  copying semantically invisible (by patching up access values to point to the
+  copy, and so forth).]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[If the full type of any part of the object is
+  immutably limited, the anonymous object is built in place.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0067-1]}
+  @ChgAdded{Version=[3],Text=[We talk about the full types being immutably
+  limited, as this is independent of the view of a type (in the same way that 
it
+  is for determining the technique of parameter passing). That is, privacy is
+  ignored for this purpose.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1],ARef=[AI05-0067-1]}
+  @ChgAdded{Version=[3],Text=[For function calls, we only require building in
+  place for immutably limited types. These are the types that would have been
+  return-by-reference types in Ada 95. We limited the requirement because
+  we want to minimize disruption to Ada 95 implementations and users.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0232-1]}
+  @ChgAdded{Version=[3],Text=[This is a dynamic property and is determined by
+  the specific type of the parts of the actual object. In particular, if a part
+  has a class-wide type, the tag of the object might need to be examined in
+  order to determine if build-in-place is required. However, we expect that 
most
+  Ada implementations will determine this property at compile-time using some
+  assume-the-worst algorithm in order to chose the appropriate method to
+  implement a given call or aggregate. In addition, there is no attribute or
+  other method for a program to determine if a particular object has this
+  property (or not), so there is no value to a more careful description of this
+  rule.]}
address@hidden
+
address@hidden,Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[In the case of an @nt{aggregate}, if the full 
type
+  of any part of the newly-created object is controlled, the anonymous object 
is
+  built in place.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0067-1]}
address@hidden,Type=[Leading],Text=[This is necessary to prevent
+elaboration problems with deferred constants of controlled types. Consider:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden P @key[is]
+   @key[type] Dyn_String @key[is private];
+   Null_String : @key[constant] Dyn_String;
+   ...
address@hidden
+   @key[type] Dyn_String @key[is new] Ada.Finalization.Controlled @key[with] 
...
+   @key[procedure] Finalize(X : @key[in out] Dyn_String);
+   @key[procedure] Adjust(X : @key[in out] Dyn_String);
address@hidden Line}
+   Null_String : @key[constant] Dyn_String :=
+      (Ada.Finalization.Controlled @key[with] ...);
+   ...
address@hidden P;]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[When Null_String is elaborated, the bodies of Finalize and 
Adjust
+clearly have not been elaborated. Without this rule, this declaration would
+necessarily raise Program_Error (unless the permissions given below are
+used by the implementation).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[An @nt{aggregate} with a controlled part
+  used in the return expression
+  of a @address@hidden@!statement} has to be built in place in the anonymous
+  return object, as this is similar to an object declaration. (This is a change
+  from Ada 95, but it is not an inconsistency as it only serves to restrict
+  implementation choices.) But this only covers the @nt{aggregate}; a separate
+  anonymous return object can still be used unless it too is required to be
+  built in place.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Similarly, an @nt{aggregate} that has
+  a controlled part but is not itself controlled and that is used to
+  initialize an object also has to be built in place. This is also a change
+  from Ada 95, but it is not an inconsistency as it only serves to restrict
+  implementation choices. This avoids problems if a type like Dyn_String
+  (in the example above) is used as a component in a type used as a
+  deferred constant in package P.]}
address@hidden
+
address@hidden,Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[In other cases, it is unspecified whether the
+  anonymous object is built in address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is left unspecified so the implementation
+  can use any appropriate criteria for determining when to build in place.
+  That includes making the decision on a call-by-call basis. Reasonable
+  programs will not care what decision is made here anyway.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0067-1]}
address@hidden,Type=[Leading],address@hidden
+what this International Standard says elsewhere, if an object is
+built in place:]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[Upon successful completion of the return
+    statement or @nt{aggregate}, the anonymous object @i<mutates into> the
+    newly-created object; that is, the anonymous object ceases to exist, and 
the
+    newly-created object appears in its address@hidden
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[Finalization is not performed on the anonymous 
object.]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[Adjustment is not performed on the 
newly-created
+    object.]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[All access values that designate parts of the
+    anonymous object now designate the corresponding parts of the newly-created
+    object.]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[All renamings of parts of the anonymous
+    object now denote views of the corresponding parts of the newly-created
+    object.]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[Coextensions of the anonymous object become
+    coextensions of the newly-created object.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This @ldquote@;address@hidden does not
+  necessarily happen atomically with
+  respect to abort and other tasks. For example, if a function call is used as
+  the parent part of an @nt{extension_aggregate}, then the tag of the anonymous
+  object (the function result) will be different from the tag of the
+  newly-created object (the parent part of the @nt{extension_aggregate}). In
+  implementation terms, this involves modifying the tag field. If the current
+  task is aborted during this modification, the object might become abnormal.
+  Likewise, if some other task accesses the tag field during this modification,
+  it constitutes improper use of shared variables, and is erroneous.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The intended implementation is that the
+  anonymous object is allocated at the
+  same address as the newly-created object. Thus, no run-time action is
+  required to cause all the access values and renamings to point to the right
+  place. They just point to the newly-created object, which is what the return
+  object has magically @ldquote@;mutated address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[There is no requirement that 'Address of the
+  return object is equal to 'Address of the newly-created object, but that will
+  be true in the intended implementation.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[For a function call, if the size of the
+  newly-created object is known at the call site, the object is allocated 
there,
+  and the address is implicitly passed to the function; the return object is
+  created at that address. Otherwise, a storage pool is implicitly passed to 
the
+  function; the size is determined at the point of the return statement, and
+  passed to the Allocate procedure. The address returned by the storage pool is
+  returned from the function, and the newly-created object uses that same
+  address. If the return statement is left without returning (via an exception
+  or a goto, for example), then Deallocate is called.  The storage pool might 
be
+  a dummy pool that represents @ldquote@;allocate on the address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The Tag of the newly-created object may be
+  different from that of the result object. Likewise, the master and
+  accessibility level may be different.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[An alternative implementation model might allow
+  objects to move around to different addresses. In this case, access values 
and
+  renamings would need to be modified at run time. It seems that this model
+  requires the full power of tracing garbage collection.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0022],ARef=[AI95-00083-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00318-02]}
address@hidden,Kind=[DeletedAddedNoDelMsg],ARef=[AI05-0067-1]}
address@hidden,address@hidden,New=[For an @nt{aggregate} of a
+controlled type whose value is assigned,
+other than by an @address@hidden,New=[],Old=[ or
+a @nt{return_statement}]}, the
+implementation shall not create a separate anonymous object for the
address@hidden The @nt{aggregate} value shall be constructed directly in the 
target
+of the assignment operation and Adjust is not called on the target 
object.],Old=[]}]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00318-02]}
address@hidden,Kind=[DeletedAddedNoDelMsg],ARef=[AI05-0067-1]}
address@hidden,Type=[Leading],address@hidden,address@hidden,
address@hidden,address@hidden,
+New=[ @i<build-in-place> requirement],Old=[]} is necessary to prevent
+elaboration problems with deferred constants of controlled types. 
Consider:],Old=[]}]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[DeletedAddedNoDelMsg]}
address@hidden,address@hidden@key[package] P @key[is]
+   @key[type] Dyn_String @key[is private];
+   Null_String : @key[constant] Dyn_String;
+   ...
address@hidden
+   @key[type] Dyn_String @key[is new] Ada.Finalization.Controlled @key[with] 
...
+   @key[procedure] Finalize(X : @key[in out] Dyn_String);
+   @key[procedure] Adjust(X : @key[in out] Dyn_String);
address@hidden Line}
+   Null_String : @key[constant] Dyn_String :=
+      (Ada.Finalization.Controlled @key[with] ...);
+   ...
address@hidden P;],Old=[]}]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[DeletedAddedNoDelMsg]}
address@hidden,address@hidden Null_String is elaborated, the bodies of Finalize 
and Adjust
+clearly have not been elaborated. Without this rule, this declaration would
+necessarily raise Program_Error (unless the permissions given below are
+used by the implementation).],Old=[]}]}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedAddedNoDelMsg]}
address@hidden,address@hidden,New=[An @nt{aggregate} of a controlled type
+used in the return expression
+of a @address@hidden@!statement} has to be built-in-place in the anonymous
+return object, as this is similar to an object declaration. (This is a change
+from Ada 95, but it is not an inconsistency as it only serves to restrict
+implementation choices.) But this only covers the @nt{aggregate}; a separate
+anonymous return object can still be used unless it too is required to be
+built-in-place (see @RefSecNum{Limited Types}).],Old=[]}]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0067-1]}
+An implementation is allowed to relax the above rules
address@hidden,New=[for @nt{assignment_statement}s],
address@hidden(for nonlimited controlled types)]]}
+in the following ways:
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI05-0067-1]}
address@hidden,Text=[The phrase @lquotes@;for nonlimited controlled
address@hidden@; follows from the fact
+that all of the following permissions apply to cases involving
+assignment.
+It is important because the programmer can count on a stricter semantics
+for limited controlled types.]}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0067-1]}
address@hidden,Text=[The relaxations apply only to nonlimited types,
+as @nt{assignment_statement}s
+are not allowed for limited types. This is important so that the programmer
+can count on a stricter semantics for limited controlled types.]}
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0067-1]}
address@hidden,New=[If],Old=[For an @nt{assignment_statement} that assigns to]}
+an object @Chg{Version=[3],New=[is assigned ],Old=[]}the value of that same
+object, the implementation need not do anything.
address@hidden
+  In other words, even if an object is controlled and a combination
+  of Finalize and Adjust on the object might have a net
+  side effect, they need not be performed.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0067-1]}
+For @Chg{Version=[3],New=[assignment of],Old=[an @nt{assignment_statement} 
for]}
+a noncontrolled type,
+the implementation may finalize and assign each
+component of the variable separately (rather than finalizing the entire
+variable and assigning the entire new value)
+unless a discriminant of the variable is changed by the assignment.
address@hidden
+For example, in a slice assignment, an anonymous object is not necessary
+if the slice is copied component-by-component in the right direction,
+since array types are not controlled (although their components may be).
+Note that the direction, and even the fact that it's a slice assignment,
+can in general be determined only at run time.
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,Text=[This potentially breaks a single assignment
+operation into many, and thus abort deferral (see
address@hidden of a Task - Abort of a Sequence of Statements}) needs to
+last only across an individual component assignment when the component
+has a controlled part. It is only important that the copy step is
+not separated (by an abort) from the adjust step, so aborts between
+component assignments is not harmful.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00147-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0067-1]}
address@hidden,New=[The],Old=[For an @nt{aggregate} or function call whose
+value is assigned into a target object,
+the implementation need not create a separate anonymous object if
+it can safely create the value of
+the @nt{aggregate} or function call
+directly in the target object.
+Similarly, for an @address@hidden, the]}
+implementation need not create an anonymous object if
+the value being assigned is the result of evaluating a @nt{name}
+denoting an object (the source object) whose storage cannot overlap
+with the target. If the source object might overlap with the
+target object, then the implementation can avoid the need for
+an intermediary anonymous object by exercising one of the
+above permissions and perform the assignment one component
+at a time (for an overlapping array assignment), or not at all
+(for an assignment where the target and the source of the assignment are
+the same object)address@hidden,New=[],Old=[ Even if an anonymous object is
+created, the implementation may move its value to the target object as part of
+the assignment without re-adjusting so long as the
+anonymous object has no aliased subcomponents.]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
address@hidden,New=[If the anonymous object is eliminated by this permission, ],
+Old=[In the @nt{aggregate} case, only one
+value adjustment is necessary, and]} there is no anonymous object to be
address@hidden,New=[ and thus the Finalize call on it is
+eliminated],Old=[]}.
+
address@hidden,Kind=[Revised],ARef=[AI95-00147-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
address@hidden,address@hidden,New=[Note that if the anonymous
+object is eliminated but the new value is not built in place in the
+target object],Old=[Similarly, in the function call case, the
+anonymous object can be eliminated. Note, however]}, that Adjust
+must be called],Old=[In the @nt{assignment_statement} case as well,
+no finalization of the anonymous object is needed.
+On the other hand, if the target has aliased subcomponents,
+then an adjustment takes place]} directly on the target object
+as the last step of the assignment, since some of the
+subcomponents may be self-referential or otherwise
address@hidden,New=[ This Adjust can be eliminated only
+by using one of the following permissions.],Old=[]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00147-01]}
address@hidden,Type=[Leading],Text=[Furthermore, an implementation is
+permitted to
+omit implicit Initialize, Adjust, and Finalize calls and associated assignment
+operations on an object of a nonlimited controlled type provided that:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[any omitted Initialize call is not a call on a
+user-defined Initialize procedure, and]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This does not apply to any calls to a user-defined
+Initialize routine that happen to occur in an Adjust or Finalize routine. It
+is intended that it is never necessary to look inside of an Adjust or Finalize
+routine to determine if the call can be omitted.]}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[We don't want to eliminate objects for which the
+Initialize might have side effects (such as locking a resource).]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[any usage of the value of the object after the implicit
+Initialize or Adjust call and before any subsequent Finalize call on the object
+does not change the external effect of the program, and]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[after the omission of such calls and operations, any
+execution of the program that executes an Initialize or Adjust call on an
+object or initializes an object by an @nt{aggregate} will also later execute a
+Finalize call on the object and will always do so prior to assigning a new
+value to the object, and]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[the assignment operations associated with omitted Adjust
+calls are also omitted.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This permission applies to Adjust and Finalize calls even
+if the implicit calls have additional external effects.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The goal of the above permissions is to allow
+typical dead assignment and dead variable removal algorithms to work for
+nonlimited controlled types. We require that @lquotes@;address@hidden@; of
+Initialize/Adjust/Finalize operations are removed. (These aren't always pairs,
+which is why we talk about @lquotes@;any execution of the address@hidden@;.)]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Controlled types and user-defined finalization are new to Ada 95.
+(Ada 83 had finalization semantics only for masters of tasks.)
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00161-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b[Amendment Correction:] Types Controlled and Limited_Controlled now have
+  Preelaborable_Initialization, so that objects of types derived from these
+  types can be used in preelaborated packages.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0020],ARef=[AI95-00126-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that 
Ada.Finalization
+  is a remote types package.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0021],ARef=[AI95-00182-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added wording to clarify 
that
+  the default initialization (whatever it is) of an ancestor part is used.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0022],ARef=[AI95-00083-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that Adjust is 
never
+  called on an @nt{aggregate} used for the initialization of an object or
+  subaggregate, or passed as a parameter.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00147-01]}
+  @ChgAdded{Version=[2],Text=[Additional optimizations are allowed for
+  nonlimited controlled types. These allow traditional dead variable
+  elimination to be applied to such types.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00318-02]}
+  @ChgAdded{Version=[2],Text=[Corrected the build-in-place requirement
+  for controlled @nt{aggregate}s to be consistent with the requirements
+  for limited types.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00348-01]}
+  @ChgAdded{Version=[2],Text=[The operations of types Controlled and
+  Limited_Controlled are now declared as null procedures (see
+  @RefSecNum{Null Procedures}) to make the semantics clear (and to provide
+  a good example of what null procedures can be used for).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00360-01]}
+  @ChgAdded{Version=[2],Text=[Types that need finalization are defined; this is
+  used by the No_Nested_Finalization restriction
+  (see @RefSec{Tasking Restrictions}).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00373-01]}
+  @ChgAdded{Version=[2],Text=[Generalized the description of objects that
+  have Initialize called for them to say that it is done for all objects that
+  are initialized by default. This is needed so that all of the new cases
+  are covered.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Package Ada.Finalization now has Pure categorization, so it can be mentioned
+  for any package. Note that this does not change the preelaborability of
+  objects descended from Controlled and Limited_Controlled.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0013-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Eliminated coextensions
+  from the @ldquote@;needs address@hidden rules, as this cannot be
+  determined in general in the compilation unit that declares the type.
+  (The designated type of the coextension may have been imported as a
+  limited view.) Uses of @ldquote@;needs address@hidden need to
+  ensure that coextensions are handled by other means (such as
+  in No_Nested_Finalization @en see @RefSecNum{Tasking Restrictions})
+  or that coextensions cannot happen.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0013-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the
+  @ldquote@;needs address@hidden rules to include class-wide types,
+  as a future extension can include a part that needs finalization.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0026-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the
+  @ldquote@;needs address@hidden rules to clearly say that they
+  ignore privacy.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0067-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Changed @ldquote@;built in 
address@hidden
+  to @RuntimeTitle and centralized the rules here. This eliminates the
+  fiction that built in place is just a combination of a permission and
+  a requirement; it clearly has noticeable semantic effects. This wording
+  change is not intended to change the semantics of any correct Ada program.]}
address@hidden
+
+
address@hidden and Finalization}
+
address@hidden
address@hidden subclause defines @i{completion} and @i{leaving} of the execution
+of constructs and entities.
+A @i{master} is the execution of a construct that
+includes finalization of local objects after it is complete
+(and after waiting for any local tasks
address@hidden see @RefSecNum(Task Dependence - Termination of Tasks)),
+but before leaving.
+Other constructs and entities are left immediately upon completion.
address@hidden,See=(finalization)}
address@hidden,See=(finalization)}]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden and leaving (completed and left)}
address@hidden, Sec=(run-time concept)}
+The execution of a construct or entity
+is @i{complete} when the end of that execution has been reached,
+or when a transfer of control
+(see @RefSecNum{Simple and Compound Statements - Sequences of Statements})
+causes it to be abandoned.
address@hidden completion}
address@hidden, Sec=(normal)}
address@hidden completion}
address@hidden, Sec=(abnormal)}
+Completion due to reaching the end of execution,
+or due to the transfer of control of an @Chg{Version=[2],
address@hidden, return statement, @nt{goto_statement}],
address@hidden, @ntf{return_}, @ntf{goto_}]},
+or @nt{requeue_statement} or of the
+selection of a @nt{terminate_alternative}
+is @i{normal completion}.
+Completion is @i{abnormal} otherwise @address@hidden
+when control is transferred out of a construct
+due to abort or the raising of an exception].
address@hidden
+Don't confuse the run-time concept of completion with
+the compile-time concept of completion
+defined in @RefSecNum{Completions of Declarations}.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00162-01],ARef=[AI95-00416-01]}
address@hidden
address@hidden
+After execution of a construct or entity is complete,
+it is @i{left},
+meaning that execution continues with the next action,
+as defined for the execution that is taking place.
address@hidden
+Leaving an execution happens immediately after its completion,
+except in the case of a @i{master}:
+the execution of
+a @Chg{Version=[2],New=[body other than a @nt{package_body};
+the execution of a @nt{statement}; or the evaluation of an
address@hidden, @nt{function_call}, or @nt{range} that
+is not part of an enclosing @nt{expression}, @nt{function_call}, @nt{range}, or
address@hidden@!statement} other than a @address@hidden@!statement}],
address@hidden, a @address@hidden,
+a @nt{subprogram_body}, an @nt{entry_body}, or an @address@hidden
+A master is finalized after it is
+complete, and before it is left.
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00162-01],ARef=[AI95-00416-01]}
+  @Chg{Version=[2],address@hidden and @nt{statement}s
+  are masters so that objects created by subprogram calls (in @nt{aggregate}s,
+  @nt{allocator}s for anonymous access-to-object types, and so on) are
+  finalized and have their tasks awaited before the @nt{expression}s or
+  @nt{statement}s are left. Note that @nt{expression}s like the @nt{condition}
+  of an @nt{if_statement} are masters, because they are not enclosed by a
+  @nt{simple_statement}. Similarly, a @nt{function_call} which is renamed
+  is a master, as it is not in a @address@hidden,
+  Old=[Note that although an @nt{accept_statement} has no
+  @nt{declarative_part}, it can call functions and evaluate @nt{aggregate}s,
+  possibly causing anonymous controlled objects to be created,
+  and we don't want those objects to escape outside the rendezvous.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[We have to include @nt{function_call}s in the
+  contexts that do not cause masters to occur so that @nt{expression}s
+  contained in a @nt{function_call} (that is not part of an @nt{expression} or
+  @nt{simple_statement}) do not individually become masters. We certainly do
+  not want the parameter @nt{expression}s of a @nt{function_call} to be
+  separate masters, as they would then be finalized before the function is
+  called.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[The fact that a @nt{function_call} is a master
+  does not change the accessibility of the return object denoted by the
+  @nt{function_call}; that depends on the use of the @nt{function_call}.
+  The @nt{function_call} is the master
+  of any short-lived entities (such as @nt{aggregate}s used as parameters of
+  types with task or controlled parts).]}
address@hidden
+
address@hidden, Sec=(of a master)}
+For the @i{finalization} of a master,
+dependent tasks are first awaited,
+as explained in @RefSecNum{Task Dependence - Termination of Tasks}.
+Then each object whose accessibility level is
+the same as that of the master is finalized
+if the object was successfully initialized and still exists.
address@hidden actions are performed whether the master is left
+  by reaching the last statement or via a transfer of control.]
+When a transfer of control causes completion of an execution, each
+included master is finalized in order, from innermost outward.
address@hidden
+  As explained in @RefSecNum{Operations of Access Types},
+  the set of objects with the same accessibility level
+  as that of the master
+  includes objects declared immediately within the master,
+  objects declared in nested packages,
+  objects created by @nt{allocator}s
+  (if the ultimate ancestor access type is declared in one of those places)
+  and subcomponents of all of these things.
+  If an object was already finalized by Unchecked_Deallocation,
+  then it is not finalized again when the master is left.
+
+  Note that any object whose accessibility level is deeper than that of
+  the master would no longer exist;
+  those objects would have been finalized by some inner master.
+  Thus, after leaving a master, the only objects yet to be
+  finalized are those whose accessibility level is less deep than that
+  of the master.
+
address@hidden
address@hidden
+Subcomponents of objects due to be finalized are not finalized
+by the finalization of the master;
+they are finalized by the finalization of the containing object.
address@hidden
address@hidden
+We need to finalize subcomponents of objects even if the containing
+object is not going to get finalized because it was not fully
+initialized.
+But if the containing object is finalized, we don't want to require
+repeated finalization of the subcomponents,
+as might normally be implied by the recursion in finalization of a
+master and the recursion in finalization of an object.
address@hidden
address@hidden
+Formally, completion and leaving refer to executions of constructs or
+entities.
+However, the standard sometimes (informally) refers
+to the constructs or entities whose executions are being completed.
+Thus, for example,
address@hidden@;the subprogram call or task is address@hidden@;
+really means
address@hidden@;@i{the execution of} the subprogram call or task is 
address@hidden@;
address@hidden
+
address@hidden@address@hidden, Sec=(of an object)}
+For the @i{finalization} of an object:
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0099-1]}
+  If @Chg{Version=[3],New=[the full type of ],Old=[]}the object is
+  @Chg{Version=[3],New=[],Old=[of ]}an elementary type, finalization
+  has no effect;
+  @begin{Reason}
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0099-1]}
+    @ChgAdded{Version=[3],Text=[We say @ldquote@;full address@hidden in this
+    and the following bullets as privacy is ignored for the purpose of
+    determining the finalization actions of an object; that is as expected
+    for @RunTimeTitle rules.]}
+  @end{Reason}
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0099-1]}
+  If @Chg{Version=[3],New=[the full type of ],Old=[]}the object is
+  @Chg{Version=[3],New=[a tagged type, and the tag of the object
+  identifies],Old=[of]} a controlled type,
+  the Finalize procedure @Chg{Version=[3],New=[of that controlled
+  type ],Old=[]}is called;
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0099-1]}
+  If @Chg{Version=[3],New=[the full type of ],Old=[]}the object is
+  @Chg{Version=[3],New=[],Old=[of ]}a protected type,
+  @Chg{Version=[3],New=[or if the full type of the object is a tagged type
+  and the tag of the object identifies a protected type, ],Old=[]}the
+  actions defined in @RefSecNum{Protected Units and Protected Objects} are 
performed;
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00416-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0099-1]}
+  If @Chg{Version=[3],New=[the full type of ],Old=[]}the object is
+  @Chg{Version=[3],New=[],Old=[of ]}a composite type, then after performing
+  the above actions, if any, every component of the object
+  is finalized in an arbitrary order, except as 
follows:@PDefn2{Term=[arbitrary order],Sec=[allowed]}
+  if the object has
+  a component with an access discriminant constrained by a per-object
+  expression, this component is finalized before any components that
+  do not have such discriminants; for an object with several components
+  with such a discriminant, they are finalized in the
+  reverse of the order of their
+  @nt<component_declaration>address@hidden,New=[;],Old=[.]}
+  @begin{Reason}
+    This allows the finalization of a component with an access discriminant
+    to refer to other components of the enclosing object prior to
+    their being finalized.
+  @end{Reason}
+  @begin{Honest}
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0099-1]}
+    @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0005-1]}
+    @ChgAdded{Version=[3],Text=[The components discussed here are all of the
+    components that the object actually has, not just those components that are
+    statically identified by the type of the object. These can be different if
+    the object has a @Chg{Version=[4],New=[class-wide],Old=[classwide]} type.]}
+  @end{Honest}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[If the object has coextensions (see
+  @RefSecNum{Operations of Access Types}), each coextension is
+  finalized after the object whose access discriminant designates it.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0066-1]}
+  @ChgAdded{Version=[3],Text=[In the case of an @nt{aggregate} or function 
call that is used
+  (in its entirety) to directly initialize a part of an object, the
+  coextensions of the result of evaluating the @nt{aggregate} or function
+  call are transfered to become coextensions of the object being
+  initialized and are not finalized until the object being initialized
+  is ultimately finalized, even if an anonymous object is created
+  as part of the operation.]}
address@hidden
+
address@hidden
+
address@hidden, Sec=(instance of Unchecked_Deallocation)}
+Immediately before an instance of Unchecked_Deallocation
+reclaims the storage of an object,
+the object is finalized.
address@hidden an instance of Unchecked_Deallocation is never applied to
+an object created by an @nt{allocator},
+the object will still exist when the corresponding master completes,
+and it will be finalized then.]
+
address@hidden,Kind=[Revised],ARef=[AI95-00280-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0051-1],ARef=[AI05-0190-1]}
+The @Chg{Version=[3],New=[],Old=[order in which the ]}finalization of a master
+performs finalization of objects @Chg{Version=[3],New=[],Old=[is as follows:
+Objects ]}created by declarations in the master
address@hidden,New=[],Old=[are finalized ]}in the reverse order of their
address@hidden,New=[],Old=[ For objects that were created by
address@hidden for an access type whose
+ultimate ancestor is declared in the master,
+this rule is applied as though each
+such object that still exists had been created
+in an arbitrary order
+at the first freezing point
+(see @RefSecNum{Freezing Rules})@PDefn2{Term=[arbitrary order],Sec=[allowed]}
+of the ultimate ancestor address@hidden,New=[; the finalization of
+these objects is called the @i<finalization of the
+collection>@Defn{finalization of the address@hidden,
+Sec=[finalization of]}],address@hidden,New=[ Objects created by
+allocators for an anonymous access type that are not coextensions of some other
+object, are finalized in an arbitrary order during the finalization of their
+associated address@hidden order],Sec=[allowed]}],address@hidden,
+New=[ After the finalization of a master is complete, the objects finalized
+as part of its finalization cease to @i<exist>, as do any types and subtypes
+defined and created within the address@hidden,Sec=[cease to]}
address@hidden to exist],Sec=[object]}
address@hidden to exist],Sec=[type]}],Old=[]}
address@hidden
+  @ChgRef{Version=[3],Kind=[Deleted],address@hidden down}
+  @ChgDeleted{Version=[3],Text=[Note that we talk about the type of the
+  @nt{allocator} here. There may be access values of a (general) access type
+  pointing at objects created by @nt{allocator}s for some other type; these are
+  not finalized at this point.]}
+
+  @ChgRef{Version=[3],Kind=[Deleted],address@hidden down}
+  @ChgDeleted{Version=[3],Text=[The freezing point of the ultimate ancestor 
access type is chosen
+  because before that point, pool elements cannot be created,
+  and after that point, access values designating (parts of)
+  the pool elements can be created.
+  This is also the point after which the pool object cannot have been
+  declared.
+  We don't want to finalize the pool elements until after anything
+  finalizing objects that contain access values designating them.
+  Nor do we want to finalize pool elements after finalizing the pool
+  object itself.]}
address@hidden
address@hidden
address@hidden,Kind=[Deleted],address@hidden down}
address@hidden,Text=[Finalization of allocated objects is done according
+  to the (ultimate ancestor) @nt{allocator} type, not according to the storage 
pool
+  in which they are allocated.
+  Pool finalization might reclaim storage (see @RefSec{Storage Management}),
+  but has nothing (directly) to do with finalization of the
+  pool elements.]}
+
address@hidden,Kind=[Deleted],address@hidden down}
address@hidden,Text=[Note that finalization is done only for objects
+that still exist; if an instance of Unchecked_Deallocation has already gotten
+rid of a given pool element, that pool element will not be finalized when
+the master is left.]}
+
+Note that a deferred constant declaration does not create the
+constant; the full constant declaration creates it.
+Therefore, the order of finalization depends on where the full
+constant declaration occurs,
+not the deferred constant declaration.
+
+An imported object is not created by its declaration.
+It is neither initialized nor finalized.
address@hidden
address@hidden
+An implementation has to ensure that the storage for an object is not
+reclaimed when references to the object are still possible
+(unless, of course, the user explicitly requests reclamation via an
+instance of Unchecked_Deallocation).
+This implies, in general, that objects cannot be deallocated one by one
+as they are finalized;
+a subsequent finalization might reference an object that has been
+finalized, and that object had better be in its (well-defined)
+finalized state.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0190-1]}
address@hidden,Type=[Leading],Text=[Each nonderived access type @i<T> has
+an associated @i<collection>,@Defn2{Term=[collection],Sec=[of an access type]}
+which is the set of objects created by @nt{allocator}s of @i<T>,
+or of types derived from @i<T>. Unchecked_Deallocation removes an object from
+its collection. Finalization of a collection consists of finalization of each
+object in the collection, in an arbitrary order. The collection of an access
+type is an object implicitly declared at the following 
place:@PDefn2{Term=[arbitrary order],Sec=[allowed]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0190-1]}
+  @ChgAdded{Version=[3],Text=[The place of the implicit declaration determines
+  when allocated objects are finalized. For multiple collections declared at 
the
+  same place, we do not define the order of their implicit declarations.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],address@hidden down}
+  @ChgAdded{Version=[3],Text=[Finalization of allocated objects is done 
according
+  to the (ultimate ancestor) @nt{allocator} type, not according to the storage
+  pool in which they are allocated. Pool finalization might reclaim storage 
(see
+  @RefSec{Storage Management}), but has nothing (directly) to do with
+  finalization of the pool elements.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],address@hidden down}
+  @ChgAdded{Version=[3],Text=[Note that finalization is done only for objects 
that
+  still exist; if an instance of Unchecked_Deallocation has already gotten rid
+  of a given pool element, that pool element will not be finalized when the
+  master is left.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],address@hidden down}
+  @ChgAdded{Version=[3],Text=[Note that we talk about the type of the
+  @nt{allocator} here. There may be access values of a (general) access type
+  pointing at objects created by @nt{allocator}s for some other type; these are
+  not (necessarily) finalized at this point.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[For a named access type, the first freezing point (see
address@hidden Rules}) of the type.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],address@hidden down}
+  @ChgAdded{Version=[3],Text=[The freezing point of the ultimate ancestor 
access
+  type is chosen because before that point, pool elements cannot be created,
+  and after that point, access values designating (parts of)
+  the pool elements can be created.
+  This is also the point after which the pool object cannot have been declared.
+  We don't want to finalize the pool elements until after anything
+  finalizing objects that contain access values designating them.
+  Nor do we want to finalize pool elements after finalizing the pool
+  object itself.]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Text=[For the type of an access parameter, the call that
+contains the @nt{allocator}.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[For the type of an access result, within the master of
+the call (see @RefSecNum{Operations of Access Types}).]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1],ARef=[AI05-0190-1]}
+  @ChgAdded{Version=[3],Text=[We mean at a place within the master consistent
+  with the execution of the call within the master. We don't say that
+  normatively, as it is difficult to explain that when the master of the call
+  need not be the master that immediately includes the call (such as when an
+  anonymous result is converted to a named access type).]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Text=[For any other anonymous access type, the first
+freezing point of the innermost enclosing declaration.]}
address@hidden
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00256-01]}
address@hidden, Sec=(assignment_statement)}
+The target of an @Chg{Version=[2],address@hidden,
+Old=[assignment statement]} is finalized before copying in the
+new value, as explained
+in @RefSecNum{Assignment and Finalization}.
+
address@hidden,Kind=[Revised],Ref=[8652/0021],ARef=[AI95-00182-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00162-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0066-1],ARef=[AI05-0142-4],ARef=[AI05-0269-1]}
address@hidden,New=[The master of an object is the master enclosing its
+creation whose accessibility level (see @RefSecNum{Operations of Access Types})
+is equal to that of the address@hidden,New=[, except
+in the case of an anonymous object representing the result of
+an @nt{aggregate} or function call. If such an anonymous object
+is part of the result of evaluating the actual parameter expression for
+an explicitly aliased
+parameter of a function call, the master of the object is the innermost
+master enclosing the evaluation of the @nt{aggregate} or function call, 
excluding
+the @nt{aggregate} or function call itself. Otherwise, the master of such
+an anonymous object is the innermost master enclosing the evaluation of the
address@hidden or function call, which may be the @nt{aggregate} or function
+call itself],Old=[]}.],
address@hidden the @address@hidden in an @nt{object_renaming_declaration}, or
+the actual parameter for a generic formal @key[in out] parameter in a
address@hidden, denotes any part of an anonymous object created by
+a function call, the anonymous object is not finalized until after it is no
+longer accessible via any name. Otherwise, an],
+Old=[The]} anonymous address@hidden,Old=[s]} created by
address@hidden ],Old=[]}function @Chg{New=[call or],Old=[calls and]} by
address@hidden ],address@hidden@Chg{New=[ is],Old=[s are]}
+finalized no later than the end of the innermost enclosing
address@hidden or @nt{statement};
+if that is a @nt{compound_statement},
address@hidden object is],Old=[they are]} finalized before starting the
+execution of any @nt{statement} within the @nt{compound_statement}.]}
address@hidden
address@hidden,Kind=[Deleted],address@hidden be ChgDeleted}
address@hidden,address@hidden@;This is not to be construed as permission to 
call Finalize
+asynchronously with respect to normal user code.
+For example,]}
address@hidden
address@hidden,Kind=[Deleted]}
address@hidden,address@hidden
+    X : Some_Controlled_Type := F(G(...));
+    address@hidden The anonymous objects created for F and G are finalized}
+    address@hidden no later than this point.}
+    Y : ...
address@hidden
+    ...
address@hidden;]}
address@hidden
+
address@hidden,Kind=[Deleted]}
address@hidden,Text=[
+The anonymous object for G should not be finalized at some random
+point in the middle of the body of F,
+because F might manipulate the same data structures as
+the Finalize operation, resulting in erroneous access
+to shared variables.]}
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00162-01]}
address@hidden,New=[This effectively imports all of the special rules for
+the accessibility level of renames, @nt{allocator}s, and so on, and applies
+them to determine where objects created in them are finalized. For instance,
+the master of a rename of a subprogram is that of the renamed subprogram.],
+Old=[It might be quite inconvenient for the implementation to defer
+finalization of the anonymous object for G until after copying the
+value of F into X, especially if the size of the result
+is not known at the call site.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0066-1]}
address@hidden,Text=[In @RefSecNum{Operations of Access Types}
+we assign an accessibility level to the result of an
address@hidden or function call that is used to directly initialize a
+part of an object based on the object being initialized. This is
+important to ensure that any access discriminants denote objects
+that live at least as long as the object being initialized.
+However, if the result of the @nt{aggregate} or function call is not
+built directly in the target object, but instead is built in an
+anonymous object that is then assigned to the target, the anonymous
+object needs to be finalized after the assignment rather than
+persisting until the target object is finalized (but not its
+coextensions). (Note than an implementation is never required to
+create such an anonymous object, and in some cases is required to
address@hidden have such a separate object, but rather to build the result
+directly in the target.)]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0142-4]}
address@hidden,Text=[The special case for explicitly aliased parameters
+of functions is needed for the same reason, as access discriminants of the
+returned object may designate one of these parameters. In that case, we want to
+lengthen the lifetime of the anonymous objects as long as the possible lifetime
+of the result.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0142-4]}
address@hidden,Text=[We don't do a similar change for other kinds of
+calls, because the extended lifetime of the parameters adds no value, but could
+constitute a storage leak. For instance, such an anonymous object created by a
+procedure call in the elaboration part of a package body would have to live
+until the end of the program, even though it could not be used after the
+procedure returns (other than via Unchecked_Access).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0142-4]}
address@hidden,Text=[Note that the lifetime of the master given to
+anonymous objects in explicitly aliased parameters of functions is not
+necessarily as long as the lifetime of the master of the object being
+initialized (if the function call is used to initialize an @nt{allocator}, for
+instance). In that case, the accessibility check on explicitly aliased
+parameters will necessarily fail if any such anonymous objects exist. This is
+necessary to avoid requiring the objects to live as long as the access type or
+having the implementation complexity of an implicit coextension.]}
address@hidden
+
+
address@hidden,Kind=[Added],Ref=[8652/0023],ARef=[AI95-00169-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00162-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0066-1],ARef=[AI05-0262-1]}
address@hidden,New=[In the case of an @nt{expression} that is a master,
+finalization of any (anonymous) objects occurs @Chg{Version=[3],New=[after
+completing],Old=[as the final part of]}
+evaluation of the @address@hidden,New=[ and all use of the
+objects, prior to starting the execution of any subsequent 
construct],Old=[]}.],
address@hidden a transfer of control or raising of an exception occurs prior to
+performing a finalization of an anonymous object, the anonymous object is
+finalized as part of the finalizations due to be performed for the object's
+innermost enclosing master.],Old=[]}]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0023],ARef=[AI95-00169-01]}
address@hidden@PDefn2{Term=(bounded error),Sec=(cause)}
+It is a bounded error for a call on Finalize or Adjust @Chg{New=[that occurs as
+part of object finalization or assignment ], Old=[]}to propagate an exception.
+The possible consequences depend on what action invoked the Finalize or
+Adjust operation:
address@hidden
+  It is not a bounded error for Initialize to propagate an
+  exception. If Initialize propagates an exception,
+  then no further calls on Initialize are performed,
+  and those components that have already been initialized
+  (either explicitly or by default)
+  are finalized in the usual way.
+
+  @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0023],ARef=[AI95-00169-01]}
+  @Chg{New=[It also is not a bounded error for an explicit call to Finalize or
+  Adjust to propagate an exception. We do not want implementations to have to
+  treat explicit calls to these routines specially.],Old=[]}
address@hidden
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+For a Finalize invoked as part of an @nt<assignment_statement>,
+Program_Error is raised at that point.
+
address@hidden,Kind=[Revised],Ref=[8652/0024],ARef=[AI95-00193-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00256-01]}
address@hidden an Adjust invoked as part of @Chg{Version=[2],New=[assignment
+operations other than those invoked as part of an @nt{assignment_statement}],
+Old=[the initialization of a controlled object]}, other adjustments due to be
+performed might or might not be performed, and then Program_Error is raised.
+During its propagation, finalization might or
+might not be applied to objects whose Adjust failed.],Old=[]}
address@hidden,Sec=(raised by failure of run-time check)}
+For an Adjust invoked as part of an @Chg{Version=[2],address@hidden,
+Old=[assignment @Chg{New=[statement],Old=[operation]}]}, any other adjustments
+due to be performed are performed, and then Program_Error is raised.
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0024],ARef=[AI95-00193-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00256-01]}
address@hidden,Text=[In the case of assignments that are part of
+initialization, there is
+no need to complete all adjustments if one propagates an exception, as the
+object will immediately be finalized. So long as a subcomponent is not going
+to be finalized, it need not be adjusted, even if it is initialized as part of
+an enclosing composite assignment operation for which some adjustments are
+performed. However, there is no harm in an implementation making additional
+Adjust calls (as long as any additional components that are adjusted are also
+finalized), so we allow the implementation flexibility here.
+On the other hand, for an @Chg{Version=[2],address@hidden,
+Old=[assignment statement]}, it is important that all
+adjustments be performed, even if one fails, because all controlled
+subcomponents are going to be address@hidden,New=[ Other kinds of
+assignment are more like initialization than @nt{assignment_statement}s, so we
+include them as well in the permission.],Old=[]}]}
address@hidden
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0024],ARef=[AI95-00193-01]}
address@hidden,Text=[Even if an Adjust invoked as part of the
+initialization of a
+controlled object propagates an exception, objects whose initialization
+(including any Adjust or Initialize calls) successfully completed will be
+finalized. The permission above only applies to objects whose Adjust failed.
+Objects for which Adjust was never even invoked must not be finalized.]}
address@hidden
+
address@hidden,Sec=(raised by failure of run-time check)}
+For a Finalize invoked as part of a call on an instance of
+Unchecked_Deallocation, any other finalizations due to
+be performed are performed, and then Program_Error is raised.
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0104],ARef=[AI95-00179-01]}
address@hidden,Text=[The standard does not specify if storage is
+recovered in this case.
+If storage is not recovered (and the object continues to exist), Finalize
+may be called on the object again (when the @nt<allocator>'s master is
+finalized).]}
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0023],ARef=[AI95-00169-01]}
address@hidden,Kind=[DeletedAdded],ARef=[AI05-0064-1]}
address@hidden,address@hidden@Defn2{Term=[Program_Error],Sec=(raised by failure 
of run-time check)}
+For a Finalize invoked as part of the finalization of the anonymous
+object created by a function call or @nt{aggregate}, any other finalizations
+due to be performed are performed, and then Program_Error is raised.],Old=[]}]}
+
address@hidden,Kind=[Added],Ref=[8652/0023],ARef=[AI95-00169-01]}
address@hidden@Defn2{Term=[Program_Error],Sec=(raised by failure of run-time 
check)}
+For a Finalize invoked due to reaching the end of the execution of a
+master, any other finalizations associated with the master are performed, and
+Program_Error is raised immediately after leaving the master.],Old=[]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0064-1]}
address@hidden
address@hidden,Text=[This rule covers both ordinary objects created
+by a declaration, and anonymous objects created as part of evaluating an
address@hidden All contexts that create objects that need finalization
+are defined to be masters.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
address@hidden,Sec=(raised by failure of run-time check)}
+For a Finalize invoked by the transfer of control of
+an @Chg{Version=[2],
address@hidden, return statement, @nt{goto_statement}],
address@hidden, @ntf{return_}, @ntf{goto_}]},
+or @address@hidden,
+Program_Error is raised no earlier than after the finalization of the
+master being finalized when the exception occurred,
+and no later than the point where normal execution would have continued.
+Any other finalizations due to be performed up to that point are
+performed before raising Program_Error.
address@hidden
+For example, upon leaving a @nt{block_statement} due to a
address@hidden, the Program_Error would be raised at the point of the
+target statement denoted by the label,
+or else in some more dynamically nested place,
+but not so nested as to allow an @nt{exception_handler} that has
+visibility upon the finalized object to handle it.
+For example,
address@hidden
address@hidden Main @key[is]
address@hidden
+    <<The_Label>>
+    Outer_Block_Statement : @key[declare]
+        X : Some_Controlled_Type;
+    @key[begin]
+        Inner_Block_Statement : @key[declare]
+            Y : Some_Controlled_Type;
+            Z : Some_Controlled_Type;
+        @key[begin]
+            @key[goto] The_Label;
+        @key[exception]
+            @key[when] Program_Error => ... address@hidden Handler number 1.}
+        @key[end];
+    @key[exception]
+        @key[when] Program_Error => ... address@hidden Handler number 2.}
+    @key[end];
address@hidden
+    @key[when] Program_Error => ... address@hidden Handler number 3.}
address@hidden Main;
address@hidden
+
+The @nt{goto_statement} will first cause
+Finalize(Y) to be called.
+Suppose that Finalize(Y) propagates an exception.
+Program_Error will be raised after leaving Inner_Block_Statement,
+but before leaving Main.
+Thus, handler number 1 cannot handle this Program_Error;
+it will be handled either by handler number 2 or handler number 3.
+If it is handled by handler number 2,
+then Finalize(Z) will be done before executing the handler.
+If it is handled by handler number 3,
+then Finalize(Z) and Finalize(X) will both
+be done before executing the handler.
address@hidden
+
+For a Finalize invoked by a transfer of control
+that is due to raising an exception,
+any other finalizations due to be performed for the same master are
+performed; Program_Error is raised immediately after leaving the master.
address@hidden
+If, in the above example, the @nt{goto_statement} were replaced by a
address@hidden, then the Program_Error would be handled by
+handler number 2, and
+Finalize(Z) would be done before executing the handler.
address@hidden
address@hidden
+We considered treating this case in the same way as the others,
+but that would render certain @nt{exception_handler}s useless.
+For example, suppose the only @nt{exception_handler} is
+one for @key{others} in the main subprogram.
+If some deeply nested call raises an exception,
+causing some Finalize operation to be called,
+which then raises an exception,
+then normal execution @lquotes@;would have address@hidden@;
+at the beginning of the @nt{exception_handler}.
+Raising Program_Error at that point would cause that
+handler's code to be skipped.
+One would need two nested @nt{exception_handler}s
+to be sure of catching such cases!
+
+On the other hand, the @nt{exception_handler} for a given master
+should not be allowed to handle exceptions raised during finalization
+of that master.
address@hidden
+
+For a Finalize invoked by a transfer of control due to
+an abort or selection of a terminate alternative,
+the exception is ignored;
+any other finalizations due to be performed are performed.
address@hidden
+This case includes an asynchronous transfer of control.
address@hidden
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+This violates the general principle that it is always possible for
+a bounded error to raise Program_Error
+(see @RefSec{Classification of Errors}).
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0107-1]}
address@hidden,Text=[If the execution of an @nt{allocator} propagates an
+exception, any parts of the allocated object that were successfully initialized
+may be finalized as part of the finalization of the innermost master enclosing
+the @nt{allocator}.]}
+
+  @begin{Reason}
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This allows deallocating the memory for the
+  allocated object at the innermost master, preventing a storage leak.
+  Otherwise, the object would have to stay around until the finalization of the
+  collection that it belongs to, which could be the entire life of the program
+  if the associated access type is library level.]}
+  @end{Reason}
+
address@hidden,Kind=[Added],ARef=[AI05-0111-3],ARef=[AI05-0262-1]}
address@hidden,Text=[The implementation may finalize objects created by
address@hidden for an access type whose storage pool supports subpools (see
address@hidden Subpools}) as if the objects were created (in an arbitrary
+order) at the point where the storage pool was elaborated instead of at the 
first
+freezing point of the access address@hidden order],Sec=[allowed]}]}
+
+  @begin{Ramification}
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This allows the finalization of such objects to
+  occur later than they otherwise would, but still as part of the finalization
+  of the same master. Accessibility rules in @RefSecNum{Storage Subpools} 
ensure
+  that it is the same master (usually that of the environment task).]}
+  @end{Ramification}
+
+  @begin{ImplNote}
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This permission is intended to allow the 
allocated
+  objects to "belong" to the subpool objects and to allow those objects to be
+  finalized at the time that the storage pool is finalized (if they are not
+  finalized earlier). This is expected to ease implementation, as the objects
+  will only need to belong to the subpool and not also to the collection.]}
+  @end{ImplNote}
+
address@hidden
+
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The rules of @Chg{Version=[3],New=[Clause],Old=[Section]} 10 imply that
+immediately prior to partition termination, Finalize operations
+are applied to library-level controlled objects (including those
+created by @nt{allocator}s of library-level access types, except those
+already finalized).
+This occurs after waiting for library-level
+tasks to terminate.
address@hidden
+We considered defining a pragma that would apply to a controlled
+type that would suppress Finalize operations for library-level objects
+of the type upon partition termination.
+This would be useful for types whose finalization actions
+consist of simply reclaiming global heap storage, when this is already
+provided automatically by the environment upon program termination.
address@hidden
+
+A constant is only constant between its initialization and
+finalization.
+Both initialization and finalization are allowed to
+change the value of a constant.
+
+Abort is deferred during certain operations related to controlled types,
+as explained in
address@hidden of a Task - Abort of a Sequence of Statements}.
+Those rules prevent an abort from causing a controlled object
+to be left in an ill-defined state.
+
+The Finalize procedure is called upon finalization of
+a controlled object, even if Finalize was called earlier,
+either explicitly or as part of an assignment; hence,
+if a controlled type is visibly controlled (implying that its Finalize
+primitive is directly callable), or is nonlimited (implying that
+assignment is allowed), its Finalize procedure should be
+designed to have no ill effect if it is applied a second time
+to the same object.
address@hidden
+  Or equivalently, a Finalize procedure
+  should be @lquotes@;address@hidden@;;
+  applying it twice to the same object should be equivalent to
+  applying it once.
address@hidden
address@hidden
+  A user-written Finalize procedure should be idempotent since it
+  can be called explicitly
+  by a client (at least if the type is "visibly" controlled).
+  Also, Finalize is used implicitly as part of the
+  @nt<assignment_statement> if the
+  type is nonlimited, and an abort is permitted to disrupt an
+  @nt<assignment_statement> between finalizing the left-hand side
+  and assigning the new value to it (an abort is not permitted to
+  disrupt an assignment operation between copying in the new value
+  and adjusting it).
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
+Either Initialize or Adjust,
+but not both, is applied to (almost) every controlled object
+when it is created:
+Initialize is done when no initial value is assigned to the object,
+whereas Adjust is done as part of assigning the initial value.
+The one exception is the @Chg{Version=[2],New=[],Old=[anonymous ]}object
address@hidden,New=[initialized],Old=[created]} by an
address@hidden@Chg{Version=[2],New=[ (both the anonymous object created for
+an aggregate, or an object initialized by an @nt{aggregate} that is
+built-in-place)],Old=[]}; Initialize is not applied to the @nt{aggregate}
+as a whole, nor is the value of the @nt<aggregate> @Chg{Version=[2],
+New=[or object ],Old=[]}adjusted.
+
address@hidden@Defn2{Term=[assignment operation], Sec=(list of uses)}
+All of the following use the assignment operation,
+and thus perform value adjustment:
address@hidden
+the @nt{assignment_statement} (see @RefSecNum{Assignment Statements});
+
+explicit initialization of a stand-alone object
+(see @RefSecNum{Object Declarations})
+or of a pool element (see @RefSecNum{Allocators});
+
+default initialization of a component of a stand-alone object
+or pool element
+(in this case, the value of each component is assigned, and therefore adjusted,
+but the value of the object as a whole is not adjusted);
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
+function return, when the result @Chg{Version=[2],New=[is not built-in-place],
+Old=[type is not a return-by-reference
+type (see @RefSecNum{Return Statements});]}
+(adjustment of the result happens before finalization of
+the address@hidden,New=[],Old=[;
+values of return-by-reference types are not
+adjusted]});
+
+predefined operators (although the only one that matters is
+concatenation; see @RefSecNum{Binary Adding Operators});
+
+generic formal objects of mode @key{in}
+(see @RefSecNum{Formal Objects});
+these are defined in terms of constant declarations; and
+
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
address@hidden (see @RefSecNum{Aggregates})@Chg{Version=[2],New=[, when
+the result is not built-in-place],Old=[]}
+(in this case, the value of each component, and the parent part, for an
address@hidden, is assigned, and therefore adjusted,
+but the value of the @nt{aggregate} as a whole is not adjusted;
+neither is Initialize called);
address@hidden
+
address@hidden@;The following also use the assignment operation,
+but adjustment never does anything interesting in these cases:
address@hidden
+By-copy parameter passing uses the assignment operation
+(see @RefSecNum{Parameter Associations}),
+but controlled objects are always passed by reference,
+so the assignment operation never does anything interesting in
+this case.
+If we were to allow by-copy parameter passing for controlled objects,
+we would need to make sure that the actual is finalized before doing
+the copy back for address@hidden @key{out} parameters.
+The finalization of the parameter itself needs to happen
+after the copy back (if any),
+similar to the finalization of an anonymous function return
+object or @nt{aggregate} object.
+
address@hidden loops use the assignment operation
+(see @RefSecNum{Loop Statements}), but since the type
+of the loop parameter is never controlled,
+nothing interesting happens there, either.
+
address@hidden,Kind=[Added],ARef=[AI95-00318-02]}
address@hidden,Text=[Objects initialized by function results and
address@hidden that are built-in-place. In this case, the assignment
+operation is never executed, and no adjustment takes place. While
+built-in-place
+is always allowed, it is required for some types @em see
address@hidden Types} and
address@hidden and Finalization} @em and that's
+important since limited types have no Adjust to call.]}
address@hidden
+
address@hidden,Kind=[Deleted],ARef=[AI95-00287-01]}
address@hidden,Text=[Because Controlled and Limited_Controlled
+are library-level tagged types,
+all controlled types will be library-level types,
+because of the accessibility rules
+(see @RefSecNum{Operations of Access Types} and @RefSecNum{Type Extensions}).
+This ensures that the Finalize operations may be applied without
+providing any @lquotes@;address@hidden@; or @lquotes@;address@hidden@;
+This simplifies finalization as a result of garbage collection,
+abort, and asynchronous transfer of control.]}
+
+Finalization of the parts of a protected object are not done as
+protected actions.
+It is possible (in pathological cases)
+to create tasks during finalization that
+access these parts in parallel with the finalization itself.
+This is an erroneous use of shared variables.
address@hidden
address@hidden
+One implementation technique for finalization is to chain the
+controlled objects together on a per-task list.
+When leaving a master, the list can be walked up to a marked place.
+The links needed to implement the list can be declared (privately)
+in types Controlled and Limited_Controlled,
+so they will be inherited by all controlled types.
+
+Another implementation technique, which we refer to as the 
@lquotes@;address@hidden@;
+approach essentially implies inserting exception handlers at various
+places, and finalizing objects based on where the exception was
+raised.
+
address@hidden approach to finalization}
address@hidden approach to finalization}
+The PC-map approach is for the compiler/linker to create a map of
+code addresses; when an exception is raised, or abort occurs,
+the map can be consulted to see where the task was executing,
+and what finalization needs to be performed.
+This approach was given in the Ada 83 Rationale as a
+possible implementation strategy for exception handling @em the
+map is consulted to determine which exception handler applies.
+
+If the PC-map approach is used, the implementation must take care in the
+case of arrays. The generated code will generally contain a loop to
+initialize an array. If an exception is raised part way through the
+array, the components that have been initialized must be finalized,
+and the others must not be finalized.
+
+It is our intention that both of these implementation methods should
+be possible.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Finalization depends on the concepts of completion and leaving,
+and on the concept of a master.
+Therefore, we have moved the definitions of these concepts here,
+from where they used to be in
address@hidden,New=[Clause],Old=[Section]} @RefSecNum{Tasks and 
Synchronization}.
+These concepts also needed to be generalized somewhat.
+Task waiting is closely related to user-defined finalization;
+the rules here refer to the task-waiting rules of
address@hidden,New=[Clause],Old=[Section]} @RefSecNum{Tasks and 
Synchronization}.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0066-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Ada 2012 
Correction:>
+  Changed the definition
+  of the master of an anonymous object used to directly initialize an
+  object, so it can be finalized immediately rather than having to hang
+  around as long as the object. In this case, the Ada 2005 definition was
+  inconsistent with Ada 95, and Ada 2012 changes it back. It is unlikely
+  that many compilers implemented the rule as written in Amendment 1,
+  so an inconsistency is unlikely to arise in practice.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0021],ARef=[AI95-00182-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Fixed the wording to say 
that
+  anonymous objects aren't finalized until the object can't be used anymore.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0023],ARef=[AI95-00169-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added wording to clarify 
what
+  happens when Adjust or Finalize raises an exception; some cases had been
+  omitted.]}
+
+  @ChgRef{Version=[1],Kind=[AddedNormal],Ref=[8652/0024],ARef=[AI95-00193-01]}
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00256-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Stated that if Adjust 
raises an
+  exception during initialization, nothing further is required. This is
+  corrected in Ada 2005 to include all kinds of assignment other than
+  @nt{assignment_statement}s.]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00162-01],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[Revised the definition of master to include
+  @nt{expression}s and @nt{statement}s, in order to cleanly define what
+  happens for tasks and controlled objects created as part of a subprogram 
call.
+  Having done that, all of the special wording to cover those cases is
+  eliminated (at least until the Ada comments start rolling in).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00280-01]}
+  @ChgAdded{Version=[2],Text=[We define @i{finalization of the collection}
+  here, so as to be able to conveniently refer to it in other rules (especially
+  in @RefSec{Allocators}).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that a coextension is finalized at
+  the same time as the outer object. (This was intended for Ada 95, but since
+  the concept did not have a name, it was overlooked.)]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0051-1],ARef=[AI05-0190-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Better defined when objects allocated from anonymous access types are
+  finalized. This could be inconsistent if objects are finalized in
+  a different order than in an Ada 2005 implementation and that order caused
+  different program behavior; however programs that depend on the order of
+  finalization within a single master are already fragile and hopefully
+  are rare.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0064-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Removed a redundant rule,
+  which is now covered by the additional places where masters are defined.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0099-1]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified the finalization
+  rules so that there is no doubt that privacy is ignored, and to ensure
+  that objects of @Chg{Version=[4],New=[class-wide],Old=[classwide]} interface
+  types are finalized based on their specific concrete type.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0107-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Allowed premature 
finalization
+  of parts of failed @nt{allocator}s. This could be an inconsistency, but the
+  previous behavior is still allowed and there is no requirement that
+  implementations take advantage of the permission.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0111-3]}
+  @ChgAdded{Version=[3],Text=[Added a permission to finalize an object 
allocated
+  from a subpool later than usual.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0142-4]}
+  @ChgAdded{Version=[3],Text=[Added text to specially define the master of
+  anonymous objects which are passed as explicitly aliased parameters (see
+  @RefSecNum{Subprogram Declarations}) of functions. The model for these
+  parameters is explained in detail in @RefSecNum{Parameter Associations}.]}
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/08.mss 
b/packages/ada-ref-man/source_2012/08.mss
new file mode 100755
index 0000000..11cb5f9
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/08.mss
@@ -0,0 +1,3841 @@
address@hidden(08, Root="ada.mss")
+
address@hidden: 2015/04/03 04:12:42 $}
address@hidden Rules}
+
address@hidden: e:\\cvsroot/ARM/Source/08.mss,v $}
address@hidden: 1.106 $}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden rules defining the scope of declarations and the rules defining
+which @nt{identifier}s, @nt{character_literal}s, and
address@hidden are visible at (or from) various places in the text of
+the program are described in this @Chg{Version=[3],New=[clause],Old=[section]}.
+The formulation of these rules uses the notion of a declarative region.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+As explained in @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden and Types},
+a declaration declares a view of an entity
+and associates a defining name with that view.
+The view comprises an identification of the viewed entity,
+and possibly additional properties.
+A usage name denotes a declaration.
+It also denotes the view declared by that declaration,
+and denotes the entity of that view.
+Thus, two different usage names might denote two different views of
+the same entity; in this case they denote the same entity.]
address@hidden
+In some cases, a usage name that denotes a declaration
+does not denote the view declared by that declaration,
+nor the entity of that view,
+but instead denotes a view of the current instance of the entity,
+and denotes the current instance of the entity.
+This sometimes happens when the usage name occurs inside
+the declarative region of the declaration.
address@hidden
address@hidden
+
address@hidden
+We no longer define the term @lquotes@;basic operation;@rquotes@;
+thus we no longer have to worry about the visibility of them.
+Since they were essentially always visible in Ada 83, this change has
+no effect. The reason for this change is that the definition in Ada
+83 was confusing, and not quite correct,
+and we found it difficult to fix. For example, one
+wonders why an @nt{if_statement} was not a basic operation of type
+Boolean. For another example, one wonders what it meant for a basic
+operation to be @lquotes@;inherent address@hidden@; something.
+Finally, this fixes the problem addressed by AI83-00027/07.
address@hidden
+
address@hidden Region}
+
address@hidden
address@hidden@Defn2{Term=[declarative region], Sec=(of a construct)}
+For each of the following constructs,
+there is a portion of the program text
+called its @i{declarative region},
address@hidden which nested declarations can occur]:
address@hidden(itemize)
+  any declaration, other than that of an enumeration type,
+  that is not a completion @Redundant[of a previous declaration];
+
address@hidden,Kind=[Added],ARef=[AI12-0094-1]}
+  @ChgAdded{Version=[4],Text=[an @nt{access_definition};]}
+
+  a @nt{block_statement};
+
+  a @nt{loop_statement};
+
address@hidden,Kind=[Added],ARef=[AI05-0255-1]}
+  @ChgAdded{Version=[3],Text=[a @nt{quantified_expression};]}
+
address@hidden,Kind=[Added],ARef=[AI95-00318-02]}
address@hidden,address@hidden number changed}
+  @ChgAdded{Version=[2],Text=[an @nt{extended_return_statement};]}
+
+  an @nt{accept_statement};
+
+  an @nt{exception_handler}.
address@hidden(itemize)
+
address@hidden
address@hidden@;The declarative region includes the text of the construct
+together with additional text determined @Redundant[(recursively)],
+as follows:
address@hidden
address@hidden
+If a declaration is included, so is its completion, if any.
+
+If the declaration of a library unit
address@hidden(including Standard @em
+see @RefSecNum{Compilation Units - Library Units})] is included,
+so are the declarations of any child units
address@hidden(and their completions, by the previous rule)].
+The child declarations occur after the declaration.
+
+If a @nt{body_stub} is included,
+so is the corresponding @nt{subunit}.
+
+If a @nt{type_declaration} is included,
+then so is a corresponding @nt{record_representation_clause},
+if any.
address@hidden
+This is so that the @nt{component_declaration}s can be directly
+visible in the @nt{record_representation_clause}.
address@hidden
address@hidden
+
+The declarative region of a declaration is also called the
address@hidden region} of any view or entity declared by the
+declaration.
address@hidden
+The constructs that have declarative regions
+are the constructs that can have declarations nested inside them.
+Nested declarations are declared in that declarative region.
+The one exception is for enumeration literals;
+although they are nested inside an enumeration type declaration,
+they behave as if they were declared at the same level as the type.
address@hidden
address@hidden
+A declarative region does not include @nt{parent_unit_name}s.
address@hidden
address@hidden
+A declarative region does not include @nt{context_clause}s.
address@hidden
+
address@hidden immediately within}
address@hidden within}
address@hidden,Sec=(immediately)}
address@hidden enclosing}
address@hidden,Sec=(immediately)}
+A declaration occurs @i{immediately within} a declarative region if this
+region is the innermost declarative region that
+encloses the declaration
+(the @i{immediately enclosing} declarative region),
+not counting the declarative region (if any)
+associated with the declaration itself.
address@hidden
+Don't confuse the declarative region of a declaration
+with the declarative region in which it immediately occurs.
address@hidden
+
address@hidden@Defn{local to}
+A declaration is @i{local} to a declarative region if
+the declaration occurs immediately within the declarative region.]
address@hidden entity is @i{local} to a declarative region if the entity is
+declared by a declaration that is local to the declarative region.]
address@hidden
+"Occurs immediately within" and "local to" are synonyms
+(when referring to declarations).
+
+Thus, @lquotes@;local address@hidden@; applies to both declarations and 
entities,
+whereas @lquotes@;occurs immediately address@hidden@; only applies to 
declarations.
+We use this term only informally; for cases where precision is required,
+we use the term "occurs immediately within", since it is less likely to
+cause confusion.
address@hidden
+
address@hidden to}
+A declaration is @i{global} to a declarative region
+if the declaration occurs immediately within
+another declarative region that encloses the
+declarative region.
+An entity is @i{global} to a declarative region if the entity is
+declared by a declaration that is global to the declarative region.
address@hidden
+
address@hidden
+The children of a parent library unit are inside the parent's
+declarative region, even though they do not occur inside the
+parent's declaration or body.
+This implies that one can use (for example) "P.Q" to refer to
+a child of P whose defining name is Q,
+and that after "@key[use] P;" Q can refer (directly) to that child.
+
+As explained above
+and in @RefSec{Compilation Units - Library Units},
+all library units are descendants of Standard,
+and so are contained in the declarative region of Standard.
+They are @i{not} inside the
+declaration or body of Standard,
+but they @i{are} inside its declarative region.
+
+For a declarative region that comes in multiple parts,
+the text of the declarative region does not contain any text that might appear
+between the parts.
+Thus, when a portion of a declarative region is said to extend from one
+place to another in the declarative region,
+the portion does not contain any text that
+might appear between the parts of the declarative region.
address@hidden
+It is necessary for the things that have a declarative region to
+include
+anything that contains declarations (except for enumeration type
+declarations).
+This includes any declaration that has a profile
+(that is, @nt{subprogram_declaration},
address@hidden,
address@hidden,
address@hidden,
address@hidden,
+access-to-subprogram @nt{type_declaration}),
+anything that has a @nt{discriminant_part}
+(that is, various kinds of @nt{type_declaration}),
+anything that has a @nt{component_list}
+(that is, record @nt{type_declaration} and
+record extension @nt{type_declaration}),
+and finally the declarations of task and protected units and packages.
address@hidden
address@hidden
+
address@hidden
address@hidden@;It was necessary to extend Ada 83's definition of declarative 
region
+to take the following Ada 95 features into account:
address@hidden
+Child library units.
+
+Derived types/type extensions @em we need a declarative region for
+inherited components and also for new components.
+
+All the kinds of types that allow discriminants.
+
+Protected units.
+
+Entries that have bodies instead of accept statements.
+
+The @nt{choice_parameter_specification} of an @nt{exception_handler}.
+
+The formal parameters of access-to-subprogram types.
+
+Renamings-as-body.
address@hidden
+
+Discriminated and access-to-subprogram type declarations
+need a declarative region.
+Enumeration type declarations cannot have one,
+because you don't have to say "Color.Red" to refer to the literal Red
+of Color.
+For other type declarations,
+it doesn't really matter whether or not there is an
+associated declarative region,
+so for simplicity, we give one to all types except enumeration types.
+
+We now say that an @nt{accept_statement} has its own declarative
+region, rather than being part of the declarative region of the
address@hidden,
+so that declarative regions are properly nested regions of text,
+so that it makes sense to talk about "inner declarative regions,"
+and "...extends to the end of a declarative region."
+Inside an @nt{accept_statement}, the @nt{name} of one of the parameters
+denotes the @nt{parameter_specification} of the @nt{accept_statement},
+not that of the @nt{entry_declaration}. If the @nt{accept_statement} is
+nested within a @nt{block_statement}, these
address@hidden can hide declarations of the
address@hidden
+The semantics of such cases was unclear in RM83.
address@hidden
+  Unfortunately, we have the same problem for the entry name
+  itself @em it should denote the @nt{accept_statement},
+  but @nt{accept_statement}s are not declarations.
+  They should be, and they should hide the entry from all visibility
+  within themselves.
address@hidden
+
+Note that we can't generalize this to @ntf{entry_bodies},
+or other bodies, because the @nt{declarative_part} of a
+body is not supposed to contain (explicit) homographs of
+things in the declaration.
+It works for @nt{accept_statement}s only because an
address@hidden does not have a @nt{declarative_part}.
+
+To avoid confusion,
+we use the term @lquotes@;local address@hidden@; only informally in Ada 95.
+Even RM83 used the term incorrectly (see, for example, RM83-12.3(13)).
+
+In Ada 83, (root) library units were inside Standard;
+it was not clear whether the declaration or body of Standard
+was meant.
+In Ada 95, they are children of Standard,
+and so occur immediately within Standard's declarative
+region, but not within either the declaration or the body.
+(See RM83-8.6(2) and RM83-10.1.1(5).)
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00318-02]}
address@hidden,address@hidden
+(see @RefSecNum{Return Statements}) is added to the list
+of constructs that have a declarative region.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0094-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada address@hidden<Corrigendum:>
+  @nt{access_definition} is added to the list of constructs that have
+  a declarative region. This allows parameter names declared in anonymous
+  access type subprogram types to be the same as other names declared
+  outside. For instance:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Foo @key[is record]
+   A : Natural;
+   B : @key[access] procedure (A : Boolean);
address@hidden record];]}
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This is now legal, as one would expect; it
+  was illegal in previous versions of Ada as the parameter A and the
+  component A were homographs in the same declarative region
+  (see @RefSecNum{Visibility}). Note that some implementations already allow
+  this common sense interpretation, so this extension may in fact be used
+  in existing code.]}
address@hidden
+
+
address@hidden of Declarations}
+
address@hidden
address@hidden each declaration, the language rules define a certain
+portion of the program text called the @i{scope} of the declaration.
+The scope of a declaration is also called the scope of any view
+or entity declared by the declaration.
+Within the scope of an entity, and only there,
+there are places where it is legal to refer
+to the declared entity.
+These places are defined by the rules of visibility and overloading.]
address@hidden
+
address@hidden
address@hidden@Defn2{Term=[immediate scope], Sec=(of a declaration)}
+The @i{immediate scope} of a declaration
+is a portion of the declarative region immediately enclosing
+the declaration.
+The immediate scope starts at the beginning of the declaration,
+except in the case of an overloadable declaration,
+in which case the immediate scope starts just after the place
+where the profile of the callable entity is determined
+(which is at the end of the @ntf<_specification> for the callable entity,
+or at the end of the @nt<generic_instantiation> if an instance).
+The immediate scope extends to the end of the declarative region,
+with the following exceptions:
address@hidden
+The reason for making overloadable declarations with profiles
+special is to simplify compilation:
+until the compiler has determined the profile,
+it doesn't know which other declarations are homographs of this one,
+so it doesn't know which ones this one should hide.
+Without this rule, two passes over the @ntf<_specification> or
address@hidden<generic_instantiation> would be required to
+resolve names that denote things with the same name as this one.
address@hidden
address@hidden
+The immediate scope of a @nt{library_item} includes only its semantic
+dependents.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,New=[Clause],Old=[Section]} 10 defines only a partial ordering 
of @nt{library_item}s.
+Therefore, it is a good idea to restrict the immediate scope
+(and the scope, defined below)
+to semantic dependents.
+
address@hidden@;Consider also examples like this:
address@hidden
address@hidden P @key[is] @key[end] P;
+
address@hidden P.Q @key[is]
+    I : Integer := 0;
address@hidden P.Q;
+
address@hidden,address@hidden AI-00080 - syntax error}
address@hidden P;
address@hidden R @key[is]
+    @key[package] X @key[renames] P;
+    @Chg{New=[J : Integer := ],address@hidden,Old=[ := 17]}; address@hidden 
Illegal!}
address@hidden R;
address@hidden
+
+The scope of P.Q does not contain R.
+Hence, neither P.Q nor X.Q are visible within R.
+However, the name R.X.Q would be visible in some other
+library unit where both R and P.Q are visible
+(assuming R were made legal by removing the offending declaration).
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00217-06]}
+  @ChgAdded{Version=[2],Text=[This rule applies to limited views as well as
+  @lquotes@;address@hidden library items. In that case, the semantic dependents
+  are the units that have a @nt{limited_with_clause} for the limited view.]}
address@hidden
+The immediate scope of
+a declaration in the private part of a library unit does
+not include the visible part of any
+public descendant of that library unit.
address@hidden,Sec=(relationship with scope)}
address@hidden
+In other words, a declaration in the private part can be
+visible within the visible part, private part and body of a private
+child unit.
+On the other hand, such a declaration
+can be visible within only the private part and body of a public
+child unit.
address@hidden
address@hidden
+The purpose of this rule is to prevent children from giving
+private information to clients.
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00231-01]}
+For a public child subprogram,
+this means that the parent's private part is not visible in the
address@hidden,New=[profile],address@hidden of the declaration
+and of the body.
+This is true even for @ntf{subprogram_bodies} that are not
+completions.
+For a public child generic unit,
+it means that the parent's private part is not visible in the
address@hidden, as well as in
+the first list of @nt{basic_declarative_item}s (for a generic package),
+or the @Chg{Version=[2],New=[(syntactic) profile],address@hidden(s)]}
+(for a generic subprogram).
address@hidden
address@hidden
+
address@hidden part}
address@hidden @i(visible part) of (a view of) an entity
+is a portion of the text of its declaration
+containing declarations that are visible from outside.]
address@hidden part}
+The @i{private part} of (a view of) an entity that has a visible part
+contains all declarations within the declaration of
+(the view of) the entity,
+except those in the visible part;
address@hidden are not visible from outside.
+Visible and private parts are defined only for these kinds of
+entities: callable entities, other program units,
+and composite types.]
address@hidden
address@hidden part], Sec=(of a view of a callable entity)}
+The visible part of a view of a callable entity is its profile.
+
address@hidden part], Sec=(of a view of a composite type)}
+The visible part of a composite type other than a task or protected type
+consists of the declarations of
+all components declared @Redundant[(explicitly or implicitly)]
+within the @nt{type_declaration}.
+
address@hidden part], Sec=(of a generic unit)}
+The visible part of a generic unit
+includes the @nt{generic_formal_part}.
+For a generic package, it also includes
+the first list of @nt{basic_declarative_item}s of the
address@hidden
+For a generic subprogram, it also includes
+the profile.
address@hidden
+Although there is no way to reference anything but the formals from
+outside a generic unit, they are still in the visible part in the sense that
+the corresponding declarations in an instance can be referenced
+(at least in some cases).
+In other words, these declarations have an effect on the outside world.
+The visible part of a generic unit needs to be defined
+this way in order to properly support
+the rule that makes a parent's private part invisible within a
+public child's visible part.
address@hidden
address@hidden
+The visible part of an instance of a generic unit is as defined
+for packages and subprograms;
+it is not defined in terms of the visible part of a generic unit.
address@hidden
+
address@hidden visible part of a package, task unit, or protected
+unit consists of declarations in the program unit's declaration
+other than those following the reserved word @key{private}, if any;
+see @RefSecNum{Package Specifications and Declarations}
+and @RefSecNum{Formal Packages} for packages,
address@hidden Units and Task Objects} for task units,
+and @RefSecNum{Protected Units and Protected Objects}
+for protected units.]
address@hidden
+
address@hidden, Sec=(of a declaration)}
+The scope of a declaration always
+contains the immediate scope of the declaration.
+In addition, for a given declaration that occurs immediately within
+the visible part of an outer declaration,
+or is a public child of an outer declaration,
+the scope of the given declaration
+extends to the end of the scope of the outer declaration,
+except that the scope of a @nt{library_item} includes only its
+semantic dependents.
address@hidden
+Note the recursion.
+If a declaration appears in the visible part of a library unit,
+its scope extends to the end of the scope of the library unit,
+but since that only includes dependents of the declaration of the library unit,
+the scope of the inner declaration also only includes those dependents.
+If X renames library package P,
+which has a child Q, a @nt{with_clause} mentioning P.Q is necessary to
+be able to refer to X.Q,
+even if P.Q is visible at the place where X is declared.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00408-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0183-1]}
address@hidden,address@hidden, Sec=(of an address@hidden@!clause)}
+The scope of an @nt{attribute_definition_clause} is identical to the scope of a
+declaration that would occur at the point of the
address@hidden@Chg{Version=[3],New=[ The scope of an
address@hidden is identical to the scope of the associated
address@hidden, Sec=(of an address@hidden)}],Old=[]}]}
+
address@hidden scope], Sec=[of (a view of) an entity]}
+The immediate scope of a declaration is also the immediate scope
+of the entity or view declared by the declaration.
address@hidden, Sec=[of (a view of) an entity]}
+Similarly,
+the scope of a declaration is also the scope
+of the entity or view declared by the declaration.
address@hidden
address@hidden@;The rule for immediate scope implies the following:
address@hidden
+If the declaration is that of a library unit,
+then the immediate scope includes the declarative region of the
+declaration itself, but not other places,
+unless they are within the scope of a @nt{with_clause} that mentions the
+library unit.
+
address@hidden@;It is necessary to attach the semantics of @nt{with_clause}s to
+[immediate] scopes (as opposed to visibility),
+in order for various rules to work properly.
+A library unit should hide a homographic implicit declaration that
+appears in its parent, but only within the scope of a @nt{with_clause}
+that mentions the library unit.
+Otherwise, we would violate the "legality determinable via semantic
+dependences" rule of @RefSec{Program Structure and Compilation Issues}.
+The declaration of a library unit should be allowed to be a homograph of
+an explicit declaration in its parent's body,
+so long as that body does not mention the library unit in a
address@hidden
+
address@hidden@;This means that one cannot denote the declaration of the 
library unit,
+but one might still be able to denote the library unit via another
+view.
+
address@hidden@;A @nt{with_clause} does not make the declaration of a library 
unit
+visible; the lack of a @nt{with_clause} prevents it from being visible.
+Even if a library unit is mentioned in a @nt{with_clause},
+its declaration can still be hidden.
+
+The completion of the declaration of a library unit
+(assuming that's also a declaration)
+is not visible, neither directly nor by selection,
+outside that completion.
+
+The immediate scope of
+a declaration immediately within the body of a library unit
+does not include any child of that library unit.
+
address@hidden@;This is needed to prevent children from looking inside their
+parent's body. The children are in the declarative region of the
+parent, and they might be after the parent's body.
+Therefore, the scope of a declaration that occurs immediately within
+the body might include some children.
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],address@hidden usual,
+    we let the paragraph numbers of non-normative text change}
address@hidden,Text=[The immediate scope of a pragma that is not used
+as a configuration pragma is defined to be address@hidden scope], Sec=(of a 
pragma)}
+region extending from immediately after the pragma
+to the end of the declarative region immediately enclosing the pragma.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+There are notations for denoting visible declarations
+that are not directly visible.
+For example, @address@hidden are in the visible part of a
address@hidden@!declaration} so that they can be used in
+named-notation calls appearing outside the called subprogram.
+For another example,
+declarations of the visible part of a package can be denoted by expanded names
+appearing outside the package,
+and can be made directly visible by a @nt{use_clause}.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+There are some obscure @Chg{Version=[2],New=[cases ],Old=[]}involving
+generics @Chg{Version=[2],New=[],Old=[cases ]}in which there is
+no such notation.
+See @Chg{Version=[3],New=[Clause],Old=[Section]} @RefSecNum{Generic Units}.
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The fact that the immediate scope of an overloadable declaration does
+not include its profile is new to Ada 95. It replaces
+RM83-8.3(16), which said that within
+a subprogram specification and within the formal part of an
+entry declaration or accept statement, all declarations with
+the same designator as the subprogram or entry were hidden from all
+visibility.
+The RM83-8.3(16) rule seemed to be overkill, and created both
+implementation difficulties and unnecessary semantic complexity.
address@hidden
+
address@hidden
+We no longer need to talk about the scope of notations,
address@hidden, @nt{character_literal}s, and @nt{operator_symbol}s.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The notion of "visible part" has been extended in Ada 95.
+The syntax of
+task and protected units now allows private parts,
+thus requiring us to be able to talk about the visible part as well.
+It was necessary to extend the concept to subprograms
+and to generic units, in order for the visibility rules
+related to child library units to work properly.
+It was necessary to define the concept separately for
+generic formal packages, since their visible part is
+slightly different from that of a normal package.
+Extending the concept to composite types made the
+definition of scope slightly simpler.
+We define visible part for some things elsewhere,
+since it makes a big difference to the user for those things.
+For composite types and subprograms, however,
+the concept is used only in arcane visibility rules,
+so we localize it to this @Chg{Version=[3],New=[subclause],Old=[clause]}.
+
+In Ada 83, the semantics of @nt{with_clause}s was described
+in terms of visibility.
+It is now described in terms of [immediate] scope.
+
address@hidden@;We have clarified that the following is illegal
+(where Q and R are library units):
address@hidden
address@hidden Q @key[is]
+    I : Integer := 0;
address@hidden Q;
+
address@hidden R @key[is]
+    @key[package] X @key[renames] Standard;
+    X.Q.I := 17; address@hidden Illegal!}
address@hidden R;
address@hidden
+
+even though Q is declared in the declarative region of Standard,
+because R does not mention Q in a @nt{with_clause}.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00408-01]}
+  @ChgAdded{Version=[2],Text=[The scope of an @nt{attribute_definition_clause}
+  is defined so that it can be used to define the visibility of such a clause,
+  so @i<that> can be used by the stream attribute availability rules
+  (see @RefSecNum{Stream-Oriented Attributes}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],Text=[The scope of an @nt{aspect_specification}
+  is defined for similar reasons that it was defined for
+  @nt{attribute_definition_clause}s.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0003-1]}
+  @ChgAdded{Version=[4],Text=[The immediate scope of a @nt{pragma} is
+  defined as it is used in other rules in the Standard.]}
address@hidden
+
+
address@hidden
+
address@hidden
address@hidden@Defn{visibility rules}
+The @i{visibility rules},
+given below, determine which declarations are
+visible and directly visible at each place within a program.
+The visibility rules apply to both explicit and implicit declarations.]
address@hidden
+
address@hidden
address@hidden, Sec=(direct)}
address@hidden visible}
address@hidden visible}
+A declaration is defined to be @i{directly visible} at places
+where a @nt<name> consisting of only an @nt{identifier} or
address@hidden is sufficient to denote the declaration;
+that is, no @nt<selected_component> notation or special context
+(such as preceding => in a named association) is necessary
+to denote the declaration.
address@hidden
+A declaration is defined to be @i{visible} wherever it is
+directly visible, as well as at other places where
+some @nt<name> (such as a @nt<selected_component>) can denote
+the declaration.
+
+The syntactic category @nt<direct_name> is used to indicate
+contexts where direct visibility is required.
+The syntactic category @nt<selector_name> is used to indicate
+contexts where visibility, but not direct visibility,
+is required.
+
address@hidden, Sec=(immediate)}
address@hidden, Sec=(use clause)}
+There are two kinds of direct visibility:
address@hidden visibility} and @i{use-visibility}.
address@hidden visible}
+A declaration is immediately visible at a place if it is directly
+visible because the place is within its immediate scope.
address@hidden
+A declaration is use-visible if it is directly visible
+because of a @nt{use_clause} (see @RefSecNum{Use Clauses}).
+Both conditions can apply.
+
address@hidden
+A declaration can be @i{hidden}, either from direct visibility,
+or from all visibility,
+within certain parts of its scope.
address@hidden from all visibility}
+Where @i{hidden from all visibility},
+it is not visible at all (neither using a @nt<direct_name>
+nor a @nt<selector_name>).
address@hidden from direct visibility}
+Where @i{hidden from direct visibility}, only direct visibility is lost;
+visibility using a @nt<selector_name> is still possible.
+
address@hidden@Defn{overloaded}
+Two or more declarations are @i{overloaded} if
+they all have the same defining name
+and there is a place where they are all directly visible.]
address@hidden
+Note that a @nt{name} can have more than one possible interpretation
+even if it denotes a nonoverloadable entity.
+For example, if there are two functions F that return records,
+both containing a component called C, then
+the name F.C has two possible interpretations,
+even though component declarations are not overloadable.
address@hidden
+
address@hidden
+The declarations of callable entities
address@hidden(including enumeration literals)]
+are @address@hidden,
+meaning that overloading is allowed for them].
address@hidden
+A @nt{generic_declaration} is not overloadable within its own
address@hidden
+This follows from the rules about when a @nt{name} denotes a current
+instance.
+See AI83-00286. This implies that within a
address@hidden, outer declarations with the same defining name
+are hidden from direct visibility. It also implies that if a generic
+formal parameter has the same defining name as the generic itself,
+the formal parameter hides the generic from direct visibility.
address@hidden
+
address@hidden
+Two declarations are @i{homographs}
+if they have the same defining name,
+and, if both are overloadable,
+their profiles are type conformant.
address@hidden conformance}
address@hidden inner declaration hides any outer homograph from direct 
visibility.]
+
+
address@hidden,Kind=[AddedNormal],Term=<Overriding operation>,
address@hidden,Text=[An overriding operation
+is one that replaces an inherited primitive operation. Operations may be marked
+explicitly as overriding or not overriding.]}]}
+
address@hidden,Kind=[Revised],Ref=[8652/0025],ARef=[AI95-00044-01]}
address@hidden@Redundant[Two homographs are not generally allowed
+immediately within the same declarative region unless one
address@hidden the other (see Legality Rules below).]
address@hidden
address@hidden only declarations that are @address@hidden are
+the implicit declarations for predefined operators and inherited primitive
+subprograms.],Old=[]}
+A declaration overrides another homograph that occurs
+immediately within the same declarative region in the
+following cases:
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0025],ARef=[AI95-00044-01]}
address@hidden declaration that is not overridable overrides one that is 
overridable],
+Old=[An explicit declaration overrides an implicit declaration of a primitive
+subprogram]}, @Redundant[regardless of which declaration occurs first];
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0025],ARef=[AI95-00044-01]}
+And regardless of whether the @Chg{New=[nonoverridable],Old=[explicit]}
+declaration is overloadable or not.
address@hidden example, @nt{statement_identifier}s are covered by this 
rule.],Old=[]}
+
+The @lquotes@;regardless of which declaration occurs address@hidden@;
+is there because the explicit declaration could be a primitive subprogram
+of a partial view, and then the full view might inherit a homograph.
+We are saying that the explicit one wins
+(within its scope), even though the implicit one comes later.
+
+If the overriding declaration is also a subprogram,
+then it is a primitive subprogram.
+
+As explained in @RefSec{Private Operations},
+some inherited primitive subprograms are never declared.
+Such subprograms cannot be overridden,
+although they can be reached by dispatching calls
+in the case of a tagged type.
address@hidden
+
+The implicit declaration of an inherited operator overrides
+that of a predefined operator;
address@hidden
+In a previous version of Ada 9X, we tried to avoid the notion of
+predefined operators, and say that they were inherited from some
+magical root type.
+However, this seemed like too much mechanism.
+Therefore, a type can have a predefined "+" as well as an inherited "+".
+The above rule says the inherited one wins.
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+The @lquotes@;regardless of which declaration occurs address@hidden@; applies 
here
+as well, in the case where @Chg{Version=[2],address@hidden,
address@hidden in the visible
+part of a public library unit derives from a private type declared in
+the parent unit, and the full view of the parent type has additional
+predefined operators, as explained in @RefSec{Private Operations}.
+Those predefined operators can be overridden by inherited subprograms
+implicitly declared earlier.
address@hidden
+
+An implicit declaration of an inherited subprogram
+overrides a previous implicit declaration of an inherited
+subprogram.
+
address@hidden,Kind=[Added],ARef=[AI95-00251-01]}
address@hidden,Type=[Leading],Text=[If two or more homographs are
+implicitly declared at the same place:]}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00251-01]}
address@hidden,Text=[If at least one is a subprogram that is neither a
+null procedure nor an abstract subprogram, and does not require overriding (see
address@hidden Types and Subprograms}), then they override those that are
+null procedures, abstract subprograms, or require overriding. If more than one
+such homograph remains that is not thus overridden, then they are all hidden
+from all visibility.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00251-01]}
address@hidden,Text=[Otherwise (all are null procedures, abstract
+subprograms, or require overriding), then any null procedure overrides all
+abstract subprograms and all subprograms that require overriding; if more than
+one such homograph remains that is not thus overridden, then if they are all
+fully conformant with one another, one is chosen arbitrarily; if not, they are
+all hidden from all visibility.
address@hidden conformance],Sec=(required)}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[In the case where the
+    implementation arbitrarily chooses one overrider from among a group
+    of inherited subprograms, users should not be able to determine which
+    member was chosen, as the set of inherited subprograms which are chosen
+    from must be fully conformant. This rule is needed in order to
+    allow]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Outer @Key{is}
+   @Key{package} P1 @Key{is}
+      @Key{type} Ifc1 @Key{is interface};
+      @Key{procedure} Null_Procedure (X : Ifc1) @Key{is null};
+      @Key{procedure} Abstract_Subp  (X : Ifc1) @Key{is abstract};
+   @Key{end} P1;],Old=[]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,New=[   @Key{package} P2 @Key{is}
+      @Key{type} Ifc2 @Key{is interface};
+      @Key{procedure} Null_Procedure (X : Ifc2) @Key{is null};
+      @Key{procedure} Abstract_Subp  (X : Ifc2) @Key{is abstract};
+   @Key{end} P2;],Old=[]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,New=[   @Key{type} T @Key{is abstract new} P1.Ifc1 @Key{and} 
P2.Ifc2 @Key{with null record};
address@hidden Outer;],Old=[]}
address@hidden
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[without requiring that T explicitly override
+    any of its inherited operations.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Full conformance is required here,
+  as we cannot allow the parameter names to differ. If they did differ, the
+  routine which was selected for overriding could be determined by using
+  named parameter notation in a call.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[When the subprograms do not conform,
+  we chose not to adopt the @lquotes@;use address@hidden rule which would make
+  them all visible resulting in likely ambiguity. If we had used such a rule,
+  any successful calls would be confusing; and the fact that there are no
+  Beaujolais-like effect to worry about means we can consider other rules.
+  The hidden-from-all-visibility homographs are still inherited
+  by further derivations, which avoids order-of-declaration dependencies
+  and other anomalies.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We have to be careful to not include arbitrary
+  selection if the routines have real bodies. (This can happen in generics, see
+  the example in the incompatibilities section below.) We don't want the
+  ability to successfully call routines where the body executed depends on the
+  compiler or a phase of the moon.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Note that if the type is concrete, abstract
+  subprograms are inherited as subprograms that require overriding. We include
+  functions that require overriding as well; these don't have real bodies, so
+  they can use the more liberal rules.]}
address@hidden
+
address@hidden
+
address@hidden an implicit declaration of a primitive subprogram in a
+generic unit, there is a copy of this declaration in an instance.]
+However, a whole new set of primitive subprograms is implicitly
+declared for each type declared within the visible part of the instance.
+These new declarations occur immediately after the type
+declaration, and override the copied ones.
address@hidden copied ones can be called only from within the instance;
+the new ones can be called only from outside the instance,
+although for tagged types, the body of a new one can be executed
+by a call to an old one.]
address@hidden
+In addition, this is also stated redundantly (again),
+and is repeated, in @RefSec{Generic Instantiation}.
+The rationale for the rule is explained there.
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0042-1]}
address@hidden,Text=[The implicit subprograms declared when an
+operation of a progenitor is implemented by an entry or subprogram also
+override the appropriate implicitly declared inherited operations of the
address@hidden,Sec=[when implemented by]}]}
address@hidden
address@hidden
+
address@hidden@Defn{visible}
address@hidden from all visibility}
+A declaration is visible within its scope,
+except where hidden from all visibility,
+as follows:
address@hidden
address@hidden from all visibility], Sec=(for overridden declaration)}
+An overridden declaration is hidden from all visibility within the
+scope of the overriding declaration.
address@hidden
+We have to talk about the scope of the overriding declaration,
+not its visibility, because it hides
+even when it is itself hidden.
+
+Note that the scope of an explicit @nt{subprogram_declaration}
+does not start until after its profile.
address@hidden
+
address@hidden@PDefn2{Term=[hidden from all visibility], Sec=(within the 
declaration itself)}
+A declaration is hidden from all visibility until the end of the
+declaration, except:
address@hidden(InnerItemize)
+  For a record type or record extension,
+  the declaration is hidden from all visibility only
+  until the reserved word @b(record);
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00345-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0177-1]}
+  For a @nt{package_declaration}, @Chg{Version=[2],New=[],Old=[task 
declaration,
+  protected declaration, address@hidden@address@hidden,
+  @Chg{Version=[3],New=[],Old=[or address@hidden@!body},
+  @Chg{Version=[3],New=[or @address@hidden@!declaration}, ],Old=[]}the
+  declaration is hidden from all visibility only until the
+  reserved word @key(is)
+  of the address@hidden,New=[;],Old=[.]}
+  @begin{Ramification}
+    We're talking about the @key{is} of the construct itself, here,
+    not some random @key{is} that might appear in a
+    @nt{generic_formal_part}.
+  @end{Ramification}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00345-01]}
+  @ChgAdded{Version=[2],Text=[For a task declaration or protected declaration,
+  the declaration is hidden from all visibility only
+  until the reserved word @key(with) of the declaration if there is one, or the
+  reserved word @key(is) of the declaration if there is no @key(with).]}
+
+  @begin{Honest}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[If there is neither a @key(with) nor @key(is),
+    then the exception does not apply and the name is hidden from all
+    visibility until the end of the declaration. This oddity was inherited
+    from Ada 95.]}
+  @end{Honest}
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[We need the @address@hidden(with) or 
@key(is)@rquotes
+    rule so that the visibility within an @nt{interface_list} does not
+    vary by construct. That would make it harder to complete private extensions
+    and would complicate implementations.]}
+  @end{Reason}
+
address@hidden(InnerItemize)
+
address@hidden from all visibility], Sec=(for a declaration completed by a 
subsequent declaration)}
+If the completion of a declaration is a declaration,
+then within the scope of the completion,
+the first declaration is hidden from all visibility.
+Similarly, a @address@hidden or
address@hidden@!specification} is hidden within the scope of a
+corresponding @address@hidden or
address@hidden@!specification} of a corresponding completion,
+or of a corresponding @address@hidden
address@hidden
+This rule means, for example, that within the scope of a
address@hidden that completes a
address@hidden,
+the name of the type will denote the @nt{full_type_declaration},
+and therefore the full view of the type.
+On the other hand, if the completion is not a declaration,
+then it doesn't hide anything,
+and you can't denote it.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00217-06],ARef=[AI95-00412-01]}
address@hidden from all visibility], Sec=(by lack of a @nt{with_clause})}
+The declaration of a library unit
+(including a @nt{library_unit_renaming_declaration})
+is hidden from all visibility @Chg{Version=[2],New=[],Old=[except ]}at
+places @Chg{Version=[2],New=[outside],Old=[that are within]} its declarative
+region @Chg{Version=[2],New=[that are not],Old=[or]} within the scope
+of a @Chg{Version=[2],address@hidden,address@hidden that
+mentions address@hidden,New=[ The limited view of a library package
+is hidden from all visibility at places that are not within the scope
+of a @nt{limited_with_clause} that mentions it; in addition, the limited view
+is hidden from all visibility within the declarative region of the package, as
+well as within the scope of any @nt{nonlimited_with_clause} that
+mentions the package. Where the declaration of the limited view of a
+package is visible, any name that denotes the package denotes the
+limited view, including those provided by a package renaming.],address@hidden
+each declaration or renaming of a generic unit as a child of
+some parent generic package, there is a corresponding declaration nested
+immediately within each instance of the parent.]
+Such a nested declaration is hidden from all visibility
+except at places that are
+within the scope of a @nt{with_clause} that mentions the child.]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00217-06]}
+This is the rule that prevents @nt{with_clause}s from being
+transitive; the [immediate] scope includes indirect semantic dependents.
address@hidden,New=[This rule also prevents the limited view of a package
+from being visible in the same place as the full view of the package, which
+prevents various ripple effects.],Old=[]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00217-06],address@hidden moved from 
above}
address@hidden,address@hidden each
+declaration or renaming of a generic unit as a child of
+some parent generic package, there is a corresponding declaration nested
+immediately within each instance of the parent.]
+Such a nested declaration is hidden from all visibility
+except at places that are
+within the scope of a @nt{with_clause} that mentions the child.]}
+
address@hidden
+
address@hidden@Defn{directly visible}
address@hidden visible}
address@hidden, Sec=(direct)}
address@hidden, Sec=(immediate)}
+A declaration with a @nt{defining_identifier} or
address@hidden is immediately visible
address@hidden(and hence
+directly visible)] within its immediate scope
address@hidden from direct visibility} except where hidden
+from direct visibility, as follows:
address@hidden
+  @PDefn2{Term=[hidden from direct visibility], Sec=(by an inner homograph)}
+  A declaration is hidden from direct visibility
+  within the immediate scope of a homograph of the
+  declaration, if the homograph occurs within an inner declarative
+  region;
+
+  @PDefn2{Term=[hidden from direct visibility], Sec=(where hidden from all 
visibility)}
+  A declaration is also hidden from direct visibility
+  where hidden from all visibility.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00195-01],ARef=[AI95-00408-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0183-1]}
address@hidden,address@hidden, Sec=(address@hidden@!clause)}
+An @nt{attribute_definition_clause} @Chg{Version=[3],New=[or an
address@hidden@PDefn2{Term=[visible], Sec=(address@hidden)}
+],Old=[]}is @i{visible} everywhere within its scope.]}
+
address@hidden
+
address@hidden
address@hidden interpretation], Sec=(for @nt{direct_name}s)}
+A @nt{direct_name} shall resolve to denote a directly visible
+declaration whose defining name is the same as the @nt{direct_name}.
address@hidden interpretation], Sec=(for @nt{selector_name}s)}
+A @nt{selector_name} shall resolve to denote
+a visible declaration whose defining name is the same as the
address@hidden
address@hidden
+"The same as" has the obvious meaning here,
+so for +,
+the possible interpretations are declarations whose defining name is "+"
+(an @nt{operator_symbol}).
address@hidden
+
+These rules on visibility and direct visibility do not apply
+in a @nt{context_clause}, a @nt{parent_unit_name},
+or a @nt{pragma} that appears at the place of a
address@hidden
+For those contexts, see the rules
+in @RefSec{Environment-Level Visibility Rules}.
address@hidden
+Direct visibility is irrelevant for @nt{character_literal}s.
+In terms of overload resolution
address@hidden are similar to other literals,
+like @key{null} @em see @RefSecNum{Literals}.
+For @nt{character_literal}s, there is no need to worry about
+hiding, since there is no way to declare homographs.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0025],Ref=[8652/0026],ARef=[AI95-00044-01],ARef=[AI95-00150-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00377-01]}
address@hidden nonoverridable],Old=[An explicit]} declaration is illegal if 
there is a
+homograph occurring immediately within the same
+declarative region that is visible at the place of the
+declaration, and is not hidden from all visibility by the
address@hidden,Old=[explicit]} declaration.
address@hidden addition, a type extension is illegal if somewhere within its
+immediate scope it has two visible components with the same name.],Old=[]}
+Similarly, the @nt<context_clause> for a @Chg{Version=[2],
+New=[compilation unit],address@hidden<subunit>]} is illegal if it mentions (in 
a
address@hidden<with_clause>) some library unit, and there is a homograph
+of the library unit that is visible at the place of the @Chg{Version=[2],
+New=[compilation unit],Old=[corresponding stub]}, and the
+homograph and the mentioned library unit are both
+declared immediately within the same declarative address@hidden contract issue}
+These rules also apply to dispatching operations declared
+in the visible part of an instance of a generic unit.
+However, they do not apply to other overloadable declarations in
+an address@hidden; such declarations may have type conformant profiles
+in the instance, so long as the corresponding declarations in the generic
+were not type conformant].
address@hidden conformance}
+
address@hidden
address@hidden@;Normally, these rules just mean you can't explicitly
+declare two homographs
+immediately within the same declarative region.
+The wording is designed to handle the
+following special cases:
address@hidden
+If the second declaration completes the first one,
+the second declaration is legal.
+
address@hidden@;If the body of a library unit contains an explicit homograph of
+a child of that same library unit, this is illegal only if the body
+mentions the child in its @nt<context_clause>, or if
+some subunit mentions the child.
+Here's an example:
address@hidden
address@hidden P @key[is]
address@hidden P;
+
address@hidden P.Q @key[is]
address@hidden P.Q;
+
address@hidden @key[body] P @key[is]
+    Q : Integer; address@hidden OK; we cannot see package P.Q here.}
+    @key[procedure] Sub @key[is] @key[separate];
address@hidden P;
+
address@hidden P.Q;
address@hidden(P)
address@hidden Sub @key[is] address@hidden Illegal.}
address@hidden
+    @key[null];
address@hidden Sub;
address@hidden
+
address@hidden@;If package body P said "@key[with] P.Q;", then it would be 
illegal
+to declare the homograph Q: Integer. But it does not, so the
+body of P is OK.
+However, the subunit would be able to see both P.Q's,
+and is therefore illegal.
+
address@hidden@;A previous version of Ada 9X allowed the subunit,
+and said that references to P.Q would tend to be ambiguous.
+However, that was a bad idea, because it requires overload resolution
+to resolve references to directly visible nonoverloadable
+homographs, which is something compilers have never before been
+required to do.
+
address@hidden,Kind=[Added],Ref=[8652/0026],Ref=[8652/0102],ARef=[AI95-00150-01],ARef=[AI95-00157-01]}
address@hidden,Type=[Leading],Text=[If a type extension contains a
+component with
+the same name as a component in an ancestor type, there must be no place
+where both components are visible. For instance:]}
address@hidden@ChgRef{Version=[1],Kind=[Added]}
address@hidden@key[package] A @key[is]
+   @key[type] T @key[is tagged private];
+   @key[package] B @key[is]
+      @key[type] NT @key[is new] T @key[with record]
+         I: Integer; -- @RI{Illegal because T.I is visible in the body.}
+      @key[end record]; -- @RI{T.I is not visible here.}
+   @key[end] B;
address@hidden
+   @key[type] T @key[is tagged record]
+      I: Integer; -- @RI{Illegal because T.I is visible in the body.}
+   @key[end record];
address@hidden A;],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00114-01]}
address@hidden@Chg{Version=[2],New=[],address@hidden A @key[is]
address@hidden @key[body] A @key[is]
+   @key[package] @key[body] B @key[is]
+      -- @RI{T.I becomes visible here.}
+   @key[end] B;
address@hidden A;],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden@key[package] A.C @key[is]
+   @key[type] NT2 @key[is new] A.T @key[with record]
+      I: Integer; -- @RI{Illegal because T.I is visible in the private part.}
+   @key[end record]; -- @RI{T.I is not visible here.}
address@hidden
+    -- @RI{T.I is visible here.}
address@hidden A.C;],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden@key[with] A;
address@hidden D @key[is]
+   @key[type] NT3 @key[is new] A.T @key[with record]
+      I: Integer; -- @RI{Legal because T.I is never visible in this package.}
+   @key[end record];
address@hidden D;],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden@key[with] D;
address@hidden A.E @key[is]
+   @key[type] NT4 @key[is new] D.NT3 @key[with null record];
+   X : NT4;
+   I1 : Integer := X.I;        -- @RI{D.NT3.I}
+   I2 : Integer := D.NT3(X).I; -- @RI{D.NT3.I}
+   I3 : Integer := A.T(X).I;   -- @RI{A.T.I}
address@hidden A.E;],Old=[]}
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0102],ARef=[AI95-00157-01]}
address@hidden,NoPrefix=[T],Text=[D.NT3 can have a component I because
+the component I of the parent type is never visible. The parent component
+exists, of course, but is never declared for the type D.NT3. In the child
+package A.E, the component I of A.T is visible, but that does not change the
+fact that the A.T.I component was never declared for type D.NT3. Thus, A.E.NT4
+does not (visibly) inherit the component I from A.T, while it does inherit the
+component I from D.NT3. Of course, both components exist, and can be accessed
+by a type conversion as shown above. This behavior stems from the fact that
+every characteristic of a type (including components) must be declared
+somewhere in the innermost declarative region containing the type @em if the
+characteristic is never visible in that declarative region, it is never
+declared. Therefore, such characteristics do not suddenly become available even
+if they are in fact visible in some other scope.
+See @RefSecNum{Private Operations} for more on the rules.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00377-01]}
address@hidden,Text=[It is illegal to mention both an explicit child of
+an instance, and a child of the generic from which the instance was
+instantiated. This is easier to understand with an example:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden
address@hidden G1 @key{is}
address@hidden G1;],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden
address@hidden G1.G2 @key{is}
address@hidden G1.G2;],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden G1;
address@hidden I1 @key{is new} G1;],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden I1.G2 @key{renames} ...]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden G1.G2;
address@hidden I1.G2;             -- @RI{Illegal}
address@hidden Bad @key{is} ...],Old=[]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,NoPrefix=[T],Text=[The context clause for Bad is illegal
+as I1 has an implicit declaration of I1.G2 based on the generic child G1.G2,
+as well as the mention of the explicit child I1.G2. As in the previous cases,
+this is illegal only if the context clause makes both children visible; the
+explicit child can be mentioned as long as the generic child is not (and
+vice-versa).]}
address@hidden
+
+Note that we need to be careful which things we make "hidden from all
+visibility" versus which things we make simply illegal for names to
+denote. The distinction is subtle.
+The rules that disallow names denoting components within a type
+declaration (see @RefSecNum{Discriminants}) do not make the components
+invisible at those places, so that the above rule makes components with
+the same name illegal.
+The same is true for the rule that disallows names denoting formal
+parameters within a @nt{formal_part} (see @RefSecNum{Subprogram Declarations}).
address@hidden
address@hidden
+The part about instances is from AI83-00012.
+The reason it says @lquotes@;overloadable address@hidden@; is because
+we don't want it to apply to type extensions that appear in an instance;
+components are not overloadable.
address@hidden
address@hidden
+
address@hidden
+Visibility for compilation units
+follows from the definition of the environment
+in @RefSecNum{The Compilation Process},
+except that it is necessary to apply a @nt{with_clause} to obtain
+visibility to a @nt{library_unit_declaration}
+or @nt{library_unit_renaming_declaration}.
+
+In addition to the visibility rules given above,
+the meaning of the occurrence of a @nt{direct_name} or
address@hidden at a given place in the text can depend on
+the overloading rules
+(see @RefSecNum{The Context of Overload Resolution}).
+
+Not all contexts where an @nt<identifier>, @nt<character_literal>,
+or @nt<operator_symbol> are allowed require visibility of a corresponding
+declaration.
+Contexts where visibility is not required
+are identified by using one of these three syntactic categories
+directly in a syntax rule, rather than using @nt<direct_name> or
address@hidden<selector_name>.
address@hidden
address@hidden@;An @nt{identifier}, @nt{character_literal} or 
@nt{operator_symbol}
+that occurs in one of the following contexts is not
+required to denote a visible or directly
+visible declaration:
address@hidden
+A defining name.
+
+The @nt{identifier}s or @nt{operator_symbol} that appear after the
+reserved word @key{end} in a @nt{proper_body}.
+Similarly for @lquotes@;@key{end address@hidden@;, etc.
+
+An @nt{attribute_designator}.
+
+A @nt{pragma} @nt{identifier}.
+
+A @address@hidden
+
+An @nt{identifier} specific to a
+pragma used in a pragma argument.
+
address@hidden,Kind=[Added],ARef=[AI05-0183-1]}
address@hidden,Text=[An @nt{aspect_mark};]}
+
address@hidden,Kind=[Added],ARef=[AI05-0183-1]}
address@hidden,Text=[An @nt{identifier} specific to an aspect used
+in an @nt{aspect_definition}.]}
address@hidden
+
+The visibility rules have nothing to do with the above cases;
+the meanings of such things are defined elsewhere.
+Reserved words are not @nt{identifier}s;
+the visibility rules don't apply to them either.
+
+Because of the way we have defined "declaration",
+it is possible for a usage name to denote a @nt{subprogram_body}, either
+within that body, or (for a nonlibrary unit) after it
+(since the body hides the corresponding declaration, if any).
+Other bodies do not work that way.
+Completions of @nt{type_declaration}s and
+deferred constant declarations do work that way.
address@hidden are never denoted, although the
address@hidden in their profiles can be.
+
address@hidden@;The scope of a subprogram does not start until after its 
profile.
+Thus, the following is legal:
address@hidden
+X : @key[constant] Integer := 17;
+...
address@hidden P @key[is]
+    @key[procedure] X(Y : @key[in] Integer := X);
address@hidden P;
address@hidden
+
+The body of the subprogram will probably be illegal,
+however, since the constant X will be hidden by then.
+
address@hidden@;The rule is different for generic subprograms,
+since they are not overloadable;
+the following is illegal:
address@hidden
+X : @key[constant] Integer := 17;
address@hidden P @key[is]
+    @key[generic]
+      Z : Integer := X; address@hidden Illegal!}
+    @key[procedure] X(Y : @key[in] Integer := X); address@hidden Illegal!}
address@hidden P;
address@hidden
+
+The constant X is hidden from direct visibility by the generic
+declaration.
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Declarations with the same defining
+name as that of a subprogram or entry being defined
+are nevertheless visible within
+the subprogram specification or entry declaration.
address@hidden
+
address@hidden
+The term @lquotes@;visible by address@hidden@; is no longer defined.
+We use the terms @lquotes@;directly address@hidden@; and 
@lquotes@;address@hidden@; (among other things).
+There are only two regions of text that are of interest, here: the
+region in which a declaration is visible,
+and the region in which it is directly visible.
+
+Visibility is defined only for declarations.
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01]}
address@hidden,Type=[Leading],address@hidden with Ada 95}
+Added rules to handle the inheritance and overriding of
+multiple homographs for a single type declaration, in order to support
+multiple inheritance from interfaces. The new rules are intended to be
+compatible with the existing rules so that programs that do not use
+interfaces do not change their legality. However, there is a very rare
+case where this is not true:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key{type} T1 @key{is private};
+   @key{type} T2 @key{is private};
address@hidden G @key{is}
+   @key{type} T @key{is null record};
+   @key{procedure} P (X : T; Y : T1);
+   @key{procedure} P (X : T; Z : T2);
address@hidden G;]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden I @key{is new} G (Integer, Integer); -- 
@RI[Exports homographs of P.]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden D @key{is new} I.T; -- @RI[Both Ps are 
inherited.]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Obj : D;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[P (Obj, Z => 10); -- @RI[Legal in Ada 95, illegal in Ada 
2005.]]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The call to P would resolve in Ada 95 by using the
+parameter name, while the procedures P would be hidden from all visibility
+in Ada 2005 and thus would not resolve.
+This case doesn't seem worth making the rules any more
+complex than they already are.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00377-01]}
+  @ChgAdded{Version=[2],address@hidden Correction:] A @nt{with_clause} is
+  illegal if it would create a homograph of an implicitly declared generic
+  child (see @RefSecNum{Compilation Units - Library Units}). An Ada 95 compiler
+  could have allowed this, but which unit of the two units involved would be
+  denoted wasn't specified, so any successful use isn't portable. Removing one
+  of the two @nt{with_clause}s involved will fix the problem.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0025],ARef=[AI95-00044-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified the overriding 
rules so
+  that "/=" and @nt{statement_identifier}s are covered.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0026],ARef=[AI95-00150-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that is it never
+  possible for two components with the same name to be visible; any such 
program
+  is illegal.]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00195-01],ARef=[AI95-00408-01]}
+  @ChgAdded{Version=[2],Text=[The visibility of an
+  @nt{attribute_definition_clause} is defined so that it can be used by the
+  stream attribute availability rules (see @RefSecNum{Stream-Oriented 
Attributes}).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00217-06]}
+  @ChgAdded{Version=[2],Text=[The visibility of a limited view of a library
+  package is defined (see @RefSecNum{Compilation Units - Library Units}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0177-1]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0157-1]}
+  @ChgAdded{Version=[3],Text=[Added wording so that the parameters of an
+  @address@hidden@!declaration} are visible in the
+  @Chg{Version=[4],New=[return expression],address@hidden
+  of the function. (It would be pretty useless without such a rule.)]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],Text=[The visibility of an
+  @nt{aspect_specification} is defined so that it can be used in various other
+  rules.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden,Name=[Overriding Indicators]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00218-03]}
address@hidden,Text=[An @nt{overriding_indicator} is used to declare
+that an operation is intended to override (or not override) an inherited
+operation.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00218-03]}
address@hidden,lhs=<@Chg{Version=[2],New=<overriding_indicator>,Old=<>}>,
+rhs="@Chg{Version=[2],New=<address@hidden @key{overriding}>,Old=<>}"}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00218-03],ARef=[AI95-00348-01],ARef=[AI95-00397-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0177-1]}
address@hidden,Type=[Leading],Text=[If an
address@hidden@address@hidden,
address@hidden@address@hidden,@Chg{Version=[3],New=[
address@hidden@address@hidden,],Old=[]}
address@hidden, @address@hidden,
address@hidden@address@hidden, @address@hidden of a
+subprogram, or @address@hidden
+other than a protected subprogram has an @address@hidden, then:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[the operation shall be a primitive operation for some
+type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[if the @nt{overriding_indicator} is
address@hidden, then the operation shall override a homograph at the place of
+the declaration or body;]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,Text=[This doesn't require that the overriding happen
+at precisely the place of the declaration or body; it only requires that the
+region in  which the overriding is known to have happened includes this
+place. That is, the overriding can happen at or before the place of the
+declaration or body.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[if the @nt{overriding_indicator} is
address@hidden overriding}, then the operation shall not override any homograph
+(at any place).]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden contract issue}In addition to the
+places where @LegalityTitle normally
+apply, these rules also apply in the private part of an instance of a generic
+unit.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The @Key{overriding} and @Key{not overriding} rules
+differ slightly. For @Key{overriding}, we want the indicator to reflect the
+overriding state at the place of the declaration; otherwise the indicator would
+be @LQuotes@;address@hidden@;. Whether a homograph is implicitly declared after
+the declaration (see 7.3.1 to see how this can happen)
+has no impact on this check. However, @Key{not overriding} is different;
address@hidden@;address@hidden@; would happen if a homograph declared later 
actually
+is overriding. So, we require this check to take into account later 
overridings.
+That can be implemented either by looking ahead, or by rechecking when
+additional operations are declared.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The @LQuotes@;no address@hidden@; rules are
+needed to prevent a @nt{subprogram_declaration} and @nt{subprogram_body}
+from having contradictory @nt{overriding_indicator}s.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00397-01]}
address@hidden,Text=[Rules for @nt{overriding_indicator}s of task and
+protected entries and of protected subprograms are found in
address@hidden and Accept Statements}
+and @RefSecNum{Protected Units and Protected Objects}, respectively.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,Type=[Leading],Text=[The use of
address@hidden allows the detection of errors at compile-time that
+otherwise might not be detected at all. For instance, we might declare a
+security queue derived from the Queue interface of 3.9.4 as:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Security_Queue @key{is new} Queue @key{with 
record} ...;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
address@hidden Append(Q : @key{in out} Security_Queue; Person : @key{in} 
Person_Name);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
address@hidden Remove_First(Q : @key{in out} Security_Queue; Person : @key{in} 
Person_Name);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
address@hidden Cur_Count(Q : @key{in} Security_Queue) @key{return} Natural;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
address@hidden Max_Count(Q : @key{in} Security_Queue) @key{return} Natural;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden overriding}
address@hidden Arrest(Q : @key{in out} Security_Queue; Person : @key{in} 
Person_Name);]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The first four subprogram declarations guarantee
+that these subprograms will override the four subprograms inherited from the
+Queue interface. A misspelling in one of these subprograms will be detected
+by the implementation. Conversely, the declaration of Arrest guarantees that
+this is a new operation.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[In this case, the subprograms are abstract, so
+  misspellings will get detected anyway. But for other subprograms
+  (especially when deriving from concrete types), the error might never be
+  detected, and a body other than the one the programmer intended might be
+  executed without warning. Thus our new motto: @lquotes@;Overriding
+  indicators @em don't derive a type without address@hidden
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00218-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @nt{Overriding_indicator}s are new. These let the
+  programmer state her overriding intentions to the compiler; if the compiler
+  disagrees, an error will be produced rather than a hard to find bug.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI95-0177-1]}
+  @ChgAdded{Version=[3],Text=[Expression functions can have overriding
+  indicators.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden Clauses}
+
address@hidden
address@hidden @nt{use_package_clause} achieves direct visibility of 
declarations that
+appear in the visible part of a package;
+a @nt{use_type_clause} achieves direct visibility of the primitive
+operators of a type.]
address@hidden
+
address@hidden
address@hidden of @nt{use_clause}s and @nt{selected_component}s}
+If and only if the visibility rules allow P.A,
+"@key[use] P;" should make A directly visible
+(barring name conflicts).
+This means, for example, that child library units, and
+generic formals of a formal package whose
address@hidden is (<>),
+should be made visible by
+a @nt{use_clause} for the appropriate package.
+
address@hidden effect}
+The rules for @nt{use_clause}s were carefully constructed to avoid
+so-called @i(Beaujolais) effects, where the addition or removal
+of a single @nt{use_clause}, or a single declaration in a "use"d
+package, would
+change the meaning of a program from one legal interpretation to another.
address@hidden
+
address@hidden
address@hidden<use_clause>,rhs="@Syn2{use_package_clause} | 
@Syn2{use_type_clause}"}
+
+
address@hidden<use_package_clause>,rhs="@key{use} @address@hidden {, 
@address@hidden;"}
+
address@hidden,Kind=[Revised],ARef=[AI05-0150-1]}
address@hidden<use_type_clause>,rhs="@key[use] @Chg{Version=[3],address@hidden 
},address@hidden @Syn2{subtype_mark} {, @Syn2{subtype_mark}};"}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00217-06]}
+A @address@hidden of a @nt{use_package_clause}
+shall denote @Chg{Version=[2],New=[a nonlimited view of ],Old=[]}a package.
address@hidden
+This includes formal packages.
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(of a @nt{use_clause})}
+For each @nt{use_clause},
+there is a certain region of text called the @i{scope} of the @nt{use_clause}.
+For a @nt{use_clause} within a @nt{context_clause} of a
address@hidden
+or @nt{library_unit_renaming_declaration},
+the scope is the entire declarative region of the declaration.
+For a @nt{use_clause} within a @nt{context_clause} of a
+body, the scope is the entire body @Redundant[and any
+subunits (including multiply
+nested subunits).
+The scope does not include @nt<context_clause>s themselves.]
+
+For a @nt{use_clause} immediately within a declarative region,
+the scope is the portion of the declarative region
+starting just after the @nt{use_clause}
+and extending to the end of the declarative region.
+However, the scope of a @nt{use_clause} in the private part of a library
+unit does not include the visible part of
+any public descendant of that library unit.
address@hidden
address@hidden@;The exception echoes the similar exception for
address@hidden@;immediate scope (of a declaration)@rquotes@;
+(see @RefSecNum{Scope of Declarations}).
+It makes @nt{use_clause}s work like this:
address@hidden
address@hidden P @key[is]
+    @key[type] T @key[is] @key[range] 1..10;
address@hidden P;
+
address@hidden P;
address@hidden Parent @key[is]
address@hidden
+    @key[use] P;
+    X : T;
address@hidden Parent;
+
address@hidden Parent.Child @key[is]
+    Y : T; address@hidden Illegal!}
+    Z : P.T;
address@hidden
+    W : T;
address@hidden Parent.Child;
address@hidden
+
+The declaration of Y is illegal because the scope of the @lquotes@;@key[use] 
address@hidden@;
+does not include that place, so T is not directly visible there.
+The declarations of X, Z, and W are legal.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00217-06]}
address@hidden,New=[A package is @i{named} in a @nt{use_package_clause} if
+it is denoted by a @address@hidden of that clause. A type is @i{named}
+in a @nt{use_type_clause} if it is determined by a @nt{subtype_mark} of that
address@hidden,Sec=[in a use clause]}],Old=[]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00217-06]}
address@hidden,Kind=[Revised],ARef=[AI05-0150-1]}
address@hidden,Type=[Leading],address@hidden to add conditional leading}
address@hidden use-visible}
+For each package @Chg{Version=[2],New=[named in ],Old=[denoted by
+a @address@hidden of ]}a @nt{use_package_clause} whose scope
+encloses a place, each declaration that occurs immediately within
+the declarative region of the package is
address@hidden(potentially use-visible) at this place
+if the declaration is visible at this place.
+For each type @i(T) or @i(T)'Class @Chg{Version=[2],New=[named in ],Old=[
+determined by a @nt<subtype_mark> of ]}a @nt{use_type_clause} whose scope
+encloses a place, the declaration of each primitive operator of type @i(T)
+is potentially use-visible at this place
+if its declaration is visible at this address@hidden, New=[ If a
address@hidden whose scope encloses a place includes the reserved
+word @key[all], then the following entities are also potentially use-visible
+at this place if the declaration of the entity is visible at this 
place:],Old=[]}
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0150-1]}
+  @ChgAdded{Version=[3],Text=[Each primitive subprogram of @i<T> including each
+  enumeration literal (if any);]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0150-1]}
+  @ChgAdded{Version=[3],Text=[Each subprogram that is declared immediately
+  within the declarative region in which an ancestor type of @i<T> is declared
+  and that operates on a class-wide type that covers @i<T>.]}
address@hidden
+
+  @begin{Ramification}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0150-1]}
+  Primitive subprograms whose defining name is an @nt{identifier} are
+  @i{not} made potentially visible by a
+  @address@hidden,New=[ unless reserved word @key[all] is
+  included],Old=[]}.
+  A @nt{use_type_clause} @Chg{Version=[3],New=[without @key[all] ],Old=[]}is 
only for operators.
+
+  The semantics described here should be similar
+  to the semantics for expanded names given
+  in @RefSec{Selected Components}
+  so as to achieve the effect requested by
+  the @lquotes@;principle of equivalence of @nt{use_clause}s and
+  @address@hidden@;
+  Thus, child library units and generic formal parameters of a formal
+  package are
+  potentially use-visible when their enclosing package is use'd.
+
+  The "visible at that place" part implies that
+  applying a @nt{use_clause} to a parent unit does not make all of its
+  children use-visible @em only those that have been made
+  visible by a @nt{with_clause}.
+  It also implies that we don't have to worry about hiding in the
+  definition of "directly visible" @em a declaration cannot be use-visible
+  unless it is visible.
+
+  Note that
+  "@key[use type] T'Class;" is equivalent to "@key[use type] T;",
+  which helps avoid breaking the generic contract model.
+  @end{Ramification}
+
address@hidden,Kind=[Added],ARef=[AI05-0131-1]}
address@hidden,Text=[Certain implicit declarations may become
+potentially use-visible in certain contexts as described in
address@hidden Subprograms}.]}
+
+
address@hidden@Defn{use-visible}
address@hidden,Sec=(use clause)}
+A declaration is @i{use-visible} if it is potentially use-visible,
+except in these naming-conflict cases:
address@hidden
+  A potentially use-visible declaration is not use-visible if the place
+  considered is within the immediate scope of a homograph of the
+  declaration.
+
+  Potentially use-visible declarations that have the same @nt{identifier}
+  are not use-visible unless each of them is an overloadable
+  declaration.
address@hidden
+  Overloadable declarations don't cancel each other out,
+  even if they are homographs,
+  though if they are not distinguishable
+  by formal parameter names or the presence or absence of
+  @nt{default_expression}s, any use will be ambiguous.
+  We only mention @nt{identifier}s here, because
+  declarations named by @nt<operator_symbol>s are
+  always overloadable, and hence never cancel each other.
+  Direct visibility is irrelevant for @nt{character_literal}s.
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(use_clause)}
+The elaboration of a @nt{use_clause} has no effect.
address@hidden
+
address@hidden
+
address@hidden@address@hidden of a use clause in a context clause:}
address@hidden
address@hidden Ada.Calendar; @key[use] Ada;
address@hidden
+
address@hidden
address@hidden@address@hidden of a use type clause:}
address@hidden
address@hidden
address@hidden type] Rational_Numbers.Rational; address@hidden see 
@RefSecNum{Package Specifications and Declarations}}
+Two_Thirds: Rational_Numbers.Rational := 2/3;
address@hidden
+
address@hidden
+In @lquotes@;@key[use] X, Y;@rquotes@;, Y cannot refer to something made 
visible by the
address@hidden@;@address@hidden@; of X.
+Thus, it's not (quite) equivalent to @lquotes@;@key[use] X; @key[use] 
Y;@rquotes@;.
+
+If a given declaration is already immediately visible,
+then a @nt{use_clause} that makes it potentially use-visible
+has no effect.
+Therefore,
+a @nt{use_type_clause} for a type whose declaration appears
+in a place other than the visible part
+of a package has no effect;
+it cannot make a declaration use-visible
+unless that declaration is already immediately visible.
+
+"@key[Use] @key[type] S1;" and "@key[use] @key[type] S2;"
+are equivalent if S1 and S2 are both subtypes of the same type.
+In particular,
+"@key[use] @key[type] S;" and "@key[use] @key[type] S'Base;"
+are equivalent.
address@hidden
address@hidden
+We considered adding a rule that prevented several declarations of
+views of the same entity that all have the same semantics from
+cancelling each other out.
+For example, if a (possibly implicit)
address@hidden for "+" is potentially use-visible,
+and a fully conformant renaming of it is also potentially
+use-visible, then they (annoyingly) cancel each other out;
+neither one is use-visible.
+The considered rule would have made just one of them use-visible.
+We gave up on this idea due to the complexity of the rule.
+It would have had to account for both overloadable and
+nonoverloadable @nt{renaming_declaration}s,
+the case where the rule should apply only to some subset of the
+declarations with the same defining name,
+and the case of @nt{subtype_declaration}s
+(since they are claimed to be sufficient for renaming of subtypes).
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The @nt{use_type_clause} is new to Ada 95.
address@hidden
+
address@hidden
+The phrase @lquotes@;omitting from this set any packages that
+enclose this address@hidden@; is no longer necessary to avoid making something
+visible outside its scope, because we explicitly state that the
+declaration has to be visible in order to be
+potentially use-visible.
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00217-06]}
+  @ChgAdded{Version=[2],Text=[Limited views of packages are not allowed in use 
clauses.
+  Defined @i<named in a use clause> for use in other limited view rules (see
+  @RefSecNum{Context Clauses - With Clauses}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0150-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}The
+  @key[use all type] version of the @nt{use_type_clause} is new to Ada 2012.
+  It works similarly to prefixed views.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0131-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added wording to allow 
other
+  declarations to be potentially use-visible, to support corrections to
+  formal subprograms.]}
address@hidden
+
+
+
address@hidden Declarations}
+
address@hidden
address@hidden @nt{renaming_declaration} declares another name for an entity,
+such as an object, exception, package, subprogram, entry,
+or generic unit.
+Alternatively, a @nt{subprogram_renaming_declaration} can be the
+completion of a previous @nt{subprogram_declaration}.]
+
address@hidden,Kind=[Added],Term=<Renaming>,
+Text=<@ChgAdded{Version=[2],Text=[A @nt{renaming_declaration} is a declaration
+that does not define a new entity, but instead defines a view of an existing
+entity.]}>}
+
address@hidden
+
address@hidden
address@hidden<renaming_declaration>,rhs="
+      @Syn2{object_renaming_declaration}
+    | @Syn2{exception_renaming_declaration}
+    | @Syn2{package_renaming_declaration}
+    | @Syn2{subprogram_renaming_declaration}
+    | @Syn2{generic_renaming_declaration}"}
address@hidden
+
address@hidden
address@hidden, Sec=(renaming_declaration)}
+The elaboration of a @nt{renaming_declaration} evaluates the @nt{name} that
+follows the reserved word @key{renames} and thereby determines the
+view and entity denoted by this name
address@hidden view}
address@hidden entity}
+(the @i{renamed view} and @i{renamed entity}).
address@hidden @nt{name} that denotes the @nt{renaming_declaration}
+denotes (a new view of) the renamed entity.]
address@hidden
+
address@hidden
+Renaming may be used to resolve name conflicts and to act as a
+shorthand. Renaming with a different @nt{identifier} or
address@hidden does not hide the old @nt{name}; the new
address@hidden and the old @nt{name} need not be visible at the same
+places.
+
+A task or protected object that is declared by an explicit
address@hidden can be renamed as an object. However, a
+single task or protected object cannot be renamed since the
+corresponding type is anonymous (meaning it has no nameable subtypes).
+For similar reasons, an object of an anonymous array or access type
+cannot be renamed.
+
address@hidden@keepnext@;A subtype defined without any additional constraint
+can be used to achieve the effect of renaming another subtype
+(including a task or protected subtype) as in
address@hidden
+   @key[subtype] Mode @key[is] Ada.Text_IO.File_Mode;
address@hidden
address@hidden
+
address@hidden
+The second sentence of RM83-8.5(3),
address@hidden@;At any point where a renaming declaration is visible,
+the identifier, or operator symbol of this declaration denotes the
+renamed address@hidden@; is incorrect. It doesn't say directly visible.
+Also, such an @nt{identifier} might resolve to something else.
+
+The verbiage about renamings being legal @lquotes@;only if exactly 
address@hidden@;,
+which appears in RM83-8.5(4) (for objects) and RM83-8.5(7) (for subprograms) is
+removed, because it follows from the normal rules about overload resolution.
+For language lawyers, these facts are obvious; for programmers, they are
+irrelevant, since failing these tests is highly unlikely.
address@hidden
+
+
address@hidden Renaming Declarations}
+
address@hidden
address@hidden @nt{object_renaming_declaration} is used to rename an object.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00423-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<object_renaming_declaration>,rhs="@Chg{Version=[2],New=[
+    ],address@hidden : @Chg{Version=[2],New=<address@hidden 
>,Old=<>address@hidden @key{renames} @address@hidden@Chg{Version=[3],New=<
+        address@hidden>,Old=[]};@Chg{Version=[2],New=[
+  | @Syn2{defining_identifier} : @Syn2{access_definition} @key{renames} 
@address@hidden@Chg{Version=[3],New=<
+        address@hidden>,Old=[]};],Old=[]}"}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00254-01],ARef=[AI95-00409-01]}
+The type of the @address@hidden shall resolve to
+the type determined by the @address@hidden,New=[,
+or in the case where the type is defined by an @nt{access_definition}, to an
+anonymous access type. If the anonymous access type is an access-to-object 
type,
+the type of the @address@hidden
+shall have the same designated type as that of the @nt{access_definition}.
+If the anonymous access type is an access-to-subprogram type,
+the type of the @address@hidden shall have a designated profile
+that is type conformant with that of the @nt{access_definition}],Old=[]}.
+
address@hidden
address@hidden@;A previous version of Ada 9X used the usual
address@hidden@;expected address@hidden@; wording:@*
address@hidden@;The expected type for the @address@hidden is
+that determined by the @address@hidden@;@*
+We changed it so that this would be illegal:
address@hidden
+X: T;
+Y: T'Class @key[renames] X; address@hidden Illegal!}
address@hidden
+
address@hidden@;When the above was legal, it was unclear whether Y
+was of type T or T'Class.
+Note that we still allow this:
address@hidden
+Z: T'Class := ...;
+W: T @key[renames] F(Z);
address@hidden
+
+where F is a function with a controlling parameter and result.
+This is admittedly a bit odd.
+
+Note that the matching rule for generic formal parameters of mode
address@hidden out] was changed to keep it consistent with the rule
+for renaming.
+That makes the rule different for @key[in] vs. @key[in out].
+
address@hidden
address@hidden
+
address@hidden
+The renamed entity shall be an object.
+
address@hidden,Kind=[Added],ARef=[AI95-00231-01],ARef=[AI95-00409-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[In the case
+where the type is defined by an @nt{access_definition},
+the type of the renamed object and the type defined by the
address@hidden:]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00231-01],ARef=[AI95-00409-01]}
address@hidden,Text=[shall both be access-to-object types with
+statically matching designated subtypes and with both or neither being
+access-to-constant types; or
address@hidden matching],Sec=(required)}]}
+
address@hidden,Kind=[Added],ARef=[AI95-00409-01]}
address@hidden,Text=[shall both be access-to-subprogram types with
+subtype conformant designated profiles.
address@hidden conformance],Sec=(required)}]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00423-01]}
address@hidden,Type=[Leading],Text=[For an
address@hidden with a @nt{null_exclusion} or an
address@hidden that has a @nt{null_exclusion}:]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[if the @address@hidden denotes a
+  generic formal object of a generic unit @i{G}, and the
+  @nt{object_renaming_declaration} occurs within the body of @i{G} or within
+  the body of a generic unit declared within the declarative region of @i{G},
+  then the declaration of the formal object of @i{G} shall have a
+  @nt{null_exclusion};]}
+
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[otherwise, the subtype of the
+  @address@hidden shall exclude null.
+  @PDefn{generic contract issue}
+  In addition to the places where @LegalityTitle normally apply
+  (see @RefSecNum{Generic Instantiation}),
+  this rule applies also in the private part of an
+  instance of a generic unit.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[This rule prevents
+  @lquotes@;address@hidden
+  @b<Null> must never be the value of an object with an explicit
+  @nt{null_exclusion}. The first bullet is an assume-the-worst rule
+  which prevents trouble in one obscure case:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Acc_I @key{is access} Integer;
address@hidden Acc_NN_I @key{is not null} Acc_I;
+Obj : Acc_I := @key{null};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   B : @key{in out} Acc_NN_I;
address@hidden Gen @key{is}
+   ...
address@hidden Gen;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden body} Gen @key{is}
+   D : @key{not null} Acc_I @key{renames} B;
address@hidden Gen;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Inst @key{is new} Gen (B => Obj);]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Without the first bullet rule, D would
+  be legal, and contain the value @key{null}, because the rule about lying
+  is satisfied for generic matching (Obj matches B; B does not explicitly
+  state @key{not null}),
+  @LegalityTitle are not rechecked in the body of any instance, and the
+  template passes the lying rule as well. The rule is so complex because it
+  has to apply to formals used in bodies of child generics as well as in
+  the bodies of generics.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0017],ARef=[AI95-00184-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00363-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0008-1]}
+The renamed entity shall not be a subcomponent that depends on
+discriminants of @Chg{Version=[3],New=[an object],Old=[a variable]}
+whose nominal subtype is address@hidden,New=[],Old=[,]}
+unless @Chg{Version=[3],New=[the object is known to be constrained],
+Old=[this subtype is indefinite, or the variable is @Chg{Version=[2],
+New=[constrained by its initial value],Old=[aliased]}]}.
+A @nt{slice} of an array shall not be renamed if
+this restriction disallows renaming of the array.
address@hidden@PDefn{generic contract issue}In addition to the places where
+Legality Rules normally apply, these rules apply also in the private part of an
+instance of a generic address@hidden,New=[],Old=[ These rules also apply for a 
renaming that appears
+in the body of a generic unit, with the additional requirement that even if the
+nominal subtype of the variable is indefinite, its type shall not be a
+descendant of an untagged generic formal derived type.]}],Old=[]}
+
address@hidden
+This prevents renaming of subcomponents that might
+disappear, which might leave dangling references.
+Similar restrictions exist for the Access attribute.
+
address@hidden,Kind=[Added],Ref=[8652/0017],ARef=[AI95-00184-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0008-1]}
address@hidden,Type=[Leading],Text=[The @lquotes@;recheck on
address@hidden@; @Chg{Version=[3],New=[requirement], Old=[and
address@hidden@;assume-the-worst in the address@hidden@;
+restrictions]} on generics @Chg{Version=[3],New=[is],Old=[are]}
+necessary to avoid renaming of components which
+could disappear even when the nominal subtype would prevent the problem:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden@key{type} T1 (D1 : Boolean) @key{is}
+   @key{record}
+      @key{case} D1 @key{is}
+         @key{when} False =>
+            C1 : Integer;
+         @key{when} True =>
+            @key{null};
+         @key{end} @key{case};
+      @key{end} @key{record};],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden@key{generic}
+   @key{type} F @key{is} @key{new} T1;
+   X : @key{in out} F;
address@hidden G @key{is}
+   C1_Ren : Integer @key{renames} X.C1;
address@hidden G;],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden@key{type} T2 (D2 : Boolean := False) @key{is} @key{new} T1 (D1 
=> D2);
address@hidden line}
+Y : T2;
address@hidden line}
address@hidden I @key{is new} G (T2, Y);
address@hidden line}
+Y := (D1 => True); -- @RI[Oops!  What happened to I.C1_Ren?]],Old=[]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0008-1]}
address@hidden,Text=[In addition, the @ldquote@;known to be address@hidden
+rules include assume-the-worst rules for generic bodies partially to
+prevent such problems.]}
+
address@hidden
address@hidden
+Note that if an implementation chooses to deallocate-then-reallocate
+on @address@hidden assigning to unconstrained definite objects,
+then it cannot represent renamings and access values as simple
+addresses, because the above rule does not apply to all components of
+such an object.
address@hidden
address@hidden
+If it is a generic formal object,
+then the assume-the-best or assume-the-worst rules are applied as
+appropriate.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00409-01]}
+An @nt{object_renaming_declaration} declares a new view
address@hidden the renamed object} whose
+properties are identical to those of the renamed view.
address@hidden, the properties of the renamed object are not affected by the
address@hidden
+In particular, its value and whether or not it is a constant
+are unaffected; similarly, address@hidden,New=[ null exclusion or],Old=[]}
+constraints that apply to an object are
+not affected by renaming (any constraint implied by the
address@hidden @Chg{Version=[2],New=[or @nt{access_definition} ],Old=[]}of
+the @nt{object_renaming_declaration} is ignored).]
address@hidden
+Because the constraints are ignored,
+it is a good idea
+to use the nominal subtype of the renamed object
+when writing an @nt{object_renaming_declaration}.
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00409-01]}
address@hidden,Text=[If no @nt{null_exclusion} is given in the
+renaming, the
+object may or may not exclude null. This is similar to the way that
+constraints need not match, and @key{constant} is not specified. The
+renaming defines a view of the
+renamed entity, inheriting the original properties.]}
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of renaming an object:}
address@hidden
address@hidden
+   L : Person @key[renames] Leftmost_Person; address@hidden see 
@RefSecNum{Incomplete Type Declarations}}
address@hidden
+   L.Age := L.Age + 1;
address@hidden;
address@hidden
address@hidden
+
address@hidden
+The phrase @lquotes@;subtype ... as defined in a corresponding
+object declaration, component declaration, or component subtype
+indication,@rquotes@; from RM83-8.5(5), is incorrect in Ada 95;
+therefore we removed it.
+It is incorrect in the case of an object with an indefinite
+unconstrained nominal subtype.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00363-01]}
address@hidden,Type=[Leading],address@hidden@;@Defn{incompatibilities with Ada 
95}
+Aliased variables are not necessarily constrained in Ada
+2005 (see @RefSecNum{Array Types}). Therefore, a subcomponent of an aliased
+variable may disappear or change shape, and renaming such a subcomponent thus
+is illegal, while the same operation would have been legal in Ada 95. Note that
+most allocated objects are still constrained by their initial value (see
address@hidden), and thus have no change in the
+legality of renaming for them. For example,
+using the type T2 of the previous example:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   AT2 : @key{aliased} T2;
+   C1_Ren : Integer @key{renames} AT2.C1; -- @RI[Illegal in Ada 2005, legal in 
Ada 95]
+   AT2 := (D1 => True);             -- @RI[Raised Constraint_Error in Ada 95,]
+                                    -- @RI[but does not in Ada 2005, so C1_Ren 
becomes]
+                                    -- @RI[invalid when this is assigned.]]}
address@hidden
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01],ARef=[AI95-00231-01],ARef=[AI95-00254-01],ARef=[AI95-00409-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  A renaming can have an anonymous access type. In that case, the accessibility
+  of the renaming is that of the original object (accessibility is not
+  lost as it is for assignment to a component or stand-alone object).]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01],ARef=[AI95-00423-01]}
+  @ChgAdded{Version=[2],Text=[A renaming can have a @nt{null_exclusion}; if so,
+  the renamed object must also exclude null, so that the @nt{null_exclusion}
+  does not lie. On the other hand, if the renaming does not have a
+  @nt{null_exclusion}. it excludes null if the renamed object does.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0017],ARef=[AI95-00184-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Fixed to forbid renamings 
of
+  depends-on-discriminant components if the type @i{might} be definite.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0008-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Simplified the description of when a discriminant-dependent component is
+  allowed to be renamed @em it's now simply when the object is
+  known to be constrained. This
+  fixes a confusion as to whether a subcomponent of an object that is not
+  certain to be constrained can be renamed. The fix introduces an
+  incompatibility, as the rule did not apply in Ada 95 if the prefix was a
+  constant; but it now applies no matter what kind of object is involved. The
+  incompatibility is not too bad, since most kinds of constants are known to be
+  constrained.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in an
+  @nt{object_renaming_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Renaming Declarations}
+
address@hidden
address@hidden @nt{exception_renaming_declaration} is used to rename an 
exception.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<exception_renaming_declaration>,rhs="@Syn2{defining_identifier} 
: @key{exception} @key{renames} @address@hidden@Chg{Version=[3],New=<
+   address@hidden>,Old=[]};"}
address@hidden
+
address@hidden
+The renamed entity shall be an exception.
address@hidden
+
address@hidden
+An @nt{exception_renaming_declaration} declares a new view
address@hidden the renamed exception}.
address@hidden
+
address@hidden
address@hidden@address@hidden of renaming an exception:}
address@hidden
+EOF : @key[exception] @key[renames] Ada.IO_Exceptions.End_Error; @RI{-- see 
@RefSecNum{Exceptions in Input-Output}}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in an
+  @nt{exception_renaming_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
address@hidden Renaming Declarations}
+
address@hidden
address@hidden @nt{package_renaming_declaration} is used to rename a package.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<package_renaming_declaration>,rhs="@key{package} 
@Syn2{defining_program_unit_name} @key{renames} 
@address@hidden@Chg{Version=[3],New=<
+   address@hidden>,Old=[]};"}
address@hidden
+
address@hidden
+The renamed entity shall be a package.
+
address@hidden,Kind=[Added],ARef=[AI95-00217-06],ARef=[AI95-00412-01]}
address@hidden,Text=[If the @address@hidden of a
address@hidden denotes a limited view of a package @i{P},
+then a name that denotes the @nt{package_renaming_declaration} shall occur
+only within the immediate scope of the renaming or the scope of a
address@hidden that mentions the package @i{P} or, if @i{P} is a nested
+package, the innermost library package enclosing @i{P}.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[The use of a renaming that designates a limited
+  view is restricted to locations where we know whether the view is limited
+  or nonlimited (based on a @nt{with_clause}). We don't want to make an
+  implicit limited view, as those are not transitive like a regular view.
+  Implementations should be able to see all limited views needed based on the
+  @nt{context_clause}.]}
address@hidden
address@hidden
+
address@hidden
+A @nt{package_renaming_declaration} declares a new view
address@hidden the renamed package}.
+
address@hidden,Kind=[Added],ARef=[AI95-00412-01]}
address@hidden,address@hidden places where the declaration of the
+limited view of the renamed package is visible, a @nt{name} that denotes the
address@hidden denotes a limited view of the package (see
address@hidden Units - Library Units}).]]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[This rule is found in @RefSec{Visibility}.]}
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of renaming a package:}
address@hidden
address@hidden TM @key[renames] Table_Manager;
address@hidden
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00217-06],ARef=[AI95-00412-01]}
+  @ChgAdded{Version=[2],Text=[Uses of renamed limited views of packages can
+  only be used within the scope of a with_clause for the renamed package.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a
+  @nt{package_renaming_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Renaming Declarations}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+A @nt{subprogram_renaming_declaration} can serve as the completion of
+a @nt{subprogram_declaration};
address@hidden
+such a @nt{renaming_declaration} is called a @i{renaming-as-body}.
address@hidden
+A @nt{subprogram_renaming_declaration} that is not a completion is
+called a @address@hidden,
+and is used to rename a subprogram
+(possibly an enumeration literal) or an entry].
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+A renaming-as-body is a declaration,
+as defined in @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden and Types}.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00218-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<subprogram_renaming_declaration>,rhs="@Chg{Version=[2],New=<
+    address@hidden
+    >,Old=<>address@hidden @key{renames} @address@hidden@Chg{Version=[3],New=<
+        address@hidden>,Old=[]};"}
address@hidden
+
address@hidden
address@hidden profile],
+  Sec=(subprogram_renaming_declaration)}
+The expected profile for the @i(callable_entity_)@nt<name>
+is the profile given in the @nt<subprogram_specification>.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0239-1]}
+The profile of a renaming-as-declaration
+shall be @Chg{Version=[3],New=[mode conformant],Old=[mode-conformant]},
+ with that of the renamed callable entity.
address@hidden conformance],Sec=(required)}
+
address@hidden,Kind=[Added],ARef=[AI95-00423-01]}
address@hidden,Type=[Leading],Text=[For a parameter or result subtype of
+the @nt{subprogram_specification} that has an explicit @nt{null_exclusion}:]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[if the @address@hidden
+  denotes a generic formal subprogram of
+  a generic unit @i{G}, and the @nt{subprogram_renaming_declaration} occurs
+  within the body of a generic unit @i{G} or within the body of a generic unit
+  declared within the declarative region of the generic unit @i{G}, then the
+  corresponding parameter or result subtype of the formal subprogram of @i{G}
+  shall have a @nt{null_exclusion};]}
+
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[otherwise, the subtype of the corresponding
+  parameter or result type of the renamed callable entity shall exclude null.
+  @PDefn{generic contract issue}
+  In addition to the places where @LegalityTitle normally apply
+  (see @RefSecNum{Generic Instantiation}),
+  this rule applies also in the private part of an
+  instance of a generic unit.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[This rule prevents
+  @lquotes@;address@hidden
+  @b<Null> must never be the value of a parameter or result with an explicit
+  @nt{null_exclusion}. The first bullet is an assume-the-worst rule
+  which prevents trouble in generic bodies (including bodies of child
+  units) when the formal subtype excludes null implicitly.]}
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0027],Ref=[8652/0028],ARef=[AI95-00135-01],ARef=[AI95-00145-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0239-1]}
+The profile of a renaming-as-body
address@hidden,Old=[shall be subtype-conformant with that of the renamed
+callable entity, and ]}shall conform fully to that of the declaration it
+completes.
address@hidden conformance],Sec=(required)}
+If the renaming-as-body completes that declaration
+before the subprogram it declares is frozen,
address@hidden profile shall be @Chg{Version=[3],New=[mode 
conformant],Old=[mode-conformant]}
address@hidden conformance],Sec=(required)}with that of the renamed
+callable entity and ],Old=[]}the subprogram it declares
+takes its convention from the renamed subprogram;
address@hidden, the profile shall be @Chg{Version=[3],New=[subtype 
conformant],Old=[subtype-conformant]}
+with that of the
+renamed callable entity and],Old=[]} the convention of the renamed subprogram
+shall not be Intrinsic.
address@hidden conformance],Sec=(required)}
address@hidden renaming-as-body is illegal if the declaration occurs before the
+subprogram whose declaration it completes is frozen, and the renaming renames
+the subprogram itself, through one or more subprogram renaming declarations,
+none of whose subprograms has been frozen.],Old=[]}
address@hidden
address@hidden,Kind=[Revised]}
+The @Chg{New=[otherwise part of the second sentence],Old=[first part of the 
first sentence]}
+is to allow an implementation of a renaming-as-body
+as a single jump instruction to the target subprogram.
+Among other things, this prevents a subprogram from being completed with
+a renaming of an entry.
+(In most cases, the target of the jump can be filled in at link time.
+In some cases, such as a renaming of a name like "A(I)address@hidden", an 
indirect
+jump is needed. Note that the name is evaluated at renaming time, not at
+call time.)
+
address@hidden,Kind=[Added],Ref=[8652/0028],ARef=[AI95-00145-01]}
address@hidden first part of the second sentence is intended to allow
+renaming-as-body of predefined operators before the @nt{subprogram_declaration}
+is frozen. For some types (such as integer types), the parameter type for
+operators is the base type, and it would be very strange address@hidden
address@hidden@ @ @ @key{function} Equal (A, B : @key{in} T) @key{return} 
Boolean;address@hidden
address@hidden@ @ @ @key{function} Equal (A, B : @key{in} T) @key{return} 
Boolean @key{renames} "=";address@hidden
+to be illegal. (Note that predefined operators cannot be renamed this way
+after the @nt{subprogram_declaration} is frozen, as they have convention
+Intrinsic.)],Old=[]}
+
address@hidden,Kind=[Revised]}
+The @Chg{New=[],Old=[second part of the ]}first sentence is
+the normal rule for completions of @nt{subprogram_declaration}s.
address@hidden
address@hidden
+An @nt{entry_declaration}, unlike a @nt{subprogram_declaration},
+cannot be completed with a @address@hidden
+Nor can a @address@hidden@!declaration}.
+
+The syntax rules prevent a protected subprogram declaration from being
+completed by a renaming.
+This is fortunate, because it allows us to avoid worrying about whether
+the implicit protected object parameter of a protected operation is
+involved in the conformance rules.
address@hidden
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0027],ARef=[AI95-00135-01]}
address@hidden,Text=[Circular renames before freezing is illegal, as the 
compiler
+would not be able to determine the convention of the subprogram. Other
+circular renames are handled below; see @BoundedTitle.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00228-01]}
address@hidden,Text=[The @address@hidden of a renaming
+shall not denote a subprogram that requires overriding
+(see @RefSecNum{Abstract Types and Subprograms}).]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00228-01]}
address@hidden,Text=[Such a rename cannot be of the inherited subprogram
+(which requires overriding because it cannot be called),
+and thus cannot squirrel away a subprogram (see below). That would be
+confusing, so we make it illegal. The renaming is allowed after the
+overriding, as then the @nt{name} will denote the overriding subprogram,
+not the inherited one.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00228-01]}
address@hidden,Text=[The @address@hidden of a
+renaming-as-body shall not denote an abstract subprogram.]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00228-01]}
address@hidden,Text=[Such a subprogram has no body, so it hardly
+can replace one in the program.]}
address@hidden
+
+A @nt{name} that denotes a formal parameter
+of the @nt{subprogram_specification}
+is not allowed within the @address@hidden
address@hidden
address@hidden@keepnext@;This is to prevent things like this:
address@hidden
address@hidden F(X : Integer) @key[return] Integer @key[renames] 
Table(X)address@hidden;
address@hidden
+
address@hidden
address@hidden@;A similar rule in @RefSecNum{Subprogram Declarations}
+forbids things like this:
address@hidden
address@hidden
address@hidden F(X : Integer; Y : Integer := X) @key[return] Integer;
address@hidden
address@hidden
address@hidden
+
address@hidden
+A renaming-as-declaration
+declares a new view of the renamed entity.
+The profile of this new view takes its subtypes, parameter modes,
+and calling convention from the original profile of the
+callable entity, while taking the formal parameter
address@hidden and @nt{default_expression}s from the profile given in the
address@hidden
+The new view is a function or procedure, never an entry.
address@hidden
+When renaming an entry as a procedure,
+the compile-time rules apply as if the new view is a procedure,
+but the run-time semantics of a call are that of an entry call.
address@hidden
address@hidden
+For example, it is illegal for the @nt{entry_call_statement} of a
address@hidden to call the new view.
+But what looks like a procedure call will do things like barrier
+waiting.
+
address@hidden,Kind=[Added],Ref=[8652/0105],ARef=[AI95-00211-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00228-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0095-1]}
address@hidden properties of the renamed entity are inherited by the new view
+unless otherwise stated by this International Standard. In particular, if the
+renamed entity is address@hidden,New=[],Old=[ or requires
+overriding (see @RefSecNum{Abstract Types and Subprograms})]}, the new view
+also is address@hidden,New=[.],Old=[ or requires overriding. (The
+renaming will often be illegal in these cases,
+as a renaming cannot be overridden.)]}],Old=[]}
address@hidden,Text=[Similarly, if the renamed entity is not a program
+unit, then neither is the renaming. (Implicitly declared subprograms are not
+program units, see @RefSecNum{Separate Compilation}).]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0014],ARef=[AI95-00064-01]}
address@hidden a call to a subprogram whose body is given as a renaming-as-body,
+the execution of the renaming-as-body is equivalent to the execution of a
address@hidden that simply calls the renamed subprogram with its formal
+parameters as the actual parameters and, if it is a function, returns the
+value of the call.],Old=[]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[This implies that the subprogram completed by the
+renaming-as-body has its own elaboration check.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0123-1]}
+For a call on a renaming of a dispatching subprogram that is overridden,
+if the overriding occurred before the renaming, then the body executed
+is that of the overriding declaration,
+even if the overriding declaration is not visible at the place of the renaming;
+otherwise, the inherited or predefined subprogram is
address@hidden,New=[ A corresponding rule applies to a call on a
+renaming of a predefined equality operator for an untagged record 
type.],Old=[]}
address@hidden
+Note that whether or not the renaming is itself primitive has
+nothing to do with the renamed subprogram.
+
address@hidden,Kind=[Revised],ARef=[AI05-0123-1]}
+Note that the above rule is only for tagged address@hidden,New=[ and
+equality of untagged record types],Old=[]}.
+
address@hidden@keepnext@;Consider the following example:
address@hidden
address@hidden P @key[is]
+    @key[type] T @key[is] @key[tagged] @key[null] @key[record];
+    @key[function] Predefined_Equal(X, Y : T) @key[return] Boolean 
@key[renames] "=";
address@hidden
+    @key[function] "="(X, Y : T) @key[return] Boolean; address@hidden Override 
predefined "=".}
address@hidden P;
+
address@hidden P; @key[use] P;
address@hidden Q @key[is]
+    @key[function] User_Defined_Equal(X, Y : T) @key[return] Boolean 
@key[renames] P."=";
address@hidden Q;
address@hidden
+
+A call on Predefined_Equal will execute the predefined equality operator
+of T, whereas a call on User_Defined_Equal will execute the body of the
+overriding declaration in the private part of P.
+
+Thus a renaming allows one to squirrel away a copy of an inherited or
+predefined subprogram before later overriding address@hidden away}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0027],ARef=[AI95-00135-01]}
address@hidden,address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,Sec=(raised by failure of run-time check)}
+If a subprogram directly or indirectly renames itself, then it is a bounded
+error to call that subprogram. Possible consequences are that Program_Error or
+Storage_Error is raised, or that the call results in infinite recursion.]}
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0027],ARef=[AI95-00135-01]}
address@hidden,Text=[This has to be a bounded error, as it is possible
+for a renaming-as-body appearing in a package body to cause this problem.
+Thus it is not possible in general to detect this problem at compile time.]}
address@hidden
address@hidden
+
address@hidden
+A procedure can only be renamed as a procedure.
+A function whose @nt{defining_designator} is either an
address@hidden or an @nt{operator_symbol}
+can be renamed with either an
address@hidden or an @nt{operator_symbol};
+for renaming as an operator, the subprogram specification given in
+the @nt{renaming_declaration} is subject to the rules given in
address@hidden of Operators}
+for operator declarations. Enumeration literals can be
+renamed as functions; similarly, @nt{attribute_reference}s that
+denote functions (such as references to Succ and Pred) can be renamed
+as functions. An entry can only be renamed as a procedure; the new
address@hidden is only allowed to appear in contexts that allow a
+procedure @nt{name}. An entry of a family can be renamed, but an
+entry family cannot be renamed as a whole.
+
+
+The operators of the root numeric types cannot be renamed because the
+types in the profile are anonymous, so the corresponding specifications
+cannot be written; the same holds for certain attributes, such as Pos.
+
+
+Calls with the new @nt{name} of a renamed entry are
address@hidden and are not allowed at places
+where the syntax requires an @nt{entry_call_statement} in
address@hidden and @nt{timed_entry_call}s,
+nor in an @nt{asynchronous_select}; similarly, the Count
+attribute is not available for the new @nt{name}.
+
+The primitiveness of a renaming-as-declaration is determined by its
+profile, and by where it occurs, as for any declaration of
+(a view of) a subprogram;
+primitiveness is not determined by the renamed view.
+In order to perform a dispatching call,
+the subprogram name has to denote a primitive subprogram,
+not a nonprimitive renaming of a primitive subprogram.
address@hidden
+A @nt{subprogram_renaming_declaration} could more properly be called
address@hidden@address@hidden@!declaration}, since you're renaming something
+as a subprogram, but you're not necessarily renaming a subprogram.
+But that's too much of a mouthful. Or, alternatively, we could call it a
address@hidden@address@hidden@!declaration}, but that's even worse.
+Not only is it a mouthful, it emphasizes the entity being renamed,
+rather than the new view, which we think is a bad idea.
+We'll live with the oddity.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of subprogram renaming declarations:}
address@hidden
address@hidden My_Write(C : @key[in] Character) @key[renames] Pool(K).Write; 
address@hidden  see @RefSecNum{Selected Components}}
+
address@hidden Real_Plus(Left, Right : Real   ) @key[return] Real    
@key[renames] "+";
address@hidden Int_Plus (Left, Right : Integer) @key[return] Integer 
@key[renames] "+";
+
address@hidden Rouge @key[return] Color @key[renames] Red;  address@hidden  see 
@RefSecNum{Enumeration Types}}
address@hidden Rot   @key[return] Color @key[renames] Red;
address@hidden Rosso @key[return] Color @key[renames] Rouge;
+
address@hidden Next(X : Color) @key[return] Color @key[renames] Color'Succ; 
address@hidden see @RefSecNum{Enumeration Types}}
address@hidden
+
address@hidden
address@hidden@address@hidden of a subprogram renaming declaration with new 
parameter names:}
address@hidden
address@hidden
address@hidden "*" (X,Y : Vector) @key[return] Real @key[renames] Dot_Product; 
address@hidden see @RefSecNum{Subprogram Declarations}}
address@hidden
+
address@hidden
address@hidden@address@hidden of a subprogram renaming declaration with a new 
default expression:}
address@hidden
address@hidden
address@hidden Minimum(L : Link := Head) @key[return] Cell @key[renames] 
Min_Cell; address@hidden see @RefSecNum{Subprogram Declarations}}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0028],ARef=[AI95-00145-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b<Corrigendum:> Allowed a renaming-as-body to be just
+  mode conformant with the specification if the subprogram is not yet frozen.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00218-03]}
+  @ChgAdded{Version=[2],address@hidden (see
+  @RefSecNum{Overriding Indicators}) is
+  optionally added to subprogram renamings.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0014],ARef=[AI95-00064-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Described the semantics of
+  renaming-as-body, so that the location of elaboration checks is clear.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0027],ARef=[AI95-00135-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that circular
+  renaming-as-body is illegal (if it can be detected in time) or a
+  bounded error.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00228-01]}
+  @ChgAdded{Version=[2],address@hidden Correction:] Clarified that
+  renaming a shall-be-overridden
+  subprogram is illegal, as well as renaming-as-body an abstract subprogram.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00423-01]}
+  @ChgAdded{Version=[2],Text=[Added matching rules for @nt{null_exclusion}s.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0123-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  Renaming of user-defined untagged record equality is now defined to call the
+  overridden body so long as the overriding occurred before the renames.
+  This could change the body called in unusual cases; the change is necessary
+  to preserve the principle that the body called for an explicit call to
+  "=" (via a renames in this case) is the same as the one inherited for a
+  derived type and used in generics. Note that any renamings before the
+  overriding will be unchanged. Any differences caused by the change will be
+  rare and most likely will fix a bug.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a
+  @nt{subprogram_renaming_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
address@hidden@Comment{For ISO version of Ada 2012 Standard}
address@hidden Renaming Declarations}
+
address@hidden
address@hidden @nt{generic_renaming_declaration} is used to rename a generic 
unit.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden, lhs=<generic_renaming_declaration>,rhs="
+    @key{generic address@hidden@Syn2{defining_program_unit_name} @key{renames} 
@address@hidden@Chg{Version=[3],New=<
+        address@hidden>,Old=[]};
+  | @key{generic address@hidden@Syn2{defining_program_unit_name} @key{renames} 
@address@hidden@Chg{Version=[3],New=<
+        address@hidden>,Old=[]};
+  | @key{generic address@hidden@Syn2{defining_program_unit_name} @key{renames} 
@address@hidden@Chg{Version=[3],New=<
+        address@hidden>,Old=[]};"}
address@hidden
+
address@hidden
+The renamed entity shall be a generic unit of the corresponding kind.
address@hidden
+
address@hidden
+A @nt{generic_renaming_declaration} declares a new view
address@hidden the renamed generic unit}.
address@hidden
+
address@hidden
+Although the properties of the new view are the same as those of the
+renamed view, the place where the @nt<generic_renaming_declaration> occurs
+may affect the legality of subsequent renamings and instantiations
+that denote the @nt<generic_renaming_declaration>,
+in particular if the renamed generic unit is a library unit
+(see @RefSecNum{Compilation Units - Library Units}).
address@hidden
+
address@hidden
address@hidden@address@hidden of renaming a generic unit:}
address@hidden
address@hidden package] Enum_IO @key[renames] Ada.Text_IO.Enumeration_IO;  
@RI{-- see @RefSecNum{Input-Output for Enumeration Types}}
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Renaming of generic units is new to Ada 95.
+It is particularly important for renaming child library
+units that are generic units. For example, it might
+be used to rename Numerics.Generic_Elementary_Functions as simply
+Generic_Elementary_Functions, to match the name for
+the corresponding Ada-83-based package.
address@hidden
+
address@hidden
+The information in RM83-8.6, @lquotes@;The Package Standard,@rquotes@;
+has been updated for the child unit feature,
+and moved to @RefSecNum{Predefined Language Environment},
+except for the definition of @lquotes@;predefined type,@rquotes@;
+which has been moved to @RefSecNum{Type Declarations}.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a
+  @nt{generic_renaming_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
address@hidden Context of Overload Resolution}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden@Defn{overload resolution}
+Because declarations can be overloaded,
+it is possible for an occurrence of a usage name
+to have more than one possible interpretation;
+in most cases, ambiguity is disallowed.
+This @Chg{Version=[3],New=[subclause],Old=[clause]} describes
+how the possible interpretations resolve
+to the actual interpretation.
+
address@hidden rules}
+Certain rules of the language (the @ResolutionTitle)
+are considered @lquotes@;overloading address@hidden@;.
+If a possible interpretation violates an overloading rule,
+it is assumed not to be the intended interpretation;
+some other possible interpretation
+is assumed to be the actual interpretation.
+On the other hand,
+violations of nonoverloading rules do not affect which
+interpretation is chosen; instead,
+they cause the construct to be illegal.
+To be legal, there usually has to be exactly one acceptable
+interpretation of a construct that is a @lquotes@;complete address@hidden@;,
+not counting any nested complete contexts.
+
address@hidden,Sec=(resolution of ambiguity)}
+The syntax rules of the language and the visibility rules
+given in @RefSecNum{Visibility}
+determine the possible interpretations.
+Most type checking rules
+(rules that require a particular type,
+or a particular class of types,
+for example)
+are overloading rules.
+Various rules for the matching of formal and actual parameters are
+overloading rules.]
address@hidden
+
address@hidden
+The type resolution rules are
+intended to minimize the need for implicit declarations
+and preference rules associated with implicit conversion and dispatching
+operations.
address@hidden
+
address@hidden
address@hidden@Defn{complete context}
address@hidden resolution is applied separately to each
address@hidden context},
+not counting inner complete contexts.}
+Each of the following constructs is a @i{complete context}:
address@hidden
+A @nt{context_item}.
+
+A @nt{declarative_item} or declaration.
address@hidden
+A @nt{loop_parameter_specification} is a declaration,
+and hence a complete context.
address@hidden
+
+A @nt{statement}.
+
+A @nt{pragma_argument_association}.
address@hidden
+  We would make it the whole @nt{pragma},
+  except that certain pragma arguments are allowed to be ambiguous,
+  and ambiguity applies to a complete context.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI12-0040-1]}
+The @Chg{Version=[4],address@hidden@nt{expression}],address@hidden
+of a @address@hidden,New=[ or @nt{case_expression}],Old=[]}.
address@hidden
+  This means that the @nt{expression} is resolved without looking
+  at the choices.
address@hidden
address@hidden
+
address@hidden@Defn2{Term=[interpretation], Sec=(of a complete context)}
address@hidden interpretation], Sec=(of a complete context)}
+An (overall) @i{interpretation} of a complete context
+embodies its meaning, and includes
+the following information about the constituents of the complete
+context,
+not including constituents of inner complete contexts:
address@hidden
+for each constituent of the complete context,
+to which syntactic categories it belongs,
+and by which syntax rules; and
address@hidden
+Syntactic address@hidden is plural here,
+because there are lots of trivial productions @em
+an @nt{expression} might also be all of the following,
+in this order: @nt{identifier},
address@hidden,
address@hidden,
address@hidden,
address@hidden,
address@hidden, and
address@hidden
+Basically, we're trying to capture all the information in the parse tree
+here, without using compiler-writer's jargon like @lquotes@;parse 
address@hidden@;.
address@hidden
+
+for each usage name, which declaration it denotes
+(and, therefore, which view and which entity it denotes); and
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00382-01]}
+In most cases, a usage name denotes the view declared by the denoted
+declaration.
+However, in certain cases, a usage name that denotes a declaration and
+appears inside the declarative region of that same declaration, denotes
+the current instance of the declaration.
+For example, within a @address@hidden,New=[ other than in
+an @nt{access_definition}],Old=[]}, a usage name that denotes the
address@hidden denotes the object containing the
+currently executing task,
+and not the task type declared by the declaration.
address@hidden
+
+for a complete context that is a @nt{declarative_item},
+whether or not it is a completion of a declaration,
+and (if so) which declaration it completes.
address@hidden
address@hidden
+Unfortunately, we are not confident that the above list is complete.
+We'll have to live with that.
address@hidden
address@hidden
+For @lquotes@;address@hidden@; interpretations, the above information is 
tentative.
address@hidden
address@hidden
+A possible interpretation (an @i{input} to overload
+resolution) contains information about what a
+usage name @i{might} denote, but what it actually @i{does} denote
+requires overload resolution to determine.
+Hence the term @lquotes@;address@hidden@; is needed for possible 
interpretations;
+otherwise, the definition would be circular.
address@hidden
+
address@hidden interpretation}
+A @i{possible interpretation} is one
+that obeys the syntax rules and the visibility rules.
address@hidden interpretation}
address@hidden,Sec=(overload resolution)}
address@hidden,Sec=(overload resolution)}
+An @i{acceptable interpretation} is a possible interpretation that
+obeys the @i{overloading address@hidden,
+that is, those rules that specify an expected type or
+expected profile, or specify how a construct shall @i(resolve)
+or be @i(interpreted).}
address@hidden
+One rule that falls into this category,
+but does not use the above-mentioned magic words,
+is the rule about numbers of parameter associations in a call
+(see @RefSecNum{Subprogram Calls}).
address@hidden
address@hidden
+The @ResolutionName@;s are the ones that appear under the
address@hidden heading.
+Some @SyntaxName@;s are written in English, instead of BNF.
+No rule is a @SyntaxName or @ResolutionName unless it appears under the
+appropriate heading.
address@hidden
+
address@hidden, Sec=(of a constituent of a complete context)}
+The @i{interpretation} of a constituent of a complete context is
+determined from the overall interpretation of the complete context as a
+whole.
address@hidden,
+for example, @lquotes@;interpreted as a @nt{function_call},@rquotes@;
+means that the construct's interpretation says that it belongs
+to the syntactic category @nt{function_call}.}
+
address@hidden@Defn{denote}
address@hidden occurrence of]
+a usage name @i{denotes} the declaration determined by its
+interpretation.
+It also denotes the view declared by its denoted
+declaration, except in the following cases:
address@hidden
+As explained below, a pragma argument is allowed to be ambiguous,
+so it can denote several declarations,
+and all of the views declared by those declarations.
address@hidden
address@hidden(itemize)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00382-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0287-1]}
+  @Defn2{Term=[current instance], Sec=(of a type)}
+  If a usage name appears within the declarative region of a
+  @nt{type_declaration} and denotes that same @nt{type_declaration},
+  then it denotes the @i{current instance} of the type (rather than
+  the type itself)@Chg{Version=[2],New=[; the],Old=[. The]} current
+  instance of a type is the object or value
+  of the type that is associated with the execution that
+  evaluates the usage address@hidden,New=[ @Chg{Version=[3],
+  New=[ Similarly, if a usage name appears within the declarative region
+  of a @nt{subtype_declaration} and denotes that same @nt{subtype_declaration},
+  then it denotes the current instance of the subtype. These rules do],
+  Old=[This rule does]} not apply if the usage name appears within the 
@nt{subtype_mark} of an
+  @nt{access_definition} for an access-to-object type, or within the subtype
+  of a parameter or result of an access-to-subprogram type.],Old=[]}
+  @begin{Reason}
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00382-01]}
+  This is needed, for example, for references to the Access attribute
+  from within the @nt{type_declaration}.
+  Also, within a @nt{task_body} or @nt{protected_body},
+  we need to be able to denote the current task or protected object.
+  (For a @nt{single_task_declaration} or
+  @nt{single_protected_declaration}, the rule about current instances
+  is not needed.)@Chg{Version=[2],New=[ We exclude anonymous access types
+  so that they can be used to create self-referencing types in the natural
+  manner (otherwise such types would be illegal).],Old=[]}
+  @end{Reason}
+  @begin{Discussion}
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00382-01]}
+  @ChgAdded{Version=[2],Text=[The phrase @lquotes@;within the @address@hidden@;
+  in the @lquotes@;this rule does not address@hidden@; part is intended to 
cover
+  a case like @key{access} T'Class appearing within the declarative region of
+  T: here T denotes the type, not the current instance.]}
+  @end{Discussion}
+
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0068-1]}
+  @ChgAdded{Version=[4],NoPrefix=[T],Text=[Within an @nt{aspect_specification}
+  for a type or subtype, the current instance represents a value of the type;
+  it is not an object. The nominal subtype of this value is given by the
+  subtype itself (the first subtype in the case of a @nt{type_declaration}),
+  prior to applying any predicate specified directly on the type or subtype. If
+  the type or subtype is by-reference, the associated object with the value
+  is the object associated (see @RefSecNum{Formal Parameter Modes}) with the
+  execution of the usage name.]}
+
+  @begin{Ramification}
+    @ChgRef{Version=[4],Kind=[AddedNormal]}
+    @ChgAdded{Version=[4],Text=[For the purposes of @LegalityTitle, the current
+    instance acts as a value within an @nt{aspect_specification}. It might
+    really be an object (and has to be for a by-reference type), but
+    that isn't discoverable by direct use of the name of the current 
instance.]}
+  @end{Ramification}
+
+  @Defn2{Term=[current instance], Sec=(of a generic unit)}
+  If a usage name appears within the declarative region of a
+  @nt{generic_declaration} (but not within its @nt{generic_formal_part})
+  and it denotes that same @nt{generic_declaration}, then it
+  denotes the @i{current instance} of the generic unit (rather than
+  the generic unit itself).
+  See also @RefSecNum{Generic Instantiation}.
+  @begin{Honest}
+    The current instance of a generic unit is the instance created
+    by whichever @nt{generic_instantiation} is of interest at any
+    given time.
+  @end{Honest}
+  @begin{Ramification}
+    Within a @nt{generic_formal_part}, a @nt{name} that denotes the
+    @nt{generic_declaration} denotes the generic unit,
+    which implies that it is not overloadable.
+  @end{Ramification}
address@hidden(itemize)
+
+A usage name that denotes a view also denotes the entity of that view.
address@hidden
+Usually, a usage name denotes only one declaration,
+and therefore one view and one entity.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01]}
address@hidden@RootDefn[expected type]
+The @i(expected type) for a given @nt<expression>, @nt<name>,
+or other construct determines, according to the @i{type resolution
+rules} given below, the types considered for the construct during
+overload resolution.
address@hidden resolution rules}
address@hidden
+The type resolution rules provide support for class-wide programming,
+universal @Chg{Version=[2],New=[],Old=[numeric ]}literals, dispatching
+operations, and anonymous access types:]
address@hidden
+  Expected types are defined throughout the RM95.
+  The most important definition is that, for a
+  subprogram, the expected type for the
+  actual parameter is the type of the formal parameter.
+
+  The type resolution rules are trivial unless either the
+  actual or expected type is universal, class-wide, or of
+  an anonymous access type.
address@hidden
address@hidden
address@hidden resolution rules],
+  Sec=(if any type in a specified class of types is expected)}
address@hidden resolution rules],
+  Sec=(if expected type is universal or class-wide)}
+If a construct is expected to be of any type in a class of types,
+or of the universal or class-wide type for a class,
+then the type of the construct shall resolve to a type in that class
+or to a universal type that covers the class.
address@hidden
+This matching rule handles (among other things) cases like the
+Val attribute, which denotes a function that takes a parameter of type
address@hidden(universal_integer).
+
address@hidden,address@hidden AI-00021 - Quoted text doesn't match}
+The last part of the rule,
address@hidden@;or to a universal type that @Chg{New=[covers],Old=[includes]} 
the
address@hidden implies that if the expected type for an expression is
address@hidden, then an expression whose type is @i{universal_real}
+(such as a real literal) is OK.
address@hidden
+
address@hidden@PDefn2{Term=[type resolution rules],
+  Sec=(if expected type is specific)}
+If the expected type for a construct is a specific type @i(T), then the type
+of the construct shall resolve either to @i(T), or:
address@hidden
address@hidden effect}
+This rule is @i{not} intended to create a preference for the specific
+type @em such a preference would cause Beaujolais effects.
address@hidden
address@hidden(Inneritemize)
+    to @i(T)'Class; or
address@hidden
+      This will only be legal as part of a call on a dispatching operation;
+      see @RefSec(Dispatching Operations of Tagged Types).
+      Note that that rule is not a @ResolutionName.
address@hidden
+
+    to a universal type that covers @i(T); or
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01],ARef=[AI95-00231-01],ARef=[AI95-00254-01],ARef=[AI95-00409-01]}
+    when @i(T) is @Chg{Version=[2],New=[a specific],Old=[an]} anonymous
+    address@hidden,New=[-to-object],Old=[]} type
+    (see @RefSecNum{Access Types}) with designated type @i(D),
+    to an address@hidden,New=[object],Old=[variable]} type
+    whose designated type is @i(D)'Class or is covered by
+    @i(D)@Chg{Version=[2],New=[; or],Old=[.]}
+
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00409-01]}
+      @ChgNote{We use Chg here, rather than ChgDeleted so that the prefix is
+      left address@hidden,New=[],Old=[Because it says 
@lquotes@;address@hidden@;
+      instead of @lquotes@;access-to-object,@rquotes@;
+      two subprograms that differ only in that one has a parameter
+      of an access-to-constant type,
+      and the other has an
+      access parameter,
+      are distinguishable during overload resolution.]}
+
+      The case where the actual is address@hidden(D)'Class will only
+      be legal as part of a call on a dispatching operation;
+      see @RefSec(Dispatching Operations of Tagged Types).
+      Note that that rule is not a @ResolutionName.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0149-1]}
address@hidden,Text=[when @i(T) is a named general access-to-object type
+    (see @RefSecNum{Access Types}) with designated type @i(D), to an anonymous
+    access-to-object type whose designated type covers or is covered by @i(D);
+    or]}
+
address@hidden,Kind=[Added],ARef=[AI95-00254-01],ARef=[AI95-00409-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0239-1]}
address@hidden,Text=[when @i(T) is an anonymous access-to-subprogram
+     type (see @RefSecNum{Access Types}), to an access-to-subprogram type
+     whose designated profile is @Chg{Version=[3],New=[type 
conformant],Old=[type-conformant]} with that of @i{T}.]}
+
address@hidden(Inneritemize)
address@hidden
+
+
address@hidden profile]
+In certain contexts,
address@hidden as in a @nt{subprogram_renaming_declaration},]
+the @ResolutionTitle define an @i(expected profile) for a given
address@hidden<name>;
address@hidden resolution rule],
+  Sec=(@nt<name> with a given expected profile)}
+in such cases, the @nt{name}
+shall resolve to the name of a callable entity whose profile is type
+conformant with the expected profile.
address@hidden conformance],Sec=(required)}
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0239-1]}
+  The parameter and result @i{sub}types are not used in overload
+  resolution.
+  Only type conformance of profiles
+  is considered during overload resolution.
+  Legality rules generally require at least @Chg{Version=[3],New=[mode 
conformance],Old=[mode-conformance]}
+  in addition, but those rules are not used in overload resolution.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00332-01]}
address@hidden, Sec=[class expected type]}
+When @Chg{Version=[2],New=[],Old=[the expected type for ]}a construct is
address@hidden,New=[one that requires that its expected type],
+Old=[required to]}
+be a @i<single> type in a given class, the type
address@hidden,New=[of],Old=[expected for]}
+the construct shall be determinable solely
+from the context in which the construct appears,
+excluding the construct itself,
+but using the requirement that it be in the given address@hidden,
+New=[],Old=[; the type of the construct is then this single expected type]}.
+Furthermore, the context shall not be one that expects any type in
+some class that contains types of the given class;
+in particular, the construct shall not be the operand of a
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],address@hidden no longer requires a single type}
+For example, the expected type for @Chg{Version=[2],New=[a string literal],
+Old=[the literal @key{null}]} is required to be a
+single @Chg{Version=[2],New=[string],Old=[access]} type.
+But the expected type for the operand of a @nt{type_conversion} is
+any type.
+Therefore, @Chg{Version=[2],New=[a string literal],
+Old=[the literal @key{null}]} is not allowed as the operand of a
address@hidden
+This is true even if there is only one @Chg{Version=[2],New=[string],
+Old=[access]} type in address@hidden,New=[ (which is never the
+case)],Old=[]}.
+The reason for these rules is so that the compiler will not have to
+search @lquotes@;address@hidden@; to see if there is exactly one type
+in a class in scope.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00332-01]}
+  @ChgAdded{Version=[2],Text=[The first sentence is carefully worded so that it
+  only mentions @lquotes@;expected address@hidden as part of identifying the
+  interesting case, but doesn't require that the context actually provide such
+  an expected type. This allows such constructs to be used inside of constructs
+  that don't provide an expected type (like qualified expressions and renames).
+  Otherwise, such constructs wouldn't allow @nt{aggregate}s, 'Access, and so
+  on.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0102-1],ARef=[AI05-0149-1],ARef=[AI05-0299-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0039-1]}
address@hidden,Text=[Other than for the
address@hidden,address@hidden@nt{simple_expression}],address@hidden
+of a membership test, if the expected type for a @nt{name} or @nt{expression}
+is not the same as the actual type of the @nt{name} or @nt{expression}, the
+actual type shall be convertible to the expected type (see
address@hidden Conversions});@Defn2{Term=[implicit conversion],
address@hidden,Sec=(required)} further, if the
+expected type is a named access-to-object type with designated type @i<D1> and
+the actual type is an anonymous access-to-object type with designated type
address@hidden<D2>, then @i<D1> shall cover @i<D2>, and the @nt{name} or 
@nt{expression}
+shall denote a view with an accessibility level for which the statically deeper
+relationship address@hidden; in particular it shall not denote an access
+parameter nor a stand-alone access object].]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This rule prevents an implicit conversion that
+  would be illegal if it was an explicit conversion. For instance, this
+  prevents assigning an access-to-constant value into a stand-alone anonymous
+  access-to-variable object. It also covers convertibility of the designated
+  type and accessibility checks.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The rule also minimizes cases of implicit
+  conversions when the tag check or the accessibility check might fail. We
+  word it this way because access discriminants should also be disallowed if
+  their enclosing object is designated by an access parameter.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This rule does not apply to expressions that
+  don't have expected types (such as the operand of a qualified expression or
+  the expression of a renames). We don't need a rule like this in those cases,
+  as the type needs to be the same; there is no implicit conversion.]}
address@hidden
+
+A complete context shall have at least one acceptable interpretation;
+if there is exactly one, then that one is chosen.
address@hidden
+This, and the rule below
+about ambiguity, are the ones that suck in all the @SyntaxName@;s and
address@hidden@;s as compile-time rules.
+Note that this and the ambiguity rule have to be @LegalityName@;s.
address@hidden
+
address@hidden, Sec=(for root numeric operators and @nt<range>s)}
+There is a @i{preference} for the primitive operators (and @nt<range>s)
+of the root numeric
+types @i{root_integer} and @i{root_real}.
+In particular,
+if two acceptable interpretations of a constituent of a complete
+context differ only in that one is for a primitive operator (or
address@hidden<range>) of the
+type @i{root_integer} or @i{root_real}, and the other is not,
+the interpretation using the primitive operator (or @nt<range>)
+of the root numeric type is @i{preferred}.
+
address@hidden
address@hidden@;The reason for this preference is so that expressions involving
+literals and named numbers can be unambiguous.
+For example, without the preference rule, the following would be ambiguous:
address@hidden
address@hidden,address@hidden AI-00022}
+N : @key[constant] := 123;
address@hidden N > 100 @key[then] address@hidden Preference for root_integer 
"@Chg{New=[>],Old=[<]}" operator.}
+    ...
address@hidden @key[if];
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0149-1]}
address@hidden,Text=[Similarly,
+there is a preference for the equality operators of the @i{universal_access}
+type (see @RefSecNum{Relational Operators and Membership Tests}). If two
+acceptable interpretations of a constituent of a
+complete context differ only in that one is for an equality operator of the
address@hidden type, and the other is not, the interpretation using the
+equality operator of the @i{universal_access} type is
address@hidden, Sec=(for universal access equality operators)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This preference is necessary because of
+  implicit conversion from an anonymous access type to a named access type,
+  which would allow the equality operator of any named access type to be used
+  to compare anonymous access values (and that way lies madness).]}
address@hidden
+
+For a complete context, if there is exactly one
+overall acceptable interpretation where each constituent's interpretation
+is the same as or preferred (in the
+above sense) over those in all other overall acceptable interpretations, then
+that one overall acceptable interpretation is chosen.
address@hidden
+Otherwise, the complete context is @i{ambiguous}.
+
+A complete context other than a @nt{pragma_argument_association}
+shall not be ambiguous.
+
+A complete context that is a @nt{pragma_argument_association}
+is allowed to be ambiguous (unless otherwise specified
+for the particular pragma),
+but only
+if every acceptable interpretation of the pragma argument is as a
address@hidden that statically denotes a callable entity.
address@hidden,Sec=(name used as a pragma argument)}
+Such a @nt{name} denotes
+all of the declarations determined by its interpretations,
+and all of the views declared by these declarations.
address@hidden
address@hidden,Kind=[Revised],address@hidden is obsolete}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+This applies to Inline, Suppress,
+Import, Export, and Convention @nt{pragma}s.
+For example, it is OK to say @lquotes@;@key[pragma] @Chg{Version=[2],
+New=[Export(C, Entity_Name],Old=[Suppress(Elaboration_Check, On]}
+=> P.Q);@rquotes@;, even if there are two directly visible P's, and
+there are two Q's declared in the visible part of each P.
+In this case, P.Q denotes four different declarations.
+This rule also applies to certain pragmas defined in the
+Specialized Needs Annexes.
+It almost applies to Pure, Elaborate_Body, and Elaborate_All @nt{pragma}s,
+but those can't have overloading for other reasons.
address@hidden,New=[ Note that almost all of
+these pragmas are obsolescent (see @RefSecNum{Specific Suppression of Checks} 
and
address@hidden Pragmas}), and a major reason is that this rule
+has proven to be too broad in practice (it is common to want to specify 
something
+on a single subprogram of an overloaded set, that can't be done easily with 
this
+rule). @nt{Aspect_specification}s,
+which are given on individual declarations, are preferred in Ada 2012.],Old=[]}
+
+Note that if a pragma argument denotes a @i{call} to a callable
+entity, rather than the entity itself,
+this exception does not apply, and ambiguity is disallowed.
+
+Note that we need to carefully define which pragma-related rules are
address@hidden@;s,
+so that, for example, a @nt{pragma} Inline does not pick up
+subprograms declared in enclosing declarative regions,
+and therefore make itself illegal.
+
+We say @lquotes@;statically address@hidden@; in the above rule in order to 
avoid
+having to worry about how many times the @nt{name} is evaluated,
+in case it denotes more than one callable entity.
address@hidden
address@hidden
+
address@hidden
+If a usage name has only one acceptable interpretation,
+then it denotes the corresponding entity.
+However, this does not mean that the usage name is necessarily legal
+since other requirements exist which are not considered for overload
+resolution; for example, the fact that an expression is static, whether
+an object is constant, mode and subtype conformance rules, freezing
+rules, order of elaboration, and so on.
+
address@hidden@;Similarly, subtypes are not considered for overload resolution 
(the
+violation of a constraint does not make a program illegal but raises an
+exception during program execution).
address@hidden
+
address@hidden
address@hidden with Ada 83}
address@hidden effect}
+The new preference rule for operators of root numeric types
+is upward incompatible,
+but only in cases that involved @i(Beaujolais) effects in Ada 83.
+Such cases are ambiguous in Ada 95.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The rule that allows an expected type to match an actual expression of a
+universal type,
+in combination with the new preference rule for operators of root numeric
+types, subsumes the Ada 83 "implicit conversion" rules
+for universal types.
address@hidden
+
address@hidden
+In Ada 83, it is not clear what the @lquotes@;syntax address@hidden@; are.
+AI83-00157 states that a certain textual rule is a syntax rule,
+but it's still not clear how one tells in general which textual rules are
+syntax rules.
+We have solved the problem by stating exactly which
+rules are syntax rules @em the ones that appear under the 
@lquotes@;@address@hidden@;
+heading.
+
+RM83 has a long list of the @lquotes@;address@hidden@; of rules that are to be
+used in overload resolution (in addition to the syntax rules).
+It is not clear exactly which rules fall under each form.
+We have solved the problem by explicitly
+marking all rules that are used in overload resolution.
+Thus, the list of kinds of rules is unnecessary.
+It is replaced with some introductory
+(intentionally vague)
+text explaining the basic idea
+of what sorts of rules are overloading rules.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+It is not clear from RM83 what information is embodied in a 
@lquotes@;address@hidden@;
+or an @lquotes@;address@hidden@;
address@hidden@;address@hidden@; and @lquotes@;address@hidden@; were intended 
to be synonymous;
+we now use the latter only in defining the rules about overload
+resolution.
address@hidden@;address@hidden@; is used only informally.
+This @Chg{Version=[3],New=[subclause],Old=[clause]} attempts to clarify what
+is meant by @lquotes@;address@hidden@;
+
address@hidden@;For example,
+RM83 does not make it clear that overload resolution is required in
+order to match @ntf{subprogram_bodies} with their corresponding
+declarations (and even to tell whether a given @nt{subprogram_body}
+is the completion of a previous declaration).
+Clearly, the information needed to do this is part of the
address@hidden@;address@hidden@; of a @nt{subprogram_body}.
+The resolution of such things is defined in terms of
+the @lquotes@;expected address@hidden@; concept.
+Ada 95 has some new cases where expected profiles
+are needed @em the resolution of P'Access,
+where P might denote a subprogram,
+is an example.
+
address@hidden@NoPrefix@;RM83-8.7(2) might seem to imply that an interpretation
+embodies information about what is denoted by each usage name,
+but not information about which syntactic category each construct belongs to.
+However, it seems necessary to include such information,
+since the Ada grammar is highly ambiguous.
+For example, X(Y) might be a @nt{function_call} or an
address@hidden, and no context-free/syntactic information can
+tell the difference.
+It seems like we should view X(Y) as being, for example, @lquotes@;interpreted 
as a
address@hidden@rquotes@; (if that's what overload resolution decides it is).
+Note that there are examples where the denotation of each usage name
+does not imply the syntactic category.
+However, even if that were not true, it seems that intuitively,
+the interpretation includes that information.
+Here's an example:
address@hidden
address@hidden T;
address@hidden A @key[is] @key[access] T;
address@hidden T @key[is] @key[array](Integer @key[range] 1..10) @key[of] A;
+I : Integer := 3;
address@hidden F(X : Integer := 7) @key[return] A;
+Y : A := F(I); address@hidden Ambiguous? (We hope so.)}
address@hidden
+
address@hidden,address@hidden be consistent with 8652/0006}
address@hidden@;Consider the declaration of Y (a complete context).
+In the above example, overload resolution can easily determine the
+declaration, and therefore the entity,
+denoted by Y, A, F, and I.
+However, given all of that information,
+we still don't know whether F(I) is a @nt{function_call}
+or an @nt{indexed_component} whose @address@hidden,Old=[prefix]} is
+a @nt{function_call}.
+(In the latter case, it is equivalent to F(7)address@hidden(I).)
+
address@hidden@;It seems clear that the declaration of Y ought to be considered
+ambiguous.
+We describe that by saying that there are two interpretations,
+one as a @nt{function_call}, and one as an @nt{indexed_component}.
+These interpretations are both acceptable to the overloading
+rules.
+Therefore, the complete context is ambiguous, and therefore illegal.
+
address@hidden effect}
+It is the intent that the Ada 95 preference rule for root numeric
+operators is more locally enforceable than that of RM83-4.6(15).
+It should also eliminate interpretation shifts due to the
+addition or removal of a @nt{use_clause}
+(the so called @i{Beaujolais} effect).
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+RM83-8.7 seems to be missing some complete contexts,
+such as @nt{pragma_argument_association}s,
address@hidden that are not
+declarations or @Chg{Version=[2],address@hidden,
address@hidden,
+and @nt{context_item}s.
+We have added these, and also replaced the @lquotes@;must be address@hidden@;
+wording of RM83-5.4(3) with the notion that the expression of a
address@hidden is a complete context.
+
+Cases like the Val attribute are now handled using the normal type
+resolution rules, instead of having special cases that explicitly allow
+things like @lquotes@;any integer address@hidden@;
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00409-01]}
+  @ChgAdded{Version=[2],Type=[Leading],address@hidden with Ada 95}
+  Ada 95 allowed name resolution to distinguish between anonymous
+  access-to-variable and access-to-constant types. This is similar to
+  distinguishing between subprograms with @key{in} and @key{in out} parameters,
+  which is known to be bad. Thus, that part of the rule was dropped as we now
+  have anonymous access-to-constant types, making this much more likely.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Cacc @key{is access constant} Integer;
address@hidden Proc (Acc : @key{access} Integer) ...
address@hidden Proc (Acc : Cacc) ...
+List : Cacc := ...;
+Proc (List); -- @RI[OK in Ada 95, ambiguous in Ada 2005.]]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If there is any code like this (such code should
+  be rare), it will be ambiguous in Ada 2005.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01],ARef=[AI95-00231-01],ARef=[AI95-00254-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Generalized the anonymous access resolution rules to support the new
+  capabilities of anonymous access types (that is, access-to-subprogram and
+  access-to-constant).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00382-01]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[We now allow the creation of
+  self-referencing types via anonymous access types. This is an extension
+  in unusual cases involving task and protected types. For example:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden type} T;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden body} T @key{is}
+   @key{procedure} P (X : @key{access} T) @key{is} -- @RI[Illegal in Ada 95, 
legal in Ada 2005]
+      ...
+   @key{end} P;
address@hidden
+   ...
address@hidden T;]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00332-01]}
+  @ChgAdded{Version=[2],Text=[Corrected the @lquotes@;single expected
+  address@hidden@; so that it works in contexts that don't have expected types
+  (like object renames and qualified expressions). This fixes a hole in Ada 95
+  that appears to prohibit using @nt{aggregate}s, 'Access, character literals,
+  string literals, and @nt{allocator}s in qualified expressions.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0149-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}Implicit
+  conversion is now allowed from anonymous access-to-object types to
+  general access-to-object types. Such conversions can make calls ambiguous.
+  That can only happen when there are two visible subprograms with the same 
name
+  and have profiles that differ only by a parameter that is of a named or
+  anonymous access type, and the actual argument is of an anonymous access 
type.
+  This should be rare, as many possible calls would be ambiguous even in Ada
+  2005 (including @nt{allocator}s and any actual of a named access type if the
+  designated types are the same).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0149-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Implicit conversion
+  is allowed from anonymous access-to-object types to general access-to-object
+  types if the designated type is convertible and runtime checks are minimized.
+  See also the incompatibilities section.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0102-1]}
+  @ChgAdded{Version=[3],Text=[Added a requirement
+  here that implicit conversions are convertible to the appropriate type.
+  This rule was scattered about the Standard, we moved a single generalized
+  version here.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0068-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Added a rule to specify that the current instance of a type or subtype is
+  a value within an @nt{aspect_specification}. This could be inconsistent if
+  a predicate or invariant uses the Constrained attribute on the current
+  instance (it will always be False now, while it might have returned True
+  in original Ada 2012). More likely, a usage of a current instance as a prefix
+  of an attribute will become illegal (such as Size or Alignment). Any such
+  code is very tricky. Moreover, as this is a new feature of Ada 2012, there
+  are not that many predicates and invariants, and the ones that exist are
+  very unlikely to be this tricky. Thus we do not believe that there will be
+  any practical effect to this change, other than to explicitly allow
+  common implementation strategies.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0040-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Added wording to clarify 
that
+  the @address@hidden of a @nt{case_expression} is a
+  complete context, just like that of a @nt{case_statement}. Clearly, everyone
+  expects these to work the same way. Moreover, since it would be a lot of 
extra
+  work to treat @nt{case_expression}s differently, it is quite unlikely that 
any
+  compiler would implement the much more complicated resolution necessary (and
+  we are not aware of any that did). Therefore, we didn't document this as a
+  potential incompatibility.]}
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/09.mss 
b/packages/ada-ref-man/source_2012/09.mss
new file mode 100755
index 0000000..41d9c36
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/09.mss
@@ -0,0 +1,5936 @@
address@hidden(09, Root="ada.mss")
+
address@hidden: 2015/04/03 04:12:42 $}
address@hidden and Synchronization}
+
address@hidden: e:\\cvsroot/ARM/Source/09.mss,v $}
address@hidden: 1.124 $}
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden, Sec=(Ada program)}
+The execution of an Ada program consists of the execution of one
+or more @i(tasks).
address@hidden
address@hidden, Sec=(between tasks)}
+Each task represents a separate thread of
+control that proceeds independently and concurrently
+between the points where it @i(interacts) with other tasks.
+The various forms of task interaction are
+described in this @Chg{Version=[3],New=[clause],Old=[section]}, and include:
address@hidden processing],See=(task)}
address@hidden
address@hidden processing],See=(task)}
address@hidden communication],See=(task)}
address@hidden(Honest)
+  The execution of an Ada program consists of the execution
+  of one or more partitions (see @RefSecNum(Program Execution)),
+  each of which in turn consists of the execution of an environment task
+  and zero or more subtasks.
address@hidden(Honest)
address@hidden(itemize)
+the activation and termination of a task;
+
address@hidden object}
+a call on a protected subprogram of a @i(protected object),
+providing exclusive read-write access, or concurrent read-only
+access to shared data;
+
+a call on an entry, either of another task,
+allowing for synchronous communication with that task,
+or of a protected object, allowing for asynchronous
+communication with one or more other tasks using that same protected
+object;
+
+a timed operation, including a simple delay statement,
+a timed entry call or accept, or a timed asynchronous
+select statement (see next
+item);
+
+an asynchronous transfer of control as part of an asynchronous
+select statement, where a task
+stops what it is doing and begins execution at a different
+point in response to the completion of an entry call or
+the expiration of a delay;
+
+an abort statement, allowing one task to cause the
+termination of another task.
address@hidden(itemize)
+
+In addition, tasks can communicate indirectly by
+reading and updating (unprotected) shared
+variables, presuming the access is properly synchronized through
+some other kind of task interaction.
+
address@hidden
+
address@hidden
address@hidden unit}
+The properties of a task are defined by a corresponding task declaration
+and @nt<task_body>, which together define a program unit
+called a @i(task unit).
address@hidden
+
address@hidden
+Over time, tasks proceed through various @i(states).
address@hidden state], Sec=(inactive)}
address@hidden, Sec=(a task state)}
address@hidden state], Sec=(blocked)}
address@hidden, Sec=(a task state)}
address@hidden state], Sec=(ready)}
address@hidden, Sec=(a task state)}
address@hidden state], Sec=(terminated)}
address@hidden, Sec=(a task state)}
+A task is initially @i(inactive); upon activation, and prior to its
address@hidden
+it is either @i(blocked) (as part
+of some task interaction) or @i(ready) to run.
address@hidden resource], Sec=(required for a task to run)}
+While ready, a task competes for the available
address@hidden(execution resources) that it requires to run.
address@hidden(Discussion)
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  @Defn{task dispatching policy}
+  @Defn{dispatching policy for tasks}
+  The means for selecting which of the ready tasks to run,
+  given the currently available execution resources, is determined by the
+  @i(task dispatching policy) in effect, which is generally
+  implementation defined, but may be controlled by
+  @Chg{Version=[3],New=[aspects, ],address@hidden,New=[, ],Old=[]}
+  and operations defined in the Real-Time Annex
+  (see @RefSecNum(Priority Scheduling) and @RefSecNum(Dynamic Priorities)).
address@hidden(Discussion)
address@hidden
+
address@hidden
+
+Concurrent task execution may be implemented on
+multicomputers, multiprocessors, or with interleaved execution on a single
+physical processor. On the other hand, whenever an implementation can
+determine that the required semantic effects can be achieved when
+parts of the execution of a
+given task are performed by different physical processors acting in
+parallel, it may choose to perform them in this way.
+
address@hidden
+
address@hidden
+The introduction has been rewritten.
+
+We use the term "concurrent" rather than "parallel" when talking
+about logically independent execution of threads of control.
+The term "parallel" is reserved for referring to the
+situation where multiple physical processors run simultaneously.
address@hidden
+
+
address@hidden Units and Task Objects}
+
address@hidden
address@hidden declaration}
+A task unit is declared by a @i(task declaration), which has
+a corresponding @nt<task_body>. A task declaration may be
+a @nt<task_type_declaration>, in which case it declares
+a named task type; alternatively, it may be a @nt<single_task_declaration>,
+in which case it defines an anonymous task type, as well as declaring
+a named task object of that type.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<task_type_declaration>,rhs="
+   @key{task} @key{type} @Syn2{defining_identifier} 
address@hidden@Chg{Version=[3],New=<
+        address@hidden>,Old=[]} address@hidden@Chg{Version=[2],New=<
+     address@hidden @Syn2{interface_list} @key{with}]
+    >,Old=<>} @Syn2{task_definition}];"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00399-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<single_task_declaration>,rhs="
+   @key{task} @Syn2{defining_identifier} @Chg{Version=[3],New=<
+        address@hidden>,address@hidden@Chg{Version=[2],New=<
+     address@hidden @Syn2{interface_list} @key{with}]
+    >,Old=<>} @Syn2{task_definition}];"}
+
+
address@hidden<task_definition>,rhs="
+     address@hidden
+  [ @key{private}
+     address@hidden
+  @key{end} address@hidden@Syn2{identifier}]"}
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden<task_item>,rhs="@Syn2{entry_declaration} | 
@address@hidden,address@hidden"}
+
address@hidden,Kind=[Revised],ARef=[AI05-0267-1]}
address@hidden<task_body>,rhs="
+   @key{task} @key{body} @address@hidden,New=<
+        address@hidden>,Old=[]} @key{is}
+     @Syn2{declarative_part}
+   @key{begin}
+     @Syn2{handled_sequence_of_statements}
+   @key{end} address@hidden@Syn2{identifier}];"}
+
address@hidden
+If a @address@hidden appears at the
+end of a @nt{task_definition} or @nt{task_body},
+it shall repeat the @nt{defining_identifier}.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],address@hidden was just moved below}
address@hidden,address@hidden a completion], Sec=(@nt{task_declaration})}
+A task declaration requires a address@hidden,
+which shall be a @nt{task_body},]
+and every @nt{task_body} shall be the completion of some
+task declaration.]}
address@hidden(Honest)
+  @ChgRef{Version=[2],Kind=[Deleted]}
+  @ChgDeleted{Version=[2],Text=[The completion can be a @nt{pragma} Import,
+  if the implementation supports it.]}
address@hidden(Honest)
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraph 8 was
+deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered.}
address@hidden
+
+
address@hidden
+
+A @nt<task_definition> defines a task type and its first subtype.
address@hidden part], Sec=(of a task unit)}
+The first list of @nt{task_item}s of a @address@hidden,
+together with the @address@hidden@!part}, if any,
+is called the visible part of the task unit.
address@hidden@PDefn2{Term=[private part], Sec=(of a task unit)}
+The optional list of @nt{task_item}s after the reserved
+word @key{private} is called the private part of the task unit.]
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Private part is defined in @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden Rules}.
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0029],ARef=[AI95-00116-01]}
address@hidden,Text=[For a task declaration without a
address@hidden, a
address@hidden without @nt{task_item}s is assumed.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01],ARef=[AI95-00397-01],ARef=[AI95-00399-01],ARef=[AI95-00419-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0042-1]}
address@hidden,Text=[For a task declaration
+with an @nt{interface_list}, the task type
+inherits user-defined primitive subprograms from each progenitor
+type (see @RefSecNum{Interface Types}), in the same way that a derived type
+inherits user-defined primitive subprograms from its progenitor types (see
address@hidden Types and Classes}). If the first
+parameter of a primitive inherited subprogram is of the task type or an access
+parameter designating the task type, and there is an @nt{entry_declaration} for
+a single entry with the same identifier within the task declaration,
+whose profile is type conformant with the
+prefixed view profile of the inherited subprogram, the inherited subprogram is
+said to be @i{implemented} by the conforming task address@hidden,
+New=[ using an implicitly declared nonabstract subprogram which
+has the same profile as the inherited subprogram and which
+overrides address@hidden,Sec=[when implemented by]}],
address@hidden,
+Sec=[by a task address@hidden conformance],Sec=(required)}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The inherited subprograms can only come from an
+  interface given as part of the task declaration.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],Aref=[AI05-0042-1]}
+  @ChgAdded{Version=[3],Text=[The part about the implicitly declared
+  subprogram is needed so that a subprogram implemented by an entry is
+  considered to be overridden for the purpose of the other rules of the
+  language. Without it, it would for instance be illegal for an abstract
+  subprogram to be implemented by an entry, because the abstract subprogram
+  would not be overridden. The @LegalityTitle below
+  ensure that there is no conflict between the implicit overriding subprogram
+  and a user-defined overriding subprogram.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],address@hidden was just moved, not changed}
address@hidden,address@hidden a completion], Sec=(@nt{task_declaration})}
+A task declaration requires a address@hidden,
+which shall be a @nt{task_body},]
+and every @nt{task_body} shall be the completion of some
+task declaration.]}
address@hidden(Honest)
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[2],address@hidden,New=[If],Old=[The completion
+  can be a @nt{pragma} Import, if]} the implementation supports
+  address@hidden,New=[, the task body can be imported
+  (using aspect Import, see @RefSecNum{Interfacing Aspects}),
+  in which case no explicit @nt{task_body} is allowed],Old=[]}.]}
address@hidden(Honest)
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01],ARef=[AI95-00399-01]}
address@hidden,address@hidden @address@hidden of an
address@hidden appearing within a task declaration shall denote
+a limited interface type that is not a protected interface.]]}
address@hidden(TheProof)
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],address@hidden Types} requires that an
+  @nt{interface_list} only name interface types, and limits the descendants of
+  the various kinds of interface types. Only a limited, task, or
+  synchronized interface can have a task type descendant. Nonlimited or
+  protected interfaces are not allowed, as they offer operations that a task
+  does not have.]}
address@hidden(TheProof)
+
address@hidden,Kind=[Added],ARef=[AI95-00397-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0090-1]}
address@hidden,Text=[The prefixed view profile of an explicitly
+declared primitive subprogram of a tagged task type shall not be type
+conformant with any entry of the task type, if the @Chg{Version=[3],New=[
+subprogram has the same defining name as the entry and the ],Old=[]}first
+parameter of the subprogram is of the task type or is an
+access parameter designating the task address@hidden 
conformance],Sec=(required)}]}
address@hidden(Reason)
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This prevents the existence of two operations
+  with the same name and profile which could be called with a prefixed view.
+  If the operation was inherited, this would be illegal by the following rules;
+  this rule puts inherited and noninherited routines on the same footing.
+  Note that this only applies to tagged task types (that is, those with an
+  interface in their declaration); we do that as there is no problem with
+  prefixed view calls of primitive operations for @lquotes@;address@hidden
+  task types, and having this rule apply to all tasks would be incompatible
+  with Ada 95.]}
address@hidden(Reason)
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01],ARef=[AI95-00399-01]}
address@hidden,Type=[Leading],Text=[For each primitive subprogram
+inherited by the type declared by a task declaration, at most one of the
+following shall apply:]}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00345-01]}
address@hidden,Text=[the inherited subprogram is overridden with a
+primitive subprogram of the task type, in which case the overriding subprogram
+shall be subtype conformant with the inherited subprogram and not abstract;
address@hidden conformance],Sec=(required)}]}
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01],ARef=[AI95-00397-01]}
address@hidden,Text=[the inherited subprogram is implemented by a
+single entry of the task type; in which case its prefixed view profile
+shall be subtype conformant with that of the task entry.
address@hidden conformance],Sec=(required)}]}
+
address@hidden(Ramification)
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[An entry may implement two subprograms from the
+  ancestors, one whose first parameter is of type @i<T> and one whose first
+  parameter is of type @key{access} @i{T}. That doesn't cause implementation
+  problems because @lquotes@;implemented address@hidden (unlike
+  @lquotes@;address@hidden) probably entails the creation of wrappers.]}
address@hidden(Ramification)
+
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Text=[If neither applies, the inherited subprogram shall be a
+null procedure. @PDefn{generic contract issue}In addition to the places where
address@hidden normally apply (see @RefSecNum{Generic Instantiation}),
+these rules also apply in the private part of an instance of a generic unit.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Each inherited subprogram can only have a single
+implementation (either from overriding a subprogram or implementing an entry),
+and must have an implementation unless the subprogram is a null procedure.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden@PDefn2{Term=[elaboration], Sec=(task declaration)}
+The elaboration of a task declaration elaborates the @nt<task_definition>.
address@hidden, Sec=(single_task_declaration)}
+The elaboration of a @nt<address@hidden@!declaration> also creates
+an object of an (anonymous) task type.]
address@hidden(TheProof)
+  This is redundant with the general rules for the elaboration
+  of a @nt<full_type_declaration> and an @nt<object_declaration>.
address@hidden(TheProof)
+
address@hidden, Sec=(task_definition)}
address@hidden elaboration of a @nt<task_definition>
+creates the task type and its first
+subtype;] it also includes the elaboration of the @nt<entry_declaration>s
+in the given order.
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden, Sec=(of a task object)}
+As part of the initialization of a task object, any
address@hidden@nt<aspect_clause>s],address@hidden<representation_clause>s]} and
+any per-object constraints associated with @nt<address@hidden>s
+of the corresponding @nt<address@hidden> are elaborated in the given order.
address@hidden
address@hidden,Kind=[Revised]}
+  The only 
@address@hidden<aspect_clause>s],address@hidden<representation_clause>s]}
+  defined for task entries are ones that specify the Address of an entry,
+  as part of defining an interrupt entry.
+  These clearly need to be elaborated per-object, not per-type.
+  Normally the address will be a function of a discriminant,
+  if such an Address clause is in a task type rather than a single task
+  declaration, though it could rely on a parameterless function
+  that allocates sequential interrupt vectors.
+
+  We do not mention representation pragmas, since each
+  pragma may have its own elaboration rules.
address@hidden
+
address@hidden, Sec=(task_body)}
+The elaboration of a @nt{task_body} has no effect other than to establish
+that tasks of the type can from then on be activated without
+failing the Elaboration_Check.
+
address@hidden execution of a @nt<task_body> is invoked by the activation of a
+task of the corresponding type
+(see @RefSecNum(Task Execution - Task Activation)).]
+
address@hidden@;The content of a task object of a given task type includes:
address@hidden(itemize)
+  The values of the discriminants of the task object, if any;
+
+  An entry queue for each entry of the task object;
+  @begin(Ramification)
+     "For each entry" implies one queue for each single entry,
+      plus one for each entry of each entry family.
+  @end(Ramification)
+
+  A representation of the state of the associated task.
address@hidden(itemize)
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00382-01]}
address@hidden,New=[Other than
+in an @nt{access_definition}, the name of a task unit within],Old=[Within]}
+the declaration or body of @Chg{Version=[2],New=[the],Old=[a]} task
address@hidden,New=[],Old=[, the name of
+the task unit]} denotes the current instance of the unit
+(see @RefSecNum(The Context of Overload Resolution)),
+rather than the first subtype of the corresponding task type (and
+thus the name cannot be used as a @nt<subtype_mark>).
address@hidden(Discussion)
address@hidden,Kind=[Revised],ARef=[AI95-00382-01]}
address@hidden,New=[It can be used as a @nt{subtype_mark} in an anonymous
+access type. In addition],Old=[However]}, it is possible to refer to
+some other subtype of the task type within its body,
+presuming such a subtype has been
+declared between the @nt<task_type_declaration> and the @nt<task_body>.
address@hidden(Discussion)
+
+The notation of a @nt<selected_component> can be used to denote a discriminant
+of a task (see @RefSecNum(Selected Components)).
+Within a task unit, the name of a discriminant of the task type
+denotes the corresponding discriminant of the current instance
+of the unit.
+
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
+A task type is a limited type (see @RefSecNum(Limited Types)),
+and hence @Chg{Version=[2],New=[precludes use of @nt{assignment_statement}s 
and],
+Old=[has neither an assignment operation nor]} predefined equality operators.
+If an application needs to store and exchange task identities, it
+can do so by defining an access type designating the corresponding
+task objects and by using access values for identification purposes.
+Assignment is available for such an access type as for any
+access type.
+Alternatively, if the implementation supports the
+Systems Programming Annex,
+the Identity attribute
+can be used for task identification
+(see @Chg{Version=[2],address@hidden(The Package Task_Identification)],
address@hidden(Task Information)]}).
address@hidden
+
address@hidden
address@hidden@address@hidden of declarations of task types:}
address@hidden
address@hidden(task) @key(type) Server @key(is)
+   @key(entry) Next_Work_Item(WI : @key(in) Work_Item);
+   @key(entry) Shut_Down;
address@hidden(end) Server;
+
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden(task) @key(type) Keyboard_Driver(ID : Keyboard_ID := New_ID) 
@key(is)@Chg{Version=[2],New=[
+      @key(new) Serial_Device @key(with)  address@hidden see 
@RefSecNum{Interface Types}]],Old=[]}
+   @key(entry) Read (C : @key(out) Character);
+   @key(entry) Write(C : @key(in)  Character);
address@hidden(end) Keyboard_Driver;
address@hidden
+
address@hidden@address@hidden of declarations of single tasks:}
address@hidden
address@hidden(task) Controller @key(is)
+   @key(entry) Request(Level)(D : Item);  address@hidden  a family of entries]
address@hidden(end) Controller;
+
address@hidden(task) Parser @key(is)
+   @key(entry) Next_Lexeme(L : @key(in)  Lexical_Element);
+   @key(entry) Next_Action(A : @key(out) Parser_Action);
address@hidden(end);
+
address@hidden(task) User;  address@hidden  has no entries]
address@hidden
+
address@hidden
address@hidden@address@hidden of task objects:}
address@hidden
address@hidden
+Agent    : Server;
+Teletype : Keyboard_Driver(TTY_ID);
+Pool     : @key(array)(1 .. 10) @key(of) Keyboard_Driver;
address@hidden
+
address@hidden
address@hidden@address@hidden of access type designating task objects:}
address@hidden
address@hidden
address@hidden(type) Keyboard @key(is) @key(access) Keyboard_Driver;
+Terminal : Keyboard := @key(new) Keyboard_Driver(Term_ID);
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised]}
address@hidden to Ada 83}
+The syntax rules for task declarations are modified to allow a
address@hidden, and to allow a private part.
+They are also modified to allow @nt{entry_declaration}s and
address@hidden@nt<aspect_clause>s],address@hidden<representation_clause>s]} to 
be mixed.
address@hidden
+
address@hidden
+The syntax rules for tasks have been split up according to task types and
+single tasks.
+In particular:
+The syntax rules for @ntf{task_declaration} and @ntf{task_specification} are
+removed. The syntax rules for
address@hidden, @nt{single_task_declaration}, @nt{task_definition}
+and @nt{task_item} are new.
+
+The syntax rule for @nt{task_body} now uses the nonterminal
address@hidden
+
+The @nt{declarative_part} of a @nt{task_body} is now required;
+that doesn't make any real difference,
+because a @nt{declarative_part} can be empty.
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00345-01],ARef=[AI95-00397-01],ARef=[AI95-00399-01],ARef=[AI95-00419-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Task types and single tasks can be derived from one or more interfaces.
+  Entries of the task type can implement the primitive operations of an
+  interface. @nt{Overriding_indicator}s can be used to specify whether or not
+  an entry implements a primitive operation.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0029],ARef=[AI95-00116-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that a task 
type has an
+  implicit empty @nt{task_definition} if none is given.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0009],ARef=[AI95-00137-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Changed representation 
clauses
+  to aspect clauses to reflect that they are used for more than just
+  representation.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],Text=[Revised the note on operations of task types to
+  reflect that limited types do have an assignment operation, but not
+  copying (@nt{assignment_statement}s).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00382-01]}
+  @ChgAdded{Version=[2],Text=[Revised the note on use of the name of
+  a task type within itself to reflect the exception for anonymous
+  access types.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1],ARef=[AI05-0267-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a
+  @nt{task_type_declaration}, a @nt{single_task_declaration}, and a
+  @nt{task_body}. This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0042-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified that an
+  inherited procedure of a progenitor is overridden when it is
+  implemented by an entry.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0090-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added the missing
+  defining name in the no conflicting primitive operation rule.]}
address@hidden
+
+
address@hidden Execution - Task Activation}
+
address@hidden
+
address@hidden, Sec=(task)}
+The execution of a task of a given task type consists of the execution
+of the corresponding @nt{task_body}.
address@hidden, Sec=(task_body)}
address@hidden, Sec=(execution)}
address@hidden, Sec=(of a task)}
address@hidden, Sec=(activation)}
+The initial part of this execution is called the @i(activation) of
+the task; it consists of the elaboration of the @nt<declarative_part>
+of the @nt<task_body>.
address@hidden failure}
+Should an exception be propagated by the elaboration
+of its @nt<declarative_part>,
+the activation of the task is defined to have @i(failed),
+and it becomes a completed task.
+
address@hidden,Kind=[Revised],ARef=[AI95-00416-01]}
+A task object (which represents one task) can be @Chg{Version=[2],New=[a part
+of a stand-alone object, of an object created by],Old=[created either as
+part of the elaboration
+of an @nt<address@hidden> occurring immediately within some
+declarative region, or as part of the evaluation of]}
+an @address@hidden,New=[, or of an anonymous object of a limited
+type, or a coextension of one of these],Old=[]}. All
address@hidden,New=[ that are part or coextensions of any
+of the stand-alone objects],Old=[]}
+created by the elaboration of @nt<address@hidden>address@hidden,
+New=[ (or @nt{generic_association}s of formal objects of
+mode @key{in})],Old=[]}
+of a single declarative address@hidden,
+New=[],Old=[ (including subcomponents of the declared objects)]}
+are activated together.
address@hidden,New=[All tasks that are part or coextensions of a single
+object that is not a stand-alone object are activated 
together.],Old=[Similarly,
+all tasks created by the evaluation of a single @nt<allocator>
+are activated together. The activation of a task is associated
+with the innermost @nt<allocator> or @nt<address@hidden>
+that is responsible for its creation.]}
address@hidden
+The initialization of an @nt{object_declaration} or @nt{allocator} can
+indirectly include the creation of other objects that contain tasks.
+For example, the default expression for a subcomponent of an object
+created by an @nt{allocator} might call a function that evaluates a
+completely different @nt{allocator}. Tasks created by the two
+allocators are @i{not} activated together.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00416-01]}
+For @Chg{Version=[2],New=[the ],address@hidden,New=[],Old=[
+created by the elaboration of @nt<object_declaration>s]}
+of a given declarative region, the activations are initiated
+within the context of the @nt<address@hidden@!statements>
+(and its associated @nt<address@hidden>s if any @em
+see @RefSecNum{Exception Handlers}), just prior to executing the
+statements of the @Chg{Version=[2],address@hidden,
address@hidden<_sequence>]}.
address@hidden a package without an explicit body or an explicit
address@hidden<address@hidden@!statements>,
+an implicit body or an implicit @nt<address@hidden> is assumed,
+as defined in @RefSecNum(Package Bodies).]
address@hidden(Ramification)
+  If Tasking_Error is raised, it can be handled by handlers of
+  the @nt<address@hidden@!statements>.
address@hidden(Ramification)
+
address@hidden,Kind=[Revised],ARef=[AI95-00416-01]}
+For tasks @Chg{Version=[2],New=[that are part or coextensions of a single
+object that is
+not a stand-alone object, activations are initiated after completing any
+initialization of the outermost object enclosing these tasks, prior
+to performing any other operation on the outermost object. In
+particular, for tasks that are part or coextensions of the object ],
+Old=[]}created by the evaluation of an @nt<allocator>,
+the activations are initiated as the last step of
+evaluating the @nt<allocator>, @Chg{Version=[2],New=[],Old=[after completing
+any initialization for the object created by the @nt<allocator>,
+and ]}prior to returning the new access
address@hidden,New=[ For tasks that are part or coextensions of an
+object that is the result of a function call, the activations are
+not initiated until after the function returns.],Old=[]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[The intent is that @lquotes@;address@hidden@;
+  objects with task parts (or coextensions) are treated similarly to an
+  object created by an
+  allocator. The @lquotes@;address@hidden@; object is initialized, and then all
+  of the task parts (including the coextensions) are activated together. Each
+  such @lquotes@;address@hidden@;
+  object has its own task activation sequence, involving the activating task
+  being suspended until all the new tasks complete their activation.]}
address@hidden
+
address@hidden, Sec=(of a task)}
address@hidden, Sec=(waiting for activations to complete)}
+The task that created the new tasks and initiated their
+activations (the @i(activator)) is
+blocked until all of these activations complete (successfully
+or not).
address@hidden,Sec=(raised by failure of run-time check)}
+Once all of these activations are complete,
+if the activation
+of any of the tasks has failed
address@hidden(due to the propagation of an exception)],
+Tasking_Error is raised in the activator, at the place at which
+it initiated the activations. Otherwise, the activator
+proceeds with its execution normally. Any tasks that are aborted
+prior to completing their activation are ignored when determining
+whether to raise Tasking_Error.
address@hidden(Ramification)
+  Note that a task created by an @nt<allocator> does not necessarily
+  depend on its activator; in such a case the activator's termination
+  can precede the termination of the newly created task.
address@hidden(Ramification)
address@hidden(Discussion)
+  Tasking_Error is raised only once, even if two or more
+  of the tasks being activated fail their activation.
address@hidden(Discussion)
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00265-01]}
+  @ChgAdded{Version=[2],Text=[The pragma Partition_Elaboration_Policy (see
+  @RefSecNum{Pragma Partition_Elaboration_Policy})
+  can be used to defer task activation to a later point, thus changing
+  many of these rules.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0045-1]}
address@hidden,New=[If the master that directly encloses the point where the
+activation of a task @i<T> would be initiated, completes before the activation
+of @i<T> is initiated, @i<T> becomes terminated and is never activated.
+Furthermore, if a return statement is left such that the return object is not
+returned to the caller, any task that was created as a part of the return
+object or one of its coextensions immediately becomes],
+Old=[Should the task that created
+the new tasks never reach the point
+where it would initiate the activations (due to an abort or
+the raising of an exception),
+the newly created tasks become]}
+terminated @Chg{Version=[3],New=[and is],Old=[are]}
+never activated.
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0045-1]}
address@hidden,Text=[The first case can only happen if the activation
+   point of T is not reached due to an exception being raised or a task or
+   statement being aborted. Note that this is exclusive; if the master
+   completes normally and starts finalization, we're already past the
+   activation point.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0045-1]}
address@hidden,Text=[The second case can happen with an exception being
+   raised in a return statement, by an exit or goto from an
+   @nt{extended_return_statement}, or by a return statement being aborted. Any
+   tasks created for the return object of such a return statement are never
+   activated.]}
address@hidden
address@hidden
+
address@hidden
+
+An entry of a task can be called before the task has been activated.
+
+If several tasks are activated together, the execution of any of these
+tasks need not await the end of the activation of the other tasks.
+
+A task can become completed during its activation either because of an
+exception or because it is aborted
+(see @RefSecNum(Abort of a Task - Abort of a Sequence of Statements)).
+
address@hidden
+
address@hidden
address@hidden@address@hidden of task activation:}
address@hidden
address@hidden(procedure) P @key(is)
+   A, B : Server;    address@hidden  elaborate the task objects A, B]
+   C    : Server;    address@hidden  elaborate the task object C]
address@hidden(begin)
+   address@hidden  the tasks A, B, C are activated together before the first 
statement]
+   ...
address@hidden(end);
address@hidden
+
address@hidden
+
address@hidden
+
+We have replaced the term @i{suspended} with @i{blocked},
+since we didn't want to consider a task blocked when it was
+simply competing for execution resources. "Suspended" is sometimes
+used more generally to refer to tasks that are not actually running
+on some processor, due to the lack of resources.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} has been rewritten
+in an attempt to improve presentation.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[Adjusted the wording for activating tasks to
+  handle the case of anonymous function return objects. This is critical;
+  we don't want to be waiting for the tasks in a return object when we exit
+  the function normally.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0045-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the wording that
+  handles tasks that are never activated to ensure that no lookahead is implied
+  and to make it clear that tasks created by return statements that never
+  return are never activated.]}
address@hidden
+
+
address@hidden Dependence - Termination of Tasks}
+
address@hidden
+
address@hidden@Defn2{Term=[dependence], Sec=(of a task on a master)}
address@hidden, Sec=(dependence)}
address@hidden, Sec=(completion)}
address@hidden, Sec=(termination)}
+Each task (other than an environment task @em see @RefSecNum(Program 
Execution))
address@hidden(depends) on one or more masters
+(see @RefSecNum(Completion and Finalization)), as follows:
address@hidden(itemize)
address@hidden,Kind=[Revised],ARef=[AI12-0070-1]}
+If the task is created by the evaluation of an @nt<allocator>
+for a given @Chg{Version=[4],New=[named ],Old=[]}access type,
+it depends on each master that includes the
+elaboration of the declaration of the ultimate ancestor of the given
+access type.
+
+If the task is created by the elaboration of an @nt<object_declaration>,
+it depends on each master that includes this elaboration.
+
address@hidden,Kind=[Added],ARef=[AI95-00416-01]}
address@hidden,Text=[Otherwise, the task depends on
+the master of the outermost object of which it is a part (as determined by the
+accessibility level of that object @em see
address@hidden of Access Types} and
address@hidden and Finalization}), as well as on any master whose
+execution includes that of the master of the outermost object.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[The master of a task created by a return
+  statement changes when the accessibility of the return object changes. Note
+  that its activation happens, if at all, only after the function returns and
+  all accessibility level changes have occurred.]}
address@hidden
address@hidden(itemize)
+
address@hidden, Sec=(of a task on another task)}
+Furthermore, if a task depends on a given master, it is defined
+to depend on the task that executes the master, and (recursively)
+on any master of that task.
address@hidden
+Don't confuse these kinds of dependences with the
+dependences among compilation units defined in
address@hidden Units - Library Units}.
address@hidden
+
+A task is said to be @i(completed) when the execution of its corresponding
address@hidden<task_body> is completed. A task is said to be @i(terminated) when
+any finalization of the @nt<task_body> has been performed
+(see @RefSecNum(Completion and Finalization)).
address@hidden first step of finalizing a master
+(including a @nt<task_body>) is to
+wait for the termination of any tasks dependent on the master.]
address@hidden, Sec=(waiting for dependents to terminate)}
+The task executing the master is blocked until all the dependents
+have terminated. @Redundant[Any remaining finalization is then performed
+and the master is left.]
+
address@hidden,address@hidden word}
address@hidden@;Completion of a task (and the corresponding @nt<task_body>) can
+occur when the task is blocked at a @nt<address@hidden> with an
address@hidden,Old=[an ]}open @nt<terminate_alternative>
+(see @RefSecNum(Selective Accept)); the open @nt<terminate_alternative>
+is selected if and only if the following conditions are satisfied:
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00415-01]}
+  The task depends on some completed master;@Chg{Version=[2],New=[ and],Old=[]}
+
+  Each task that depends on the master considered is either already
+  terminated or similarly blocked at a @nt<select_statement>
+  with an open @nt{terminate_alternative}.
address@hidden
+
+When both conditions are satisfied, the task considered becomes
+completed, together with all tasks that depend on the master
+considered that are not yet completed.
address@hidden(Ramification)
+  Any required finalization is performed after the selection
+  of @nt<terminate_alternative>s. The tasks are not callable
+  during the finalization. In some ways it is as though they were
+  aborted.
address@hidden(Ramification)
+
address@hidden
+
address@hidden
+
+The full view of a limited private type can be a task type, or
+can have subcomponents of a task type. Creation of an object of
+such a type creates dependences according to the full type.
+
+An @nt<object_renaming_declaration> defines a new view of an
+existing entity and hence creates no further dependence.
+
+The rules given for the collective completion of a group
+of tasks all blocked on @nt<select_statement>s with
+open @nt<terminate_alternative>s ensure that the collective
+completion can occur only when there are no remaining active
+tasks that could call one of the tasks being collectively completed.
+
+If two or more tasks are blocked on @nt<select_statement>s
+with open @nt{terminate_alternative}s, and become
+completed collectively, their finalization actions proceed concurrently.
+
address@hidden@keepnext@;The completion of a task can occur due to any of the 
following:
address@hidden
+the raising of an exception during the elaboration of the
address@hidden of the corresponding @nt{task_body};
+
+the completion of the
address@hidden of the corresponding
address@hidden;
+
+the selection of
+an open @nt<terminate_alternative> of a @nt<select_statement>
+in the corresponding @nt<task_body>;
+
+the abort of the task.
address@hidden
+
address@hidden
+
address@hidden
address@hidden@address@hidden of task dependence:}
address@hidden
address@hidden(declare)
+   @key(type) Global @key(is) @key(access) Server;        address@hidden  see 
@RefSecNum(Task Units and Task Objects)]
+   A, B : Server;
+   G    : Global;@Softpage
address@hidden(begin)
+   address@hidden  activation of A and B]
+   @key(declare)
+      @key(type) Local @key(is) @key(access) Server;
+      X : Global := @key(new) Server;  address@hidden  activation of 
address@hidden
+      L : Local  := @key(new) Server;  address@hidden  activation of 
address@hidden
+      C : Server;@Softpage
+   @key(begin)
+      address@hidden  activation of C]
+      G := X;  address@hidden  both G and X designate the same task object]
+      ...
+   @key(end;)  address@hidden  await termination of C and address@hidden (but 
not address@hidden)]
+   ...
address@hidden(end;)  address@hidden  await termination of A, B, and 
address@hidden
address@hidden
+
address@hidden
+
address@hidden
+We have revised the wording to be consistent with the definition
+of master now given in @RefSec(Completion and Finalization).
+
+Tasks that used to depend on library packages in Ada 83, now depend on the
+(implicit) @nt<task_body> of the
+environment task (see @RefSecNum(Program Execution)).
+Therefore, the environment task has to wait for
+them before performing library level finalization and terminating
+the partition.
+In Ada 83 the requirement to wait for tasks that depended
+on library packages was not as clear.
+
+What was "collective termination" is now "collective completion"
+resulting from selecting @nt<terminate_alternative>s. This is because
+finalization still occurs for such tasks, and this happens after
+selecting the @nt<terminate_alternative>, but before termination.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[Added missing wording that explained the
+  master of tasks that are neither @nt{object_declaration}s nor 
@nt{allocator}s,
+  such as function returns.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0070-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Ensured that the master of
+  tasks that are not @nt{allocator}s of named access types is correctly
+  determined. (Ignoring the accessibility rules of
+  @RefSecNum{Operations of Access Types} could not be intended.)]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden Units and Protected Objects}
+
address@hidden
address@hidden object}
address@hidden operation}
address@hidden subprogram}
address@hidden entry}
+A @i(protected object) provides coordinated access to shared data,
+through calls on its visible @i(protected operations),
+which can be @i{protected subprograms} or @i{protected entries}.
address@hidden declaration}
address@hidden unit}
address@hidden declaration}
+A @i{protected unit} is declared by a @i(protected declaration), which has
+a corresponding @nt<protected_body>.
+A protected declaration may be a @nt<protected_type_declaration>,
+in which case it declares
+a named protected type; alternatively,
+it may be a @nt<single_protected_declaration>,
+in which case it defines an anonymous protected type, as well as declaring
+a named protected object of that type.
address@hidden signal],See=(protected object)}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<protected_type_declaration>,rhs="
+  @key{protected} @key{type} @Syn2{defining_identifier} 
address@hidden@Chg{Version=[3],New=<
+        address@hidden>,Old=[]} @address@hidden,New=<
+     address@hidden @Syn2{interface_list} @key{with}]
+    >,Old=<>} @Syn2{protected_definition};"}
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00399-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<single_protected_declaration>,rhs="
+  @key{protected} @address@hidden,New=<
+        address@hidden>,Old=[]} @address@hidden,New=<
+     address@hidden @Syn2{interface_list} @key{with}]
+    >,Old=<>} @Syn2{protected_definition};"}
+
+
address@hidden<protected_definition>,rhs="
+    { @Syn2{protected_operation_declaration} }
+[ @key{private}
+    { @Syn2{protected_element_declaration} } ]
+  @key{end} address@hidden@Syn2{identifier}]"}
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden<protected_operation_declaration>,
+  rhs="@Syn2{subprogram_declaration}
+     | @Syn2{entry_declaration}
+     | @address@hidden,address@hidden"}
address@hidden<protected_element_declaration>,
+  rhs="@Syn2<protected_operation_declaration>
+     | @Syn2<component_declaration>"}
address@hidden
+     We allow the operations and components to be mixed because that's how
+     other things work (for example, package
+     declarations). We have relaxed the
+     ordering rules for the items inside @nt{declarative_part}s and
+     @nt{task_definition}s as well.
address@hidden
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0267-1]}
address@hidden<protected_body>,rhs="
+  @key{protected} @key{body} @address@hidden,New=<
+        address@hidden>,Old=[]} @key{is}
+   { @Syn2{protected_operation_item} }
+  @key{end} address@hidden@Syn2{identifier}];"}
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[Revised],ARef=[AI12-0147-1]}
address@hidden<protected_operation_item>,
+  rhs="@Syn2{subprogram_declaration}
+     | @Syn2{subprogram_body}
+     | @Chg{Version=[4],address@hidden
+     | @Syn2{expression_function_declaration}
+     | ],address@hidden
+     | @address@hidden,address@hidden"}
+
address@hidden
+If a @address@hidden appears at
+the end of a @nt{protected_definition} or @nt{protected_body},
+it shall repeat the @nt{defining_identifier}.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],address@hidden was just moved below}
address@hidden,address@hidden a completion], Sec=(@nt{protected_declaration})}
+A protected declaration requires a address@hidden,
+which shall be a @address@hidden,]
+and every @address@hidden shall be the completion of some
+protected declaration.]}
address@hidden(Honest)
+  @ChgRef{Version=[2],Kind=[Deleted]}
+  @ChgDeleted{Version=[2],Text=[The completion can be a @nt{pragma} Import,
+  if the implementation supports it.]}
address@hidden(Honest)
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraph 10 was
+deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered.}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00345-01],address@hidden
+is no change here, but both of these AIs reference this paragraph, adding and 
removing text.}
+A @nt<protected_definition> defines a protected type and its first subtype.
address@hidden part], Sec=(of a protected unit)}
+The list of @address@hidden@!declaration}s of a
address@hidden@!definition},
+together with the @address@hidden@!part}, if any,
+is called the visible part of the protected unit.
address@hidden@PDefn2{Term=[private part], Sec=(of a protected unit)}
+The optional list of @address@hidden@!declaration}s after the reserved
+word @key{private} is called the private part of the protected
+unit.]
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Private part is defined in @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden Rules}.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01],ARef=[AI95-00397-01],ARef=[AI95-00399-01],ARef=[AI95-00419-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0042-1]}
address@hidden,Text=[For a protected declaration
+with an @nt{interface_list}, the protected type inherits user-defined primitive
+subprograms from each progenitor type (see @RefSecNum{Interface Types}), in the
+same way that a derived type inherits user-defined primitive subprograms from
+its progenitor types (see @RefSecNum{Derived Types and Classes}). If the first
+parameter of a primitive inherited subprogram is of the protected type or an
+access parameter designating the protected type, and there is a
address@hidden for a protected subprogram or single entry
+with the same identifier within the protected declaration, whose
+profile is type conformant with the prefixed view profile of the
+inherited subprogram, the inherited subprogram is said to be
address@hidden by the conforming protected subprogram or
address@hidden,New=[ using an implicitly declared nonabstract
+subprogram which has the same profile as the inherited subprogram and which
+overrides address@hidden,Sec=[when implemented by]}],
address@hidden,
+Sec=[by a protected address@hidden,
+Sec=[by a protected entry]}
address@hidden conformance],Sec=(required)}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The inherited subprograms can only come from an
+  interface given as part of the protected declaration.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],Aref=[AI05-0042-1]}
+  @ChgAdded{Version=[3],Text=[The part about the implicitly declared
+  subprogram is needed so that a subprogram implemented by an entry or
+  subprogram is considered to be overridden for the purpose of the
+  other rules of the language. Without it, it would for instance be illegal
+  for an abstract subprogram to be implemented by an entry, because the
+  abstract subprogram would not be overridden. The @LegalityTitle below
+  ensure that there is no conflict between the implicit overriding subprogram
+  and a user-defined overriding subprogram.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],address@hidden was just moved, not changed}
address@hidden,address@hidden a completion], Sec=(@nt{protected_declaration})}
+A protected declaration requires a address@hidden,
+which shall be a @address@hidden,]
+and every @address@hidden shall be the completion of some
+protected declaration.]}
address@hidden(Honest)
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[2],address@hidden,New=[If],Old=[The completion
+  can be a @nt{pragma} Import, if]} the implementation supports
+  address@hidden,New=[, the protected body can be imported
+  (using aspect Import, see @RefSecNum{Interfacing Aspects}),
+  in which case no explicit @nt{protected_body} is allowed],Old=[]}.]}
address@hidden(Honest)
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01],ARef=[AI95-00399-01]}
address@hidden,address@hidden @address@hidden of an
address@hidden appearing within a protected declaration shall denote a
+limited interface type that is not a task interface.]]}
address@hidden(TheProof)
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],address@hidden Types} requires that an
+  @nt{interface_list} only name interface types, and limits the descendants of
+  the various kinds of interface types. Only a limited, protected, or
+  synchronized interface can have a protected type descendant. Nonlimited or
+  task interfaces are not allowed, as they offer operations that a protected
+  type does not have.]}
address@hidden(TheProof)
+
address@hidden,Kind=[Added],ARef=[AI95-00397-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0042-1]}
address@hidden,Text=[The prefixed view profile of an explicitly declared
+primitive subprogram of a tagged protected type shall not be type conformant
+with any protected operation of the protected type, if address@hidden,New=[
+subprogram has the same defining name as the protected operation and
+the],Old=[]} first parameter of
+the subprogram is of the protected type or is an access parameter designating
+the protected address@hidden conformance],Sec=(required)}]}
address@hidden(Reason)
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This prevents the existence of two operations
+  with the same name and profile which could be called with a prefixed view.
+  If the operation was inherited, this would be illegal by the following rules;
+  this rule puts inherited and noninherited routines on the same footing.
+  Note that this only applies to tagged protected types (that is, those with an
+  interface in their declaration); we do that as there is no problem with
+  prefixed view calls of primitive operations for @lquotes@;address@hidden
+  protected types, and having this rule apply to all protected types would be
+  incompatible with Ada 95.]}
address@hidden(Reason)
+
+
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01],ARef=[AI95-00399-01]}
address@hidden,Type=[Leading],Text=[For each primitive subprogram
+inherited by the type declared by a protected declaration, at most one of the
+following shall apply:]}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00345-01]}
address@hidden,Text=[the inherited subprogram is overridden with a
+primitive subprogram of the protected type, in which case the overriding
+subprogram shall be subtype conformant with the inherited
+subprogram and not abstract; address@hidden conformance],Sec=(required)}]}
+
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01],ARef=[AI95-00397-01]}
address@hidden,Text=[the inherited subprogram is implemented by a
+protected subprogram or single entry of the protected type,
+in which case its prefixed view profile shall be subtype conformant with that
+of the protected subprogram or entry.
address@hidden conformance],Sec=(required)}]}
+
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Text=[If neither applies, the inherited subprogram shall
+be a null procedure. @PDefn{generic contract issue}In addition to the places
+where @LegalityTitle normally apply (see @RefSecNum{Generic Instantiation}),
+these rules also apply in the private part of an instance of a generic unit.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Each inherited subprogram can only have a single
+  implementation (either from overriding a subprogram, implementing a
+  subprogram, or implementing an entry), and must have an implementation unless
+  the subprogram is a null procedure.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0291-1]}
address@hidden,Text=[If an inherited subprogram is implemented by a
+protected procedure or an entry, then the first parameter of the inherited
+subprogram shall be of mode @key{out} or @key{in out}, or an
+access-to-variable address@hidden,New=[
+If an inherited subprogram is implemented by a protected function, then the
+first parameter of the inherited subprogram shall be of mode @key{in}, but not
+an access-to-variable parameter.],Old=[]}]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised]}
address@hidden,Text=[For a protected procedure or entry, the protected
+object can be read or written (see
address@hidden Subprograms and Protected Actions}). A subprogram
+that is implemented by a protected procedure or entry must have a profile
+which reflects that in order to avoid address@hidden,New=[
+Similarly, a protected function has a parameter that is a constant,
+and the inherited routine should reflect that.],Old=[]}]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00397-01]}
address@hidden,Type=[Leading],Text=[If a protected subprogram
+declaration has an @nt{overriding_indicator}, then at the point of the
+declaration:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[if the @nt{overriding_indicator} is
address@hidden, then the subprogram shall
+implement an inherited subprogram;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[if the @nt{overriding_indicator} is
address@hidden overriding}, then the subprogram shall
+not implement any inherited subprogram.]}
+
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden contract issue}In addition to the
+places where @LegalityTitle normally apply (see
address@hidden Instantiation}), these rules also apply in the private part
+of an instance of a generic unit.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[These rules are subtly different than those for
+  subprograms (see @RefSecNum{Overriding Indicators}) because there cannot be
+  @lquotes@;address@hidden inheritance of primitives from interfaces. Hidden
+  (that is, private) interfaces are prohibited explicitly (see
+  @RefSecNum{Private Types and Private Extensions}), as are hidden primitive
+  operations (as private operations of public abstract types are prohibited
+  @em see @RefSecNum{Abstract Types and Subprograms}).]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden@PDefn2{Term=[elaboration], Sec=(protected declaration)}The
+elaboration of a protected declaration
+elaborates the @nt<protected_definition>.
address@hidden, Sec=(single_protected_declaration)}
+The elaboration of a @nt<address@hidden@!declaration> also creates
+an object of an (anonymous) protected type.]
address@hidden(TheProof)
+  This is redundant with the general rules for the elaboration
+  of a @nt<full_type_declaration> and an @nt<object_declaration>.
address@hidden(TheProof)
+
address@hidden, Sec=(protected_definition)}
address@hidden elaboration of a @nt<protected_definition>
+creates the protected type and its first
+subtype;] it also includes the elaboration of the
address@hidden<component_declaration>s and @nt<protected_operation_declaration>s
+in the given order.
+
address@hidden@PDefn2{Term=[initialization], Sec=(of a protected object)}As
+part of the initialization of a protected object,
+any per-object constraints (see @RefSecNum{Record Types}) are elaborated.]
address@hidden
+  We do not mention pragmas since each pragma has its
+  own elaboration rules.
address@hidden
+
address@hidden, Sec=(protected_body)}
+The elaboration of a @nt{protected_body} has no other effect than to establish
+that protected operations of the type can from then on be called without
+failing the Elaboration_Check.
+
address@hidden@keepnext@;The content of an object of a given protected type 
includes:
address@hidden(itemize)
+  The values of the components of the
+  protected object, including (implicitly)
+  an entry queue for each entry declared for the protected object;
+  @begin(Ramification)
+     "For each entry" implies one queue for each single entry,
+      plus one for each entry of each entry family.
+  @end(Ramification)
+
+  @PDefn2{Term=[execution resource], Sec=(associated with a protected object)}
+  A representation of the state of the execution resource
+  @i(associated) with the protected object
+  (one such resource is associated with each protected object).
address@hidden(itemize)
+
address@hidden execution resource associated with a protected object
+has to be acquired to
+read or update any components of the protected object;
+it can be acquired (as part of a protected action @em
+see @RefSecNum(Protected Subprograms and Protected Actions))
+either for concurrent read-only access, or for exclusive
+read-write access.]
+
address@hidden, Sec=(of a protected object)}
address@hidden,Sec=(raised by failure of run-time check)}
+As the first step of the @i{finalization} of a protected object,
+each call remaining on any entry queue of the object
+is removed from its queue and
+Program_Error is raised at the place of the corresponding
address@hidden<address@hidden@!statement>.
address@hidden(Reason)
+  @leading@;This is analogous to the raising of Tasking_Error in callers
+  of a task that completes before accepting the calls.
+  This situation can only occur due to a
+  requeue (ignoring premature unchecked_deallocation), since any task that
+  has accessibility to a protected object is awaited before finalizing
+  the protected object.
+  For example:
address@hidden
address@hidden Main @key[is]
+    @key[task] T @key[is]
+        @key[entry] E;
+    @key[end] T;
+
+    @key[task] @key[body] T @key[is]
+        @key[protected] PO @key[is]
+            @key[entry] Ee;
+        @key[end] PO;
+
+        @key[protected] @key[body] PO @key[is]
+            @key[entry] Ee @key[when] False @key[is]
+            @key[begin]
+                @key[null];
+            @key[end] Ee;
+        @key[end] PO;
+    @key[begin]
+        @key[accept] E @key[do]
+            @key[requeue] PO.Ee;
+        @key[end] E;
+    @key[end] T;
address@hidden
+    T.E;
address@hidden Main;
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+The environment task is queued on address@hidden,New=[Ee],Old=[EE]}
+when PO is finalized.
+
+In a real example, a server task might park callers on a local protected
+object for some useful purpose, so we didn't want to disallow this case.
address@hidden(Reason)
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00280-01]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to call an entry or subprogram of a
+protected object after that object is finalized. If the error is detected,
+Program_Error is raised. Otherwise, the call proceeds normally, which may leave
+a task queued forever.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This is very similar to the finalization rule. It
+is a bounded error so that an implementation can avoid the overhead of the
+check if it can ensure that the call still will operate properly. Such an
+implementation cannot need to return resources (such as locks) to an
+executive that it needs to execute calls.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[This case can happen (and has
+happened in
+production code) when a protected object is accessed from the Finalize routine
+of a type. For example:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Finalization.Controlled;
address@hidden Window_Manager @key{is}
+    ...
+    @key{type} Root_Window @key{is new} Ada.Finalization.Controlled @key{with 
private};
+    @key{type} Any_Window @key{is access all} Root_Window;
+    ...
address@hidden
+    ...
+    @key{procedure} Finalize (Object : @key{in out} Root_Window);
+    ...
address@hidden Window_Manager;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden body} Window_Manager @key{is}
+   @key{protected type} Lock @key{is}
+       @key{entry} Get_Lock;
+       @key{procedure} Free_Lock;
+   ...
+   @key{end} Lock;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   Window_Lock : Lock;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} Finalize (Object : @key{in out} 
Root_Window) @key{is}
+   @key{begin}
+       Window_Lock.Get_Lock;
+       ...
+       Window_Lock.Free_Lock;
+   @key{end} Finalize;
+   ...
+   A_Window : Any_Window := @key{new} Root_Window;
address@hidden Window_Manager;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The environment task will call Window_Lock for
+the object allocated for A_Window when the collection for Any_Window
+is finalized, which
+will happen after the finalization of Window_Lock (because finalization of the
+package body will occur before that of the package specification).]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00382-01]}
+Within the declaration or body of a protected address@hidden,New=[ other
+than in an @nt{access_definition}],Old=[]}, the name of
+the protected unit denotes the current instance of the unit
+(see @RefSecNum(The Context of Overload Resolution)),
+rather than the first subtype of the corresponding protected type (and
+thus the name cannot be used as a @nt<subtype_mark>).
address@hidden(Discussion)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00382-01]}
+  @Chg{Version=[2],New=[It can be used as a @nt{subtype_mark} in an anonymous
+  access type. In addition],Old=[However]}, it is possible to refer to
+  some other subtype of the protected type within its body,
+  presuming such a subtype has been
+  declared between the @nt<protected_type_declaration>
+  and the @nt<protected_body>.
address@hidden(Discussion)
+
+A @nt<selected_component> can be used to denote a discriminant
+of a protected object (see @RefSecNum(Selected Components)).
+Within a protected unit, the name of a discriminant of the protected type
+denotes the corresponding discriminant of the current instance
+of the unit.
+
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
+A protected type is a limited type (see @RefSecNum(Limited Types)),
+and hence @Chg{Version=[2],New=[precludes use of @nt{assignment_statement}s 
and],
+Old=[has neither an assignment operation nor]} predefined equality operators.
+
+The bodies of the protected operations given in the @nt<protected_body>
+define the actions that take place upon calls to the protected operations.
+
+The declarations in the private part are only
+visible within the private part and the body of the
+protected unit.
address@hidden
address@hidden are disallowed in a @nt{protected_body}
+because, for efficiency, we wish to allow the compiler to
+determine the size of protected objects (when not dynamic);
+the compiler cannot necessarily see the body.
+Furthermore, the semantics of initialization of such objects would be
+problematic @em we do not wish to give protected objects complex
+initialization semantics similar to task activation.
+
+The same applies to @nt{entry_declaration}s,
+since an entry involves an implicit component @em the entry queue.
address@hidden
+
address@hidden
+
address@hidden
address@hidden@address@hidden of declaration of protected type and 
corresponding body:}
address@hidden
address@hidden(protected) @key(type) Resource @key(is)
+   @key(entry) Seize;
+   @key(procedure) Release;
address@hidden(private)
+   Busy : Boolean := False;
address@hidden(end) Resource;
+
address@hidden(protected) @key(body) Resource @key(is)
+   @key(entry) Seize @key(when not) Busy @key(is)
+   @key(begin)
+      Busy := True;
+   @key(end) Seize;
+
+   @key(procedure) Release @key(is)
+   @key(begin)
+      Busy := False;
+   @key(end) Release;
address@hidden(end) Resource;
address@hidden
+
address@hidden
address@hidden@address@hidden of a single protected declaration and 
corresponding body:}
address@hidden
address@hidden
address@hidden(protected) Shared_Array @key(is)
+   address@hidden  Index, Item, and Item_Array are global types]
+   @key(function)  Component    (N : @key(in) Index) return Item;
+   @key(procedure) Set_Component(N : @key(in) Index; E : @key(in)  Item);
address@hidden(private)
+   Table : Item_Array(Index) := (others => Null_Item);
address@hidden(end) Shared_Array;
+
address@hidden(protected) @key(body) Shared_Array @key(is)
+   @key(function) Component(N : @key(in) Index) @key(return) Item @key(is)
+   @key(begin)
+      @key(return) Table(N);
+   @key(end) Component;
+
+   @key(procedure) Set_Component(N : @key(in) Index; E : @key(in) Item) 
@key(is)
+   @key(begin)
+      Table(N) := E;
+   @key(end) Set_Component;
address@hidden(end) Shared_Array;
address@hidden
+
address@hidden
address@hidden@address@hidden of protected objects:}
address@hidden
address@hidden
+Control  : Resource;
+Flags    : @key(array)(1 .. 100) @key(of) Resource;
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden to Ada 83}
+This entire @Chg{Version=[3],New=[subclause],Old=[clause]} is new;
+protected units do not exist in Ada 83.
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00345-01],ARef=[AI95-00397-01],ARef=[AI95-00399-01],ARef=[AI95-00401-01],ARef=[AI95-00419-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Protected types and single protected objects can be derived from one or
+  more interfaces. Operations declared in the protected type can implement
+  the primitive operations of an interface. @nt{Overriding_indicator}s can
+  be used to specify whether or not a protected operation implements a
+  primitive operation.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0009],ARef=[AI95-00137-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Changed representation 
clauses
+  to aspect clauses to reflect that they are used for more than just
+  representation.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00280-01]}
+  @ChgAdded{Version=[2],Text=[Described what happens when an operation of a
+  finalized protected object is called.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],Text=[Revised the note on operations of
+  protected types to
+  reflect that limited types do have an assignment operation, but not
+  copying (@nt{assignment_statement}s).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00382-01]}
+  @ChgAdded{Version=[2],Text=[Revised the note on use of the name of
+  a protected type within itself to reflect the exception for anonymous
+  access types.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0291-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  @b<Correction:> When an inherited subprogram is implemented by a protected
+  function, the first parameter has to be an @key[in] parameter, but not
+  an access-to-variable type. Original Ada 2005 allowed access-to-variable
+  parameters in this case; the parameter will need to be changed to
+  access-to-constant with the addition of the @key[constant] keyword.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1],ARef=[AI05-0267-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a
+  @nt{protected_type_declaration}, a @nt{single_protected_declaration},
+  and a @nt{protected_body}. This is described in @RefSecNum{Aspect 
Specifications}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0042-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified that an
+  inherited subprogram of a progenitor is overridden when it is
+  implemented by an entry or subprogram.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0090-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added the missing
+  defining name in the no conflicting primitive operation rule.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0147-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada 2012}
+  @b<Corrigendum:> Null procedures and expression functions are allowed
+  in protected bodies. We consider this an omission, as there is no
+  reason why the convinient shorthand notations should not be allowed
+  in this context.]}
address@hidden
+
+
address@hidden Communication}
+
address@hidden
address@hidden communication}
address@hidden section],See=(intertask communication)}
+The primary means for intertask
+communication is provided by
+calls on entries and protected subprograms.
+Calls on protected subprograms allow coordinated access
+to shared data objects.
+Entry calls allow for blocking the caller until
+a given condition is satisfied (namely, that the corresponding entry is open
address@hidden see @RefSecNum(Entry Calls)),
+and then communicating data or control information directly
+with another task or
+indirectly via a shared protected object.
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0225-1],ARef=[AI05-0291-1]}
address@hidden@;@Chg{Version=[3],address@hidden object],
+  Sec=(of the name of an entry or a protected subprogram)}],
address@hidden object],
+  Sec=(of a call on an entry or a protected subprogram)}]}
address@hidden,New=[When a @nt{name} or @nt{prefix} denotes],Old=[Any call on]}
+an address@hidden,New=[,],Old=[ or on a]}
+protected address@hidden,New=[, or a
+prefixed view of a primitive subprogram of a limited interface whose
+first parameter is a controlling parameter, the @nt{name} or @nt{prefix}
+determines],Old=[ identifies]}
+a @i(target object)@Chg{Version=[3],New=[],Old=[ for the operation,
+which is either a task (for an entry call) or a protected object (for an entry
+call or a protected subprogram call). The target object is considered an
+implicit parameter to the operation, and is determined by the operation
address@hidden<name> (or @nt<prefix>) used in the call on the operation]},
+as follows:
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0291-1]}
+  @ChgAdded{Version=[3],Text=[This wording uses "denotes" to mean "denotes a
+  view of an entity" (when the term is used in Legality Rules), and "denotes an
+  entity" (when the term is used in Dynamic Semantics rules). It does not mean
+  "view of a declaration", as that would not include renames (a renames is not
+  an entry or protected subprogram).]}
address@hidden
+
address@hidden(Itemize)
address@hidden,Kind=[Revised],ARef=[AI05-0291-1]}
+  If it is a @nt<direct_name> or expanded name
+  that denotes the declaration (or body) of the operation, then
+  the target object is implicitly specified to be
+  the current instance of the task or protected unit
+  immediately enclosing the operation;
+  @Defn{internal call}
+  @Chg{Version=[3],New=[],Old=[such ]}a address@hidden,New=[ using
+  such a name],Old=[]} is defined to be an @i(internal call);
+
address@hidden,Kind=[Revised],ARef=[AI05-0291-1]}
+  If it is a @nt<selected_component> that is not
+  an expanded name, then the target object is explicitly
+  specified to be the @Chg{Version=[3],New=[],Old=[task or protected]} object
+  denoted by the @nt<prefix> of the @nt<name>;
+  @Defn{external call}
+  @Chg{Version=[3],New=[],Old=[such ]}a address@hidden,New=[ using
+  such a name],Old=[]} is defined to be an @i(external call);
+  @begin{Discussion}
+  For example:
address@hidden
address@hidden @key[type] Pt @key[is]
+  @key[procedure] Op1;
+  @key[procedure] Op2;
address@hidden Pt;
+
+PO : Pt;
+Other_Object : Some_Other_Protected_Type;
+
address@hidden @key[body] Pt @key[is]
+  @key[procedure] Op1 @key[is] @key[begin] ... @key[end] Op1;
+
+  @key[procedure] Op2 @key[is]
+  @key[begin]
+    Op1; address@hidden An internal call.}
+    Pt.Op1; address@hidden Another internal call.}
+    PO.Op1; address@hidden An external call. It the current instance is PO, 
then}
+            address@hidden this is a bounded error (see @RefSecNum{Protected 
Subprograms and Protected Actions}).}
+    Other_Object.Some_Op; address@hidden An external call.}
+  @key[end] Op2;
address@hidden Pt;
address@hidden
+  @end{Discussion}
+
address@hidden,Kind=[Revised],ARef=[AI05-0291-1]}
+  If the @nt<name> or @nt<prefix> is a dereference
+  (implicit or explicit) of an
+  access-to-protected-subprogram value,
+  then the target object is determined by the
+  @nt<prefix> of the Access @nt<attribute_reference>
+  that produced the access value address@hidden,New=[; a],
+  Old=[, and the]} address@hidden,New=[ using
+  such a name],Old=[]} is defined to be an @i(external call);
+
+  If the @nt<name> or @nt<prefix> denotes a
+  @nt<subprogram_renaming_declaration>,
+  then the target object is as determined by the @nt<name> of the renamed
+  entity.
+
address@hidden(Itemize)
+
address@hidden,Kind=[Added],ARef=[AI05-0291-1]}
address@hidden,Text=[A call on an entry or a protected subprogram either
+uses a @nt{name} or @nt{prefix} that determines a target object implicitly, as
+above, or is a call on (a non-prefixed view of) a primitive subprogram of a
+limited interface whose first parameter is a controlling parameter, in which
+case the target object is identified explicitly by the first parameter. This
+latter case is an @i<external call>.]}
+
address@hidden object],
+  Sec=(of a @nt<requeue_statement>)}
address@hidden requeue}
address@hidden requeue}
+A corresponding definition of target object applies
+to a @nt<requeue_statement> (see @RefSecNum(Requeue Statements)),
+with a corresponding distinction between an @i(internal requeue)
+and an @i(external requeue).
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00345-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0225-1],ARef=[AI05-0291-1]}
address@hidden,address@hidden,New=[If a @nt{name} or
address@hidden determines a target object, and the name denotes],Old=[The view 
of
+the target protected object associated with a call of]}
+a protected @Chg{Version=[3],New=[entry],Old=[procedure]} or
address@hidden,New=[procedure, then the target object],Old=[entry]}
+shall be a address@hidden,New=[, unless the
address@hidden is for an @nt{attribute_reference} to the Count
+attribute (see @RefSecNum{Task and Entry Attributes})],Old=[]}.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0225-1]}
+  @ChgAdded{Version=[3],Text=[The point is to prevent any calls to such a
+  @nt{name} whose target object is a constant view of a protected object,
+  directly, or via an access value, renames, or generic formal
+  subprogram. It is, however, legal to say P'Count in a protected function 
body,
+  even though the protected object is a constant view there.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0291-1]}
+  @ChgAdded{Version=[3],Text=[This rule does not apply to calls that are not to
+  a prefixed view. Specifically a "normal" call to a primitive operation of a
+  limited interface is not covered by this rule. In that case, the normal
+  parameter passing mode checks will prevent passing a constant protected
+  object to an operation implemented by a protected entry or procedure
+  as the mode is required to be @key[in out] or @key[out].]}
address@hidden
address@hidden
+
address@hidden
+Within the body of a protected operation, the current instance
+(see @RefSecNum(The Context of Overload Resolution))
+of the immediately enclosing protected unit is determined by the target object
+specified (implicitly or explicitly) in the call (or requeue) on the
+protected operation.
address@hidden
+The current instance is defined in the same way
+within the body of a subprogram declared immediately within a
address@hidden
address@hidden
+
+Any call on a protected procedure or entry of a target
+protected object is defined to be an update to the object,
+as is a requeue on such an entry.
address@hidden(Reason)
+  Read/write access to the components of a protected
+  object is granted while inside the body
+  of a protected procedure or entry.
+  Also, any protected entry call can change the value of the Count
+  attribute, which represents an update.
+  Any protected procedure call can result in servicing the entries,
+  which again might change the value of a Count attribute.
address@hidden(Reason)
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0030-2],ARef=[AI05-0215-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<synchronization_kind>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<By_Entry | By_Protected_Procedure | 
Optional>,Old=<>}"}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0215-1]}
address@hidden,Type=[Leading],Text=[For the declaration of a primitive
+procedure of a synchronized tagged type the following language-defined
+representation aspect may be specified with an @nt{aspect_specification} (see
address@hidden Specifications}):]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden specified, the aspect definition
+shall be a @address@hidden
+
address@hidden,Kind=[AddedNormal],Aspect=[Synchronization],
+  address@hidden,Text=[Defines whether a given primitive operation
+    of a synchronized interface must be implemented by an entry or protected
+    procedure.]}]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0030-2],ARef=[AI05-0215-1]}
address@hidden,Text=[Inherited subprograms inherit the Synchronization
+aspect, if any, from the corresponding subprogram of the parent or progenitor
+type. If an overriding operation does not have a directly specified
+Synchronization aspect then the Synchronization aspect of the inherited
+operation is inherited by the overriding operation.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0030-2],ARef=[AI05-0215-1]}
address@hidden,Text=[The @nt{synchronization_kind}
+By_Protected_Procedure shall not be applied to a primitive procedure of a task
+interface.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0030-2],ARef=[AI05-0215-1]}
address@hidden,Text=[A procedure for which the specified
address@hidden is By_Entry shall be implemented by an entry. A
+procedure for which the specified @nt{synchronization_kind} is
+By_Protected_Procedure shall be implemented by a protected procedure. A
+procedure for which the specified @nt{synchronization_kind} is Optional may be
+implemented by an entry or by a procedure (including a protected procedure).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0030-2],ARef=[AI05-0215-1]}
address@hidden,Text=[If a primitive procedure overrides an inherited
+operation for which the Synchronization aspect has been specified to be 
By_Entry
+or By_Protected_Procedure, then any specification of the aspect Synchronization
+applied to the overriding operation shall have the same
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0030-2]}
address@hidden,address@hidden contract issue}In addition to the
+places where @LegalityTitle normally apply (see
address@hidden Instantiation}), these rules also apply in the
+private part of an instance of a generic unit.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0030-2],ARef=[AI05-0215-1]}
address@hidden,Text=[The @nt{synchronization_kind} By_Protected_Procedure
+implies that the operation will not block.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00345-01]}
+  @ChgAdded{Version=[2],Text=[Added a @LegalityName to make it crystal-clear
+  that the protected object of an entry or procedure call must be a variable.
+  This rule was implied by the @RuntimeTitle here, along with the
+  @StaticSemTitle of @RefSecNum{Objects and Named Numbers}, but it is much
+  better to explicitly say it. While many implementations have gotten this
+  wrong, this is not an incompatibility @em allowing updates of protected
+  constants has always been wrong.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0030-2],ARef=[AI05-0215-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Added the Synchronization aspect to allow
+  specifying that an interface procedure is really an entry or a
+  protected procedure.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0225-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified that the target 
object
+  of any name denoted a protected procedure or entry can never be a constant
+  (other than for the 'Count attribute). This closes holes involving calls to
+  access-to-protected, renaming as a procedure, and generic formal 
subprograms.]}
address@hidden
+
+
address@hidden Subprograms and Protected Actions}
+
address@hidden
address@hidden subprogram}
address@hidden procedure}
address@hidden function}
+A @i{protected subprogram} is a subprogram declared immediately
+within a @nt{protected_definition}.
+Protected procedures provide exclusive read-write access
+to the data of a protected object; protected functions provide
+concurrent read-only access to the data.
address@hidden
+A subprogram declared immediately within a @nt{protected_body} is not a
+protected subprogram; it is an intrinsic subprogram.
+See @RefSec{Conformance Rules}.
address@hidden
address@hidden
+
address@hidden
address@hidden the body of a protected function
+(or a function declared immediately within a @nt<protected_body>),
+the current instance of the enclosing protected unit is defined to be a
+constant
+(that is, its subcomponents may be read but not updated).
+Within the body of a protected procedure
+(or a procedure declared immediately within a @nt<protected_body>),
+and within an @nt<entry_body>,
+the current instance is defined to be a variable
+(updating is permitted).]
address@hidden(TheProof)
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0120-1]}
+  @ChgAdded{Version=[3],Text=[All constant views are defined in
+  @RefSec{Objects and Named Numbers}, anything not named there
+  is a variable view.]}
address@hidden(TheProof)
address@hidden(Ramification)
+  The current instance is like an implicit parameter,
+  of mode @key(in) for a protected function, and of mode @key(in out)
+  for a protected procedure (or protected entry).
address@hidden(Ramification)
+
address@hidden,Kind=[Added],ARef=[AI12-0129-1]}
address@hidden,Type=[Leading],Text=[For a type declared by a
address@hidden or for the
+anonymous type of an object declared by a @nt{single_protected_declaration},
+the following language-defined type-related representation aspect
+may be specified:]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],address@hidden type of aspect
+  Exclusive_Functions is Boolean. If not specified (including by inheritance),
+  the aspect is address@hidden
+
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],address@hidden value of True for this aspect indicates 
that
+  protected functions behave in the same way as protected procedures
+  with respect to mutual exclusion and queue servicing (see below).]}
+
+  @ChgAspectDesc{Version=[4],Kind=[Added],Aspect=[Exclusive_Functions],
+    address@hidden,Text=[Specifies mutual exclusion behavior of
+      protected functions in a protected type.]}]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0129-1]}
address@hidden,Text=[A protected procedure or entry is an @i<exclusive>
+protected address@hidden,Sec=[protected operation]} A
+protected function of a protected type @i<P> is an exclusive protected
+operation if the Exclusive_Functions aspect of @i<P> is True.]}
+
address@hidden
+
address@hidden
+
address@hidden, Sec=(protected subprogram call)}
+For the execution of a call on a protected subprogram,
+the evaluation of the @nt<name> or @nt<prefix>
+and of the parameter associations,
+and any assigning back of @key[in out] or @key[out] parameters,
+proceeds as for a normal subprogram call (see @RefSecNum{Subprogram Calls}).
+If the call is an internal call (see @RefSecNum(Intertask Communication)),
+the body of the subprogram
+is executed as for a normal subprogram call.
+If the call is an external call, then
+the body of the subprogram is executed as part of a new
address@hidden(protected action) on the target protected object;
+the protected action completes after the body of the
+subprogram is executed.
address@hidden protected action can also be started by an entry call
+(see @RefSecNum{Entry Calls}).]
+
address@hidden,Kind=[Revised],ARef=[AI12-0129-1]}
address@hidden@Defn{protected action}
+A new protected action is not started on a protected object
+while another protected action on the same protected object is underway,
+unless both actions are the result of a call on a
address@hidden,New=[nonexclusive ],Old=[]}protected function.
+This rule is expressible in terms of the execution resource
+associated with the protected object:
address@hidden(Itemize)
address@hidden,Kind=[Revised],ARef=[AI12-0129-1]}
address@hidden action], Sec=(start)}
address@hidden, Sec=(execution resource associated with protected object)}
address@hidden(Starting) a protected action on a protected object
+corresponds to @i(acquiring) the execution resource associated
+with the protected object, either
+for @Chg{Version=[4],New=[exclusive read-write],Old=[concurrent read-only]}
+access if the protected action is for a call on @Chg{Version=[4],New=[an
+exclusive protected operation],Old=[a protected function]}, or
+for @Chg{Version=[4],New=[concurrent read-only],Old=[exclusive read-write]}
+access otherwise;
+
address@hidden action], Sec=(complete)}
address@hidden, Sec=(execution resource associated with protected object)}
address@hidden(Completing) the protected action
+corresponds to @i(releasing) the associated execution resource.
address@hidden(Itemize)
+
address@hidden,Kind=[Revised],ARef=[AI12-0129-1]}
address@hidden performing an @Chg{Version=[4],New=[exclusive
+protected ],Old=[]}operation on a protected address@hidden,New=[],Old=[
+other than a call on a protected function]}, but prior
+to completing the associated protected action,
+the entry queues (if any)
+of the protected object are
+serviced (see @RefSecNum(Entry Calls)).]
address@hidden
+
address@hidden
address@hidden@PDefn2{Term=(bounded error),Sec=(cause)}
+During a protected action, it is a bounded error to invoke an operation that
+is @i(potentially blocking).
address@hidden blocking operation}
address@hidden, potentially}
+The following are defined to be potentially blocking operations:
address@hidden
+  Some of these operations are not directly blocking.
+  However, they are still treated as bounded errors during a protected
+  action, because allowing them might impose an undesirable
+  implementation burden.
address@hidden
address@hidden
+a @nt{select_statement};
+
+an @nt{accept_statement};
+
+an @nt{entry_call_statement};
+
+a @nt{delay_statement};
+
+an @nt{abort_statement};
+
+task creation or activation;
+
+an external call on a protected subprogram (or an external requeue)
+with the same target object as that of the protected action;
address@hidden(Reason)
+  This is really a deadlocking call, rather than a blocking call,
+  but we include it in this list for simplicity.
address@hidden(Reason)
+
+a call on a subprogram whose body contains a
+potentially blocking operation.
address@hidden(Reason)
+  This allows an implementation to check and raise Program_Error
+  as soon as a subprogram is called, rather than waiting to find out
+  whether it actually reaches the potentially blocking operation.
+  This in turn allows the potentially blocking operation check
+  to be performed prior to run time in some environments.
address@hidden(Reason)
address@hidden
+
address@hidden,Sec=(raised by failure of run-time check)}
+If the bounded error is detected, Program_Error is raised.
+If not detected, the bounded error
+might result in deadlock or a (nested)
+protected action on the same target object.
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00305-01]}
address@hidden,Text=[By @lquotes@;nested protected address@hidden,
+we mean that an additional protected action can be started by another task
+on the same protected object. This means that mutual exclusion may be broken
+in this bounded error case. A way to ensure that this does not happen is to use
+pragma Detect_Blocking (see @RefSecNum{Pragma Detect_Blocking}).]}
address@hidden
+
+Certain language-defined subprograms are
+potentially blocking.
+In particular, the subprograms of
+the language-defined input-output packages that manipulate
+files (implicitly or explicitly) are potentially blocking.
+Other potentially blocking subprograms are identified
+where they are defined.
+When not specified as potentially blocking,
+a language-defined subprogram is nonblocking.
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00178-01]}
address@hidden,Text=[Any subprogram in a language-defined input-output
+package that has a file parameter or result or operates on a default file is
+considered to manipulate a file. An instance of a language-defined input-output
+generic package provides subprograms that are covered by this rule. The only
+subprograms in language-defined input-output packages not covered by this rule
+(and thus not potentially blocking) are the Get and Put routines that take
+string parameters defined in the packages nested in address@hidden
+was the resolution of a ramification.}
address@hidden
address@hidden
+
address@hidden
+If two tasks both try to start a protected action
+on a protected object, and at most one is calling
+a protected function, then only one of the tasks can proceed.
+Although the other task cannot proceed, it is not considered
+blocked, and it might be consuming processing resources while it
+awaits its turn. There is no language-defined ordering or queuing
+presumed for tasks competing to start a protected action @em
+on a multiprocessor such tasks might use busy-waiting; for
+monoprocessor considerations, see @RefSec{Priority Ceiling Locking}.
address@hidden
+The intended implementation on a multi-processor is in terms of
address@hidden@;spin address@hidden@; @em the waiting task will spin.
address@hidden
+
+The body of a protected unit may contain declarations and bodies for local
+subprograms. These are not visible outside the protected unit.
+
+The body of a protected function can contain internal calls
+on other protected functions, but not protected procedures,
+because the current instance is a constant.
+On the other hand, the body of a protected procedure
+can contain internal calls on both protected functions and procedures.
+
+From within a protected action,
+an internal call on a protected subprogram,
+or an external call on a protected subprogram with a different
+target object is not considered a potentially blocking operation.
address@hidden(Reason)
+  This is because a task is not considered blocked
+  while attempting to acquire the execution resource associated with
+  a protected object. The acquisition of such a resource
+  is rather considered part of the normal competition for execution
+  resources between the various tasks that are ready.
+  External calls that turn out to be on the same target
+  object are considered potentially blocking, since they
+  can deadlock the task indefinitely.
address@hidden(Reason)
+
address@hidden,Kind=[Added],ARef=[AI95-00305-01]}
address@hidden,Text=[The @nt{pragma} Detect_Blocking may be used to
+ensure that all executions of potentially blocking operations during a
+protected action raise Program_Error.
+See @RefSecNum{Pragma Detect_Blocking}.]}
address@hidden
+
address@hidden
address@hidden@i{Examples of protected subprogram calls
+(see @RefSecNum(Protected Units and Protected Objects)):}
address@hidden
+Shared_Array.Set_Component(N, E);
+E := Shared_Array.Component(M);
+Control.Release;
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00305-01]}
+  @ChgAdded{Version=[2],Text=[Added a note pointing out the existence of
+  @nt{pragma} Detect_Blocking. This pragma can be used to ensure portable
+  (somewhat pessimistic) behavior of protected actions by converting the
+  Bounded Error into a required check.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0129-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada 2012}
+  @b<Corrigendum:> Aspect Exclusive_Functions is new. The term
+  @ldquote@;exclusive protected address@hidden is new.]}
address@hidden
+
+
+
address@hidden and Accept Statements}
+
address@hidden
address@hidden<Entry_declaration>s, with the corresponding @ntf<entry_bodies>
+or @nt<accept_statement>s,
+are used to define potentially queued operations on
+tasks and protected objects.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00397-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<entry_declaration>,rhs="@Chg{Version=[2],New=<
+   address@hidden>,Old=[]}
+   @key{entry} @Syn2{defining_identifier} 
[(@Syn2{discrete_subtype_definition})] @address@hidden,New=<
+      address@hidden>,Old=[]};"}
+
+
address@hidden<accept_statement>,rhs="
+   @key{accept} @address@hidden [(@Syn2{entry_index})] 
@Syn2{parameter_profile} address@hidden
+     @Syn2{handled_sequence_of_statements}
+   @key{end} address@hidden@Syn2{identifier}]];"}
address@hidden
+  We cannot use @nt{defining_identifier} for @nt<accept_statement>s.
+  Although an @nt{accept_statement} is sort of like a body, it can appear
+  nested within a @nt{block_statement}, and therefore be hidden from
+  its own entry by an outer homograph.
address@hidden
+
address@hidden<entry_index>,rhs="@Syn2{expression}"}
+
+
address@hidden<entry_body>,rhs="
+  @key{entry} @Syn2{defining_identifier}  @Syn2{entry_body_formal_part}  
@Syn2{entry_barrier} @key{is}
+    @Syn2{declarative_part}
+  @key{begin}
+    @Syn2{handled_sequence_of_statements}
+  @key{end} address@hidden@Syn2{identifier}];"}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00397-01]}
+  @ChgAdded{Version=[2],Text=[We don't allow an @nt{overriding_indicator} on
+  an @nt{entry_body} because entries always implement procedures at the
+  point of the type declaration; there is no late implementation. And we
+  don't want to have to think about @nt{overriding_indicator}s on
+  @nt{accept_statement}s.]}
address@hidden
+
address@hidden<entry_body_formal_part>,
+  rhs="[(@Syn2{entry_index_specification})] @Syn2{parameter_profile}"}
+
+
address@hidden<entry_barrier>,
+  rhs="@key{when} @Syn2{condition}"}
+
+
address@hidden<entry_index_specification>,
+  rhs="@key{for} @Syn2{defining_identifier} @key{in} 
@Syn2{discrete_subtype_definition}"}
+
address@hidden
+If an @address@hidden appears at the end of an
address@hidden, it shall repeat the @address@hidden@nt<address@hidden>.
+If an @address@hidden@nt{identifier} appears at the end of an @address@hidden, 
it shall repeat the
address@hidden@!identifier}.
+
address@hidden @nt{entry_declaration} is allowed only in a protected or task
+declaration.]
address@hidden(TheProof)
+  This follows from the BNF.
address@hidden(TheProof)
+
address@hidden,Kind=[Added],ARef=[AI95-00397-01]}
address@hidden,Text=[An @nt{overriding_indicator} is not allowed in an
address@hidden that includes a @nt{discrete_subtype_definition}.]}
address@hidden(Reason)
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[An entry family can never implement something,
+  so allowing an indicator is felt by the majority of the ARG to be 
redundant.]}
address@hidden(Reason)
address@hidden
address@hidden
+
address@hidden
+
address@hidden profile],
+  Sec=(accept_statement @address@hidden<direct_name>)}
+In an @nt<accept_statement>,
+the expected profile for the @address@hidden<direct_name>
+is that of the @nt<address@hidden>;
address@hidden type],
+  Sec=(entry_index)}
+the expected type for an @nt<entry_index> is that
+of the subtype defined by the @nt<address@hidden@!definition>
+of the corresponding @nt<address@hidden>.
+
+Within the @nt<handled_sequence_of_statements> of an @nt<accept_statement>,
+if a @nt<address@hidden> has a @nt<prefix> that denotes
+the corresponding @nt<address@hidden>, then the
+entity denoted by the @nt<prefix> is the @nt<address@hidden>, and
+the @nt<address@hidden> is interpreted as an expanded name
+(see @RefSecNum(Selected Components))@Redundant[; the @nt<selector_name>
+of the @nt<address@hidden> has to be the @nt<identifier> for
+some formal parameter of the @nt<address@hidden>].
address@hidden
+  The only declarations that occur immediately within the
+  declarative region of an @nt<accept_statement> are those
+  for its formal parameters.
address@hidden
address@hidden
+
address@hidden
+
+An @nt<entry_declaration> in a task declaration shall not contain
+a specification for an access parameter (see @RefSecNum(Access Types)).
address@hidden(Reason)
+  @leading@;Access parameters for task entries would require a complex
+  implementation. For example:
+  @begin(Example)
address@hidden(task) T @key(is)
+   @key(entry) E(Z : @key(access) Integer); address@hidden Illegal!}
address@hidden(end) T;
+
address@hidden(task body) T @key(is)
address@hidden(begin)
+   @key(declare)
+      @key(type) A @key(is access all) Integer;
+      X : A;
+      Int : @key(aliased) Integer;
+      @key(task) Inner;
+      @key(task body) Inner @key(is)
+      @key(begin)
+         T.E(Int'Access);
+      @key(end) Inner;
+   @key(begin)
+      @key(accept) E(Z : @key(access) Integer) @key(do)
+         X := A(Z); address@hidden Accessibility_Check}
+      @key(end) E;
+   @key(end);
address@hidden(end) T;
address@hidden(Example)
+
+Implementing the Accessibility_Check inside the @nt<accept_statement> for
+E is difficult, since one does not know whether the entry caller
+is calling from inside the immediately enclosing declare block or from
+outside it. This means that the lexical nesting level associated with
+the designated object is not sufficient to determine whether the
+Accessibility_Check should pass or fail.
+
+Note that such problems do not arise with protected entries, because
address@hidden<entry_bodies> are always nested immediately within the
address@hidden<protected_body>; they cannot be further nested as can
address@hidden<accept_statement>s, nor can they be called from within the
address@hidden<protected_body> (since no entry calls are permitted inside
+a @nt<protected_body>).
address@hidden(Reason)
+
address@hidden,Kind=[Added],ARef=[AI95-00397-01]}
address@hidden,Type=[Leading],Text=[If an @nt{entry_declaration} has an
address@hidden, then at
+the point of the declaration:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[if the @nt{overriding_indicator} is
address@hidden, then the entry shall implement an inherited subprogram;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[if the @nt{overriding_indicator} is
address@hidden overriding}, then the entry shall not implement any inherited
+subprogram.]}
+
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden contract issue}In addition to the
+places where @LegalityTitle normally apply (see
address@hidden Instantiation}), these rules also apply in the private part
+of an instance of a generic unit.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[These rules are subtly different than those for
+  subprograms (see @RefSecNum{Overriding Indicators}) because there cannot be
+  @lquotes@;address@hidden inheritance of primitives from interfaces. Hidden
+  (that is, private) interfaces are prohibited explicitly (see
+  @RefSecNum{Private Types and Private Extensions}), as are hidden primitive
+  operations (as private operations of public abstract types are prohibited
+  @em see @RefSecNum{Abstract Types and Subprograms}).]}
address@hidden
+
+For an @nt<accept_statement>,
+the innermost enclosing body shall be a @nt<task_body>,
+and the @i(entry_)@address@hidden<address@hidden> shall
+denote an @nt<address@hidden> in the corresponding task declaration;
+the profile of the @address@hidden shall
+conform fully to that of the corresponding @nt<address@hidden>.
address@hidden conformance],Sec=(required)}
+An @nt<address@hidden> shall have a parenthesized @nt<address@hidden> if
+and only if the corresponding @nt<address@hidden> has a
address@hidden<address@hidden@!definition>.
+
+An @nt<accept_statement> shall not be within another
address@hidden that corresponds to the same @nt<address@hidden>,
+nor within an @nt<address@hidden> inner to
+the enclosing @nt<task_body>.
address@hidden(Reason)
address@hidden<Accept_statement>s are required to be immediately within
+the enclosing @nt<task_body> (as opposed to being in a nested
+subprogram) to ensure that a nested task does not
+attempt to accept the entry of its enclosing task. We considered
+relaxing this restriction, either by making the check a run-time
+check, or by allowing a nested task to accept an entry of its
+enclosing task. However, neither change seemed to provide sufficient
+benefit to justify the additional implementation burden.
+
+Nested @nt<accept_statement>s for the same entry (or entry family)
+are prohibited to ensure that there is no ambiguity in the
+resolution of an expanded name for a formal parameter of the
+entry. This could be relaxed by allowing the inner
+one to hide the outer one from all visibility, but again the
+small added benefit didn't seem to justify making the change for Ada 95.
+
address@hidden<Accept_statement>s are not permitted within 
@nt<asynchronous_select>
+statements to simplify the semantics and implementation:
+an @nt<accept_statement> in an @nt<abortable_part> could result
+in Tasking_Error being propagated from an entry call even though
+the target task was still callable; implementations that use
+multiple tasks implicitly to implement an @nt<asynchronous_select>
+might have trouble supporting "up-level" accepts.
+Furthermore, if @nt<accept_statement>s were permitted in
+the @nt<abortable_part>, a task could call its own
+entry and then accept it in the @nt<abortable_part>, leading
+to rather unusual and possibly difficult-to-specify semantics.
address@hidden(Reason)
+
address@hidden a completion], Sec=(protected @nt{entry_declaration})}
+An @nt{entry_declaration} of a protected unit requires
+a address@hidden, which shall be an @nt{entry_body},]
address@hidden as a completion], Sec=(@nt<entry_body>)}
+and every @nt<address@hidden> shall be the completion
+of an @nt<address@hidden> of a protected unit.
address@hidden legality], Sec=(@nt<entry_body>)}
+The profile of the @nt<address@hidden> shall conform fully to that
+of the corresponding declaration.
address@hidden conformance],Sec=(required)}
address@hidden
+An @nt<entry_declaration>, unlike a @nt<subprogram_declaration>,
+cannot be completed with a @nt<address@hidden>.
address@hidden
address@hidden(Honest)
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  @Chg{Version=[3],New=[If],Old=[The completion
+  can be a @nt{pragma} Import, if]} the implementation supports
+  address@hidden,New=[, the entry body can be imported
+  (using aspect Import, see @RefSecNum{Interfacing Aspects}),
+  in which case no explicit @nt{entry_body} is allowed],Old=[]}.
address@hidden(Honest)
address@hidden
+The above applies only to protected entries,
+which are the only ones completed with @ntf{entry_bodies}.
+Task entries have corresponding @nt{accept_statement}s
+instead of having @ntf{entry_bodies}, and
+we do not consider an @nt{accept_statement} to be a 
@lquotes@;completion,@rquotes@;
+because a task @nt{entry_declaration} is allowed to have zero, one, or more
+than one corresponding @nt{accept_statement}s.
address@hidden
+
+An @nt{entry_body_formal_part} shall have an @address@hidden@!specification}
+if and only if the corresponding @address@hidden has
+a @nt<address@hidden@!definition>.
+In this case, the @nt<address@hidden@!definition>s of the
address@hidden<address@hidden> and the @nt<address@hidden@!specification>
+shall fully conform to one another (see @RefSecNum(Conformance Rules)).
address@hidden conformance],Sec=(required)}
+
+A name that denotes a formal parameter of an @nt<entry_body> is not
+allowed within the @nt<entry_barrier> of the @nt<entry_body>.
+
address@hidden
+
address@hidden
+The parameter modes defined for parameters in the @nt<parameter_profile>
+of an @nt{entry_declaration}
+are the same as for a @nt<subprogram_declaration> and have
+the same meaning (see @RefSecNum(Formal Parameter Modes)).
address@hidden
+Note that access parameters are not allowed for task entries (see above).
address@hidden
+
address@hidden, Sec=(entry)}
address@hidden family}
address@hidden index subtype}
+An @nt<entry_declaration> with a @nt<discrete_subtype_definition>
+(see @RefSecNum(Array Types)) declares a @i(family) of distinct
+entries having the same profile, with one such entry for each
+value of the @i(entry index subtype) defined
+by the @nt<address@hidden@!definition>.
address@hidden name for an entry of a family takes the form of
+an @nt<indexed_component>, where the @nt<prefix> denotes
+the @nt<entry_declaration> for the family, and the index value
+identifies the entry within the family.]
address@hidden entry}
address@hidden, Sec=(single)}
+The term @i(single entry) is used to refer to any entry other
+than an entry of an entry family.
+
+In the @nt<entry_body> for an entry family,
+the @nt<entry_index_specification> declares a named constant
+whose subtype is the entry index subtype defined by the
+corresponding @nt<entry_declaration>;
address@hidden entry index}
+the value of the @i(named entry index) identifies
+which entry of the family was called.
address@hidden
+The @nt<discrete_subtype_definition> of the @nt<entry_index_specification>
+is not elaborated; the subtype of the named constant declared
+is defined by the @nt<discrete_subtype_definition> of the corresponding
address@hidden<entry_declaration>, which is elaborated, either when the
+type is declared, or when the object is created, if its constraint
+is per-object.
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0002],ARef=[AI95-00171-01]}
address@hidden, Sec=(entry_declaration)}
address@hidden elaboration of an @nt<entry_declaration> for an entry family
+consists of the elaboration of the @nt<address@hidden@!definition>, as
+described in @RefSecNum(Record Types).],
+Old=[For the elaboration of an @nt<address@hidden> for an
+entry family, if the
address@hidden@address@hidden contains no per-object expressions
+(see @RefSecNum(Record Types)), then the @nt<address@hidden@!definition>
+is elaborated. Otherwise, the elaboration of the
address@hidden<address@hidden> consists of the evaluation of any
+expression of the @nt<address@hidden@!definition>
+that is not a per-object expression (or part of one).]}
+The elaboration of an @nt<address@hidden> for a single entry
+has no effect.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The elaboration of the declaration of a protected subprogram has
+no effect, as specified in @Chg{Version=[3],New=[subclause],Old=[clause]}
address@hidden(Subprogram Declarations).
+The default initialization of an object of a task or protected
+type is covered in @RefSecNum(Object Declarations).
address@hidden
+
address@hidden actions to be performed when
+an entry is called are specified by the
+corresponding @address@hidden (if any) for an entry of a task unit,
+and by the corresponding @nt<address@hidden> for an entry of a protected unit.]
+
address@hidden, Sec=(accept_statement)}
+For the execution of an @nt{accept_statement}, the @nt<entry_index>, if
+any, is first evaluated and converted to the entry index subtype;
+this index value identifies which entry of the family is to be accepted.
address@hidden subtype conversion],Sec=(entry index)}
address@hidden, Sec=(on an @nt<accept_statement>)}
address@hidden, Sec=(of an entry caller)}
+Further execution of the @nt<accept_statement> is then blocked
+until a caller of the corresponding entry is selected
+(see @RefSecNum(Entry Calls)), whereupon
+the @nt<handled_sequence_of_statements>, if any, of the @nt<accept_statement>
+is executed, with the formal parameters associated with the
+corresponding actual parameters of the selected entry call.
+Upon completion of the @nt<handled_sequence_of_statements>,
+the @nt<accept_statement> completes and is left.
+When an exception is propagated from the
address@hidden of an @nt{accept_statement},
+the same exception is also raised by the execution of the corresponding
address@hidden
address@hidden
+This is in addition to propagating it to the construct
+containing the @nt{accept_statement}.
+In other words, for a rendezvous, the raising splits in two,
+and continues concurrently in both tasks.
+
+The caller gets a new occurrence;
+this isn't considered propagation.
+
+Note that we say @lquotes@;propagated from the
address@hidden of an @address@hidden@;,
+not @lquotes@;propagated from an @address@hidden@;
+The latter would be wrong @em we don't want exceptions propagated by
+the @nt<entry_index> to be sent to the caller (there is none yet!).
address@hidden
+
address@hidden
+The above interaction between a calling task and an
+accepting task is called a @i(rendezvous).
address@hidden a rendezvous, the two tasks continue
+their execution independently.]
+
address@hidden @nt<entry_body> is executed when the @nt<condition> of the
address@hidden<entry_barrier> evaluates to True and a caller of the 
corresponding
+single entry, or entry of the corresponding entry family,
+has been selected (see @RefSecNum(Entry Calls)).]
address@hidden, Sec=(entry_body)}
+For the execution of the @nt<address@hidden>,
+the @nt<address@hidden> of the @nt<address@hidden> is elaborated,
+and the @nt<address@hidden@!statements>
+of the body is executed, as for the execution
+of a @nt<subprogram_body>. The value of the named entry index, if any,
+is determined by the value of the entry index specified in the
address@hidden(entry_)@nt<name> of the selected entry call (or intermediate
address@hidden<address@hidden> @em see @RefSecNum(Requeue Statements)).
address@hidden(Honest)
+If the entry had been renamed as a subprogram,
+and the call was a @nt<procedure_call_statement> using
+the name declared by the renaming, the entry index (if any) comes from
+the entry @nt<name> specified in the
address@hidden<subprogram_renaming_declaration>.
address@hidden(Honest)
+
address@hidden
+
address@hidden
+
+A task entry has corresponding accept_statements (zero or more),
+whereas a protected entry has a corresponding entry_body (exactly
+one).
+
+A consequence of the rule regarding the allowed placements of
address@hidden is that a task can execute @nt{accept_statement}s
+only for its own entries.
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
+A @Chg{Version=[2],New=[return statement],address@hidden
+(see @RefSecNum(Return Statements))
+or a @nt<requeue_statement> (see @RefSecNum(Requeue Statements))
+may be used to complete the execution of
+an @nt<accept_statement> or an @nt<entry_body>.
address@hidden
+An @nt<accept_statement> need not have a @nt<handled_sequence_of_statements>
+even if the corresponding entry has parameters. Equally, it can have
+a @nt<handled_sequence_of_statements> even if the corresponding entry
+has no parameters.
address@hidden
address@hidden
+A single entry overloads a subprogram, an enumeration literal, or another
+single entry if they have the same @nt{defining_identifier}. Overloading is
+not allowed for entry family names.
+A single entry or an entry of an entry family
+can be renamed as a procedure as explained in
address@hidden Renaming Declarations}.
address@hidden
+
+The @nt<condition> in the @nt{entry_barrier} may reference
+anything visible except the formal parameters of the entry.
+This
+includes the entry index (if any), the components (including discriminants) of
+the protected object, the Count attribute of an entry of that protected object,
+and data global to the protected unit.
+
address@hidden@;The restriction against referencing the formal parameters 
within an
address@hidden ensures that all calls of the same entry see
+the same barrier value.
+If it is necessary to look at the parameters of an entry
+call before deciding whether to handle it, the @nt<entry_barrier>
+can be @lquotes@;@key(when) address@hidden@; and the caller can
+be requeued (on some private entry)
+when its parameters indicate that it cannot be handled immediately.
address@hidden
+
address@hidden
address@hidden@address@hidden of entry declarations:}
address@hidden
address@hidden(entry) Read(V : @key(out) Item);
address@hidden(entry) Seize;
address@hidden(entry) Request(Level)(D : Item);  address@hidden  a family of 
entries]
address@hidden
+
address@hidden
address@hidden@address@hidden of accept statements:}
address@hidden
address@hidden
address@hidden(accept) Shut_Down;
+
address@hidden(accept) Read(V : @key(out) Item) @key(do)
+   V := Local_Item;
address@hidden(end) Read;
+
address@hidden(accept) Request(Low)(D : Item) @key(do)
+   ...
address@hidden(end) Request;
address@hidden
+
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax rule for @nt{entry_body} is new.
+
address@hidden can now have @nt{exception_handler}s.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0002],ARef=[AI95-00171-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified the elaboration 
of
+  per-object constraints.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00397-01]}
+  @ChgAdded{Version=[2],address@hidden can be used on
+  entries; this is only useful when a task or protected type inherits
+  from an interface.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in an 
@nt{entry_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
address@hidden Calls}
+
address@hidden
address@hidden call}
address@hidden @nt<entry_call_statement> (an @i(entry call)) can appear in
+various contexts.]
address@hidden entry call}
address@hidden call}, Sec=(simple)}
+A @i(simple) entry call is a stand-alone statement that
+represents an unconditional call on an entry of a target
+task or a protected object.
address@hidden calls can also appear
+as part of @nt<select_statement>s
+(see @RefSecNum(Select Statements)).]
address@hidden
+
address@hidden
address@hidden<entry_call_statement>,rhs="@address@hidden address@hidden;"}
address@hidden
+
address@hidden
+The @i(entry_)@nt<name> given in an @nt<entry_call_statement> shall resolve
+to denote an entry. The rules for parameter
+associations are the same as for subprogram calls (see @RefSecNum(Subprogram 
Calls)
+and @RefSecNum(Parameter Associations)).
address@hidden
+
address@hidden
address@hidden @i(entry_)@nt<name> of an @nt<entry_call_statement> specifies
+(explicitly or implicitly) the target object of the call,
+the entry or entry family, and the entry index, if any
+(see @RefSecNum(Intertask Communication)).]
address@hidden
+
address@hidden
address@hidden@Defn{open entry}
address@hidden, Sec=(open)}
address@hidden entry}
address@hidden, Sec=(closed)}
+Under certain circumstances (detailed below), an entry of a task
+or protected
+object is checked to see whether it is @i(open) or @i(closed):
address@hidden(Itemize)
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden entry], Sec=(of a task)}
address@hidden entry], Sec=(of a task)}
+An entry of a task is open if the task
+is blocked on an @nt<accept_statement>
+that corresponds to the entry (see @RefSecNum(Entries and Accept Statements)),
+or on a @nt<selective_accept>
+(see @RefSecNum(Selective Accept)) with an open
address@hidden<accept_alternative> that corresponds to the entry;
address@hidden,New=[,],Old=[]} it is closed.
+
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden entry], Sec=(of a protected object)}
address@hidden entry], Sec=(of a protected object)}
+An entry of a protected object is open if
+the @nt<condition> of the @nt<entry_barrier> of the
+corresponding @nt<entry_body> evaluates to True;
address@hidden,New=[,],Old=[]} it is closed.
address@hidden,Sec=(raised by failure of run-time check)}
+If the evaluation of the @nt<condition> propagates an exception, the
+exception Program_Error is propagated
+to all current callers of all entries of the protected object.
address@hidden(Reason)
+  An exception during barrier evaluation is considered essentially
+  a fatal error. All current entry callers are notified with a Program_Error.
+  In a fault-tolerant system, a protected object might provide a Reset
+  protected procedure, or equivalent, to support attempts to restore such
+  a "broken" protected object to a reasonable state.
address@hidden(Reason)
address@hidden(Itemize)
address@hidden(Discussion)
+  Note that the definition of when a task entry is open is
+  based on the state of the (accepting) task, whereas the
+  "openness" of a protected entry is defined only
+  when it is explicitly checked, since the barrier expression needs to
+  be evaluated. Implementation permissions are given (below) to
+  allow implementations to evaluate the barrier expression more or
+  less often than it is checked, but the basic semantic model presumes
+  it is evaluated at the times when it is checked.
address@hidden(Discussion)
+
address@hidden@PDefn2{Term=[execution], Sec=(entry_call_statement)}
+For the execution of an @nt{entry_call_statement},
+evaluation of the @nt<name>
+and of the parameter associations
+is as for a subprogram call (see @RefSecNum{Subprogram Calls}).
address@hidden, Sec=(an entry call)}
+The entry call is then @i(issued):
+For a call on an entry of a protected object, a new protected
+action is started on the object (see @RefSecNum(Protected Subprograms and 
Protected Actions)).
+The named entry is checked to see if it is open;
address@hidden an entry call], Sec=(immediately)}
+if open, the entry call is said to be @i(selected immediately),
+and the execution of the call proceeds as follows:
address@hidden(Itemize)
+  For a call on an open entry of a task, the accepting task becomes ready and
+  continues the execution of the corresponding @nt<accept_statement>
+  (see @RefSecNum(Entries and Accept Statements)).
+
+  For a call on an open entry of a protected object, the corresponding
+  @nt<entry_body> is executed (see @RefSecNum(Entries and Accept Statements))
+  as part of the protected action.
address@hidden(Itemize)
+
+If the @nt<accept_statement> or @nt<entry_body> completes other than
+by a requeue (see @RefSecNum(Requeue Statements)), return is made to the
+caller (after servicing the entry queues @em see below);
+any necessary assigning back
+of formal to actual parameters occurs,
+as for a subprogram call (see @RefSecNum(Parameter Associations));
+such assignments take
+place outside of any protected action.
address@hidden(Ramification)
+  The return to the caller will generally not occur until
+  the protected action completes, unless some other thread of
+  control is given the job of completing the protected action
+  and releasing the associated execution resource.
address@hidden(Ramification)
+
+If the named entry is closed, the entry call is added to an @i(entry queue)
+(as part of the protected action, for a call on a protected entry),
+and the call remains queued until it is selected or cancelled;
address@hidden queue}
+there is a separate (logical) entry queue for each entry of a
+given task or protected object
address@hidden(including each entry of an entry family)].
+
address@hidden@Defn2{Term=[service], Sec=(an entry queue)}
address@hidden an entry call], Sec=(from an entry queue)}
+When a queued call is @i{selected}, it is removed from its entry queue.
+Selecting a queued call from a particular entry queue is
+called @i{servicing} the entry queue.
+An entry with queued calls can be serviced under
+the following circumstances:
address@hidden(Itemize)
+  When the associated task reaches a corresponding @nt<accept_statement>, or
+  a @nt<selective_accept> with a corresponding
+  open @nt<accept_alternative>;
+
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0129-1]}
+  If after performing, as part of a protected action on the
+  associated protected object, an
+  @Chg{Version=[4],New=[exclusive protected ],Old=[]}operation
+  on the address@hidden,New=[],Old=[ other than
+  a call on a protected function]},
+  the entry is checked and found to be open.
address@hidden(Itemize)
+
address@hidden an entry call], Sec=(from an entry queue)}
+If there is at least one call on a queue corresponding to
+an open entry, then one such call is selected according to the
address@hidden(entry queuing policy) in effect (see below), and the
+corresponding @nt<accept_statement> or @nt<entry_body> is
+executed as above for an entry call that is selected immediately.
+
address@hidden queuing policy}
+The entry queuing policy controls selection among queued calls
+both for task and protected entry queues.
address@hidden entry queuing policy}
address@hidden queuing policy], Sec=(default policy)}
+The default entry queuing policy is to select calls on a given entry
+queue in order of arrival. If calls from two or more queues are
+simultaneously eligible for selection, the default entry queuing policy
+does not specify which queue is serviced first.
+Other entry queuing policies can be specified by @nt{pragma}s
+(see @RefSecNum(Entry Queuing Policies)).
+
+For a protected object, the above servicing of entry queues continues
+until there are no open entries with queued calls, at which point
+the protected action completes.
address@hidden(Discussion)
+  While servicing the entry queues of a protected object, no new calls
+  can be added to any entry queue of the object,
+  except due to an internal requeue (see @RefSecNum(Requeue Statements)).
+  This is because the first step of a call on a protected entry
+  is to start a new protected action, which implies acquiring
+  (for exclusive read-write access)
+  the execution resource associated with the protected object, which cannot
+  be done while another protected action is already in progress.
address@hidden(Discussion)
+
address@hidden, Sec=(during an entry call)}
+For an entry call that is added to a queue,
+and that is not the @nt<triggering_statement> of an
address@hidden<address@hidden>
+(see @RefSecNum{Asynchronous Transfer of Control}),
+the calling task is blocked until the call is cancelled,
+or the call is selected and a corresponding @nt<accept_statement>
+or @nt<entry_body> completes without requeuing.
+In addition, the calling task is blocked during a rendezvous.
+
address@hidden
+
+For a call on a protected entry,
+the caller is not blocked if the call is selected immediately,
+unless a requeue causes the call to be queued.
+
address@hidden
+
address@hidden, Sec=(of an entry call)}
+An attempt can be made to cancel an entry call upon an abort
+(see @RefSecNum(Abort of a Task - Abort of a Sequence of Statements))
+and as part of certain forms of @nt<select_statement>
+(see @RefSecNum(Timed Entry Calls),
address@hidden(Conditional Entry Calls), and
address@hidden(Asynchronous Transfer of Control)).
+The cancellation does not take place until
+a point (if any) when the call is on some entry queue,
+and not protected from cancellation as part of a requeue
+(see @RefSecNum(Requeue Statements)); at such a point, the
+call is removed from the entry queue and the call completes due
+to the cancellation.
+The cancellation of a call on an entry of a protected object
+is a protected address@hidden, and as such cannot take place
+while any other protected action is occurring on the protected object.
+Like any protected action, it includes servicing of the entry queues
+(in case some entry barrier depends on a Count attribute).]
address@hidden(ImplNote)
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00114-01]}
+  In the case of an attempted cancellation due to abort,
+  this removal might have to be performed by the calling task
+  itself if the ceiling priority of the protected object
+  is lower than the @Chg{Version=[2],New=[priority of the ],Old=[]}task
+  initiating the abort.
address@hidden(ImplNote)
+
address@hidden,Sec=(raised by failure of run-time check)}
+A call on an entry of a task that has already completed its execution
+raises the exception Tasking_Error at the point of the call;
+similarly, this exception is raised at the point of the call if the
+called task completes its execution or becomes abnormal before accepting
+the call or completing the rendezvous
+(see @RefSecNum(Abort of a Task - Abort of a Sequence of Statements)).
+This applies equally to a simple entry call and to an entry call as part
+of a @nt<select_statement>.
+
address@hidden
+
address@hidden
+
+An implementation may perform the sequence of steps of a protected action
+using any thread of control; it need not be that of the task
+that started the protected action.
+If an @nt<entry_body> completes without requeuing, then the
+corresponding calling task may be made ready
+without waiting for the entire protected action to complete.
address@hidden(Reason)
+  These permissions are intended to allow flexibility for implementations
+  on multiprocessors. On a monoprocessor, which thread of control executes
+  the protected action is essentially invisible, since the thread is
+  not abortable in any case, and the "current_task" function is not
+  guaranteed to work during a protected action
+  (see @Chg{Version=[2],address@hidden(The Package Task_Identification)],
+  address@hidden(Task Information)]}).
address@hidden(Reason)
+
address@hidden,Kind=[Revised],ARef=[AI12-0129-1]}
+When the entry of a protected object is checked to see whether it
+is open, the implementation need not reevaluate
+the @nt<condition> of the corresponding @nt<entry_barrier>
+if no variable or attribute referenced by
+the @nt<condition> (directly or indirectly)
+has been altered by the execution (or cancellation) of a
address@hidden,New=[],Old=[protected procedure or entry ]}call
address@hidden,New=[to an exclusive protected operation of],Old=[on]} the
+object since the @nt<condition> was last evaluated.
address@hidden(Ramification)
+  @ChgRef{Version=[4],Kind=[Revised]}
+  Changes to variables referenced by an entry barrier that
+  result from actions outside of a
+  @Chg{Version=[4],New=[],Old=[protected procedure or entry ]}call
+  @Chg{Version=[4],New=[to an exclusive protected operation of],Old=[on]} the
+  protected object need not be "noticed." For example, if
+  a global variable is referenced by an entry barrier, it should not
+  be altered (except as part of a protected action on the object) any
+  time after the barrier is first evaluated.
+  In other words, globals can be used to "parameterize" a protected object,
+  but they cannot reliably be used to control it after the first
+  use of the protected object.
address@hidden(Ramification)
address@hidden
+  Note that even if a global variable is volatile,
+  the implementation need only reevaluate a barrier if the
+  global is updated during a protected action on the protected object.
+  This ensures that an entry-open bit-vector implementation
+  approach is possible, where the bit-vector is computed at
+  the end of a protected action, rather than upon each entry call.
address@hidden
+
+An implementation may evaluate the @nt<condition>s of all @nt<entry_barrier>s
+of a given protected object any time any entry of the object
+is checked to see if it is open.
address@hidden(Ramification)
+  In other words, any side effects of evaluating an entry barrier
+  should be innocuous, since an entry barrier might be evaluated more
+  or less often than is implied by the "official" dynamic semantics.
address@hidden(Ramification)
address@hidden(ImplNote)
+  It is anticipated that when the number of entries is known to be small,
+  all barriers will be evaluated any time one of them needs to be,
+  to produce an "entry-open bit-vector." The appropriate bit will
+  be tested when the entry is called, and only if the bit is false
+  will a check be made to see whether the bit-vector might need to
+  be recomputed. This should allow an implementation to maximize
+  the performance of a call on an open entry, which seems like the
+  most important case.
+
+  In addition to the entry-open bit-vector, an "is-valid"
+  bit is needed per object, which indicates whether the current
+  bit-vector setting is valid.
+  A "depends-on-Count-attribute" bit is needed per type.
+  The "is-valid" bit is set to false
+  (as are all the bits of the bit-vector) when the protected object is first
+  created, as well as any time an exception is propagated from computing
+  the bit-vector. Is-valid would also be set false any time the
+  Count is changed and
+  "depends-on-Count-attribute" is true for the type, or a
+  protected procedure or entry returns indicating it might have updated a
+  variable referenced in some barrier.
+
+  A single procedure can be compiled to evaluate all of the barriers,
+  set the entry-open bit-vector accordingly, and set the is-valid bit to true.
+  It could have a "when others" handler to set them all false,
+  and call a routine to propagate Program_Error to all queued callers.
+
+  For protected types where the number of entries is not known to be
+  small, it makes more sense to evaluate a barrier only when the
+  corresponding entry is checked to see if it is open. It isn't worth
+  saving the state of the entry between checks, because of the space
+  that would be required. Furthermore, the entry queues probably want
+  to take up space only when there is actually a caller on them, so
+  rather than an array of all entry queues, a linked list of nonempty
+  entry queues make the most sense in this case, with the first caller
+  on each entry queue acting as the queue header.
address@hidden(ImplNote)
+
+When an attempt is made to cancel an entry call, the implementation
+need not make the attempt using the thread of control of the
+task (or interrupt) that initiated the cancellation; in particular,
+it may use the thread of control of the caller itself to attempt the
+cancellation, even if this might allow the entry call to be
+selected in the interim.
address@hidden
+  Because cancellation of a protected entry call is a protected
+  action (which helps make the Count attribute of a protected
+  entry meaningful), it might
+  not be practical to attempt the cancellation from the thread
+  of control that initiated the cancellation. For example,
+  if the cancellation is due to the expiration of a delay,
+  it is unlikely that the handler of the timer interrupt could
+  perform the necessary protected action itself (due to being
+  on the interrupt level). Similarly, if the cancellation
+  is due to an abort, it is possible that the task initiating
+  the abort has a priority higher than the ceiling priority of the
+  protected object (for implementations that support ceiling priorities).
+  Similar considerations could apply in a multiprocessor situation.
address@hidden
+
address@hidden
+
address@hidden
+
+If an exception is raised during the execution of an @nt{entry_body}, it is
+propagated to the corresponding caller (see @RefSecNum(Exception Handling)).
+
+For a call on a protected entry, the entry is checked to see if
+it is open prior to queuing the call, and again thereafter
+if its Count attribute (see @RefSecNum{Task and Entry Attributes})
+is referenced in some entry barrier.
address@hidden(Ramification)
+  Given this, extra care is required if
+  a reference to the Count attribute of an entry
+  appears in the entry's own barrier.
address@hidden(Ramification)
address@hidden(Reason)
+  An entry is checked to see if it is open prior to queuing
+  to maximize the performance of a call on an open entry.
address@hidden(Reason)
+
+In addition to simple entry calls,
+the language permits timed, conditional, and asynchronous entry calls
+(see @RefSecNum(Timed Entry Calls), @RefSecNum(Conditional Entry Calls),
+and see @RefSecNum(Asynchronous Transfer of Control)).
address@hidden
+A task can call its own entries, but
+the task will deadlock if the call is a simple entry call.
address@hidden
+
+The @nt<condition> of an @nt<entry_barrier> is allowed to be evaluated by
+an implementation more often than strictly necessary, even if the
+evaluation might have side effects. On the other hand, an implementation
+need not reevaluate the @nt<condition> if nothing it references was
+updated by an intervening protected action on the protected object,
+even if the @nt<condition> references some global variable that might
+have been updated by an action performed from outside of a protected action.
address@hidden
+
address@hidden
address@hidden@address@hidden of entry calls:}
address@hidden
+Agent.Shut_Down;                      address@hidden  see @RefSecNum(Task 
Units and Task Objects)]
+Parser.Next_Lexeme(E);                address@hidden  see @RefSecNum(Task 
Units and Task Objects)]
+Pool(5).Read(Next_Char);              address@hidden  see @RefSecNum(Task 
Units and Task Objects)]
+Controller.Request(Low)(Some_Item);   address@hidden  see @RefSecNum(Task 
Units and Task Objects)]
+Flags(3).Seize;                       address@hidden  see @RefSecNum(Protected 
Units and Protected Objects)]
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0129-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Revised wording to talk
+  about @ldquote@;exclusive protected address@hidden
+  (see @RefSecNum{Protected Subprograms and Protected Actions}).]}
address@hidden
+
+
address@hidden Statements}
+
address@hidden
address@hidden @nt<requeue_statement>
+can be used to complete an @nt<accept_statement> or @nt<entry_body>,
+while redirecting the corresponding entry call to a new (or the same)
+entry queue.
address@hidden
+Such a @i(requeue) can be performed with or without allowing
+an intermediate cancellation of the call, due to an abort or
+the expiration of a delay.
address@hidden control],See=(requeue)}
address@hidden signal],See=(requeue)}]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0030-2]}
address@hidden<requeue_statement>,
+  rhs="@key{requeue} @address@hidden,New=[procedure_or_entry_],address@hidden 
address@hidden @key{abort}];"}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0030-2],ARef=[AI05-0215-1]}
address@hidden,address@hidden target}],address@hidden entry], Sec=(of a 
@nt<requeue_statement>)}]}
+The @Chg{Version=[3],address@hidden,address@hidden(entry_)address@hidden
+of a @nt{requeue_statement} shall resolve
+to denote @Chg{Version=[3],New=[a procedure or ],Old=[]}an entry (the
address@hidden,address@hidden }],address@hidden@Chg{Version=[3],New=[],
address@hidden entry}]})@Chg{Version=[3],New=[. The profile of
+the entry, or the profile or prefixed profile of the procedure, 
shall],Old=[that]}
+either @Chg{Version=[3],New=[have],Old=[has]} no parameters, or 
@Chg{Version=[3],
+New=[be],Old=[that has
+a profile that is]} type conformant (see @RefSecNum(Conformance Rules)) with
+the profile of the innermost enclosing @nt<address@hidden> or
address@hidden<address@hidden>.
address@hidden conformance],Sec=(required)}
address@hidden
+
address@hidden
+
+A @nt{requeue_statement} shall be within a callable
+construct that is either an @nt{entry_body} or an
address@hidden, and this construct shall
+be the innermost enclosing body or callable construct.
+
address@hidden,Kind=[Revised],ARef=[AI05-0030-2],ARef=[AI05-0215-1]}
+If the
address@hidden,New=[requeue ],address@hidden,New=[],Old=[ entry]}
+has parameters, then its @Chg{Version=[3],New=[(prefixed) ],Old=[]}profile
+shall be subtype conformant with
+the profile of the innermost enclosing callable construct.
address@hidden conformance],Sec=(required)}
+
address@hidden,Kind=[Added],ARef=[AI12-0090-1]}
address@hidden,Type=[Leading],Text=[Given a requeue_statement where the
+innermost enclosing callable construct is for an entry @i<E1>, for every
address@hidden or class-wide ]postcondition expression @i<P1> that
+applies to @i<E1>, there shall exist a postcondition expression @i<P2> that
+applies to the requeue target @i<E2> such that]}
address@hidden
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],address@hidden<P1> is fully conformant with
+  the expression produced by replacing each reference in @i<P2> to a formal
+  parameter of @i<E2> with a reference to the corresponding formal paramter
+  of @i<E1>; and]}
+
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Text=[if @i<P1> is enabled, then @i<P2> is also 
enabled.]}
address@hidden
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[Roughly speaking, the postcondition of the 
requeue
+  target is required to imply that of the enclosing callable construct.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0090-1]}
address@hidden,Text=[The requeue target shall not have an applicable
+specific or class-wide postcondition which includes an Old
+attribute_reference.]}
+
address@hidden,Kind=[Added],ARef=[AI12-0090-1]}
address@hidden,Text=[If the requeue target is declared immediately
+within the @nt{task_definition} of a named task type or the
address@hidden of a named protected type, and if the requeue
+statement occurs within the body of that type, and if the requeue is an 
external
+requeue, then the requeue target shall not have a specific or class-wide
+postcondition which includes a name denoting either the current instance of 
that
+type or any entity declared within the declaration of that type.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[The above pair of rules always apply; they
+  don't depend on whether or not any of the postconditions are enabled.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0030-2],ARef=[AI05-0215-1]}
address@hidden,Kind=[RevisedAdded],address@hidden a number change}
address@hidden,Text=[If the target is a procedure, the name shall
+denote a renaming of an entry, or shall denote a view or a prefixed view of a
+primitive subprogram of a synchronized interface, where the first parameter
+of the unprefixed view of the primitive subprogram shall be a
+controlling parameter, and the Synchronization aspect shall be specified
+with @nt{synchronization_kind} By_Entry for the primitive subprogram.]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0030-2]}
address@hidden rule],Sec=(requeue statement)}
+In a @nt<requeue_statement> of an @nt<accept_statement> of
+some task unit, either the target object shall be a part of a
+formal parameter of the @nt<accept_statement>,
+or the accessibility level of the target object
+shall not be equal to or statically deeper than any
+enclosing @nt<accept_statement> of the task unit.
+In a @nt<address@hidden> of an @nt<address@hidden>
+of some protected unit, either the target object shall be
+a part of a formal parameter of the @nt<address@hidden>,
+or the accessibility level of the target object
+shall not be statically deeper than that
+of the @nt<entry_declaration>@Chg{Version=[3],New=[ for the 
@nt{entry_body}],Old=[]}.
+
address@hidden
+  In the @nt{entry_body} case, the intent is that the target object can
+  be global,
+  or can be a component of the protected unit,
+  but cannot be a local variable of the @nt{entry_body}.
address@hidden
address@hidden(Reason)
+  These restrictions ensure that the target object of the requeue outlives the
+  completion and finalization of the enclosing callable construct.
+  They also prevent requeuing from a nested
+  @nt<accept_statement> on a parameter of an outer @nt<accept_statement>,
+  which could create some strange "long-distance" connections between
+  an entry caller and its server.
+
+  Note that in the strange case where a @nt<task_body> is nested inside
+  an @nt<accept_statement>, it is permissible to requeue from an
+  @nt<accept_statement> of the inner @nt<task_body> on parameters of
+  the outer @nt<accept_statement>. This is not
+  a problem because all calls on the inner task have to complete before
+  returning from the outer @nt<accept_statement>, meaning no "dangling
+  calls" will be created.
address@hidden(Reason)
address@hidden(ImplNote)
+  By disallowing certain requeues,
+  we ensure that the normal @nt<terminate_alternative> rules remain
+  sensible, and that explicit clearing of the entry queues of a protected
+  object during finalization is rarely necessary. In particular, such
+  clearing of the entry queues is necessary only (ignoring premature
+  Unchecked_Deallocation) for protected objects declared in a
+  @nt<task_body> (or created by an allocator for an access type declared
+  in such a body) containing one or more @nt<requeue_statement>s.
+  Protected objects declared in subprograms, or at the library level,
+  will never need to have their entry queues explicitly cleared during
+  finalization.
address@hidden(ImplNote)
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0030-2]}
address@hidden,Kind=[Revised],ARef=[AI12-0090-1]}
address@hidden, Sec=(requeue_statement)}
+The execution of a @nt{requeue_statement} proceeds by first evaluating the
address@hidden,address@hidden,address@hidden(entry_)address@hidden<name>@Redundant[,
+including the @nt<prefix> identifying the target task
+or protected object and the @nt<expression> identifying the entry within an
+entry family, if any]. @Chg{Version=[4],New=[Precondition checks are then
+performed as for a call to the requeue target entry or subprogram. ],Old=[]}The
address@hidden or @nt{accept_statement} enclosing the @nt{requeue_statement} is
+then address@hidden, finalized, and
+left (see @RefSecNum(Completion and Finalization))].
+
address@hidden, Sec=(requeue task entry)}
+For the execution of a requeue on an entry of a target task,
+after leaving the enclosing callable construct, the named entry
+is checked to see if it is open and the requeued call is either
+selected immediately or queued, as for a normal entry call
+(see @RefSecNum(Entry Calls)).
+
address@hidden@PDefn2{Term=[execution], Sec=(requeue protected entry)}
+For the execution of a requeue on an entry of a target protected
+object, after leaving the enclosing callable construct:
address@hidden(Itemize)
+  if the requeue is an internal requeue
+  (that is, the requeue is back on an entry of the same protected object @em
+  see @RefSecNum(Intertask Communication)),
+  the call is added to the queue of the named entry and
+  the ongoing protected action continues (see @RefSecNum(Protected Subprograms 
and Protected Actions));
+  @begin(Ramification)
+    Note that for an internal requeue, the call
+    is queued without checking whether the target entry is open.
+    This is because the entry queues will be serviced before the
+    current protected action completes anyway, and considering the
+    requeued call immediately might allow it to "jump" ahead of
+    existing callers on the same queue.
+  @end(Ramification)
+
+  if the requeue is an external requeue (that is, the target protected
+  object is not implicitly the same as the current object @em
+  see @RefSecNum(Intertask Communication)),
+  a protected action is started on the target object and proceeds
+  as for a normal entry call (see @RefSecNum(Entry Calls)).
address@hidden(Itemize)
+
address@hidden,Kind=[Revised],ARef=[AI05-0030-2]}
address@hidden,Kind=[Revised],ARef=[AI05-0090-1]}
+If the @Chg{Version=[3],New=[requeue target],Old=[new entry]}
+named in the @nt<requeue_statement>
+has formal parameters, then during the execution of the
address@hidden<accept_statement> or @nt<entry_body> corresponding to the new
address@hidden,New=[ and during the checking of
+any preconditions of the new entry],Old=[]},
+the formal parameters denote the same objects as
+did the corresponding formal parameters
+of the callable construct completed by the requeue.
address@hidden any case, no parameters are specified in a
address@hidden<requeue_statement>; any parameter passing is implicit.]
+
address@hidden@Defn{requeue-with-abort}
+If the @nt<requeue_statement> includes the reserved words @key(with abort)
+(it is a @i(requeue-with-abort)), then:
address@hidden(Itemize)
+  if the original entry call has been aborted
+  (see @RefSecNum(Abort of a Task - Abort of a Sequence of Statements)), then
+  the requeue acts as an abort completion point for the call,
+  and the call is cancelled and no requeue is
+  performed;
+
+  if the original entry call was timed (or conditional),
+  then the original expiration time is the expiration
+  time for the requeued call.
address@hidden(Itemize)
+
+If the reserved words @key(with abort) do not appear, then the
+call remains protected against cancellation while queued as the result
+of the @nt<requeue_statement>.
address@hidden(Ramification)
+  This protection against cancellation lasts only until the
+  call completes or a subsequent requeue-with-abort is performed
+  on the call.
address@hidden(Ramification)
address@hidden(Reason)
+  We chose to protect a requeue, by default, against abort or cancellation.
+  This seemed safer, since it is likely that extra steps need to be taken
+  to allow for possible cancellation once the servicing of an entry
+  call has begun. This also means that in the absence of @key(with abort)
+  the usual Ada 83 behavior is preserved, namely that once an
+  entry call is accepted, it cannot be cancelled until it completes.
address@hidden(Reason)
address@hidden
+
address@hidden
+
+A requeue is permitted from a single entry to an entry of
+an entry family, or vice-versa. The entry index, if any,
+plays no part in the subtype conformance check between the
+profiles of the two entries; an entry index
+is part of the @i(entry_)@nt<name> for an entry of a family.
address@hidden conformance}
+
address@hidden
+
address@hidden
address@hidden@address@hidden of requeue statements:}
address@hidden
address@hidden Request(Medium) @key[with abort];
+                    address@hidden requeue on a member of an entry family of 
the current task, see @RefSecNum{Task Units and Task Objects}]
+
address@hidden Flags(I).Seize;
+                    address@hidden requeue on an entry of an array component, 
see @RefSecNum{Protected Units and Protected Objects}]
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The @nt<requeue_statement> is new.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0030-2],ARef=[AI05-0215-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Added the ability
+  to requeue on operations of synchronized interfaces that are
+  declared to be an entry.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0090-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  We now define that any preconditions of the requeue target are evaluated
+  as part of a @nt<requeue_statement>. Original Ada 2012 did not specify this,
+  so a program that requeues when the preconditions fail will raise an
+  exception when none would happen in original Ada 2012. We don't expect this
+  to be a problem, as in that case, the entry body would be called with some
+  of its preconditions evaluating as False; the body is likely to assume that
+  they are true and probably will have failed in some other way anyway.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0090-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  If a requeue target has a different postcondition than the original
+  entry, the requeue is now illegal. In such a case, the original postcondition
+  would never have been evaluated, and assumptions that the caller relied upon
+  might not be true. A requeue should be invisible to the caller with respect
+  to any postconditions; thus we only allow it when the original entry has no
+  postconditions or the requeue target has (at least) the same 
postconditions.]}
address@hidden
+
+
address@hidden Statements, Duration, and Time}
+
address@hidden
address@hidden@PDefn{expiration time}
+A @nt<delay_statement> is used to block further execution until
+a specified @i(expiration time) is reached.
+The expiration time
+can be specified either as a particular point in time (in a
address@hidden<address@hidden@!statement>), or in seconds from the current time
+(in a @nt<address@hidden@!statement>).
+The language-defined
+package Calendar provides definitions for a type Time and associated
+operations, including a function Clock that returns the current time.
address@hidden,See=(delay_statement)}]
address@hidden
+
address@hidden
address@hidden<delay_statement>,
+  rhs="@Syn2{delay_until_statement} | @Syn2{delay_relative_statement}"}
+
+
address@hidden<delay_until_statement>,
+  rhs="@key{delay until} @SynI(delay_)@Syn2{expression};"}
+
address@hidden<delay_relative_statement>,
+  rhs="@key{delay} @SynI(delay_)@Syn2{expression};"}
address@hidden
+
address@hidden
+
address@hidden type],
+  Sec=(delay_relative_statement expression)}
+The expected type for the @i(delay_)@nt{expression} in a
address@hidden is the predefined type Duration.
address@hidden type],
+  Sec=(delay_until_statement expression)}
+The @i(delay_)@nt<expression> in a @nt<delay_until_statement>
+is expected to be of any nonlimited type.
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
address@hidden type}
address@hidden base}
address@hidden
+There can be multiple time bases, each with a corresponding
+clock, and a corresponding @i{time type}.
+The type of the @i(delay_)@nt<expression>
+in a @nt{delay_until_statement} shall be a time type @em either the
+type Time defined in the language-defined package Calendar (see
+below),@Chg{Version=[3],New=[ the type Time in the package Real_Time
+(see @RefSecNum(Monotonic Time)),],Old=[]}
+or some other implementation-defined time address@hidden,New=[],Old=[
+(see @RefSecNum(Monotonic Time))]}.
address@hidden implementation-defined time types.}
address@hidden
+
address@hidden
address@hidden is a predefined fixed point type
+named Duration, declared in the visible part of package Standard;]
+a value of type Duration is used to represent the length
+of an interval of time, expressed in seconds.
address@hidden type Duration is not specific to a particular time base,
+but can be used with any time base.]
+
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
+A value of the type Time in package Calendar, or of some other
address@hidden,New=[],Old=[implementation-defined ]}time type,
+represents a time as reported by a corresponding clock.
+
address@hidden@keepnext@;The following language-defined library package exists:
address@hidden
address@hidden,Child=[Calendar]}
address@hidden(package) Ada.Calendar @key(is)
+  @key(type) @AdaTypeDefn{Time} @key(is) @key(private);
+
address@hidden,Kind=[Revised],ARef=[AI95-00351-01]}
+  @key(subtype) @AdaSubtypeDefn{Name=[Year_Number],Of=[Integer]}  @key(is) 
Integer @key(range) 1901 .. @Chg{Version=[2],New=[2399],Old=[2099]};
+  @key(subtype) @AdaSubtypeDefn{Name=[Month_Number],Of=[Integer]} @key(is) 
Integer @key(range) 1 .. 12;
+  @key(subtype) @AdaSubtypeDefn{Name=[Day_Number],Of=[Integer]}   @key(is) 
Integer @key(range) 1 .. 31;
+  @key(subtype) @AdaSubtypeDefn{Name=[Day_Duration],Of=[Duration]} @key(is) 
Duration @key(range) 0.0 .. 86_400.0;
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00351-01]}
+  @ChgAdded{Version=[2],Text=[A range of 500 years was chosen, as that only
+  requires one extra bit for the year as compared to Ada 95. This was done
+  to minimize disruptions with existing implementations. (One implementor
+  reports that their time values represent nanoseconds, and this year range
+  requires 63.77 bits to represent.)]}
address@hidden
+
+  @key(function) @AdaSubDefn{Clock} @key(return) Time;
+
+  @key(function) @AdaSubDefn{Year}   (Date : Time) @key(return) Year_Number;
+  @key(function) @AdaSubDefn{Month}  (Date : Time) @key(return) Month_Number;
+  @key(function) @AdaSubDefn{Day}    (Date : Time) @key(return) Day_Number;
+  @key(function) @AdaSubDefn{Seconds}(Date : Time) @key(return) Day_Duration;
+
+  @key(procedure) @AdaSubDefn{Split} (Date  : @key(in) Time;
+                   Year    : @key(out) Year_Number;
+                   Month   : @key(out) Month_Number;
+                   Day     : @key(out) Day_Number;
+                   Seconds : @key(out) Day_Duration);
+
+  @key(function) @AdaSubDefn{Time_Of}(Year  : Year_Number;
+                   Month   : Month_Number;
+                   Day     : Day_Number;
+                   Seconds : Day_Duration := 0.0)
+   @key(return) Time;
+
+  @key(function) "+" (Left : Time;   Right : Duration) @key(return) Time;
+  @key(function) "+" (Left : Duration; Right : Time) @key(return) Time;
+  @key(function) "-" (Left : Time;   Right : Duration) @key(return) Time;
+  @key(function) "-" (Left : Time;   Right : Time) @key(return) Duration;
+
+  @key(function) "<" (Left, Right : Time) @key(return) Boolean;
+  @key(function) "<="(Left, Right : Time) @key(return) Boolean;
+  @key(function) ">" (Left, Right : Time) @key(return) Boolean;
+  @key(function) ">="(Left, Right : Time) @key(return) Boolean;
+
+  @AdaExcDefn{Time_Error} : @key(exception;)
+
address@hidden(private)
+   ... -- @RI{not specified by the language}
address@hidden(end) Ada.Calendar;
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden, Sec=(delay_statement)}
+For the execution of a @nt<delay_statement>, the @i(delay_)@nt<expression>
+is first evaluated.
address@hidden time], Sec=(for a @nt<delay_until_statement>)}
+For a @nt<delay_until_statement>, the expiration time for the
+delay is the value of the @i(delay_)@nt<expression>, in the time
+base associated with the type of the @nt<expression>.
address@hidden time], Sec=(for a @nt<delay_relative_statement>)}
+For a @nt<delay_relative_statement>, the expiration time is
+defined as the current time, in the time base associated
+with relative delays, plus
+the value of the @i(delay_)@nt<expression>
+converted to the type Duration, and then rounded up
+to the next clock tick.
address@hidden subtype conversion],Sec=(delay expression)}
+The time base associated with relative delays
+is as defined in @RefSec{Delay Accuracy} or is
+implementation defined.
address@hidden time base associated with relative delays.}
address@hidden
+  Rounding up to the next clock tick means that the reading of the
+  delay-relative clock when the delay expires should be no less than
+  the current reading of the delay-relative
+  clock plus the specified duration.
address@hidden
+
address@hidden, Sec=(on a @nt<delay_statement>)}
+The task executing a @nt<delay_statement> is blocked
+until the expiration time is reached, at which point it
+becomes ready again. If the expiration time
+has already passed, the task is not blocked.
address@hidden(Discussion)
+  For a @nt<delay_relative_statement>, this case corresponds to
+  when the value of the @i(delay_)@nt<expression> is zero
+  or negative.
+
+  Even though the task is not blocked,
+  it might be put back on the end of its ready queue.
+  See @RefSec(Priority Scheduling).
address@hidden(Discussion)
+
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
address@hidden, Sec=(of a @nt<delay_statement>)}
+If an attempt is made to @i(cancel) the @nt<delay_statement>
address@hidden(as part of an @nt<address@hidden> or abort @em
+see @RefSecNum{Asynchronous Transfer of Control} and
address@hidden of a Task - Abort of a Sequence of Statements})],
+the @Chg{Version=[3],New=[statement],address@hidden<_statement>]}
+is cancelled if the expiration time has not yet passed,
+thereby completing the @nt<delay_statement>.
address@hidden(Reason)
+  This is worded this way so that in an @nt<asynchronous_select>
+  where the @nt<triggering_statement> is a @nt<delay_statement>,
+  an attempt to cancel the delay when the @nt<abortable_part> completes
+  is ignored if the expiration time has already passed, in which case the
+  optional statements of the @nt<triggering_alternative> are executed.
address@hidden(Reason)
+
+The time base associated with the type Time of package Calendar
+is implementation defined. The function Clock of package Calendar
+returns a value representing the current time for this time base.
address@hidden implementation-defined value of the
+named number System.Tick (see @RefSecNum(The Package System))
+is an approximation of the length of the real-time
+interval during which the value of Calendar.Clock remains constant.]
address@hidden time base of the type Calendar.Time.}
+
address@hidden,Kind=[Revised],ARef=[AI95-00351-01]}
+The functions Year,
+Month, Day, and Seconds return the corresponding values for
+a given value of the type Time,
+as appropriate to an implementation-defined
address@hidden,New=[time zone],Old=[timezone]}; the procedure Split
+returns all four
+corresponding values. Conversely, the function Time_Of combines a
+year number, a month number, a day number, and a duration, into
+a value of type Time. The operators "+" and "@en@;" for addition
+and subtraction of times and durations, and the relational operators
+for times, have the conventional meaning.
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[The @Chg{Version=[2],New=[time zone],Old=[timezone]} used for
+package Calendar operations.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0119-1]}
+  @ChgAdded{Version=[3],Text=[The behavior of these values and subprograms if
+  the time zone changes is also implementation-defined. In particular, the
+  changes associated with summer time adjustments (like Daylight Savings Time 
in
+  the United States) should be treated as a change in the 
implementation-defined
+  time zone. The language does not specify whether the time zone information is
+  stored in values of type Time; therefore the results of binary operators are
+  unspecified when the operands are the two values with different
+  effective time zones. In particular, the results of "-" may differ from the
+  "real" result by the difference in the time zone adjustment. Similarly, the
+  result of UTC_Time_Offset (see 9.6.1) may or may not reflect a time zone
+  adjustment.]}
address@hidden
+
+If Time_Of is called with a seconds value of 86_400.0, the value
+returned is equal to the value of Time_Of for the next day
+with a seconds value of 0.0.
+The value returned by the function
+Seconds or through the Seconds parameter of the procedure
+Split is always less than 86_400.0.
+
address@hidden,Kind=[Revised],Ref=[8652/0030],ARef=[AI95-00113-01]}
+The exception Time_Error is raised by the function Time_Of if the
+actual parameters do not form a proper date. This exception
+is also raised by the operators "+" and "@en@;" if the
+result is not representable in the type Time or Duration, as appropriate.
+This exception is also raised by the
address@hidden,Old=[]} address@hidden, Month, Day, and Seconds and],
+Old=[or]} the procedure Split if the year number of the given date is
+outside of the range of the subtype Year_Number.
address@hidden(Honest)
+  @ChgRef{Version=[1],Kind=[Revised],Ref=[8652/0106],ARef=[AI95-00160-01]}
+  By "proper date" above we mean that the given year has
+  a month with the given day. For example, February 29th is
+  a proper date only for a leap year. @Chg{New=[We do not mean to include
+  the Seconds in this notion; in particular, we do not mean to require
+  implementations to check for the @lquotes@;missing address@hidden that occurs
+  when Daylight Savings Time starts in the spring.],Old=[]}
address@hidden(Honest)
address@hidden(Reason)
+  @ChgRef{Version=[1],Kind=[Revised],Ref=[8652/0030],ARef=[AI95-00113-01]}
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00351-01]}
+  We allow Year and Split to raise Time_Error because the arithmetic operators
+  are allowed (but not required) to produce times that are outside the range
+  of years from 1901 to @Chg{Version=[2],New=[2399],Old=[2099]}. This is
+  similar to the way integer operators may
+  return values outside the base range of their type so long as the value is
+  mathematically correct.
+  @Chg{New=[We allow the functions Month, Day and Seconds to raise Time_Error
+  so that they can be implemented in terms of Split.],Old=[]}
address@hidden(Reason)
address@hidden
+
address@hidden
+The implementation of the type Duration shall allow representation of
+time intervals (both positive and negative) up to at least 86400 seconds (one
+day); Duration'Small shall not be greater than twenty milliseconds.
+The implementation of the type Time shall allow representation of
+all dates with year numbers in the range of address@hidden; it
+may allow representation of other dates as well (both earlier and later).]
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
+An implementation may define additional time
address@hidden,New=[],Old=[ (see @RefSecNum{Monotonic Time})]}.
+
+An implementation may raise Time_Error if the
+value of a @address@hidden<expression> in a @nt<delay_until_statement>
+of a @nt<select_statement> represents a time more than 90 days past the
+current time. The actual limit, if any, is implementation-defined.
address@hidden limit on @nt<delay_until_statement>s of @nt<select_statement>s.}
address@hidden
+  This allows an implementation to implement @nt<select_statement>
+  timeouts using
+  a representation that does not support the full range of a time type.
+  In particular 90 days of seconds can be represented in 23 bits,
+  allowing a signed 24-bit representation for the seconds part of
+  a timeout.
+  There is no similar restriction allowed for stand-alone
+  @nt<delay_until_statement>s, as these can be implemented
+  internally using a loop if necessary to accommodate a long delay.
address@hidden
+
address@hidden
+
address@hidden
+
+Whenever possible in an implementation, the value of
+Duration'Small should be no greater than 100 microseconds.
address@hidden(ImplNote)
+  This can be satisfied using a 32-bit 2's complement representation
+  with a @i(small) of 2.0**(@en@;14) @em that is, 61 microseconds @em and a
+  range of @PorM 2.0**17 @em that is, 131_072.0.
address@hidden(ImplNote)
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The value of Duration'Small should be no greater than 100 
microseconds.]}]}
+
+The time base for @nt{delay_relative_statement}s should be monotonic;
+it need not be the same time base as used for Calendar.Clock.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The time base for @nt{delay_relative_statement}s should be monotonic.]}]}
+
address@hidden
+
address@hidden
+
+A @nt{delay_relative_statement} with a negative value of the
address@hidden(delay_)@nt<expression> is equivalent to one with a zero value.
+
+A @nt{delay_statement} may be executed by the environment task;
+consequently @nt{delay_statement}s may be executed as part of
+the elaboration of a @nt{library_item} or the execution of the main subprogram.
+Such statements delay the environment task (see @RefSecNum(Program Execution)).
+
address@hidden blocking operation],Sec=(delay_statement)}
address@hidden, potentially],Sec=(delay_statement)}
+A @nt{delay_statement} is an abort completion point and
+a potentially blocking operation,
+even if the task is not actually blocked.
+
+There is no necessary relationship between System.Tick (the
+resolution of the clock of package Calendar)
+and Duration'Small (the @i(small) of type Duration).
address@hidden
+The inaccuracy of the @nt{delay_statement} has no relation to System.Tick.
+In particular, it is possible that the clock used for the
address@hidden is less accurate than Calendar.Clock.
+
+We considered making Tick a run-time-determined quantity,
+to allow for easier configurability.
+However, this would not be upward compatible,
+and the desired configurability can be achieved using
+functionality defined in @RefSec{Real-Time Systems}.
address@hidden
+
+Additional requirements associated with @nt<delay_statement>s
+are given in @RefSec(Delay Accuracy).
+
address@hidden
+
address@hidden
address@hidden@address@hidden of a relative delay statement:}
address@hidden
address@hidden(delay) 3.0;  address@hidden delay 3.0 seconds]
address@hidden
+
address@hidden
address@hidden@address@hidden task],Sec=(example)}
address@hidden task],See=(delay_until_statement)}
address@hidden of a periodic task:}
address@hidden
address@hidden
address@hidden(declare)
+   @key(use) Ada.Calendar;
+   Next_Time : Time := Clock + Period;
+                      address@hidden Period is a global constant of type 
Duration]
address@hidden(begin)
+   @key(loop)               address@hidden repeated every Period seconds]
+      @key(delay) @key(until) Next_Time;
+      ... address@hidden perform some actions]
+      Next_Time := Next_Time + Period;
+   @key(end) @key(loop;)
address@hidden(end;)
address@hidden
address@hidden
+
address@hidden
address@hidden with Ada 83}
+For programs that raise Time_Error on "+" or "@en@;" in Ada 83,the exception
+might be deferred until a call on Split or Year_Number, or might
+not be raised at all (if the offending time is never Split after being
+calculated). This should not affect typical programs,
+since they deal only with times corresponding to the relatively
+recent past or near future.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax rule for @nt{delay_statement} is modified to allow
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00351-01]}
+The type Time may represent dates with year numbers outside of Year_Number.
+Therefore, the operations "+" and
+"@en@;" need only raise Time_Error if the result is not representable
+in Time (or Duration); also, Split or Year will now raise Time_Error
+if the year number is outside of Year_Number.
+This change is intended to simplify the implementation
+of "+" and "@en@;" (allowing them to depend on overflow for
+detecting when to raise Time_Error) and to allow local
address@hidden,New=[time zone],Old=[timezone]} information to be
+considered at the time of Split rather than Clock (depending on
+the implementation approach). For example, in a POSIX environment,
+it is natural for the type Time to be based on GMT, and
+the results of procedure Split (and the functions
+Year, Month, Day, and Seconds) to depend on local time zone information.
+In other environments, it is more natural for the type Time to
+be based on the local time zone, with the results of
+Year, Month, Day, and Seconds being pure functions of their input.
+
address@hidden,Kind=[Deleted],ARef=[AI95-00351-01]}
address@hidden,Text=[We anticipate that implementations will provide
+child packages of Calendar to provide more explicit control over time zones
+and other environment-dependent time-related issues.
+These would be appropriate for standardization in a given
+environment (such as POSIX).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00351-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}The upper bound
+  of Year_Number has been changed to avoid a year 2100 problem. A program
+  which expects years past 2099 to raise Constraint_Error will fail in Ada 
2005.
+  We don't expect there to be many programs which are depending on an exception
+  to be raised. A program that uses Year_Number'Last as a magic number may also
+  fail if values of Time are stored outside of the program.
+  Note that the lower bound of Year_Number wasn't changed, because
+  it is not unusual to use that value in a constant to represent an unknown
+  time.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0002],ARef=[AI95-00171-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that Month, 
Day, and
+  Seconds can raise Time_Error.]}
address@hidden
+
+
address@hidden,Name=[Formatting, Time Zones, and other operations for Time]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01],ARef=[AI95-00427-01]}
address@hidden,Text=[The following language-defined library packages exist:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden,address@hidden(package) Ada.Calendar.Time_Zones 
@key(is)]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Time zone manipulation:]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<type> @AdaTypeDefn{Time_Offset} @key<is range> 
-28*60 .. 28*60;]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[2],Text=[We want to be able to specify the difference
+  between any two arbitrary time zones. You might think that 1440 (24 hours)
+  would be enough, but there are places (like Tonga, which is UTC+13hr) which
+  are more than 12 hours @Chg{Version=[4],New=[different ],Old=[]}than UTC.
+  Combined with summer time (known as daylight saving time in some parts of the
+  world) @en which switches opposite in the northern and
+  @Chg{Version=[4],New=[southern],Old=[souther]} hemispheres @en and even 
greater
+  differences are possible. We know of cases of a 26 hours difference, so we 
err
+  on the safe side by selecting 28 hours as the limit.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaExcDefn{Unknown_Zone_Error} : @key<exception>;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{UTC_Time_Offset} (Date : 
Time := Clock) @key<return> Time_Offset;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<end> Ada.Calendar.Time_Zones;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden,Child=[Arithmetic]}
address@hidden(package) Ada.Calendar.Arithmetic @key(is)]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Arithmetic on days:]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<type> @AdaTypeDefn{Day_Count} @key<is range>
+     -366*(1+Year_Number'Last - Year_Number'First)
+     ..
+     366*(1+Year_Number'Last - Year_Number'First);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<subtype> 
@AdaSubtypeDefn{Name=[Leap_Seconds_Count],Of=[Integer]} @key<is> Integer 
@key<range> -2047 .. 2047;]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The maximum number of leap seconds is likely
+  to be much less than this, but we don't want to reach the limit too soon
+  if the earth's behavior suddenly changes. We believe that the maximum number
+  is 1612, based on the current rules, but that number is too weird to use 
here.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<procedure> @AdaSubDefn{Difference} (Left, Right : 
@key<in> Time;
+                         Days : @key<out> Day_Count;
+                         Seconds : @key<out> Duration;
+                         Leap_Seconds : @key<out> Leap_Seconds_Count);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> "+" (Left : Time; Right : Day_Count) 
@key<return> Time;
+   @key<function> "+" (Left : Day_Count; Right : Time) @key<return> Time;
+   @key<function> "-" (Left : Time; Right : Day_Count) @key<return> Time;
+   @key<function> "-" (Left, Right : Time) @key<return> Day_Count;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<end> Ada.Calendar.Arithmetic;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden,Child=[Formatting]}
address@hidden<with> Ada.Calendar.Time_Zones;
address@hidden(package) Ada.Calendar.Formatting @key(is)]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Day of the week:]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<type> @AdaTypeDefn{Day_Name} @key<is> 
(@AdaObjDefn{Monday}, @AdaObjDefn{Tuesday}, @AdaObjDefn{Wednesday}, 
@AdaObjDefn{Thursday},
+       @AdaObjDefn{Friday}, @AdaObjDefn{Saturday}, @AdaObjDefn{Sunday});]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Day_of_Week} (Date : Time) 
@key<return> Day_Name;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Hours:Minutes:Seconds access:]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<subtype> 
@AdaSubtypeDefn{Name=[Hour_Number],Of=[Natural]}         @key<is> Natural 
@key<range> 0 .. 23;
+   @key<subtype> @AdaSubtypeDefn{Name=[Minute_Number],Of=[Natural]}       
@key<is> Natural @key<range> 0 .. 59;
+   @key<subtype> @AdaSubtypeDefn{Name=[Second_Number],Of=[Natural]}       
@key<is> Natural @key<range> 0 .. 59;
+   @key<subtype> @AdaSubtypeDefn{Name=[Second_Duration],Of=[Day_Duration]}     
@key<is> Day_Duration @key<range> 0.0 .. 1.0;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Year}       (Date : Time;
+                        Time_Zone  : Time_Zones.Time_Offset := 0)
+                           @key<return> Year_Number;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Month}      (Date : Time;
+                        Time_Zone  : Time_Zones.Time_Offset := 0)
+                           @key<return> Month_Number;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Day}        (Date : Time;
+                        Time_Zone  : Time_Zones.Time_Offset := 0)
+                           @key<return> Day_Number;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Hour}       (Date : Time;
+                        Time_Zone  : Time_Zones.Time_Offset := 0)
+                           @key<return> Hour_Number;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Minute}     (Date : Time;
+                        Time_Zone  : Time_Zones.Time_Offset := 0)
+                           @key<return> Minute_Number;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Second}     (Date : Time)
+                           @key<return> Second_Number;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Sub_Second} (Date : Time)
+                           @key<return> Second_Duration;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Seconds_Of} (Hour   :  
Hour_Number;
+                        Minute : Minute_Number;
+                        Second : Second_Number := 0;
+                        Sub_Second : Second_Duration := 0.0)
+       @key<return> Day_Duration;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<procedure> @AdaSubDefn{Split} (Seconds    : 
@key<in> Day_Duration;
+                    Hour       : @key<out> Hour_Number;
+                    Minute     : @key<out> Minute_Number;
+                    Second     : @key<out> Second_Number;
+                    Sub_Second : @key<out> Second_Duration);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Time_Of} (Year       : 
Year_Number;
+                     Month      : Month_Number;
+                     Day        : Day_Number;
+                     Hour       : Hour_Number;
+                     Minute     : Minute_Number;
+                     Second     : Second_Number;
+                     Sub_Second : Second_Duration := 0.0;
+                     Leap_Second: Boolean := False;
+                     Time_Zone  : Time_Zones.Time_Offset := 0)
+                             @key<return> Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Time_Of} (Year       : 
Year_Number;
+                     Month      : Month_Number;
+                     Day        : Day_Number;
+                     Seconds    : Day_Duration := 0.0;
+                     Leap_Second: Boolean := False;
+                     Time_Zone  : Time_Zones.Time_Offset := 0)
+                             @key<return> Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<procedure> @AdaSubDefn{Split} (Date       : 
@key<in> Time;
+                    Year       : @key<out> Year_Number;
+                    Month      : @key<out> Month_Number;
+                    Day        : @key<out> Day_Number;
+                    Hour       : @key<out> Hour_Number;
+                    Minute     : @key<out> Minute_Number;
+                    Second     : @key<out> Second_Number;
+                    Sub_Second : @key<out> Second_Duration;
+                    Time_Zone  : @key<in> Time_Zones.Time_Offset := 0);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<procedure> @AdaSubDefn{Split} (Date       : 
@key<in> Time;
+                    Year       : @key<out> Year_Number;
+                    Month      : @key<out> Month_Number;
+                    Day        : @key<out> Day_Number;
+                    Hour       : @key<out> Hour_Number;
+                    Minute     : @key<out> Minute_Number;
+                    Second     : @key<out> Second_Number;
+                    Sub_Second : @key<out> Second_Duration;
+                    Leap_Second: @key<out> Boolean;
+                    Time_Zone  : @key<in> Time_Zones.Time_Offset := 0);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<procedure> @AdaSubDefn{Split} (Date       : 
@key<in> Time;
+                    Year       : @key<out> Year_Number;
+                    Month      : @key<out> Month_Number;
+                    Day        : @key<out> Day_Number;
+                    Seconds    : @key<out> Day_Duration;
+                    Leap_Second: @key<out> Boolean;
+                    Time_Zone  : @key<in> Time_Zones.Time_Offset := 0);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Simple image and value:]
+   @key<function> @AdaSubDefn{Image} (Date : Time;
+                   Include_Time_Fraction : Boolean := False;
+                   Time_Zone  : Time_Zones.Time_Offset := 0) @key<return> 
String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Value} (Date : String;
+                   Time_Zone  : Time_Zones.Time_Offset := 0) @key<return> 
Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Image} (Elapsed_Time : 
Duration;
+                   Include_Time_Fraction : Boolean := False) @key<return> 
String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Value} (Elapsed_Time : 
String) @key<return> Duration;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<end> Ada.Calendar.Formatting;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Text=[Type Time_Offset represents the number of minutes
+difference between the implementation-defined time zone used by Calendar
+and another time zone.]}
+
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> UTC_Time_Offset (Date : 
Time := Clock) @key<return> Time_Offset;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0119-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[Returns, as a number of minutes, the
address@hidden,New=[result of subtracting],Old=[difference between]}
+the implementation-defined time zone of address@hidden,New=[ from],Old=[, and]}
+UTC time, at the time Date. If the time zone of the Calendar implementation is
+unknown, then Unknown_Zone_Error is raised.]}
address@hidden
+    @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0119-1]}
+    @ChgAdded{Version=[3],Text=[In North America, the result will be negative;
+    in Europe, the result will be zero or positive.]}
address@hidden
address@hidden
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[The Date parameter is needed to take
+    into account time differences caused by daylight-savings time and other
+    time changes. This parameter is measured in the time zone of Calendar,
+    if any, not necessarily the UTC time zone.]}
+
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[Other time zones can be supported with a
+    child package. We don't define one because of the lack of agreement
+    on the definition of a time zone.]}
+
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[The accuracy of this routine is not specified;
+    the intent is that the facilities of the underlying target operating system
+    are used to implement it.]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<procedure> Difference (Left, Right : 
@key<in> Time;
+                      Days : @key<out> Day_Count;
+                      Seconds : @key<out> Duration;
+                      Leap_Seconds : @key<out> Leap_Seconds_Count);]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01],ARef=[AI95-00427-01]}
address@hidden,Type=[Trailing],Text=[Returns the difference between
+Left and Right. Days is the number of days of difference, Seconds is the
+remainder seconds of difference excluding leap seconds, and Leap_Seconds is
+the number of leap seconds. If Left < Right, then Seconds <= 0.0, Days <= 0,
+and Leap_Seconds <= 0. Otherwise, all values are nonnegative.
+The absolute value of Seconds is always less than 86_400.0.
+For the returned values, if Days =
+0, then Seconds + Duration(Leap_Seconds) = Calendar."@en" (Left, Right).]}
address@hidden
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[Leap_Seconds, if any, are not included in
+    Seconds. However, Leap_Seconds should be included in calculations
+    using the operators defined in Calendar, as is specified for "@en" above.]}
address@hidden
+
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> "+" (Left : Time; Right : 
Day_Count) @key<return> Time;
address@hidden<function> "+" (Left : Day_Count; Right : Time) @key<return> 
Time;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Type=[Trailing],Text=[Adds a number of days to a time value.
+Time_Error is raised if the result is not representable as a value of type
+Time.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> "-" (Left : Time; Right : 
Day_Count) @key<return> Time;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Type=[Trailing],Text=[Subtracts a number of days from a time 
value.
+Time_Error is raised if the result is not representable as a value of type
+Time.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> "-" (Left, Right : Time) 
@key<return> Day_Count;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Type=[Trailing],Text=[Subtracts two time values, and returns the
+number of days between them. This is the same value that Difference would
+return in Days.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Day_of_Week (Date : Time) 
@key<return> Day_Name;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Type=[Trailing],Text=[Returns the day of the week for Time. This 
is
+based on the Year, Month, and Day values of Time.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Year       (Date : Time;
+                     Time_Zone  : Time_Zones.Time_Offset := 0)
+                        @key<return> Year_Number;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00427-01]}
address@hidden,Type=[Trailing],Text=[Returns the year for Date, as
+appropriate for the specified time zone offset.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Month      (Date : Time;
+                     Time_Zone  : Time_Zones.Time_Offset := 0)
+                        @key<return> Month_Number;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00427-01]}
address@hidden,Type=[Trailing],Text=[Returns the month for Date, as
+appropriate for the specified time zone offset.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Day        (Date : Time;
+                     Time_Zone  : Time_Zones.Time_Offset := 0)
+                        @key<return> Day_Number;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00427-01]}
address@hidden,Type=[Trailing],Text=[Returns the day number for Date, as
+appropriate for the specified time zone offset.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Hour       (Date : Time;
+                     Time_Zone  : Time_Zones.Time_Offset := 0)
+                        @key<return> Hour_Number;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Type=[Trailing],Text=[Returns the hour for Date, as appropriate 
for
+the specified time zone offset.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Minute     (Date : Time;
+                     Time_Zone  : Time_Zones.Time_Offset := 0)
+                        @key<return> Minute_Number;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Type=[Trailing],Text=[Returns the minute within the hour for 
Date,
+as appropriate for the specified time zone offset.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Second     (Date : Time)
+                        @key<return> Second_Number;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01],ARef=[AI95-00427-01]}
address@hidden,Type=[Trailing],Text=[Returns the second within the hour and 
minute
+for Date.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Sub_Second (Date : Time)
+                        @key<return> Second_Duration;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01],ARef=[AI95-00427-01]}
address@hidden,Type=[Trailing],Text=[Returns the fraction of second for
+Date (this has the same accuracy as Day_Duration). The value returned is always
+less than 1.0.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Seconds_Of (Hour   : 
Hour_Number;
+                     Minute : Minute_Number;
+                     Second : Second_Number := 0;
+                     Sub_Second : Second_Duration := 0.0)
+    @key<return> Day_Duration;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01],ARef=[AI95-00427-01]}
address@hidden,Type=[Trailing],Text=[Returns a Day_Duration value for
+the combination of the given Hour, Minute, Second, and Sub_Second.
+This value can be used in Calendar.Time_Of as
+well as the argument to Calendar."+" and Calendar."@en". If Seconds_Of is
+called with a Sub_Second value of 1.0, the value returned is equal to the value
+of Seconds_Of for the next second with a Sub_Second value of 0.0.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<procedure> Split (Seconds    : 
@key<in> Day_Duration;
+                 Hour       : @key<out> Hour_Number;
+                 Minute     : @key<out> Minute_Number;
+                 Second     : @key<out> Second_Number;
+                 Sub_Second : @key<out> Second_Duration);]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01],ARef=[AI95-00427-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0238-1]}
address@hidden,Type=[Trailing],Text=[Splits Seconds into Hour, Minute,
+Second and Sub_Second in such a way that the resulting values all belong to
+their respective subtypes. The value returned in the Sub_Second
+parameter is always less than address@hidden,New=[ If Seconds = 86400.0,
+Split propagates Time_Error.],Old=[]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[There is only one way to do the split which
+  meets all of the requirements.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0238-1]}
+  @ChgAdded{Version=[3],Text=[If Seconds = 86400.0, one of the returned values
+  would have to be out of its defined range (either Sub_Second = 1.0 or Hour =
+  24 with the other value being 0). This doesn't seem worth breaking the
+  invariants.]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Time_Of (Year       : 
Year_Number;
+                  Month      : Month_Number;
+                  Day        : Day_Number;
+                  Hour       : Hour_Number;
+                  Minute     : Minute_Number;
+                  Second     : Second_Number;
+                  Sub_Second : Second_Duration := 0.0;
+                  Leap_Second: Boolean := False;
+                  Time_Zone  : Time_Zones.Time_Offset := 0)
+                          @key<return> Time;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01],ARef=[AI95-00427-01]}
address@hidden,Type=[Trailing],Text=[If Leap_Second is False,
+returns a Time built from the date and time
+values, relative to the specified time zone offset. If Leap_Second is True,
+returns the Time that represents the time within the leap second that is one
+second later than the time specified by the other parameters.
+Time_Error is raised if the parameters do not form a proper date or time.
+If Time_Of is called with a Sub_Second value of 1.0, the value
+returned is equal to the value of Time_Of for the next second with
+a Sub_Second value of 0.0.]}
address@hidden
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[Time_Error should be raised if Leap_Second
+    is True, and the date and time values do not represent the second before
+    a leap second. A leap second always occurs at midnight UTC,
+    and is 23:59:60 UTC in ISO notation. So, if the time zone is UTC and
+    Leap_Second is True, if any of Hour /= 23, Minute /= 59, or Second /= 59,
+    then Time_Error should be raised.
+    However, we do not say that, because other time zones will have different
+    values where a leap second is allowed.]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Time_Of (Year       : 
Year_Number;
+                  Month      : Month_Number;
+                  Day        : Day_Number;
+                  Seconds    : Day_Duration := 0.0;
+                  Leap_Second: Boolean := False;
+                  Time_Zone  : Time_Zones.Time_Offset := 0)
+                          @key<return> Time;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01],ARef=[AI95-00427-01]}
address@hidden,Type=[Trailing],Text=[If Leap_Second is False, returns
+a Time built from the date and time
+values, relative to the specified time zone offset. If Leap_Second is True,
+returns the Time that represents the time within the leap second that is one
+second later than the time specified by the other parameters.
+Time_Error is raised if the parameters do not form a proper date or time.
+If Time_Of is called with a Seconds value of 86_400.0, the value
+returned is equal to the value of Time_Of for the next day with
+a Seconds value of 0.0.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<procedure> Split (Date       : 
@key<in> Time;
+                 Year       : @key<out> Year_Number;
+                 Month      : @key<out> Month_Number;
+                 Day        : @key<out> Day_Number;
+                 Hour       : @key<out> Hour_Number;
+                 Minute     : @key<out> Minute_Number;
+                 Second     : @key<out> Second_Number;
+                 Sub_Second : @key<out> Second_Duration;
+                 Leap_Second: @key<out> Boolean;
+                 Time_Zone  : @key<in> Time_Zones.Time_Offset := 0);]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01],ARef=[AI95-00427-01]}
address@hidden,Type=[Trailing],Text=[If Date does not represent a time
+within a leap second, splits Date into its constituent parts (Year, Month, Day,
+Hour, Minute, Second, Sub_Second), relative to the specified time zone offset,
+and sets Leap_Second to False. If Date represents a time within a leap second,
+set the constituent parts to values corresponding to a time one second earlier
+than that given by Date, relative to the specified time zone offset, and sets
+Leap_Seconds to True. The value returned in the Sub_Second parameter is always
+less than 1.0.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<procedure> Split (Date       : 
@key<in> Time;
+                 Year       : @key<out> Year_Number;
+                 Month      : @key<out> Month_Number;
+                 Day        : @key<out> Day_Number;
+                 Hour       : @key<out> Hour_Number;
+                 Minute     : @key<out> Minute_Number;
+                 Second     : @key<out> Second_Number;
+                 Sub_Second : @key<out> Second_Duration;
+                 Time_Zone  : @key<in> Time_Zones.Time_Offset := 0);]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01],ARef=[AI95-00427-01]}
address@hidden,Type=[Trailing],Text=[Splits Date into its constituent parts 
(Year,
+Month, Day, Hour, Minute, Second, Sub_Second), relative to the specified time
+zone offset. The value returned in the Sub_Second parameter is always less
+than 1.0.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<procedure> Split (Date       : 
@key<in> Time;
+                 Year       : @key<out> Year_Number;
+                 Month      : @key<out> Month_Number;
+                 Day        : @key<out> Day_Number;
+                 Seconds    : @key<out> Day_Duration;
+                 Leap_Second: @key<out> Boolean;
+                 Time_Zone  : @key<in> Time_Zones.Time_Offset := 0);]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01],ARef=[AI95-00427-01]}
address@hidden,Type=[Trailing],Text=[If Date does not represent a time
+within a leap second, splits Date into its constituent parts (Year, Month, Day,
+Seconds), relative to the specified time zone offset, and sets Leap_Second to
+False. If Date represents a time within a leap second, set the constituent
+parts to values corresponding to a time one second earlier than that given by
+Date, relative to the specified time zone offset, and sets Leap_Seconds to
+True. The value returned in the Seconds parameter is always less than 
86_400.0.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Image (Date : Time;
+                Include_Time_Fraction : Boolean := False;
+                Time_Zone  : Time_Zones.Time_Offset := 0) @key<return> 
String;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Type=[Trailing],Text=[Returns a string form of the Date relative 
to
+the given Time_Zone.
+The format is "Year-Month-Day Hour:Minute:Second", where the Year is a
+4-digit value, and all others are 2-digit values, of the functions
+defined in Calendar and Calendar.Formatting, including a leading zero,
+if needed. The separators between the values are
+a minus, another minus, a colon, and a single space between the Day and Hour.
+If Include_Time_Fraction is True, the integer part of Sub_Seconds*100 is
+suffixed to the string as a point followed by a 2-digit value.]}
address@hidden
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[The Image provides a string in ISO 8601 
format, the
+    international standard time format. Alternative representations allowed
+    in ISO 8601 are not supported here.]}
+
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[ISO 8601 allows 24:00:00 for midnight; and a 
seconds
+    value of 60 for leap seconds. These are not allowed here (the routines
+    mentioned above cannot produce those results).]}
address@hidden
+
address@hidden
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[The fractional part is truncated, not rounded.
+    It would be quite hard to define the result with proper rounding, as it can
+    change all of the values of the image. Values can be rounded up by adding
+    an appropriate constant (0.5 if Include_Time_Fraction is False,
+    0.005 otherwise) to the time before taking the image.]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Value (Date : String;
+                Time_Zone  : Time_Zones.Time_Offset := 0) @key<return> Time;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Type=[Trailing],Text=[Returns a Time value for the image given as
+Date, relative to the given time zone. Constraint_Error is raised if the string
+is not formatted as described for Image, or the function cannot interpret the
+given string as a Time value.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[The intent is that the implementation
+  enforce the same range rules on the string as the appropriate function
+  Time_Of, except for the hour, so
+  @lquotes@;cannot interpret the given string as a Time address@hidden
+  happens when one of the values is out of the required range.
+  For example, "2005-08-31 @Chg{Version=[3],New=[24:00:00],Old=[24:0:0]}"
+  should raise Constraint_Error (the hour is out of range).]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Image (Elapsed_Time : 
Duration;
+                Include_Time_Fraction : Boolean := False) @key<return> 
String;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Type=[Trailing],Text=[Returns a string form of the Elapsed_Time.
+The format is "Hour:Minute:Second", where all values are
+2-digit values, including a leading zero, if needed.
+The separators between the values are colons.
+If Include_Time_Fraction is True, the integer part of Sub_Seconds*100 is
+suffixed to the string as a point followed by a 2-digit value.
+If Elapsed_Time < 0.0, the result is Image (@key<abs> Elapsed_Time,
+Include_Time_Fraction) prefixed with a minus sign. If @key<abs> Elapsed_Time
+represents 100 hours or more, the result is implementation-defined.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The result of Calendar.Formating.Image if its argument represents more
+than 100 hours.]}]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This cannot be implemented (directly) by calling
+    Calendar.Formatting.Split, since it may be out of the range of
+    Day_Duration, and thus the number of hours may be out of the range of
+    Hour_Number.]}
+
address@hidden,Text=[If a Duration value can represent more then 100 hours,
+    the implementation will need to define a format for the return of Image.]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden<function> Value (Elapsed_Time : 
String) @key<return> Duration;]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Type=[Trailing],Text=[Returns a Duration value for the image 
given
+as Elapsed_Time. Constraint_Error is raised if the string is not formatted as
+described for Image, or the function cannot interpret the given string as a
+Duration value.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The intent is that the implementation
+  enforce the same range rules on the string as the appropriate function
+  Time_Of, except for the hour, so
+  @lquotes@;cannot interpret the given string as a Time address@hidden
+  happens when one of the values is out of the required range.
+  For example, "10:23:60" should raise Constraint_Error (the seconds value
+  is out of range).]}
address@hidden
+
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Text=[An implementation should support leap seconds if the
+target system supports them. If leap seconds are not supported, Difference
+should return zero for Leap_Seconds, Split should return False for Leap_Second,
+and Time_Of should raise Time_Error if Leap_Second is True.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Leap seconds should be supported if the target system supports them.
+Otherwise, operations in Calendar.Formatting should return results
+consistent with no leap seconds.]}]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[An implementation can always support leap seconds
+when the target system does not; indeed, this isn't particularly
+hard (all that is required is a table of when leap seconds were inserted). As
+such, leap second support isn't @lquotes@;impossible or address@hidden
+in the sense of @RefSecNum{Conformity of an Implementation with the Standard}.
+However, for some purposes, it may be important to follow the target system's
+lack of leap second support (if the target is a GPS satellite, which does not
+use leap seconds, leap second support would be a handicap to work around).
+Thus, this @ImplAdviceTitle should be read as giving permission to not support
+leap seconds on target systems that don't support leap seconds. Implementers
+should use the needs of their customers to determine whether or not support
+leap seconds on such targets.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Text=[The implementation-defined time zone of package Calendar
+may, but need not, be the local time zone. UTC_Time_Offset always returns the
+difference relative to the implementation-defined time zone of package
+Calendar. If UTC_Time_Offset does not raise Unknown_Zone_Error, UTC time
+can be safely calculated (within the accuracy of the underlying time-base).]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00351-01]}
+  @ChgAdded{Version=[2],Text=[The time in the time zone known as Greenwich
+  Mean Time (GMT) is generally very close to UTC time; for most purposes they
+  can be treated the same. GMT is the time based on the rotation of the Earth;
+  UTC is the time based on atomic clocks, with leap seconds periodically
+  inserted to realign with GMT (because most human activities depend on the
+  rotation of the Earth). At any point in time, there will be a sub-second
+  difference between GMT and UTC.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00351-01]}
address@hidden,Text=[Calling Split on the results of subtracting
+Duration(UTC_Time_Offset*60) from Clock provides the components (hours,
+minutes, and so on) of the UTC time. In the United States, for example,
+UTC_Time_Offset will generally be negative.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is an illustration to help specify the 
value of
+  UTC_Time_Offset. A user should pass UTC_Time_Offset as the Time_Zone
+  parameter of Split, rather than trying to make the above calculation.]}
address@hidden
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00351-01],ARef=[AI95-00428-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Packages Calendar.Time_Zones, Calendar.Arithmetic, and Calendar.Formatting
+  are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0238-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Defined that Split for Seconds raises Time_Error for a value of exactly
+  86400.0, rather than breaking some invariant or raising some other exception.
+  Ada 2005 left this unspecified; a program that depended on what some
+  implementation does might break, but such a program is not portable anyway.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0119-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified the sign of
+  UTC_Time_Offset.]}
address@hidden
+
+
address@hidden Statements}
+
address@hidden
address@hidden are four forms of the @nt{select_statement}. One form provides a
+selective wait for one or more @nt{select_alternative}s. Two provide
+timed and conditional entry calls. The fourth provides asynchronous
+transfer of control.]
address@hidden
+
address@hidden
address@hidden<select_statement>,rhs="
+   @Syn2{selective_accept}
+  | @Syn2{timed_entry_call}
+  | @Syn2{conditional_entry_call}
+  | @Syn2{asynchronous_select}"}
address@hidden
+
address@hidden
address@hidden@address@hidden of a select statement:}
address@hidden
address@hidden(select)
+   @key(accept) Driver_Awake_Signal;
address@hidden(or)
+   @key(delay) 30.0*Seconds;
+   Stop_The_Train;
address@hidden(end) @key(select);
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
address@hidden is new.
address@hidden
+
address@hidden Accept}
+
address@hidden
address@hidden form of the @nt{select_statement} allows a combination of 
waiting for,
+and selecting from, one or more alternatives. The
+selection may depend on conditions associated with each alternative of the
address@hidden
address@hidden,See=(selective_accept)}]
address@hidden
+
address@hidden
address@hidden<selective_accept>,rhs="
+  @key{select}
+   address@hidden
+     @Syn2{select_alternative}
+{ @key{or}
+   address@hidden
+     @Syn2{select_alternative} }
+[ @key{else}
+   @Syn2{sequence_of_statements} ]
+  @key{end select};"}
+
address@hidden<guard>,rhs="@key{when} @Syn2{condition} =>"}
+
+
address@hidden<select_alternative>,rhs="
+   @Syn2{accept_alternative}
+  | @Syn2{delay_alternative}
+  | @Syn2{terminate_alternative}"}
+
+
address@hidden<accept_alternative>,rhs="
+  @Syn2{accept_statement} address@hidden"}
+
address@hidden<delay_alternative>,rhs="
+  @Syn2{delay_statement} address@hidden"}
+
address@hidden<terminate_alternative>,rhs="@key{terminate};"}
+
address@hidden(SyntaxText)
address@hidden@;A @nt{selective_accept} shall contain at least one 
@nt{accept_alternative}.
+In addition, it can contain:
address@hidden
+a @nt{terminate_alternative} (only one); or
+
+one or more @nt{delay_alternative}s; or
+
address@hidden part], Sec=(of a @nt<selective_accept>)}
+an @i(else part) (the reserved word @key(else) followed
+by a @nt<sequence_of_statements>).
address@hidden
+
+These three possibilities are mutually exclusive.
address@hidden(SyntaxText)
address@hidden
+
address@hidden
+
+If a @nt{selective_accept} contains more than one @nt{delay_alternative},
+then all shall be @nt<address@hidden@!statement>s,
+or all shall be @nt<address@hidden@!statement>s for the same time type.
address@hidden
+  This simplifies the implementation and the description of the semantics.
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden alternative}
+A @nt<select_alternative> is said to be @i(open) if
+it is not immediately preceded by a @nt<guard>, or if
+the @nt<condition> of its @nt<guard> evaluates to True. It
+is said to be @i(closed) otherwise.
+
address@hidden, Sec=(selective_accept)}
+For the execution of a @nt{selective_accept}, any @nt{guard}
address@hidden are evaluated; open alternatives are
+thus determined. For an open @nt{delay_alternative}, the
address@hidden(delay_)@nt<expression> is also evaluated. Similarly, for an open
address@hidden for
+an entry of a family, the @nt{entry_index} is also evaluated.
+These evaluations are performed in an arbitrary order, except that
+a @i(delay_)@nt<expression> or @nt<entry_index> is not evaluated until
+after evaluating the corresponding @nt<condition>, if any.
+Selection and execution of one open alternative, or of the else part, then
+completes the execution of the @nt{selective_accept}; the rules for
+this selection are described address@hidden order],Sec=[allowed]}
+
+Open @nt{accept_alternative}s are first considered. Selection of one such
+alternative takes place immediately if the corresponding
+entry already has queued calls. If several alternatives
+can thus be selected, one of them is selected according to the
+entry queuing policy in effect (see @RefSecNum(Entry Calls) and
address@hidden(Entry Queuing Policies)).
+When such an
+alternative is selected, the selected call is
+removed from its entry queue and the @nt<address@hidden>
+(if any) of the corresponding @nt{accept_statement} is executed; after the
+rendezvous completes any subsequent @nt<address@hidden>
+of the alternative is executed.
address@hidden, Sec=(execution of a @nt<selective_accept>)}
+If no selection is immediately possible (in the above sense)
+and there is no else part, the task
+blocks until an open alternative can be selected.
+
address@hidden@;Selection of the other forms of alternative or of an else part 
is performed
+as follows:
address@hidden
+
+An open @nt{delay_alternative} is selected when
+its expiration time is reached if no @address@hidden
+or other @nt<address@hidden> can be selected prior to the
+expiration time. If several
address@hidden@!alternative}s have this same expiration time,
+one of them is selected according to the queuing policy in
+effect (see @RefSecNum{Entry Queuing Policies}); the default queuing
+policy chooses arbitrarily among the @nt<address@hidden>s
+whose expiration time has passed.
+
+The else part is selected and its @nt<address@hidden> is executed
+if no @nt{accept_alternative} can immediately be selected;
+in particular, if all alternatives are closed.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+An open @nt{terminate_alternative} is selected if the conditions stated at the
+end of @Chg{Version=[3],New=[subclause],Old=[clause]}
address@hidden Dependence - Termination of Tasks}
+are satisfied.
address@hidden(Ramification)
+  In the absence of a @nt<requeue_statement>, the conditions stated
+  are such that a @nt<terminate_alternative> cannot be selected while
+  there is a queued entry call for any entry of the task.
+  In the presence of requeues from a task to one of its subtasks,
+  it is possible that when a @nt<terminate_alternative> of the
+  subtask is selected, requeued calls (for closed entries only) might still
+  be queued on some entry of the subtask. Tasking_Error will
+  be propagated to such callers, as is usual when a task completes
+  while queued callers remain.
address@hidden(Ramification)
+
address@hidden
+
address@hidden,Sec=(raised by failure of run-time check)}
+The exception Program_Error is raised if all alternatives are closed and
+there is no else part.
+
address@hidden
+
address@hidden
+
+A @nt{selective_accept} is allowed to have several open
address@hidden A @nt{selective_accept} is allowed
+to have several open
address@hidden for the same entry.
+
address@hidden
+
address@hidden
address@hidden@address@hidden of a task body with a selective accept:}
address@hidden
address@hidden(task) @key(body) Server @key(is)
+   Current_Work_Item : Work_Item;
address@hidden(begin)
+   @key(loop)
+      @key(select)
+         @key(accept) Next_Work_Item(WI : @key(in) Work_Item) @key(do)
+            Current_Work_Item := WI;
+         @key(end);
+         Process_Work_Item(Current_Work_Item);
+      @key(or)
+         @key(accept) Shut_Down;
+         @key(exit);       address@hidden Premature shut down requested]
+      @key(or)
+         @key(terminate);  address@hidden Normal shutdown at end of scope]
+      @key(end) @key(select);
+   @key(end) @key(loop);
address@hidden(end) Server;
address@hidden
address@hidden
+
address@hidden
+The name of @ntf{selective_wait} was changed to @nt{selective_accept} to
+better describe what is being waited for.
+We kept @nt{select_alternative} as is, because
address@hidden<selective_accept_alternative> was too easily confused
+with @nt<accept_alternative>.
address@hidden
+
+
address@hidden Entry Calls}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden @nt{timed_entry_call} issues an entry call that is
+cancelled if the call (or a requeue-with-abort of the call)
+is not selected before the expiration time is
address@hidden,New=[ A procedure call may appear rather than
+an entry call for cases where the procedure might be implemented by
+an entry.],Old=[]}
address@hidden,See=(timed_entry_call)}]
address@hidden
+
address@hidden
address@hidden<timed_entry_call>,rhs="
+  @key{select}
+   @Syn2{entry_call_alternative}
+  @key{or}
+   @Syn2{delay_alternative}
+  @key{end select};"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden<entry_call_alternative>,rhs="
+  @Chg{Version=[2],address@hidden,address@hidden address@hidden"}
+
address@hidden,Kind=[Added],ARef=[AI95-00345-01]}
address@hidden,lhs=<@Chg{Version=[2],New=[procedure_or_entry_call],Old=[]}>,rhs="
+  @Chg{Version=[2],address@hidden | @Syn2{entry_call_statement}],Old=[]}"}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00345-01]}
address@hidden,Text=[If a @nt{procedure_call_statement} is used for a
address@hidden, the @address@hidden or
address@hidden@nt{prefix} of the @nt{procedure_call_statement} shall
+statically denote an entry renamed as a procedure or (a view of) a
+primitive subprogram of a limited interface whose first parameter is a
+controlling parameter (see @RefSecNum{Dispatching Operations of Tagged 
Types}).]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This would be a confusing way to call a procedure,
+so we only allow it when it is possible that the procedure is actually an
+entry. We could have allowed formal subprograms here, but we didn't because
+we'd have to allow all formal subprograms, and it would increase the
+difficulty of generic code sharing.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[We say @lquotes@;statically address@hidden
+because an access-to-subprogram cannot be primitive, and we don't have
+anything like access-to-entry. So only names of entries or procedures are
+possible.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00345-01]}
address@hidden,Kind=[DeletedAddedNoDelMsg],address@hidden
+We don't need a message here, as this is the last inserted paragraph}
address@hidden,address@hidden,New=[],Old=[If a
address@hidden is used for a @nt{procedure_or_entry_call}, and
+the procedure is implemented by an entry, then the @address@hidden,
+or @address@hidden and possibly the first parameter of the
address@hidden, determine the target object of the call and the
+entry to be called.]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg]}
+  @ChgAdded{Version=[2],address@hidden,New=[],Old=[The above says 
@lquotes@;possibly the first
+    address@hidden@;, because Ada allows entries to be renamed and passed as
+    formal subprograms. In those cases, the task or protected object is 
implicit
+    in the name of the routine; otherwise the object is an explicit parameter 
to
+    the call.]}]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden, Sec=(timed_entry_call)}
+For the execution of a @nt{timed_entry_call}, the 
@SynI(entry_)@nt<name>@Chg{Version=[2],
+New=[, @address@hidden, or @address@hidden,],Old=[]}
+and any actual parameters are evaluated,
+as for a simple entry call (see @RefSecNum(Entry Calls))@Chg{Version=[2],New=[
+or procedure call (see @RefSecNum{Subprogram Calls})],Old=[]}.
+The expiration time
+(see @RefSecNum(Delay Statements, Duration, and Time))
+for the call is determined by evaluating
+the @i(delay_)@nt<expression> of the
address@hidden<delay_alternative>@Chg{Version=[2],New=[. If the call is an 
entry call or
+a call on a procedure implemented by an entry,],Old=[;]}
+the entry call is then address@hidden,New=[ Otherwise, the call
+proceeds as described in @RefSecNum{Subprogram Calls} for a procedure call,
+followed by the @address@hidden of the @address@hidden;
+the @address@hidden of the @address@hidden is ignored.],Old=[]}
+
+
+If the call is queued (including due to a requeue-with-abort),
+and not selected before the expiration
+time is reached, an attempt to cancel the call is made.
+If the call completes due to the cancellation, the optional
address@hidden<address@hidden> of the @nt<address@hidden> is
+executed; if the entry call completes normally, the optional
address@hidden<address@hidden> of the @nt<address@hidden> is
+executed.
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00345-01]}
address@hidden,Text=[The fact that the syntax calls for
+an @nt{entry_call_statement} means
+that this fact is used in overload resolution.
+For example,
+if there is a procedure X and an entry X (both with no parameters),
+then "select X; ..." is legal,
+because overload resolution knows that the entry is the one that was
+meant.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden@address@hidden of a timed entry call:}
address@hidden
address@hidden(select)
+   Controller.Request(Medium)(Some_Item);
address@hidden(or)
+   @key(delay) 45.0;
+   address@hidden  controller too busy, try something else]
address@hidden(end) @key(select);
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} comes before the one
+for Conditional Entry Calls,
+so we can define conditional entry calls in terms of timed entry calls.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00345-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  A procedure @Chg{Version=[3],New=[call ],Old=[]}can be used as the
+  @Chg{Version=[3],address@hidden ],Old=[]}in a timed or
+  conditional entry call, if the procedure
+  might actually be an entry. Since the fact that something is an entry
+  could be used in resolving these calls in Ada 95, it is possible for
+  timed or conditional entry calls that resolved in Ada 95 to be ambiguous
+  in Ada 2005. That could happen if both an entry and procedure with the
+  same name and profile exist, which should be rare.]}
address@hidden
+
+
address@hidden Entry Calls}
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden @nt{conditional_entry_call} issues an entry call that is
+then cancelled if it is not selected immediately (or if a requeue-with-abort
+of the call is not selected immediately)address@hidden,New=[ A procedure
+call may appear rather than
+an entry call for cases where the procedure might be implemented by
+an entry.],Old=[]}]
address@hidden(Honest)
+  In the case of an entry call on a protected object, it is OK if the entry
+  is closed at the start of the corresponding protected action, so long as
+  it opens and the call is selected before the end of that protected
+  action (due to changes in the Count attribute).
address@hidden(Honest)
+
address@hidden
+
address@hidden
address@hidden<conditional_entry_call>,rhs="
+  @key{select}
+   @Syn2{entry_call_alternative}
+  @key{else}
+   @Syn2{sequence_of_statements}
+  @key{end select};"}
address@hidden
+
address@hidden
+
address@hidden, Sec=(conditional_entry_call)}
+The execution of a @nt<conditional_entry_call> is defined to be equivalent
+to the execution of a @nt<address@hidden@!call> with a @nt<address@hidden>
+specifying an immediate expiration time and the
+same @nt<address@hidden> as given after the reserved word @key(else).
address@hidden
+
address@hidden
+
+A @nt{conditional_entry_call} may briefly increase the Count attribute of
+the entry, even if the conditional call is not selected.
+
address@hidden
+
address@hidden
address@hidden@address@hidden of a conditional entry call:}
address@hidden
address@hidden(procedure) Spin(R : @key[in] Resource) @key(is)
address@hidden(begin)
+   @key(loop)
+      @key(select)
+         R.Seize;
+         @key(return);
+      @key(else)
+         @key(null);  address@hidden  busy waiting]
+      @key(end) @key(select);
+   @key(end) @key(loop);
address@hidden(end);
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} comes after the
+one for Timed Entry Calls, so we can define conditional entry calls in terms of
+timed entry calls.
+We do that so that an "expiration time" is defined for both,
+thereby simplifying the definition of what happens on
+a requeue-with-abort.
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden Transfer of Control}
+
address@hidden
address@hidden asynchronous @nt{select_statement} provides
+asynchronous transfer of control
+upon completion of an entry call or the expiration of a delay.]
address@hidden
+
address@hidden
address@hidden<asynchronous_select>,rhs="
+  @key{select}
+   @Syn2{triggering_alternative}
+  @key{then abort}
+   @Syn2{abortable_part}
+  @key{end select};"}
+
address@hidden<triggering_alternative>,rhs="@Syn2{triggering_statement} 
address@hidden"}
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden<triggering_statement>,rhs="@Chg{Version=[2],address@hidden,address@hidden
 | @Syn2{delay_statement}"}
+
address@hidden<abortable_part>,rhs="@Syn2{sequence_of_statements}"}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden,
+  Sec=(asynchronous_select with an entry call trigger)}
address@hidden,address@hidden,
+  Sec=(asynchronous_select with a procedure call trigger)}],Old=[]}
+For the execution of an @nt{asynchronous_select}
+whose @nt<address@hidden> is @Chg{Version=[2],
+New=[a @nt<procedure_or_entry_call>],Old=[an @nt<entry_call_statement>]},
+the @Syni(entry_)@nt<name>@Chg{Version=[2],New=[, @address@hidden,
+or @address@hidden,],Old=[]} and actual parameters are evaluated
+as for a simple entry call (see @RefSecNum(Entry Calls))@Chg{Version=[2],New=[
+or procedure call (see @RefSecNum{Subprogram Calls}).
+If the call is an entry call or a call on a procedure implemented by an
+entry,],Old=[, and]} the entry call is issued.
+If the entry call is queued (or requeued-with-abort),
+then the @nt<abortable_part> is executed.
address@hidden the entry call is selected immediately,
+and never requeued-with-abort,
+then the @nt<abortable_part> is never address@hidden,New=[ If the
+call is on a procedure that is not implemented by an entry, the call proceeds
+as described in @RefSecNum{Subprogram Calls}, followed by the
address@hidden@!statements} of the @address@hidden@Redundant[;
+the @nt{abortable_part} is never started].],Old=[]}
+
+
address@hidden,
+  Sec=(asynchronous_select with a delay_statement trigger)}
+For the execution of an @nt<asynchronous_select> whose
address@hidden<address@hidden> is a @nt<delay_statement>,
+the @i(delay_)@nt<expression> is evaluated
+and the expiration time is determined,
+as for a normal @nt<delay_statement>.
+If the expiration time has not already passed, the @nt<abortable_part>
+is executed.
+
+If the @nt<abortable_part> completes and is left prior to completion of the
address@hidden<address@hidden>,
+an attempt to cancel the @nt<address@hidden> is made.
+If the attempt to cancel succeeds (see @RefSecNum(Entry Calls) and
address@hidden(Delay Statements, Duration, and Time)), the
address@hidden<asynchronous_select> is complete.
+
+If the @nt<address@hidden> completes other than
+due to cancellation,
+the @nt<abortable_part>
+is aborted (if started but not yet completed @em
+see @RefSecNum(Abort of a Task - Abort of a Sequence of Statements)).
+If the @nt<address@hidden> completes normally, the optional
address@hidden<address@hidden> of the @nt<address@hidden> is
+executed after the @nt<abortable_part> is left.
address@hidden(Discussion)
+  We currently don't specify when the by-copy address@hidden(in)] @key(out)
+  parameters are assigned back into the actuals. We considered
+  requiring that to happen after the @nt<abortable_part> is
+  left. However, that doesn't seem useful enough
+  to justify possibly overspecifying the implementation approach,
+  since some of the parameters are passed by reference anyway.
+
+  In an earlier description, we required that the @nt<address@hidden>
+  of the @nt<address@hidden> execute after aborting
+  the @nt<abortable_part>, but before waiting for it to complete
+  and finalize, to provide more rapid response to the triggering event
+  in case the finalization was unbounded. However, various reviewers felt
+  that this created unnecessary complexity in the description,
+  and a potential for undesirable concurrency (and nondeterminism)
+  within a single task. We have now reverted to simpler, more
+  deterministic semantics,
+  but anticipate that further discussion of this issue might be
+  appropriate during subsequent reviews.
+  One possibility is to leave this area implementation defined,
+  so as to encourage experimentation. The user would then have
+  to assume the worst about what kinds of actions are appropriate
+  for the @nt<address@hidden> of the @nt<address@hidden>
+  to achieve portability.
address@hidden(Discussion)
+
address@hidden
+
address@hidden
address@hidden@address@hidden handling], Sec=(example)}
address@hidden,Sec=(example using @nt<asynchronous_select>)}
address@hidden interrupt], Sec=(example)}
address@hidden(Example of a main command loop for a command interpreter:)
address@hidden(Example)
address@hidden(loop)
+   @key(select)
+      Terminal.Wait_For_Interrupt;
+      Put_Line("Interrupted");
+   @key(then abort)
+      -- @RI(This will be abandoned upon terminal interrupt)
+      Put_Line("-> ");
+      Get_Line(Command, Last);
+      Process_Command(Command(1..Last));
+   @key(end) @key(select);
address@hidden(end) @key(loop);
address@hidden(Example)
+
address@hidden
address@hidden@address@hidden(Example of a time-limited calculation:)
address@hidden,See=(asynchronous_select)}
address@hidden,Sec=(example)}
address@hidden limit],Sec=(example)}
address@hidden,Sec=(example using @nt<asynchronous_select>)}
address@hidden interrupt],Sec=(example)}
address@hidden
address@hidden(Example)
address@hidden(select)
+   @key(delay) 5.0;
+   Put_Line("Calculation does not converge");
address@hidden(then abort)
+   -- @RI(This calculation should finish in 5.0 seconds;)
+   -- @RI( if not, it is assumed to diverge.)
+   Horribly_Complicated_Recursive_Function(X, Y);
address@hidden(end) @key(select);
address@hidden(Example)
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0098-1]}
address@hidden,Text=[Note that these examples presume that there are
+abort completion points within the execution of the @nt{abortable_part}.]}
address@hidden
+
address@hidden
address@hidden to Ada 83}
address@hidden<Asynchronous_select> is new.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00345-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  A procedure can be used as the
+  @address@hidden of an @nt<asynchronous_select>, if the procedure
+  might actually be an entry.]}
address@hidden
+
+
address@hidden of a Task - Abort of a Sequence of Statements}
+
address@hidden
address@hidden @nt{abort_statement} causes one or more tasks to become 
abnormal, thus
+preventing any further interaction with such tasks. The completion
+of the @nt<address@hidden> of an @nt<asynchronous_select>
+causes a @address@hidden to be aborted.]
address@hidden
+
address@hidden
address@hidden<abort_statement>,
+  rhs="@key{abort} @address@hidden {, @address@hidden;"}
address@hidden
+
address@hidden
+
address@hidden type], Sec=(abort_statement task_name)}
+Each @address@hidden is expected to be of any task
address@hidden; they need not all be of the same task type.]
+
address@hidden
+
address@hidden
+
address@hidden, Sec=(abort_statement)}
+For the execution of an @nt<abort_statement>, the given @i(task_)@nt<name>s
+are evaluated in an arbitrary address@hidden order],Sec=[allowed]}
address@hidden, Sec=(of a task)}
address@hidden task}
address@hidden state], Sec=(abnormal)}
+Each named task is
+then @i(aborted), which consists of making the task @i(abnormal)
+and aborting the execution of the corresponding @nt<task_body>,
+unless it is already completed.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+Note that aborting those tasks is not defined to be an
+abort-deferred operation.
+Therefore, if one of the named tasks is the task executing the
address@hidden, or if the task executing the
address@hidden depends on one of the named tasks,
+then it is possible for the execution of the @nt{abort_statement} to be
+aborted, thus leaving some of the tasks unaborted.
+This allows the implementation to use either a sequence of calls to an
address@hidden@;abort address@hidden@; @Chg{Version=[2],New=[run-time
+system],Old=[RTS]} primitive, or a single call to an @lquotes@;abort list of
address@hidden@; @Chg{Version=[2],New=[run-time system],Old=[RTS]} primitive.
address@hidden
+
address@hidden@PDefn2{Term=[execution], Sec=(aborting the execution of a 
construct)}
address@hidden, Sec=(of the execution of a construct)}
+When the execution of a construct
+is @i(aborted) (including that of a @nt<address@hidden> or of a
address@hidden<address@hidden>), the execution of every construct
+included within the aborted execution is also aborted,
+except for executions included within the execution of an @i(abort-deferred)
+operation; the execution of an abort-deferred operation
+continues to completion without being affected by the abort;
address@hidden operation}
+the following are the abort-deferred operations:
address@hidden(Itemize)
+  a protected action;
+
+  waiting for an entry call to complete (after having
+  initiated the attempt to cancel it @em see below);
+
+  waiting for the termination of dependent tasks;
+
+  the execution of an Initialize procedure as the last step
+  of the default initialization of a controlled object;
+
+  the execution of a Finalize procedure as part of the
+  finalization of a controlled object;
+
+  an assignment operation to an object with a controlled part.
address@hidden(Itemize)
+
address@hidden last three of these are discussed further in
address@hidden(Assignment and Finalization).]
address@hidden
+  Deferring abort during Initialize and finalization allows,
+  for example, the result of an allocator performed in
+  an Initialize operation to be assigned into an access object without
+  being interrupted in the middle, which would cause storage leaks.
+  For an object with several controlled parts,
+  each individual Initialize is abort-deferred.
+  Note that there is generally no semantic difference between
+  making each Finalize
+  abort-deferred, versus making a group of them abort-deferred,
+  because if the task gets aborted, the first thing it will do is
+  complete any remaining finalizations.
+  Individual objects are finalized prior to an assignment operation
+  (if nonlimited controlled) and as part of Unchecked_Deallocation.
address@hidden
address@hidden(Ramification)
+Abort is deferred during the entire assignment operation
+to an object with a controlled part,
+even if only some subcomponents are controlled.
+Note that this says "assignment operation,"
+not "@nt{assignment_statement}."
+Explicit calls to Initialize, Finalize, or Adjust are
+not abort-deferred.
address@hidden(Ramification)
+
+
+When a master is aborted, all tasks
+that depend on that master are aborted.
+
address@hidden
+The order in which tasks become abnormal as the result
+of an @nt<abort_statement> or the abort of a @nt<address@hidden>
+is not specified by the language.
+
address@hidden@;If the execution of an entry call is aborted,
+an immediate attempt is made to cancel the entry call
+(see @RefSecNum(Entry Calls)).
+If the execution of a construct
+is aborted at a time when the execution is blocked,
+other than for an entry call, at a point that is outside
+the execution of an abort-deferred operation,
+then the execution of the construct completes immediately.
+For an abort due to an @nt<abort_statement>,
+these immediate effects occur before the execution of
+the @nt<abort_statement> completes.
+Other than for these immediate cases, the execution
+of a construct that is aborted does not necessarily
+complete before the @nt<abort_statement> completes.
+However, the execution of the aborted construct
+completes no later than its next @i(abort completion point) (if any)
+that occurs outside of an abort-deferred operation;
address@hidden completion point}
+the following are abort completion points for an execution:
address@hidden(Itemize)
+  the point where the execution initiates the activation of another task;
+
+  the end of the activation of a task;
+
+  the start or end of the execution of an entry call,
+  @nt<accept_statement>, @nt<delay_statement>, or @nt<abort_statement>;
+  @begin(Ramification)
+    Although the abort completion point doesn't occur until the end
+    of the entry call or @nt<delay_statement>, these operations might
+    be cut short because an abort attempts to cancel them.
+  @end(Ramification)
+
+  the start of the execution of a @nt<select_statement>,
+  or of the @nt<address@hidden> of an @nt<exception_handler>.
+  @begin(Reason)
+    The start of an @nt<exception_handler> is considered an abort completion
+    point simply because it is easy for an implementation to check
+    at such points.
+  @end(Reason)
+  @begin(ImplNote)
+    Implementations may of course check for abort more often than at
+    each abort completion point; ideally, a fully preemptive
+    implementation of abort will be provided.
+    If preemptive abort is not supported in a given environment,
+    then supporting the checking for abort
+    as part of subprogram calls and loop iterations might be a useful option.
+  @end(ImplNote)
address@hidden(Itemize)
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden(bounded error),Sec=(cause)}
+An attempt to execute an @nt<asynchronous_select> as
+part of the execution of an abort-deferred operation is a bounded error.
+Similarly, an attempt to create a task that depends on a master
+that is included entirely within the execution of
+an abort-deferred operation is a bounded error.
address@hidden,Sec=(raised by failure of run-time check)}
+In both cases, Program_Error is raised if the error is detected
+by the implementation; address@hidden,New=[,],Old=[]} the
+operations proceed as they would outside an abort-deferred operation, except
+that an abort of the @nt<abortable_part>
+or the created task might or might not have an effect.
address@hidden(Reason)
+  An @nt<asynchronous_select> relies on an abort of the
+  @nt<abortable_part> to effect the
+  asynchronous transfer of control. For an @nt<asynchronous_select>
+  within an abort-deferred operation, the abort might
+  have no effect.
+
+  Creating a task dependent on a master included within an abort-deferred
+  operation is considered an error, because such tasks could be aborted while
+  the abort-deferred operation was still progressing, undermining the
+  purpose of abort-deferral. Alternatively, we could say that such
+  tasks are abort-deferred for their entire execution, but that seems
+  too easy to abuse. Note that task creation is already a bounded error
+  in protected actions, so this additional rule only applies to local task
+  creation as part of Initialize, Finalize, or Adjust.
address@hidden(Reason)
address@hidden
+
address@hidden
address@hidden state of an object}
address@hidden state of an object}
address@hidden of an assignment}
address@hidden(erroneous execution),Sec=(cause)}
+If an assignment operation completes prematurely due to an abort,
+the assignment is said to be @i{disrupted};
+the target of the assignment or its parts can become abnormal,
+and certain subsequent uses of the object can be erroneous,
+as explained in @RefSecNum{Data Validity}.
address@hidden
+
address@hidden
+
+An @nt{abort_statement} should be used only in situations
+requiring unconditional termination.
+
+A task is allowed to abort any task it can name, including itself.
+
+Additional requirements associated with abort
+are given in @RefSec(Preemptive Abort).
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} has been rewritten to
+accommodate the concept
+of aborting the execution of a construct, rather than just of a task.
address@hidden
+
+
address@hidden and Entry Attributes}
+
address@hidden
+
address@hidden@;
+For @PrefixType{a @nt<prefix> T that
+is of a task type @Redundant[(after
+any implicit dereference)]},
+the following attributes are defined:
address@hidden
address@hidden@ChgAttribute{Version=[2], Kind=[Revised], ChginAnnex=[F], 
Leading=[F],
+  Prefix=<T>, AttrName=<Callable>, ARef=[AI95-00345],
+  Text=<Yields the value True when the task denoted by T
+                is @i(callable), and False otherwise;>}
+                @PDefn2{Term=[task state], Sec=(callable)}
+                @Defn{callable}
+                a task is callable unless it is completed or abnormal.
+                The value of this attribute is of the predefined
+                type Boolean.}
address@hidden<T>, AttrName=<Callable>,
+  Text=<Yields the value True when the task denoted by T
+                is @i(callable), and False otherwise;>}
+                @PDefn2{Term=[task state], Sec=(callable)}
+                @Defn{callable}
+                a task is callable unless it is completed or abnormal.
+                The value of this attribute is of the predefined
+                type Boolean.
+
address@hidden<T>, AttrName=<Terminated>,
+  Text=<Yields the value True if the task denoted by T is
+                terminated, and False otherwise. The value of this
+                attribute is of the predefined type Boolean.>}
address@hidden
address@hidden
+
+For @PrefixType{a @nt<prefix> E that denotes an entry
+of a task or protected unit},
+the following attribute is defined.
+This attribute is only allowed within the body of the task or protected
+unit, but excluding, in the case of an entry of a task unit, within any
+program unit that is, itself, inner to the body of the task unit.
address@hidden
+
address@hidden<E>, AttrName=<Count>,
+  Text=<Yields the number of calls presently queued on the
+                entry E of the current instance of the unit.
+                The value of this attribute is of the type
+                @i{universal_integer}.>}
+
address@hidden
address@hidden
address@hidden
+
address@hidden
+
+For the Count attribute, the entry can be either a single entry or an
+entry of a family. The name of the entry or entry
+family can be either a @nt<direct_name> or an expanded name.
+
+Within task units, algorithms interrogating the attribute E'Count should
+take precautions to allow for the increase of the value of this attribute
+for incoming entry calls, and its decrease, for example with
address@hidden Also, a @nt{conditional_entry_call} may briefly
+increase this value, even if the conditional call is not accepted.
+
+Within protected units, algorithms interrogating the attribute E'Count
+in the @nt<entry_barrier> for the entry E should take precautions to
+allow for the evaluation of the @nt<condition> of the barrier both before
+and after queuing a given caller.
address@hidden
+
+
+
address@hidden Variables}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0009-1],ARef=[AI05-0201-1],ARef=[AI05-0229-1],ARef=[AI05-0295-1]}
address@hidden variable], Sec=(protection of)}
address@hidden addressable}
+If two different objects, including nonoverlapping
+parts of the same object, are @i{independently addressable},
+they can be manipulated concurrently by two different tasks
+without synchronization.
address@hidden,New=[Any two nonoverlapping objects are independently
+addressable if either object is specified as independently addressable (see
address@hidden Variable Control}). Otherwise,
+two nonoverlapping objects are independently addressable
+except when they are both parts of a composite object for which
+a nonconfirming value is specified for any of the following representation
+aspects: (record) Layout, Component_Size, Pack, Atomic, or Convention;
+in this case it is unspecified whether the parts are independently
address@hidden,
+Old=[Normally, any two
+nonoverlapping objects are independently addressable.
+However, if packing, record layout, or Component_Size
+is specified for a given composite object,
+then it is implementation defined whether or not
+two nonoverlapping parts of that composite object
+are independently addressable.]}
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,New=[],Old=[Whether or not two
+nonoverlapping parts of a composite
+object are independently addressable,
+in the case where packing, record layout, or Component_Size
+is specified for the object.]}]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+Independent addressability is the only high level semantic effect of
address@hidden,New=[aspect],Old=[a @nt{pragma}]} Pack.
+If two objects are independently addressable,
+the implementation should allocate them in such a way
+that each can be written by the hardware without writing the other.
+For example, unless the user asks for it,
+it is generally not feasible to choose a bit-packed
+representation on a machine without an atomic bit field
+insertion instruction,
+because there might be tasks that update neighboring subcomponents
+concurrently,
+and locking operations on all subcomponents is generally not a good
+idea.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+Even if @Chg{Version=[3],New=[Pack],Old=[packing]} or one of the other
+above-mentioned aspects is specified, subcomponents should still be updated
+independently if the hardware efficiently supports it.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0009-1],ARef=[AI05-0201-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0001-1]}
address@hidden,Text=[An atomic object (including atomic
+components) is always independently addressable from any other nonoverlapping
+object. @Chg{Version=[4],address@hidden and representation
+items cannot change that fact],Old=[Any @nt{aspect_specification} or
+representation item which would prevent this from being true should be 
rejected,
+notwithstanding what this Standard says elsewhere]}. Note, however, that the
+components of an atomic object are not necessarily atomic.]}
address@hidden
address@hidden
+
address@hidden
address@hidden@redundant[Separate tasks normally proceed independently and 
concurrently
+with one another. However, task interactions can be used
+to synchronize the actions of two or more tasks to allow,
+for example, meaningful communication by the direct updating and
+reading of variables shared between the tasks.]
+The actions of two different tasks are synchronized in this
+sense when an
+action of one task @i(signals) an action of the other task;
address@hidden, Sec=(as defined between actions)}
+an action A1 is defined to signal an action A2 under the following
+circumstances:
address@hidden(Itemize)
+  If A1 and A2 are part of the execution of the same task,
+  and the language rules require A1 to be performed before A2;
+
+  If A1 is the action of an activator that initiates the
+  activation of a task, and
+  A2 is part of the execution of the task that is activated;
+
+  If A1 is part of the activation of a task, and A2
+  is the action of
+  waiting for completion of the activation;
+
+  If A1 is part of the execution of a task, and A2 is
+  the action of waiting for the termination of the task;
+
+  @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0031],ARef=[AI95-00118-01]}
+  @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0072-1]}
+  @ChgAdded{Version=[1],Text=[If A1 is the termination of a task T, and A2 is
+  either @Chg{Version=[3],New=[an],Old=[the]} evaluation of the expression
+  T'address@hidden,New=[ that results in True,],Old=[]} or
+  a call to Ada.Task_Identification.Is_Terminated with an actual parameter that
+  identifies T @Chg{Version=[3],New=[and a result of True ],Old=[]}(see
+  @RefSecNum(The Package Task_Identification));]}
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0262-1]}
+  If A1 is the action of issuing an entry call, and A2 is
+  part of the corresponding execution of the appropriate
+  @nt<entry_body> or @nt<accept_statement>@Chg{Version=[3],New=[;],Old=[.]}
+  @begin(Ramification)
+    Evaluating the @nt<entry_index> of an @nt<accept_statement>
+    is not synchronized with a corresponding entry call,
+    nor is evaluating the entry barrier of an @nt<entry_body>.
+  @end(Ramification)
+
+  If A1 is part of the execution of an @nt<accept_statement> or
+  @nt<entry_body>, and A2 is the action of returning
+  from the corresponding entry call;
+
+  If A1 is part of the execution of a protected procedure body
+  or @nt<entry_body> for a given protected object, and A2 is part of
+  a later execution of an @nt<entry_body> for the same
+  protected object;
+  @begin(Reason)
+    The underlying principle here is that
+    for one action to @lquotes@;address@hidden@; a second, the second action 
has to follow
+    a potentially blocking operation, whose blocking is dependent on
+    the first action in some way.
+    Protected procedures are not potentially blocking, so they can
+    only be "signalers," they cannot be signaled.
+  @end(Reason)
+  @begin(Ramification)
+    Protected subprogram calls are not defined to signal one another,
+    which means that such calls alone cannot be used to synchronize
+    access to shared data outside of a protected object.
+  @end(Ramification)
+  @begin(Reason)
+    The point of this distinction is so that on multiprocessors with
+    inconsistent caches, the caches only need to be refreshed at
+    the beginning of an entry body, and forced out at the end of an
+    entry body or protected procedure that leaves an entry open.
+    Protected function calls, and protected subprogram calls for
+    entryless protected objects do not require full cache consistency.
+    Entryless protected objects are intended to be treated roughly like
+    atomic objects @em each operation is indivisible with respect to
+    other operations (unless both are reads), but such operations cannot
+    be used to synchronize access to other nonvolatile
+    shared variables.
+  @end(Reason)
+
+  @address@hidden "Leading" is to help fit the next example on one page.}
+  If A1 signals some action that in turn signals A2.
address@hidden(Itemize)
+
address@hidden
+
address@hidden
address@hidden@;@PDefn2{Term=(erroneous execution),Sec=(cause)}
+Given an action of assigning to an object,
+and an action of reading or updating a part of the same object
+(or of a neighboring object if the two are not
+independently addressable), then the execution of the actions is erroneous
+unless the actions are @i(sequential).
address@hidden, Sec=(actions)}
+Two actions are sequential if one of the following is true:
address@hidden(Itemize)
+  One action signals the other;
+
+  Both actions occur as part of the execution of the same task;
+  @begin{Reason}
+    Any two actions of the same task are sequential, even
+    if one does not signal the other because they can be
+    executed in an @lquotes@;address@hidden@;
+    (but necessarily equivalent to some @lquotes@;address@hidden@;) order.
+  @end{Reason}
+
+  Both actions occur as part
+  of protected actions on the same protected object, and
+  at most one of the actions is part of a call on a protected function
+  of the protected object.
+  @begin(Reason)
+    Because actions within protected actions do not always imply
+    signaling, we have to mention them here explicitly to make sure
+    that actions occurring within different protected actions of the
+    same protected object are sequential with respect to one another
+    (unless both are part of calls on protected functions).
+  @end(Reason)
+  @begin(Ramification)
+    It doesn't matter whether or not the variable being assigned is
+    actually a subcomponent of the protected object; globals can be
+    safely updated from within the bodies of protected procedures or entries.
+  @end(Ramification)
address@hidden(Itemize)
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[Aspect],Old=[A @nt{pragma}]}
+Atomic or @Chg{Version=[3],New=[aspect ],Old=[]}Atomic_Components may also
+be @Chg{Version=[3],New=[specified],Old=[used]} to
+ensure that certain reads and updates are sequential @em
+see @RefSecNum(Shared Variable Control).
address@hidden(Ramification)
+  If two actions are @lquotes@;address@hidden@; it is known that their 
executions
+  don't overlap in time, but it is not necessarily specified which occurs 
first.
+  For example, all actions of a single task are sequential, even though
+  the exact order of execution is not fully specified for all constructs.
address@hidden(Ramification)
address@hidden(Discussion)
+  Note that if two assignments to the same variable are sequential,
+  but neither signals the other, then the program is not erroneous,
+  but it is not specified which assignment ultimately prevails.
+  Such a situation usually corresponds to a programming mistake, but
+  in some (rare) cases, the order makes no difference, and for this
+  reason this situation is not considered erroneous nor even a bounded error.
+  In Ada 83, this was considered an @lquotes@;incorrect order address@hidden@; 
if
+  the @lquotes@;address@hidden@; of the program was affected, but 
@lquotes@;address@hidden@; was never
+  fully defined. In Ada 95, this situation represents a potential
+  nonportability, and a friendly compiler might want to warn the
+  programmer about the situation, but it is not considered an error.
+  An example where this would come up would be in gathering statistics
+  as part of referencing some information, where the assignments
+  associated with
+  statistics gathering don't need to be ordered since they are
+  just accumulating aggregate counts, sums, products, etc.
address@hidden(Discussion)
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0031],ARef=[AI95-00118-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that a task T2 
can rely on
+  values of variables that are updated by another task T1, if task T2 first
+  verifies that T1'Terminated is True.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0009-1],ARef=[AI05-0201-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Revised the definition of
+  independent addressability to exclude conforming representation clauses
+  and to require that atomic and independent objects always have
+  independent addressability. This should not change behavior that the
+  user sees for any Ada program, so it is not an inconsistency.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0072-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the wording of
+  AI95-00118-01 to actually say what was intended (as described above).]}
address@hidden
+
+
address@hidden of Tasking and Synchronization}
+
address@hidden
+
address@hidden@;The following example defines a buffer protected object
+to smooth variations between
+the speed of output of a producing task and the speed of input of some
+consuming task. For instance, the producing task might have the
+following structure:
+
address@hidden(Example)
address@hidden(task) Producer;
+
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden(task body) Producer @key(is)
+   @Chg{Version=[2],New=[Person : Person_Name; address@hidden see 
@RefSecNum{Incomplete Type Declarations}]],Old=[Char : Character;]}
address@hidden(begin)
+   @key(loop)
+      ... address@hidden  @Chg{Version=[2],New=[simulate arrival of the next 
customer],Old=[produce the next character Char]}]
+      address@hidden,New=[Append_Wait(Person)],Old=[Write(Char)]};
+      @key(exit) @key(when) @Chg{Version=[2],New=[Person = 
@key(null)],Old=[Char = ASCII.EOT]};
+   @key(end) @key(loop);
address@hidden(end) Producer;
address@hidden(Example)
+
address@hidden@keepnext@;and the consuming task might have the following 
structure:
+
address@hidden(Example)
address@hidden(task) Consumer;
+
address@hidden@ChgRef{Version=[2],Kind=[Revised],address@hidden(task body) 
Consumer @key(is)
+   @Chg{Version=[2],New=[Person : Person_Name;],Old=[Char : Character;]}
address@hidden(begin)
+   @key(loop)
+      address@hidden,New=[Remove_First_Wait(Person)],Old=[Read(Char)]};
+      @key(exit) @key(when) @Chg{Version=[2],New=[Person = 
@key(null)],Old=[Char = ASCII.EOT]};
+      ... address@hidden  @Chg{Version=[2],New=[simulate serving a 
customer],Old=[consume the character Char]}]
+   @key(end) @key(loop);
address@hidden(end) Consumer;
address@hidden(Example)
+
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
+The buffer object contains an internal @Chg{Version=[2],New=[array],Old=[pool]}
+of @Chg{Version=[2],New=[person names],Old=[characters]} managed in a
+round-robin fashion. The @Chg{Version=[2],New=[array],Old=[pool]} has two
+indices, an In_Index denoting the @Chg{Version=[2],New=[index],Old=[space]}
+for the next input @Chg{Version=[2],New=[person name],Old=[character]} and an
+Out_Index denoting the @Chg{Version=[2],New=[index],Old=[space]} for the next
+output @Chg{Version=[2],New=[person name],Old=[character]}.
+
address@hidden,Kind=[Added],ARef=[AI95-00433-01]}
address@hidden,Text=[The Buffer is defined as an extension of the
+Synchronized_Queue interface (see @RefSecNum{Interface Types}), and as such
+promises to implement the abstraction defined by that interface. By doing so,
+the Buffer can be passed to the Transfer class-wide operation defined for
+objects of a type covered by Queue'Class.]}
+
address@hidden(Example)
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden(protected) Buffer @key(is)@Chg{Version=[2],New=[ @key(new) 
Synchronized_Queue @key(with)  address@hidden see @RefSecNum{Interface 
Types}]],Old=[]}
+   @key(entry) @Chg{Version=[2],New=[Append_Wait(Person : @key(in) 
Person_Name);],Old=[Read (C : @key(out) Character);]}
+   @key(entry) @Chg{Version=[2],New=[Remove_First_Wait(Person : @key(out) 
Person_Name);
+   @key(function) Cur_Count @key(return) Natural;
+   @key(function) Max_Count @key(return) Natural;
+   @key(procedure) Append(Person : @key(in) Person_Name);
+   @key(procedure) Remove_First(Person : @key(out) Person_Name);],Old=[Write(C 
: @key(in)  Character);]}
address@hidden(private)
+   Pool      : @Chg{Version=[2],New=[Person_Name_Array],Old=[String]}(1 .. 
100);
+   Count     : Natural := 0;
+   In_Index, Out_Index : Positive := 1;
address@hidden(end) Buffer;
+
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden(protected body) Buffer @key(is)
+   @key(entry) @Chg{Version=[2],New=[Append_Wait(Person : @key(in) 
Person_Name)],Old=[Write(C : @key(in) Character)]}
+      @key(when) Count < Pool'Length @key(is)
+   @key(begin)
+      @Chg{Version=[2],New=[Append(Person);],Old=[Pool(In_Index) := C;
+      In_Index := (In_Index @key(mod) Pool'Length) + 1;
+      Count    := Count + 1;]}
+   @key(end) @Chg{Version=[2],New=[Append_Wait],Old=[Write]};
+
address@hidden,Kind=[Added],ARef=[AI95-00433-01]}
address@hidden,Text=[   @key(procedure) Append(Person : @key(in) Person_Name) 
@key(is)
+   @key(begin)
+      @key(if) Count = Pool'Length @key(then)
+         @key(raise) Queue_Error @key(with) "Buffer Full";  address@hidden see 
@RefSecNum{Raise Statements and Raise Expressions}]
+      @key(end if);
+      Pool(In_Index) := Person;
+      In_Index       := (In_Index @key(mod) Pool'Length) + 1;
+      Count          := Count + 1;
+   @key(end) Append;]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
+   @key(entry) @Chg{Version=[2],New=[Remove_First_Wait(Person : @key(out) 
Person_Name)],Old=[Read(C : @key(out) Character)]}
+      @key(when) Count > 0 @key(is)
+   @key(begin)
+      @Chg{Version=[2],New=[Remove_First(Person);],Old=[C := Pool(Out_Index);
+      Out_Index := (Out_Index @key(mod) Pool'Length) + 1;
+      Count     := Count - 1;]}
+   @key(end) @Chg{Version=[2],New=[Remove_First_Wait],Old=[Read;
address@hidden(end) Buffer]};
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,Text=[   @key(procedure) Remove_First(Person : @key(out) 
Person_Name) @key(is)
+   @key(begin)
+      @key(if) Count = 0 @key(then)
+         @key(raise) Queue_Error @key(with) "Buffer Empty"; address@hidden see 
@RefSecNum{Raise Statements and Raise Expressions}]
+      @key(end if);
+      Person    := Pool(Out_Index);
+      Out_Index := (Out_Index @key(mod) Pool'Length) + 1;
+      Count     := Count - 1;
+   @key(end) Remove_First;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,Text=[   @key(function) Cur_Count @key(return) Natural @key(is)
+   @key(begin)
+       @key(return) Buffer.Count;
+   @key(end) Cur_Count;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,Text=[   @key(function) Max_Count @key(return) Natural @key(is)
+   @key(begin)
+       @key(return) Pool'Length;
+   @key(end) Max_Count;
address@hidden(end) Buffer;]}
address@hidden(Example)
+
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/10.mss 
b/packages/ada-ref-man/source_2012/10.mss
new file mode 100755
index 0000000..16ae6c5
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/10.mss
@@ -0,0 +1,4083 @@
address@hidden(10, Root="ada.mss")
+
address@hidden: 2015/04/03 04:12:42 $}
address@hidden Structure and Compilation Issues}
+
address@hidden: e:\\cvsroot/ARM/Source/10.mss,v $}
address@hidden: 1.106 $}
address@hidden changes added, 2000/04/24, RLB}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden overall structure of programs and the facilities for separate
+compilation are described in this @Chg{Version=[3],New=[clause],Old=[section]}.
+A @i(program) is a set of @i(partitions), each of which
+may execute in a separate address space, possibly on a separate
+computer.
address@hidden<Program>,
+  Text=<A @i(program) is a set of @i(partitions), each of which
+  may execute in a separate address space, possibly on a separate
+  computer.
+  A partition consists of a set of library units.>}
address@hidden<Partition>,
+  Text=<A @i(partition) is a part of a program.
+  Each partition consists of a set of library units.
+  Each partition may run in a separate address space,
+  possibly on a separate computer.
+  A program may contain just one partition.
+  A distributed program typically contains multiple partitions,
+  which can execute concurrently.>}
+
address@hidden unit],Sec=(informal introduction)}
address@hidden,Sec=(informal introduction)}
address@hidden,Sec=(informal introduction)}
+As explained below,
+a partition is constructed from @i{library units}.
+Syntactically, the declaration of a library unit is a @nt{library_item},
+as is the body of a library unit.
+An implementation may support a concept of a @i{program library}
+(or simply, a @lquotes@;address@hidden@;),
+which contains @nt{library_item}s
+and their subunits.
address@hidden library],See=(library)}
+Library units may be organized into a hierarchy of
+children, grandchildren, and so on.]
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[clause],Old=[section]} has two
address@hidden,New=[subclauses],Old=[clauses]}:
address@hidden Compilation}
+discusses compile-time issues related to separate compilation.
address@hidden Execution}
+discusses issues related to what is traditionally known as @lquotes@;link 
address@hidden@;
+and @lquotes@;run address@hidden@; @em building and executing partitions.
+
address@hidden
+
address@hidden
address@hidden overspecifying environmental issues}
+We should avoid specifying details that are outside the domain of the
+language itself.
+The standard is intended (at least in part)
+to promote portability of Ada programs at the source level.
+It is not intended to standardize extra-language issues such as how one
+invokes the compiler (or other tools),
+how one's source is represented and organized,
+version management, the format of error messages, etc.
+
address@hidden separate compilation}
address@hidden compilation], Sec=(safe)}
+The rules of the language should be enforced
+even in the presence of separate compilation.
+Using separate compilation should not make a
+program less safe.
+
address@hidden determinable via semantic dependences}
+It should be possible to determine the legality of a
+compilation unit by looking only at the compilation unit itself
+and the compilation units upon which it depends semantically.
+As an example, it should be possible to analyze the legality of
+two compilation units in parallel if they do not depend semantically
+upon each other.
+
+On the other hand, it may be necessary to look outside that set in
+order to generate code @em this is generally true for
+generic instantiation and inlining, for example.
+Also on the other hand,
+it is generally necessary to look outside that set in
+order to check @LinkTimeName@;s.
+
+See also the @lquotes@;generic contract address@hidden@; @MetaRulesName of
address@hidden Instantiation}.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The @Chg{Version=[3],New=[clause],Old=[section]} organization mentioned above 
is
+different from that of RM83. @end{DiffWord83}
+
address@hidden Compilation}
+
address@hidden
address@hidden@Defn{separate compilation}
address@hidden, Sec=(separate)}
address@hidden<Program unit>,
+  Text=<A @i(program unit) is either a package, a task unit,
+  a protected unit, a protected entry, a generic unit,
+  or an explicitly declared subprogram other than an enumeration
+  literal.
+  Certain kinds of program units can be separately compiled.
+  Alternatively, they can appear physically nested within
+  other program units.>}
+
address@hidden<Compilation unit>,
+  Text=<The text of a program can be submitted to the compiler in one or
+  more @nt(compilation)s.
+  Each @nt(compilation) is a succession of @nt(compilation_unit)s.
+  A @nt(compilation_unit) contains either
+  the declaration, the body, or a renaming of a program unit.>}]
+The representation for a @nt<compilation> is implementation-defined.
address@hidden representation for a @nt{compilation}.}
address@hidden
+Some implementations might choose to make a
address@hidden be a source (text) file.
+Others might allow multiple source files to be automatically
+concatenated to form a single @nt{compilation}.
+Others still may represent the source in a nontextual form such as a parse
+tree.
+Note that the RM95 does not even define the concept of a
+source file.
+
+Note that a protected subprogram is a subprogram,
+and therefore a program unit.
+An instance of a generic unit is a program unit.
+
+A protected entry is a program unit,
+but protected entries cannot be separately compiled.
address@hidden
+
address@hidden<Library unit>,
+  Text=<A library unit is a separately compiled
+  program unit,
+  and is always a package, subprogram, or generic unit.
+  Library units may have other (logically nested) library units as children,
+  and may have other program units physically nested within them.
+  @Defn(subsystem)
+  A root library unit, together with its children and grandchildren
+  and so on, form a @i(subsystem).>}
+
address@hidden
+
address@hidden
+An implementation may impose implementation-defined restrictions
+on @nt{compilation}s that contain multiple @nt<compilation_unit>s.
address@hidden restrictions on @nt<compilation>s that contain
+multiple @nt<compilation_unit>s.}
address@hidden
+For example, an implementation might disallow a @nt{compilation} that
+contains two versions of the same compilation unit, or that
+contains the declarations for library packages P1 and P2,
+where P1 precedes P2 in the @nt<compilation> but P1 has a
address@hidden<with_clause> that mentions P2.
address@hidden
address@hidden
+
address@hidden
+The interactions between language issues and environmental issues
+are left open in Ada 95. The environment concept is new.
+In Ada 83, the concept of the program library, for example,
+appeared to be quite concrete,
+although the rules had no force,
+since implementations could get around them simply by defining various
+mappings from the concept of an Ada program library to whatever data
+structures were actually stored in support of separate compilation.
+Indeed, implementations were encouraged to do so.
+
+In RM83, it was unclear which was the official definition of
address@hidden@;program address@hidden@;
+Definitions appeared in RM83-5, 6, 7, and 9, but not 12.
+Placing it here seems logical,
+since a program unit is sort of a potential compilation unit.
address@hidden
+
address@hidden Units - Library Units}
+
address@hidden
address@hidden @nt{library_item} is a compilation unit that is the declaration, 
body,
+or renaming of a library unit.
+Each library unit (except Standard) has a @i{parent unit},
+which is a library package or generic library package.]
address@hidden, Sec=(of a library unit)}
+A library unit is a @i{child} of its parent unit.
+The @i{root} library units are the children of
+the predefined library package Standard.
address@hidden
+Standard is a library unit.
address@hidden
address@hidden
+
address@hidden
address@hidden<compilation>,rhs="address@hidden"}
+
+
address@hidden<compilation_unit>,rhs="
+    @Syn2{context_clause} @Syn2{library_item}
+  | @Syn2{context_clause} @Syn2{subunit}"}
+
+
address@hidden<library_item>,rhs="address@hidden @Syn2{library_unit_declaration}
+  | @Syn2{library_unit_body}
+  | address@hidden @Syn2{library_unit_renaming_declaration}"}
+
+
address@hidden, lhs=<library_unit_declaration>,rhs="
+     @address@hidden| @Syn2{package_declaration}
+   | @address@hidden| @Syn2{generic_instantiation}"}
+
+
address@hidden<library_unit_renaming_declaration>,rhs="
+   @Syn2{package_renaming_declaration}
+ | @Syn2{generic_renaming_declaration}
+ | @Syn2{subprogram_renaming_declaration}"}
+
+
address@hidden<library_unit_body>,rhs="@Syn2{subprogram_body} | 
@Syn2{package_body}"}
+
+
address@hidden<parent_unit_name>,rhs="@Syn2{name}"}
+
address@hidden,Kind=[Added],ARef=[AI95-00397-01]}
address@hidden,Text=[An @nt{overriding_indicator} is not allowed in a
address@hidden, @nt{generic_instantiation}, or
address@hidden that declares a library unit.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[All of the listed items syntactically include
+  @nt{overriding_indicator}, but a library unit can never override anything.
+  A majority of the ARG thought that allowing @key{not overriding} in that
+  case would be confusing instead of helpful.]}
address@hidden
address@hidden
+
address@hidden
address@hidden unit}
address@hidden@Comment{There is a different definition of library in 10.1.4.}
address@hidden,Other=[library level]}
address@hidden,Other=[library unit]}
address@hidden,Other=[library_item]}
+A @i{library unit} is a program unit that is declared by a
address@hidden
+When a program unit is a library unit,
+the prefix @lquotes@;address@hidden@; is used to refer to it (or 
@lquotes@;generic address@hidden@;
+if generic),
+as well as to its declaration and body,
+as in @lquotes@;library address@hidden@;, @lquotes@;library @address@hidden@;, 
or
address@hidden@;generic library address@hidden@;.
address@hidden unit}
+The term @i{compilation unit} is used to refer to
+a @nt{compilation_unit}.
+When the meaning is clear from context,
+the term is also used to refer to the @nt{library_item}
+of a @nt{compilation_unit}
+or to the @nt{proper_body} of a @nt{subunit}
address@hidden(that is, the @nt{compilation_unit} without the
address@hidden and the @key[separate] (@nt{parent_unit_name}))].
address@hidden
address@hidden@keepnext@;In this example:
address@hidden
address@hidden Ada.Text_IO;
address@hidden P @key[is]
+    ...
address@hidden P;
address@hidden
+
+the term @lquotes@;compilation address@hidden@; can refer to this text: 
@lquotes@;@key[with] Ada.Text_IO;
address@hidden P @key[is] ... @key[end] P;@rquotes@; or to this text:
address@hidden@;@key[package] P @key[is] ... @key[end] P;@rquotes@;. We use 
this shorthand
+because it corresponds to common usage.
+
+We like to use the word @lquotes@;address@hidden@; for declaration-plus-body 
things,
+and @lquotes@;address@hidden@; for declaration or body separately (as in
address@hidden).
+The terms @lquotes@;@nt{compilation_unit},@rquotes@; @lquotes@;compilation 
unit,@rquotes@;
+and @lquotes@;@address@hidden@; are exceptions to this rule.
+We considered changing @lquotes@;@nt{compilation_unit},@rquotes@; 
@lquotes@;compilation address@hidden@;
+to @lquotes@;@ntf{compilation_item},@rquotes@; @lquotes@;compilation 
item,@rquotes@;
+respectively, but we decided not to.
address@hidden
+
address@hidden declaration], Sec=(of a @nt{library_item})}
address@hidden declaration], Sec=(of a library unit)}
+The @i{parent declaration} of a @nt{library_item}
+(and of the library unit) is the declaration denoted
+by the @address@hidden, if any, of the
address@hidden@address@hidden of the @nt<library_item>.
address@hidden library unit}
+If there is no @address@hidden,
+the parent declaration is the declaration of Standard,
+the @nt{library_item} is a @i{root} @nt{library_item}, and
+the library unit (renaming) is a @i{root} library
+unit (renaming).
+The declaration and body of Standard itself have no parent declaration.
address@hidden unit], Sec=(of a library unit)}
+The @i{parent unit} of a @nt{library_item} or library unit is the
+library unit declared by its parent declaration.
address@hidden
+The declaration and body of Standard are presumed to exist from
+the beginning of time, as it were.
+There is no way to actually write them,
+since there is no syntactic way to indicate lack of a parent.
+An attempt to compile a package Standard would result in
+Standard.Standard.
address@hidden
address@hidden
+Library units (other than Standard)
+have @lquotes@;parent address@hidden@; and @lquotes@;parent address@hidden@;.
+Subunits have @lquotes@;parent address@hidden@;.
+We didn't bother to define the other possibilities:
+parent body of a library unit,
+parent declaration of a subunit,
+parent unit of a subunit.
+These are not needed,
+and might get in the way of a correct definition of @lquotes@;address@hidden@;
address@hidden
+
address@hidden children of a library unit occur immediately
+within the declarative region of the declaration of the library unit.]
address@hidden, Sec=(of a library unit)}
+The @i{ancestors} of a library unit are itself, its parent,
+its parent's parent, and so on.
address@hidden(Standard is an ancestor of every library unit.)]
address@hidden
+The @i{descendant} relation is the inverse of the ancestor relation.
address@hidden
+These definitions are worded carefully to avoid defining subunits as
+children. Only library units can be children.
+
+We use the unadorned term @lquotes@;address@hidden@; here to concisely define 
both
address@hidden@;ancestor address@hidden@; and @lquotes@;ancestor 
address@hidden@;
address@hidden
+
address@hidden library unit}
address@hidden declaration of a library unit}
address@hidden library unit}
address@hidden declaration of a library unit}
+A @nt<library_unit_declaration>
+or a @nt<address@hidden@address@hidden> is @i{private}
+if the declaration is immediately preceded
+by the reserved word @key{private};
+it is otherwise @i{public}. A library unit is private or public
+according to its declaration.
address@hidden descendant], Sec=(of a library unit)}
+The @i{public descendants} of a library unit are the library unit
+itself, and the public descendants of its public children.
address@hidden descendant], Sec=(of a library unit)}
+Its other descendants are @i{private descendants}.
address@hidden
+The first concept defined here is that a @nt<library_item> is either public
+or private (not in relation to anything else @em it's just a property of
+the library unit).
+The second concept is that a @nt<library_item>
+is a public descendant or
+private descendant @i{of a given ancestor}.
+A given @nt<library_item> can be a
+public descendant of one of its ancestors,
+but a private descendant of some other ancestor.
+
+A subprogram declared by a @nt{subprogram_body}
+(as opposed to a @nt{subprogram_declaration})
+is always public,
+since the syntax rules disallow the reserved word @key[private]
+on a body.
+
+Note that a private library unit is a @i{public}
+descendant of itself,
+but a @i{private} descendant of its parent.
+This is because it is visible outside itself @em its
+privateness means that it is not visible outside its
+parent.
+
+Private children of Standard are legal, and follow the normal rules.
+It is intended that implementations might have some method for taking an
+existing environment, and treating it as a package to be 
@lquotes@;address@hidden@; into
+another environment, treating children of Standard in the imported environment
+as children of the imported package.
address@hidden
address@hidden
address@hidden@;Suppose we have a public library unit A,
+a private library unit A.B, and a public library unit A.B.C.
+A.B.C is a public descendant of itself and of A.B,
+but a private descendant of A;
+since A.B is private to A, we don't allow A.B.C to escape outside A
+either.
+This is similar to the situation that would occur with physical
+nesting, like this:
address@hidden
address@hidden A @key[is]
address@hidden
+    @key[package] B @key[is]
+        @key[package] C @key[is]
+        @key[end] C;
+    @key[private]
+    @key[end] B;
address@hidden A;
address@hidden
+
+Here, A.B.C is visible outside itself and outside A.B, but not outside A.
+(Note that this example is intended to illustrate the visibility
+of program units from the outside;
+the visibility within child units is not quite identical to that of
+physically nested units,
+since child units are nested after their parent's declaration.)
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00217-06]}
address@hidden,Text=[For each library @nt{package_declaration} in the
+environment, there is an implicit declaration of a
address@hidden view} of that library address@hidden view} The
+limited view of a package contains:]}
+
address@hidden(Itemize)
address@hidden,Kind=[Added],ARef=[AI95-00217-06]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0129-1],ARef=[AI05-0262-1]}
address@hidden,Text=[For address@hidden,New=[],Old=[ nested]}
address@hidden@Chg{Version=[3],New=[ occurring immediately within
+the visible part],Old=[]}, a declaration of the limited view of that package,
+with the same @nt{defining_program_unit_name}.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00217-06],ARef=[AI95-00326-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0108-1],ARef=[AI05-0129-1],ARef=[AI05-0262-1]}
address@hidden,Text=[For each @nt{type_declaration}
address@hidden,New=[occurring immediately within],Old=[in]} the visible
address@hidden,New=[ that is not an
address@hidden,Old=[]}, an incomplete view
+of the address@hidden,New=[ with no @nt{discriminant_part}],Old=[]};
+if the @nt{type_declaration} is tagged, then the view is a
+tagged incomplete view.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0108-1]}
+  @ChgAdded{Version=[3],Text=[The incomplete view of a type does not have
+  a discriminant_part even if the @nt{type_declaration} does have
+  one. This is necessary because semantic analysis (and the associated
+  dependence on @nt{with_clause}s) would be necessary
+  to determine the types of the discriminants.]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0129-1]}
+  @ChgAdded{Version=[3],Text=[No incomplete views of incomplete types are
+  included in the limited view. The rules of
+  @RefSecNum{Incomplete Type Declarations} ensure that the completion of any
+  visible incomplete type is declared in the same visible part, so such
+  an incomplete view would simply be redundant.]}
address@hidden
address@hidden(Itemize)
+
address@hidden(Discussion)
address@hidden,Kind=[Added],ARef=[AI95-00217-06]}
address@hidden,Text=[The implementation model of a limited view is that it
+can be determined solely from the syntax of the source of the unit, without
+any semantic analysis. That allows it to be created without the semantic
+dependences of a full unit, which is necessary for it to break mutual
+dependences of units.]}
address@hidden(Discussion)
+
address@hidden(Ramification)
address@hidden,Kind=[Added]}
address@hidden,Text=[The limited view does not include package instances and
+their contents. Semantic analysis of a unit (and dependence on its
address@hidden) would be needed to determine the contents of an instance.]}
address@hidden(Ramification)
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The limited view of a library @nt{package_declaration} is 
private if that
+library @nt{package_declaration} is immediately preceded by the reserved word
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden is no syntax for declaring limited
+views of packages, because they are always implicit.] The implicit declaration
+of a limited view of a library package @Redundant[is not the declaration of a
+library unit (the library @nt{package_declaration} is); nonetheless, it] is a
address@hidden The implicit declaration of the limited view of a library
+package forms an (implicit) compilation unit whose @nt{context_clause} is
+empty.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[A library @nt{package_declaration} is the completion of
+the declaration of its limited view.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is notwithstanding the rule in
+  @RefSecNum{Completions of Declarations} that says that implicit declarations
+  don't have completions.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This rule explains where to find the completions
+  of the incomplete views defined by the limited view.]}
address@hidden
+
address@hidden
+
address@hidden
+The parent unit of a @nt<library_item> shall be a
address@hidden package or generic @Redundant[library] package.
+
+If a @nt{defining_program_unit_name} of a given
+declaration or body has a @nt{parent_unit_name},
+then the given declaration or body shall be a @nt<library_item>.
+The body of a program unit shall be a @nt{library_item} if and only
+if the declaration of the program unit is a @nt<library_item>.
+In a @address@hidden@address@hidden,
+the @Redundant[(old)] @nt{name}
+shall denote a @nt<library_item>.
address@hidden
+We could have allowed nested program units to be children
+of other program units;
+their semantics would make sense.
+We disallow them to keep things simpler
+and because they wouldn't be particularly useful.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00217-06]}
+A @nt{parent_unit_name} @Redundant[(which can be used within a
address@hidden<defining_program_unit_name> of a @nt<library_item>
+and in the @key[separate] clause of a @nt<subunit>)],
+and each of its @nt{prefix}es,
+shall not denote a @nt{renaming_declaration}.
address@hidden the other hand,
+a name that denotes a @address@hidden@address@hidden is allowed
+in a @Chg{Version=[2],address@hidden,address@hidden
+and other places where the name of a library unit is allowed.]
+
+If a library package is an instance of
+a generic package, then every child of the
+library package shall either be itself an instance or be a renaming of
+a library unit.
address@hidden
+A child of an instance of a given generic unit
+will often be an instance of a (generic) child of the given
+generic unit.
+This is not required, however.
address@hidden
address@hidden
address@hidden@;Instances are forbidden from having noninstance children for 
two reasons:
address@hidden(Enumerate)
+We want all source code that can depend on information from
+the private part of a library unit to be inside the "subsystem"
+rooted at the library unit.
+If an instance of a generic unit were allowed to have a noninstance
+as a child, the source code of that child might depend on information
+from the private part of the generic unit, even though it is outside
+the subsystem rooted at the generic unit.
+
+Disallowing noninstance children simplifies the description of the
+semantics of children of generic packages.
address@hidden(Enumerate)
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0004-1]}
+A child of a generic library package shall either be itself a generic unit
+or be a renaming of some other child of the same generic address@hidden,
+New=[],Old=[ The renaming of a child of a generic package shall occur
+only within the declarative region of the generic package.]}
+
+
+A child of a parent generic package shall be
+instantiated or renamed only within the declarative region
+of the parent generic.
+
address@hidden,Kind=[Revised],ARef=[AI95-00331-01]}
+For each @Chg{Version=[2],New=[child @i<C>],
+Old=[declaration or renaming of a generic unit as a child]} of some parent
+generic address@hidden,New=[ @i<P>],Old=[]}, there is
+a corresponding declaration @Chg{Version=[2],address@hidden<C>],Old=[]} nested
+immediately within each instance @Chg{Version=[2],New=[of @i<P>. For the
+purposes of this rule, if a child @i<C> itself has a child @i<D>, each
+corresponding declaration for @i<C> has a corresponding
+child @i<D>], Old=[of the parent]}.
address@hidden@Chg{Version=[2],New=[The corresponding],Old=[This]}
+declaration @Chg{Version=[2],New=[for a child within an instance ],Old=[]}is
+visible only within the scope of a @nt{with_clause} that
+mentions the @Chg{Version=[2],New=[(original) ],Old=[]}child generic unit.]
+
address@hidden
+Within the child, like anything nested in a generic unit,
+one can make up-level references to the current instance of its
+parent, and thereby gain access to the formal parameters of the
+parent, to the types declared in the parent, etc.
+This @lquotes@;address@hidden@; model applies even within the
address@hidden of the child,
+as it does for a generic child of a nongeneric unit.
address@hidden
address@hidden
+
+  Suppose P is a generic library package,
+  and P.C is a generic child of P.
+  P.C can be instantiated inside the declarative region of P.
+  Outside P, P.C can be mentioned only in a @nt{with_clause}.
+  Conceptually, an instance I of P is a package that has a nested
+  generic unit called I.C.
+  Mentioning P.C in a @nt{with_clause} allows I.C to be instantiated.
+  I need not be a library unit,
+  and the instantiation of I.C need not be a library unit.
+  If I is a library unit, and an instance of I.C is a child of I,
+  then this instance has to be called something other than C.
+
address@hidden
+
+A library subprogram shall not override a primitive subprogram.
address@hidden
+This prevents certain obscure anomalies.
+For example, if a library subprogram were to override a subprogram
+declared in its parent package, then in a compilation unit that depends
address@hidden on the library subprogram, the library subprogram could
+hide the overridden operation from all visibility,
+but the library subprogram itself would not be visible.
+
+Note that even without this rule, such subprograms would be illegal for
+tagged types, because of the freezing rules.
address@hidden
+
+The defining name of a function that is a compilation unit
+shall not be an @nt{operator_symbol}.
address@hidden
+  Since overloading is not permitted among compilation units,
+  it seems unlikely that it would be useful to define one as
+  an operator. Note that a subunit could be renamed within its
+  parent to be an operator.
address@hidden
+
address@hidden
+
address@hidden
+
+A @nt<subprogram_renaming_declaration>
+that is a @address@hidden@address@hidden is a
+renaming-as-declaration, not a renaming-as-body.
+
+
+
address@hidden@address@hidden are two kinds of dependences among
+compilation units:]
address@hidden
address@hidden @i{semantic dependences}
+(see below)
+are the ones needed to check the
+compile-time rules across compilation unit boundaries;
+a compilation unit depends semantically on
+the other compilation units needed to determine its legality.
+The visibility rules are based on the semantic dependences.
+
+The @i{elaboration dependences}
+(see @RefSecNum{Program Execution})
+determine the order of elaboration of @nt{library_item}s.]
address@hidden
address@hidden
+Don't confuse these kinds of dependences with the run-time
+dependences among tasks and masters defined in
address@hidden Dependence - Termination of Tasks}.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00217-06]}
address@hidden dependence], Sec=(of one compilation unit upon another)}
address@hidden, Sec=(semantic)}
+A @nt{library_item} depends semantically upon its
+parent declaration.
+A subunit depends semantically upon its parent body.
+A @nt{library_unit_body} depends semantically upon the corresponding
address@hidden, if any.
address@hidden,New=[The declaration of the limited view of a
+library package depends semantically upon the declaration of the
+limited view of its parent.
+The declaration of a library package depends semantically upon the
+declaration of its limited view.],Old=[]}
+A compilation unit depends semantically upon each @nt<library_item>
+mentioned in a @nt{with_clause} of the compilation unit.
+In addition, if a given compilation unit contains an @nt{attribute_reference}
+of a type defined in another compilation unit,
+then the given compilation unit depends semantically upon the
+other compilation unit.
+The semantic dependence relationship is transitive.
+
address@hidden
+The @lquotes@;if address@hidden@; in the third sentence is necessary
+because library subprograms are not required to have a
address@hidden
address@hidden
address@hidden
+If a given compilation unit contains a
address@hidden,
+then the given compilation unit depends semantically upon the
+declaration of Ada.Exceptions.
+
+If a given compilation unit contains a @nt{pragma} with an
+argument of a type defined in another compilation unit,
+then the given compilation unit depends semantically upon the
+other compilation unit.
address@hidden
address@hidden
+For example, a compilation unit containing
+X'Address depends semantically upon the declaration of package
+System.
+
+For the Address attribute, this fixes a hole in Ada 83.
+Note that in almost all cases, the dependence will need to exist
+due to @nt{with_clause}s, even without this rule.
+Hence, the rule has very little effect on programmers.
+
+Note that the semantic dependence does not have the same effect as a
address@hidden; in order to denote a declaration in one of those
+packages, a @nt{with_clause} will generally be needed.
+
+Note that no special rule is needed for an
address@hidden, since an expression after @key[use]
+will require semantic dependence upon the compilation unit containing
+the @nt{type_declaration} of interest.
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00217-06]}
address@hidden,Text=[Unlike a full view of a package, a limited view
+does not depend semantically on units mentioned in @nt{with_clause}s of the
address@hidden that defines the package. Formally, this is
+achieved by saying that the limited view has an empty @nt{context_clause}.
+This is necessary so that they
+can be useful for their intended purpose: allowing mutual dependences between
+packages. The lack of semantic dependence limits the contents of a limited view
+to the items that can be determined solely from the syntax of the source of the
+package, without any semantic analysis. That allows it to be created without
+the semantic dependences of a full package.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00217-06]}
address@hidden,Text=[The elaboration of the declaration of the limited
+view of a package has no effect.]}
address@hidden
+
address@hidden
+A simple program may consist of a single compilation unit.
+A @nt{compilation} need not have any compilation units;
+for example, its text can consist of @nt{pragma}s.
address@hidden
+Such @nt{pragma}s cannot have any arguments that are @nt{name}s,
+by a previous rule of this subclause.
+A @nt{compilation} can even be entirely empty,
+which is probably not useful.
+
+Some interesting properties of the three kinds of dependence:
+The elaboration dependences also include the semantic dependences,
+except that subunits are taken together with their parents.
+The semantic dependences partly determine the order in which the
+compilation units appear in the environment at compile time.
+At run time, the order is partly determined by the elaboration
+dependences.
+
address@hidden@;The model whereby a child is inside its parent's declarative 
region,
+after the parent's declaration,
+as explained in @RefSecNum{Declarative Region},
+has the following ramifications:
address@hidden(itemize)
+The restrictions on @lquotes@;address@hidden@; use of a private type 
(RM83-7.4.1(4))
+or a deferred constant (RM83-7.4.3(2))
+do not apply to uses in child units, because they follow
+the full declaration.
+
+A library subprogram is never primitive, even if its profile includes a
+type declared immediately within the parent's @nt{package_specification},
+because the child is not declared immediately within the same
address@hidden as the type (so it doesn't declare a new
+primitive subprogram), and because the child is forbidden from overriding
+an old primitive subprogram. It is immediately within the same declarative
+region, but not the same @nt{package_specification}. Thus, for a tagged type,
+it is not possible to call a child subprogram in a dispatching manner.
+(This is also forbidden by the freezing rules.)
+Similarly, it is not possible for the user to declare primitive
+subprograms of the types declared in the declaration of Standard,
+such as Integer (even if the rules were changed to allow a library unit
+whose name is an operator symbol).
+
+When the parent unit is @lquotes@;address@hidden@; the simple names of the
+with'd child units are directly visible (see @RefSec{Use Clauses}).
+
+When a parent body with's its own child, the defining name of
+the child is directly visible, and the parent body
+is not allowed to
+include a declaration of a homograph of the child unit
+immediately within the @nt{declarative_part} of the body
+(RM83-8.3(17)).
address@hidden(itemize)
+
+Note that @lquotes@;declaration of a library address@hidden@;
+is different from @lquotes@;@address@hidden@;
address@hidden the former includes @nt{subprogram_body}.
+Also, we sometimes really mean @lquotes@;declaration of a view of a
+library address@hidden@;, which includes
address@hidden@address@hidden@!declaration}s.
+
+The visibility rules generally imply that the renamed view of a
address@hidden@address@hidden@!declaration} has to be mentioned in a
address@hidden@!clause} of the @address@hidden@address@hidden
address@hidden
address@hidden
+The real rule is that the renamed library unit
+has to be visible in the @address@hidden@address@hidden
address@hidden
address@hidden
+In most cases, @lquotes@;has to be address@hidden@; means there has to be a
address@hidden
+However, it is possible in obscure cases to avoid the need for a
address@hidden; in particular, a compilation unit such as
address@hidden@;@key[package] P.Q @key[renames] P;@rquotes@;
+is legal with no @nt{with_clause}s
+(though not particularly interesting).
+ASCII is physically nested in Standard,
+and so is not a library unit,
+and cannot be renamed as a library unit.
address@hidden
+
+The @nt{designator} of a library function cannot be an @nt{operator_symbol},
+but a nonlibrary @nt{renaming_declaration} is allowed to rename a library
+function as an operator.
+Within a partition,
+two library subprograms are required to have distinct
+names and hence cannot overload each other.
+However,
address@hidden are allowed to define overloaded names for
+such subprograms, and a locally declared subprogram is allowed to
+overload a library subprogram. The expanded name Standard.L can be
+used to denote a root library unit L (unless the declaration of
+Standard is hidden)
+since root library unit declarations occur immediately within the
+declarative region of package Standard.
address@hidden
+
address@hidden
address@hidden@address@hidden of library units:}
address@hidden
address@hidden Rational_Numbers.IO @key[is]  address@hidden public child of 
Rational_Numbers, see @RefSecNum{Package Specifications and Declarations}]
+   @key[procedure] Put(R : @key[in]  Rational);
+   @key[procedure] Get(R : @key[out] Rational);
address@hidden Rational_Numbers.IO;
+
address@hidden procedure] Rational_Numbers.Reduce(R : @key[in out] Rational);
+                                address@hidden private child of 
Rational_Numbers]
+
address@hidden Rational_Numbers.Reduce;   address@hidden refer to a private 
child]
address@hidden body] Rational_Numbers @key[is]
+   ...
address@hidden Rational_Numbers;
+
address@hidden Rational_Numbers.IO; @key[use] Rational_Numbers;
address@hidden Ada.Text_io;               address@hidden see @RefSecNum{Text 
Input-Output}]
address@hidden Main @key[is]               address@hidden a root library 
procedure]
+   R : Rational;
address@hidden
+   R := 5/3;                    address@hidden construct a rational number, 
see @RefSecNum{Package Specifications and Declarations}]
+   Ada.Text_IO.Put("The answer is: ");
+   IO.Put(R);
+   Ada.Text_IO.New_Line;
address@hidden Main;
+
address@hidden Rational_Numbers.IO;
address@hidden Rational_IO @key[renames] Rational_Numbers.IO;
+                                address@hidden a library unit renaming 
declaration]
address@hidden
+
+Each of the above @nt{library_item}s can be submitted to the compiler
+separately.
address@hidden
address@hidden@address@hidden of a generic package with children:}
+
address@hidden
address@hidden
+   @key[type] Element @key[is] @key[private];
+   @key[with] @key[function] Image(E : Element) @key[return] String;
address@hidden Generic_Bags @key[is]
+   @key[type] Bag @key[is] @key[limited] @key[private]; address@hidden A bag 
of Elements.}
+   @key[procedure] Add(B : @key[in] @key[out] Bag; E : Element);
+   @key[function] Bag_Image(B : Bag) @key[return] String;
address@hidden
+   @key[type] Bag @key[is] ...;
address@hidden Generic_Bags;
+
address@hidden
address@hidden Generic_Bags.Generic_Iterators @key[is]
+   ... address@hidden various additional operations on Bags.}
+
+   @key[generic]
+      @key[with] @key[procedure] Use_Element(E : @key[in] Element);
+         address@hidden Called once per bag element.}
+   @key[procedure] Iterate(B : @key[in] Bag);
address@hidden Generic_Bags.Generic_Iterators;
address@hidden
+
address@hidden
address@hidden@keepnext@;A package that instantiates the above generic units:
address@hidden
address@hidden
address@hidden Generic_Bags;
address@hidden Generic_Bags.Generic_Iterators;
address@hidden My_Abstraction @key[is]
+    @key[type] My_Type @key[is] ...;
+    @key[function] Image(X : My_Type) @key[return] String;
+    @key[package] Bags_Of_My_Type @key[is] @key[new] Generic_Bags(My_Type, 
Image);
+    @key[package] Iterators_Of_Bags_Of_My_Type @key[is] @key[new] 
Bags_Of_My_Type.Generic_Iterators;
address@hidden My_Abstraction;
address@hidden
+
+In the above example, Bags_Of_My_Type has a nested generic unit called
+Generic_Iterators.
+The second @nt{with_clause} makes that nested unit visible.
+
address@hidden@;Here we show how the generic body could depend on one of its own
+children:
address@hidden
address@hidden Generic_Bags.Generic_Iterators;
address@hidden @key[body] Generic_Bags @key[is]
+   @key[procedure] Add(B : @key[in] @key[out] Bag; E : Element) @key[is] ... 
@key[end] Add;
+
+   @key[package] Iters @key[is] @key[new] Generic_Iterators;
+
+   @key[function] Bag_Image(B : Bag) @key[return] String @key[is]
+      Buffer : String(1..10_000);
+      Last : Integer := 0;
+
+      @key[procedure] Append_Image(E : @key[in] Element) @key[is]
+         Im : @key[constant] String := Image(E);
+      @key[begin]
+         @key[if] Last /= 0 @key[then] address@hidden Insert a comma.}
+            Last := Last + 1;
+            Buffer(Last) := ',';
+         @key[end] @key[if];
+         Buffer(Last+1 .. Last+Im'Length) := Im;
+         Last := Last + Im'Length;
+      @key[end] Append_Image;
+
+      @key[procedure] Append_All @key[is] @key[new] 
Iters.Iterate(Append_Image);
+   @key[begin]
+      Append_All(B);
+      @key[return] Buffer(1..Last);
+   @key[end] Bag_Image;
address@hidden Generic_Bags;
address@hidden
+
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax rule for @nt{library_item} is modified to allow the
+reserved word @key{private} before a @nt{library_unit_declaration}.
+
+Children (other than children of Standard)
+are new in Ada 95.
+
+Library unit renaming is new in Ada 95.
address@hidden
+
address@hidden
+Standard is considered a library unit in Ada 95.
+This simplifies the descriptions,
+since it implies that the parent of each library unit is a library unit.
+(Standard itself has no parent, of course.)
+As in Ada 83, the language does not define any way to recompile
+Standard, since the name given in the declaration of a library unit is
+always interpreted in relation to Standard.
+That is,
+an attempt to compile a package Standard would result in
+Standard.Standard.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00217-06]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The concept of a limited view is new. Combined with @nt{limited_with_clause}s
+  (see @RefSecNum{Context Clauses - With Clauses}), they facilitate
+  construction of mutually recursive types in multiple packages.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00331-01]}
+  @ChgAdded{Version=[2],Text=[Clarified the wording so that a grandchild
+  generic unit will work as expected.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0108-1],ARef=[AI05-0129-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified the wording so 
that
+  it is clear that limited views of types never have discriminants and never
+  are of incomplete types.]}
address@hidden
+
+
address@hidden Clauses - With Clauses}
+
address@hidden
address@hidden @nt{context_clause} is used to specify
+the @nt<library_item>s whose
+names are needed within a compilation unit.]
address@hidden
+
address@hidden
address@hidden @nt{context_clause}s}
+The reader should be able to understand a @nt{context_clause} without
+looking ahead.
+Similarly, when compiling a @nt{context_clause},
+the compiler should not have to look ahead at
+subsequent @nt{context_item}s, nor at the compilation unit
+to which the @nt{context_clause} is attached.
+(We have not completely achieved this.)
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00217-06]}
address@hidden,address@hidden effect}A @i<ripple effect> occurs
+when the legality of a compilation unit could be affected by adding or removing
+an otherwise unneeded @nt{with_clause} on some compilation unit on which the
+unit depends, directly or indirectly. We try to avoid ripple effects because
+they make understanding and maintenance more difficult. However, ripple effects
+can occur because of direct visibility (as in child units); this seems
+impossible to eliminate. The ripple effect for @nt{with_clause}s is somewhat
+similar to the Beaujolais effect (see @RefSecNum{Use Clauses}) for
address@hidden, which we also try to avoid.]}
address@hidden
+
address@hidden
address@hidden<context_clause>,rhs="address@hidden"}
+
+
address@hidden<context_item>,rhs="@Syn2{with_clause} | @Syn2{use_clause}"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00217-06],ARef=[AI95-00262-01]}
address@hidden<with_clause>,rhs="@Chg{Version=[2],New=<@Syn2{limited_with_clause}
 | @Syn2{nonlimited_with_clause}>,Old=<@key{with} @address@hidden {, 
@address@hidden;>}"}
+
address@hidden,Kind=[Added]}
address@hidden,lhs=<@Chg{Version=[2],New=<limited_with_clause>,Old=<>}>,rhs="@Chg{Version=[2],New=<@key{limited}
 address@hidden @key{with} @address@hidden {, @address@hidden;>,Old=<>}"}
+
address@hidden,Kind=[Added]}
address@hidden,lhs=<@Chg{Version=[2],New=<nonlimited_with_clause>,Old=<>}>,rhs="@Chg{Version=[2],New=<address@hidden
 @key{with} @address@hidden {, @address@hidden;>,Old=<>}"}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00217-06]}
address@hidden,Text=[A @nt{limited_with_clause} makes a limited view
+of a unit visible.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00262-01]}
address@hidden,address@hidden with_clause}A @nt{with_clause}
+containing the reserved word @key{private} is called a @i{private with_clause}.
+It can be thought of as making items visible only in the private part, although
+it really
+makes items visible everywhere except the visible part. It can be used both for
+documentation purposes (to say that a unit is not used in the visible part),
+and to allow access to private units that otherwise would be
+prohibited.]}
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(of a @nt{with_clause})}
+The @i{scope} of a @nt{with_clause} that appears on a
address@hidden@address@hidden
+or @address@hidden@address@hidden
+consists of the entire declarative region of the address@hidden,
+which includes all children and subunits].
+The scope of a @nt{with_clause} that appears on a
+body consists of the address@hidden, which includes all subunits].
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00262-01]}
+Suppose a @Chg{Version=[2],New=[nonprivate ],Old=[]} @nt{with_clause} of a
+public library unit mentions one of its private siblings.
+(This is only allowed on the body of the public library unit.)
+We considered making the scope of that @nt{with_clause}
+not include the visible part of the public library unit.
+(This would only matter for a @nt{subprogram_body},
+since those are the only kinds of body that have a visible part,
+and only if the @nt{subprogram_body} completes a
address@hidden, since otherwise the @nt{with_clause}
+would be illegal.)
+We did not put in such a rule for two reasons:
+(1) It would complicate the wording of the rules,
+because we would have to split each @nt{with_clause}
+into pieces, in order to correctly handle @lquotes@;@key[with] P, Q;@rquotes@;
+where P is public and Q is private.
+(2) The conformance rules prevent any problems.
+It doesn't matter if a type name in the spec of the body denotes
+the completion of a @nt{private_type_declaration}.
+
+A @nt{with_clause} also affects visibility within subsequent
address@hidden and @nt{pragma}s of the same @nt{context_clause},
+even though those are not in the scope of the @nt{with_clause}.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00217-06]}
address@hidden,Sec=[in a @nt<with_clause>]}
address@hidden, Sec=(mentioned in)}
+A @nt<library_item> @Chg{Version=[2],New=[(and the corresponding library
+unit) ],Old=[]}is
address@hidden,address@hidden
address@hidden,Sec=[in a @nt<with_clause>]}
address@hidden, Sec=(named in)}],address@hidden ]}in a
address@hidden<with_clause> if it is denoted by
+a @i(library_unit_)@nt<name> @Chg{Version=[2],New=[],Old=[or a @nt<prefix> ]}
+in the @nt<with_clause>.
address@hidden,New=[A @nt{library_item} (and the corresponding library unit)
+is @i<mentioned> in a @nt{with_clause}
+if it is named in the @nt{with_clause} or if it is denoted by a @nt{prefix} in
+the @nt{with_clause}.],Old=[]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden control the visibility of
+declarations or renamings of library units.
+Mentioning a root library unit in a
address@hidden makes its declaration
+directly visible. Mentioning a nonroot library unit
+makes its declaration visible.
+See @Chg{Version=[3],New=[Clause],Old=[Section]} @RefSecNum{Visibility Rules}
+for details.
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+Note that this rule implies that @lquotes@;@key{with} A.B.C;@rquotes@; is
address@hidden,New=[almost ],Old=[]}equivalent to
address@hidden@;@key{with} A, A.B, 
A.B.C;@rquotes@;@Chg{Version=[2],New=[.],Old=[]}
+The reason for making a @nt{with_clause} apply to all the ancestor
+units is to avoid @lquotes@;visibility address@hidden@; @em situations in 
which an inner
+program unit is visible while an outer one is not.
+Visibility holes would cause semantic complexity and implementation
address@hidden,New=[ (This
+is not exactly equivalent because the latter @nt{with_clause} names
+A and A.B, while the previous one does not. Whether a unit is
address@hidden@;address@hidden does not have any effect on visibility, however,
+so it is equivalent for visibility purposes.)],Old=[]}
+
address@hidden
+
address@hidden its own declarative region,
+the declaration or renaming of
+a library unit can be visible only within the scope of a
address@hidden that mentions it.
+The visibility of the declaration or renaming of a
+library unit otherwise
+follows from its placement in the environment.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00262-01]}
+If a @nt{with_clause} of a given @nt<compilation_unit> mentions
+a private child of some library unit,
+then the given @nt{compilation_unit} shall be @Chg{Version=[2],New=[one of:],
+Old=[either the declaration of a private descendant of that library unit
+or the body or subunit of a @Redundant[(public or private)] descendant of
+that library unit.]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00262-01]}
address@hidden,Text=[the declaration, body, or subunit of a private
+descendant of that library unit;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00220-01],ARef=[AI95-00262-01]}
address@hidden,Text=[the body or subunit of a public descendant of that
+library unit, but not a subprogram body acting as a subprogram declaration (see
address@hidden Compilation Process}); or]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00262-01]}
address@hidden,Text=[the declaration of a public descendant of that
+library unit, in which case the @nt<with_clause> shall include the reserved 
word
address@hidden<private>.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00262-01]}
+The purpose of this rule is to prevent a private child from being
+visible @Chg{Version=[2],New=[],Old=[(or even semantically depended-on) ]}from
+outside the subsystem rooted at its parent. @Chg{Version=[2],New=[A private
+child can be semantically depended-on without violating this principle if it is
+used in a private @nt{with_clause}.],Old=[]}
address@hidden
address@hidden
+This rule violates the one-pass @nt{context_clause}s
address@hidden We rationalize this by saying that at least that
address@hidden works for legal compilation units.
+
address@hidden@keepnext@;Example:
address@hidden
address@hidden A @key[is]
address@hidden A;
+
address@hidden A.B @key[is]
address@hidden A.B;
+
address@hidden @key[package] A.B.C @key[is]
address@hidden A.B.C;
+
address@hidden A.B.C.D @key[is]
address@hidden A.B.C.D;
+
address@hidden A.B.C; -- @RI[(1)]
address@hidden @key[package] A.B.X @key[is]
address@hidden A.B.X;
+
address@hidden A.B.Y @key[is]
address@hidden A.B.Y;
+
address@hidden A.B.C; -- @RI[(2)]
address@hidden @key[body] A.B.Y @key[is]
address@hidden A.B.Y;
+
address@hidden,address@hidden,address@hidden @key[with] A.B.C; -- @RI[(3)]
address@hidden A.B.Z @key[is]
address@hidden A.B.Z;]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00262-01]}
+(1) is OK because it's a private child of A.B @em it would be illegal if
+we made A.B.X a public child of A.B.
+(2) is OK because it's the body of a child of A.B.
address@hidden,New=[(3) is OK because it's a child of A.B, and it is a
+private @nt{with_clause}.],Old=[]}
+It would be illegal to say @lquotes@;@key[with] A.B.C;@rquotes@; on any
address@hidden whose name does not start with @lquotes@;address@hidden@;.
+Note that mentioning A.B.C.D in a @nt{with_clause} automatically
+mentions A.B.C as well,
+so @lquotes@;@key[with] A.B.C.D;@rquotes@; is illegal in the same places as
address@hidden@;@key[with] A.B.C;@rquotes@;.
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[Deleted],ARef=[AI05-0005-1]}
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00262-01]}
+  @ChgDeleted{Version=[3],Text=[For the purposes of this rule,
+  if a @nt{subprogram_body} has no preceding @nt{subprogram_declaration},
+  the @nt{subprogram_body} should be considered a declaration and not a body.
+  Thus, it is illegal for such a @nt{subprogram_body} to mention one of
+  its siblings in a @Chg{Version=[2],New=[nonprivate ],address@hidden
+  if the sibling is a private library unit.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00262-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0077-1],ARef=[AI05-0122-1]}
address@hidden,Type=[Leading],Text=[A @nt<name> denoting a
address@hidden,address@hidden (or the corresponding declaration
+for a child of a generic within an instance @em see
address@hidden Units - Library Units}), if it],Old=[library item that]}
+is visible only due to being mentioned in
+one or more @nt<with_clause>s that include the reserved word
address@hidden<private>@Chg{Version=[3],New=[,],Old=[]} shall appear only 
within:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[a private part;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[a body, but not within the
address@hidden<subprogram_specification> of a library subprogram body;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[a private descendant of the unit on which one of these
address@hidden<with_clause>s appear; or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[a pragma within a context clause.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[These rules apply only if all of the
address@hidden that mention the name include the reserved word
address@hidden They do not apply if the name is mentioned in any
address@hidden that does not include @key{private}.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0077-1]}
address@hidden,Text=[These rules make the
address@hidden,address@hidden,Old=[library item]}
+visible anywhere that
+is not visible outside the subsystem rooted at the @nt{compilation_unit} having
+the private @nt{with_clause}, including private parts of packages
+nested in the visible part, private parts of child packages, the visible part
+of private children, and context clause pragmas like Elaborate_All.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[We considered having the scope of a private
address@hidden not include the visible part. However, that rule would mean
+that moving a declaration between the visible part and the private part could
+change its meaning from one legal interpretation to a different legal
+interpretation. For example:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden A @key{is}
+    @key{function} B @key{return} Integer;
address@hidden A;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden B @key{return} Integer;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden A;
address@hidden @key{with} B;
address@hidden C @key{is}
+    @key{use} A;
+    V1 : Integer := B; -- (1)
address@hidden
+    V2 : Integer := B; -- (2)
address@hidden C;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If we say that library subprogram B is not in scope
+in the visible part of C, then the B at (1) resolves to A.B, while (2)
+resolves to library unit B. Simply moving a declaration could silently change
+its meaning. With the legality rule defined above, the B at (1) is illegal.
+If the user really meant A.B, they still can say that.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00217-06]}
address@hidden,address@hidden @nt{library_item} mentioned in a
address@hidden shall be the implicit declaration of the limited view
+of a library package, not the declaration of a subprogram, generic unit,
+generic instance, or a renaming.]]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is redundant because only such implicit
+  declarations are visible in a @nt{limited_with_clause}. See
+  @RefSecNum{Environment-Level Visibility Rules}.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00217-06],ARef=[AI95-00412-01]}
address@hidden,Text=[A @nt{limited_with_clause} shall not appear on a
address@hidden, @nt{subunit}, or @address@hidden@address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00412-01]}
+  @ChgAdded{Version=[2],Text=[We don't allow a @nt{limited_with_clause} on a
+  @address@hidden@address@hidden because it would be useless and
+  therefore probably is a mistake. A
+  renaming cannot appear in a @nt{limited_with_clause} (by the rule prior
+  to this one), and a renaming of a limited view cannot appear in a
+  @nt{nonlimited_with_clause} (because the name
+  would not be within the scope of a @nt{with_clause} denoting the package, see
+  @RefSecNum{Package Renaming Declarations}). Nor could it be the parent of
+  another unit. That doesn't leave anywhere that the name of such a renaming
+  @b<could> appear, so we simply make writing it illegal.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00217-06]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[A
address@hidden that names a library package shall not appear:]}
+
address@hidden(Itemize)
address@hidden,Kind=[AddedNormal],ARef=[AI95-00217-06]}
address@hidden,Kind=[Revised],ARef=[AI05-0040-1]}
address@hidden,Text=[in the @nt{context_clause} for the
+explicit declaration of the named library address@hidden,New=[ or
+any of its descendants],Old=[]};]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[We have to explicitly disallow]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden @key{with} P;
address@hidden P @key{is} ...]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[as we can't depend on the semantic dependence
+  rules to do it for us as with regular withs. This says 
@lquotes@;address@hidden
+  and not @lquotes@;address@hidden in order that]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden @key{private} @key{with} P.Child;
address@hidden P @key{is} ...]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[can be used to allow a mutual dependence between
+  the private part of P and the private child P.Child, which occurs in
+  interfacing and other problems. Since the child always semantically depends
+  on the parent, this is the only way such a dependence can be broken.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0040-1]}
+  @ChgAdded{Version=[3],Text=[The part about descendants catches examples 
like]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden @key{with} P;
address@hidden P.Child @key{is} ...]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00217-06]}
address@hidden,Kind=[Revised],ARef=[AI05-0077-1],ARef=[AI05-0262-1]}
address@hidden,address@hidden,New=[within a], Old=[in the same]}
address@hidden
address@hidden,New=[for a @nt{library_item} that is],Old=[as, or]}
+within the scope address@hidden,New=[],Old=[,]}
+a @nt{nonlimited_with_clause} that mentions the same library package; or]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0077-1]}
+  @ChgAdded{Version=[3],Text=[This applies to @nt{nonlimited_with_clause}s
+  found in the same @nt{context_clause}, as well as 
@nt{nonlimited_with_clause}s
+  found on parent units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0077-1]}
+  @ChgAdded{Version=[2],Text=[Such a @nt{limited_with_clause} could have no
+  effect, and would be confusing. address@hidden,New=[],Old=[ it is
+  within the scope of]} a @address@hidden,New=[
+  for the same package is inherited from a parent unit or given],Old=[, or
+  if such a clause is]} in the @nt{context_clause},
+  the full view is available, which strictly provides more information than
+  the limited view.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00217-06]}
address@hidden,Kind=[Revised],ARef=[AI05-0077-1],ARef=[AI05-0262-1]}
address@hidden,address@hidden,New=[within a], Old=[in the same]}
address@hidden
address@hidden,New=[for a @nt{library_item} that is],Old=[as, or]}
+within the scope address@hidden,New=[],Old=[,]}
+a @nt{use_clause} that names an entity declared within the
+declarative region of the library package.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0077-1]}
+  @ChgAdded{Version=[3],Text=[This applies to @nt{use_clause}s found in the
+  same @nt{context_clause}, as well as @nt{use_clause}s found in (or on)
+  parent units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This prevents visibility issues, where whether an
+  entity is an incomplete or full view depends on how the name of the entity is
+  written. The @nt{limited_with_clause} cannot be useful, as we must have the
+  full view available in the parent in order for the @nt{use_clause} to be
+  legal.]}
address@hidden
+
address@hidden(Itemize)
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00217-06]}
+A @nt<library_item> mentioned in a @Chg{Version=[2],
address@hidden,address@hidden of a compilation unit
+is visible within the compilation unit and hence acts
+just like an ordinary declaration.
+Thus, within a compilation unit that mentions its declaration, the name of a
+library package can be given in @nt{use_clause}s and can be used to
+form expanded names, a library subprogram can be called,
+and instances of a generic library unit can be declared.
+If a child of a parent generic package is mentioned in a
address@hidden, address@hidden,address@hidden,
+then the corresponding declaration nested within each visible instance
+is visible within the compilation address@hidden, New=[ Similarly,
+a @nt{library_item} mentioned in a
address@hidden of a compilation unit is visible within the
+compilation unit and thus can be used to form expanded names.],Old=[]}
+
address@hidden
+The rules given for @nt{with_clause}s are such that the same effect
+is obtained whether the name of a library unit is mentioned once or
+more than once by the applicable @nt{with_clause}s, or even within a
+given @nt{with_clause}.
+
+If a @nt{with_clause} mentions a
address@hidden@address@hidden@!declaration},
+it only @lquotes@;address@hidden@; the @nt<prefix>es appearing explicitly
+in the @nt<with_clause>
+(and the renamed view itself);
+the @nt{with_clause} is not defined to mention the ancestors of the
+renamed entity.
+Thus, if X renames Y.Z, then @lquotes@;with X;@rquotes@; does not make the
+declarations of Y or Z visible.
+Note that this does not cause the dreaded visibility holes mentioned
+above.
address@hidden
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,address@hidden(package) Office @key(is)
address@hidden Office;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,address@hidden(with) Ada.Strings.Unbounded;
address@hidden(package) Office.Locations @key(is)
+   @key(type) Location @key(is new) Ada.Strings.Unbounded.Unbounded_String;
address@hidden(end) Office.Locations;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,address@hidden(limited with) Office.Departments;  address@hidden 
types are incomplete]
address@hidden(private with) Office.Locations;    address@hidden only visible 
in private part]
address@hidden(package) Office.Employees @key(is)
+   @key(type) Employee @key(is private);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key(function) Dept_Of(Emp : Employee) @key(return 
access) Departments.Department;
+   @key(procedure) Assign_Dept(Emp  : @key(in out) Employee;
+                         Dept : @key(access) Departments.Department);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ...
address@hidden(private
+   type) Employee @key(is
+      record)
+         Dept : @key(access) Departments.Department;
+         Loc : Locations.Location;
+         ...
+      @key(end record);
address@hidden(end) Office.Employees;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden(limited with) Office.Employees;
address@hidden(package) Office.Departments @key(is)
+   @key(type) Department @key(is private);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key(function) Manager_Of(Dept : Department) 
@key(return access) Employees.Employee;
+   @key(procedure) Assign_Manager(Dept : @key(in out) Department;
+                            Mgr  : @key(access) Employees.Employee);
+   ...
address@hidden(end) Office.Departments;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,Text=[The @nt{limited_with_clause} may be used to support
+mutually dependent abstractions that are split across multiple packages. In
+this case, an employee is assigned to a department, and a department has a
+manager who is an employee. If a @nt{with_clause} with the reserved word
address@hidden(private) appears on one library unit and mentions a second 
library unit,
+it provides visibility to the second library unit, but restricts that
+visibility to the private part and body of the first unit. The compiler checks
+that no use is made of the second unit in the visible part of the first unit.]}
+
address@hidden
+
+
+
address@hidden
address@hidden to Ada 83}
+The syntax rule for @nt{with_clause} is modified to allow expanded name
+notation.
+
+A @nt<use_clause> in a @nt<context_clause> may be for
+a package (or type) nested in a library package.
address@hidden
+
address@hidden
+The syntax rule for @nt{context_clause} is modified to more closely reflect
+the semantics.
+The Ada 83 syntax rule implies that the @nt{use_clause}s that appear
+immediately after a particular @nt{with_clause} are somehow attached to
+that @nt{with_clause}, which is not true.
+The new syntax allows a @nt{use_clause} to appear first,
+but that is prevented by a textual rule that already exists in Ada 83.
+
+The concept of @lquotes@;scope of a @address@hidden@; (which is a region of 
text)
+replaces RM83's notion of @lquotes@;apply address@hidden@;
+(a @nt{with_clause} applies to a @nt{library_item})
+The visibility rules are interested in a region of text,
+not in a set of compilation units.
+
+No need to define @lquotes@;apply address@hidden@; for @nt{use_clause}s.
+Their semantics are fully covered by the @lquotes@;scope (of a 
@nt{use_clause})@rquotes@;
+definition in @RefSecNum{Use Clauses}.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00220-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] A subprogram body acting as a declaration cannot
+  @key[with] a private child unit. This would allow public export of types
+  declared in private child packages, and thus cannot be allowed. This was
+  allowed by mistake in Ada 95; a subprogram that does this will now be
+  illegal.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00217-06]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @nt{limited_with_clause}s are new. They make a limited view of a package
+  visible, where all of the types in the package are incomplete. They 
facilitate
+  construction of mutually recursive types in multiple packages.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00262-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0077-1]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The syntax rules for @nt{with_clause} are modified to allow the reserved
+  word @key{private}. Private @nt{with_clause}s do not allow the use of their
+  @Chg{Version=[3],address@hidden,Old=[library item]}
+  in the visible part of their @nt{compilation_unit}. They also
+  allow using private units in more locations than in Ada 95.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0040-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Added missing rule that
+  a limited with clause cannot name an ancestor unit. This is incompatible
+  if an Ada 2005 program does this, but as this is a new Ada 2005 feature and
+  the unintentionally allowed capability is not useful, the
+  incompatibility is very unlikely to occur in practice.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0077-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Fixed wording so that
+  we are not checking whether something in a @nt{context_clause}
+  is @ldquote@;within the scope address@hidden something, as 
@nt{context_clause}s
+  are never included in anything's scope. The intended meaning is unchanged,
+  however.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0122-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Fixed wording so the
+  rules for private with clauses also apply to "sprouted" generic child
+  units.]}
address@hidden
+
+
address@hidden of Compilation Units}
+
address@hidden
address@hidden are like child units, with these (important) differences:
+subunits support the separate compilation of bodies
+only (not declarations);
+the parent contains a @nt{body_stub}
+to indicate the existence and place of each of its subunits;
+declarations appearing in the parent's body
+can be visible within the subunits.]
address@hidden
+
address@hidden
address@hidden<body_stub>,rhs="@Syn2{subprogram_body_stub} | 
@Syn2{package_body_stub} | @Syn2{task_body_stub} | @Syn2{protected_body_stub}"}
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00218-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0267-1]}
address@hidden<subprogram_body_stub>,rhs="@Chg{Version=[2],New=<
+   address@hidden
+   >,address@hidden @key{is} @address@hidden,New=<
+      address@hidden>,Old=[]};"}
+
address@hidden
+Although this syntax allows a @nt{parent_unit_name},
+that is disallowed by @RefSec{Compilation Units - Library Units}.
address@hidden
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0267-1]}
address@hidden<package_body_stub>,rhs="@Chg{Version=[3],New=<
+   >,address@hidden @key{body} @Syn2{defining_identifier} @key{is} 
@address@hidden,New=<
+      address@hidden>,Old=[]};"}
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0267-1]}
address@hidden<task_body_stub>,rhs="@Chg{Version=[3],New=<
+   >,address@hidden @key{body} @Syn2{defining_identifier} @key{is} 
@address@hidden,New=<
+      address@hidden>,Old=[]};"}
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0267-1]}
address@hidden<protected_body_stub>,rhs="@Chg{Version=[3],New=<
+   >,address@hidden @key{body} @Syn2{defining_identifier} @key{is} 
@address@hidden,New=<
+      address@hidden>,Old=[]};"}
+
+
address@hidden<subunit>,rhs="@key{separate} (@Syn2{parent_unit_name}) 
@Syn2{proper_body}"}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00243-01]}
address@hidden body], Sec=(of a subunit)}
+The @i{parent body} of a subunit is the body of the program unit
+denoted by its @nt{parent_unit_name}.
address@hidden The term @i{subunit} is used to refer to
+a @nt{subunit} and also to the @nt{proper_body} of a @nt{subunit}.
address@hidden,New=<The @i<subunits
+of a program unit> include any subunit that
+names that program unit as its parent, as well as any subunit that
+names such a subunit as its parent (recursively)address@hidden,
+Sec=(of a program unit)}>,Old=[]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00243-01]}
address@hidden,Text=[We want any rule that applies to a subunit to apply
+to a subunit of a subunit as well.]}
address@hidden
+
+The parent body of a subunit shall be present in the current environment,
+and shall contain a corresponding @nt{body_stub}
+with the same @nt{defining_identifier} as the subunit.
address@hidden
+This can't be a @ResolutionName, because a @nt{subunit} is not a
+complete context.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0004-1]}
+A @nt{package_body_stub} shall be the completion of a
address@hidden@!declaration} or @address@hidden@!declaration};
+a @address@hidden@!stub} shall be the completion of a
address@hidden,New=[task declaration],address@hidden@!declaration}]};
+a @address@hidden shall be the completion of a
address@hidden,New=[protected declaration],address@hidden@!declaration}]}.
+
+In contrast,
+a @nt{subprogram_body_stub} need not be the completion of a previous
+declaration,
address@hidden which case the @ntf{_stub} declares the subprogram].
+If the @ntf{_stub} is a completion, it shall be the completion of a
address@hidden or @nt{generic_subprogram_declaration}.
+The profile of a @nt{subprogram_body_stub} that completes a declaration
+shall conform fully to that of the declaration.
address@hidden conformance],Sec=(required)}
address@hidden
+The part about @nt{subprogram_body_stub}s echoes the corresponding rule
+for @ntf{subprogram_bodies} in @RefSec{Subprogram Bodies}.
address@hidden
+
+A subunit that corresponds to a @nt{body_stub} shall be of
+the same kind
+(@ntf{package_}, @ntf{subprogram_}, @ntf{task_}, or @ntf{protected_})
+as the @nt{body_stub}.
+The profile of a @nt{subprogram_body}
+subunit shall be fully conformant to
+that of the corresponding @nt{body_stub}.
address@hidden conformance],Sec=(required)}
+
+A @nt{body_stub} shall appear immediately within the
address@hidden of a compilation unit body.
+This rule does not apply within an instance of a generic unit.
address@hidden
address@hidden restriction}
+This is a methodological restriction;
+that is, it is not necessary for the semantics of the language to
+make sense.
address@hidden
+
+The @nt{defining_identifier}s of all @nt{body_stub}s that appear
+immediately within a particular @nt{declarative_part} shall be
+distinct.
address@hidden
+
address@hidden
+For each @nt{body_stub}, there shall be a subunit containing
+the corresponding @nt{proper_body}.
address@hidden
+
address@hidden
address@hidden@;The rules in @RefSec{The Compilation Process}
+say that a @nt{body_stub} is equivalent to the corresponding
address@hidden This implies:
address@hidden
+Visibility within a subunit is the
+visibility that would be obtained at the place of the corresponding
address@hidden (within the parent body) if the
address@hidden of the subunit were appended to
+that of the parent body.
address@hidden
+Recursively.
+Note that this transformation might make the parent illegal;
+hence it is not a true equivalence, but applies only to visibility
+within the subunit.
address@hidden
+
+The effect of the elaboration of a @nt{body_stub} is to elaborate
+the subunit.
address@hidden
+The elaboration of a subunit is part of its parent body's elaboration,
+whereas the elaboration of a child unit is not part of its parent
+declaration's elaboration.
address@hidden
address@hidden
address@hidden
+A @nt<library_item> that is mentioned in a @nt{with_clause} of a
+subunit can be hidden (from direct @Chg{Version=[2],New=[visibility],
+Old=[visiblity]}) by a declaration (with the same
address@hidden) given in the subunit.
+Moreover, such a @nt<library_item> can even be hidden by a declaration
+given within the parent body since a library unit is declared in its
+parent's declarative region; this however does not affect the
+interpretation of the @nt{with_clause}s themselves, since only
address@hidden<library_item>s
+are visible or directly visible
+in @nt{with_clause}s.
+
+The body of a protected operation cannot be a subunit.
+This follows from the syntax rules.
+The body of a protected unit can be a subunit.
address@hidden
address@hidden
+
address@hidden
address@hidden@keepnext@;The package Parent is first written without subunits:
address@hidden
address@hidden Parent @key[is]
+    @key[procedure] Inner;
address@hidden Parent;
+
address@hidden Ada.Text_IO;
address@hidden @key[body] Parent @key[is]
+    Variable : String := "Hello, there.";
+    @key[procedure] Inner @key[is]
+    @key[begin]
+        Ada.Text_IO.Put_Line(Variable);
+    @key[end] Inner;
address@hidden Parent;
address@hidden
+
address@hidden
address@hidden@;The body of procedure Inner may be turned into a subunit by 
rewriting
+the package body as follows (with the declaration of Parent remaining
+the same):
address@hidden
address@hidden
address@hidden @key[body] Parent @key[is]
+    Variable : String := "Hello, there.";
+    @key[procedure] Inner @key[is] @key[separate];
address@hidden Parent;
+
address@hidden Ada.Text_IO;
address@hidden(Parent)
address@hidden Inner @key[is]
address@hidden
+    Ada.Text_IO.Put_Line(Variable);
address@hidden Inner;
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Subunits of the same ancestor library unit are no longer restricted
+to have distinct identifiers.
+Instead, we require only that the full expanded names be distinct.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00218-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  An @nt{overriding_indicator} (see
+  @RefSecNum{Overriding Indicators}) is allowed on a subprogram stub.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00243-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that a subunit of a subunit is still a
+  subunit.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0267-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a
+  @nt{body_stub}. This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
address@hidden Compilation Process}
+
address@hidden
address@hidden
address@hidden @nt<declarative_part>}
+Each compilation unit submitted to the compiler is compiled in the
+context of an @i{environment} @nt<declarative_part> (or simply, an
address@hidden),
+which is a conceptual @nt<declarative_part> that forms
+the outermost declarative region of the
+context of any @nt{compilation}.
+At run time, an environment forms the @nt<declarative_part> of
+the body of the environment task of a partition
+(see @RefSec{Program Execution}).
address@hidden
+At compile time, there is no particular construct that the
+declarative region is considered to be nested within
address@hidden the environment is the universe.
address@hidden
address@hidden
+The environment is really just a portion of a @nt{declarative_part},
+since there might, for example, be bodies that do not yet exist.
address@hidden
+
+The @nt{declarative_item}s of the environment
+are @nt{library_item}s appearing in an order
+such that there are no forward semantic dependences.
+Each included subunit
+occurs in place of the corresponding stub.
+The visibility rules apply as if the environment were the outermost
+declarative region,
+except that @address@hidden are needed to make
+declarations of library units visible
+(see @RefSecNum{Context Clauses - With Clauses}).
+
address@hidden,Kind=[Revised],ARef=[AI95-00217-06]}
+The mechanisms for creating an environment
+and for adding and replacing compilation units within an environment
+are implementation address@hidden,New=[ The mechanisms for adding a
+compilation unit mentioned in a @nt{limited_with_clause} to an
+environment are implementation defined.],Old=[]}
address@hidden mechanisms for creating an environment
+and for adding and replacing compilation units.}
address@hidden,Kind=[Added],address@hidden,New=[The
+mechanisms for adding a compilation unit mentioned in a 
@nt{limited_with_clause}
+to an environment.],Old=[]}]}
address@hidden
+The traditional model, used by most Ada 83 implementations,
+is that one places a compilation unit in the environment
+by compiling it.
+Other models are possible.
+For example, an implementation might define the environment to
+be a directory;
+that is, the compilation units in the environment are all the
+compilation units in the source files contained in the directory.
+In this model, the mechanism for replacing a compilation unit with a
+new one is simply to edit the source file containing that compilation
+unit.
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0032],ARef=[AI95-00192-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
+If a @nt<library_unit_body> that is a @nt<subprogram_body> is
+submitted to the compiler, it is interpreted only as a completion
+if a @nt<library_unit_declaration> @Chg{New=[], Old=[for a subprogram
+or a generic subprogram ]}with the same @nt<defining_program_unit_name>
+already exists in the environment @Chg{New=[for a subprogram other than
+an instance of a generic subprogram or for a generic subprogram ], Old=[]}
+(even if the profile of the body is not type conformant with that of the
+declaration); address@hidden,New=[,],Old=[]} the
address@hidden<subprogram_body> is
+interpreted as both the declaration and body of a library subprogram.
address@hidden conformance}
address@hidden
+  The principle here is that a @nt{subprogram_body} should be
+  interpreted as only a completion if and only if it @lquotes@;address@hidden@;
+  be legal as the completion of some preexisting declaration,
+  where @lquotes@;address@hidden@; is defined in a way that does not require 
overload
+  resolution to determine.
+
+  Hence, if the preexisting declaration is a @nt{subprogram_declaration}
+  or @nt{generic_subprogram_declaration}, we treat the new
+  @nt{subprogram_body} as its completion, because it 
@lquotes@;address@hidden@; be legal.
+  If it turns out that the profiles don't fully conform,
+  it's an error.
+  In all other cases (the preexisting declaration is a
+  package or a generic package,
+  or an instance of a generic subprogram,
+  or a renaming,
+  or a @lquotes@;address@hidden@; subprogram,
+  or in the case where there is no preexisting thing),
+  the @nt{subprogram_body} declares a new subprogram.
+
+  See also AI83-00266/09.
address@hidden
address@hidden
+
address@hidden
+When a compilation unit is compiled,
+all compilation units upon which it depends semantically
+shall already exist in the environment;
address@hidden, Sec=(among compilation units)}
+the set of these compilation units shall be @i{consistent} in the
+sense that the new compilation unit shall not semantically depend
+(directly or indirectly) on two different versions of the same compilation
+unit, nor on an earlier version of itself.
address@hidden
+For example, if package declarations A and B both say
address@hidden@;@key[with] X;@rquotes@;, and the user compiles a compilation 
unit that says
address@hidden@;@key[with] A, B;@rquotes@;, then the A and B have to be talking 
about the
+same version of X.
address@hidden
address@hidden
+  What it means to be a @lquotes@;different address@hidden@; is not specified 
by the
+  language. In some implementations, it means that the compilation
+  unit has been recompiled. In others, it means that the
+  source of the compilation unit has been edited in some significant way.
+
+Note that an implementation cannot require the existence of
+compilation units upon which the given one does not semantically
+depend.
+For example, an implementation is required to be able to compile a
+compilation unit that says "@key{with} A;" when A's body does not
+exist.
+It has to be able to detect errors without looking at A's body.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+Similarly, the implementation has to be able to compile a call to a
+subprogram for which @Chg{Version=[3],New=[aspect],Old=[a @nt{pragma}]}
+Inline has been specified without
+seeing the body of that subprogram @em inlining would not be
+achieved in this case, but the call is still legal.
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00217-06]}
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,Text=[The @Chg{Version=[2],New=[consistency],
+Old=[second]} rule applies to limited views as well
+as the full view of a compilation unit. That means that an implementation needs
+a way to enforce consistency of limited views, not just of full views.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00217-06]}
+The implementation may require that a compilation unit be legal before
address@hidden,New=[it can be mentioned in a @nt{limited_with_clause} or
+it can be inserted],Old=[inserting it]} into the environment.
+
address@hidden,Kind=[Revised],ARef=[AI95-00214-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+When a compilation unit that declares or renames a library unit
+is added to the environment,
+the implementation may remove from the environment
+any preexisting @nt<library_item>
address@hidden,New=[or @nt<subunit> with the same full expanded name],
+Old=[with the same @nt<address@hidden@!unit_name>]}.
+When a compilation unit that is a subunit or the body
+of a library unit is added to the environment,
+the implementation may remove from the environment
+any preexisting version of the same compilation unit.
address@hidden,New=[When a compilation unit that
+contains a @nt<body_stub> is added to the environment, the implementation may
+remove any preexisting @nt<library_item> or @nt<subunit> with the same full
+expanded name as the @nt<body_stub>.],Old=[]}
+When a given compilation unit is removed from the environment,
+the implementation may also remove any compilation unit that depends
+semantically upon the given one.
+If the given compilation unit contains the body of a subprogram 
@Chg{Version=[3],New=[for],Old=[to]}
+which @Chg{Version=[3],New=[aspect],Old=[a @nt{pragma}]} Inline 
@Chg{Version=[3],New=[is True],Old=[applies]},
+the implementation may also remove any compilation unit containing a
+call to that subprogram.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+The permissions given in this paragraph correspond to the traditional
+model, where compilation units enter the environment by being
+compiled into it, and the compiler checks their legality at that time.
address@hidden,New=[An],Old=[A]} implementation model in which the
+environment consists of all source files in a given directory might not
+want to take advantage of these permissions.
+Compilation units would not be checked for
+legality as soon as they enter the environment; legality checking
+would happen later, when compilation units are compiled.
+In this model, compilation units might never be automatically removed
+from the environment;
+they would be removed when the user explicitly deletes a source file.
+
+Note that the rule is recursive: if the above permission is used to
+remove a compilation unit containing an inlined subprogram call,
+then compilation units that depend semantically upon the removed one
+may also be removed, and so on.
+
+Note that here we are talking about dependences among existing
+compilation units in the environment;
+it doesn't matter what @nt{with_clause}s are attached to the new
+compilation unit that triggered all this.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+An implementation may have other modes in which compilation units
+in addition to the ones mentioned above are removed.
+For example, an implementation might inline subprogram calls without
+an explicit @Chg{Version=[3],New=[aspect],address@hidden Inline.
+If so, it either has to have a mode in which that optimization is
+turned off, or it has to automatically regenerate code for the inlined
+calls without requiring the user to resubmit them to the compiler.
address@hidden
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0108],ARef=[AI95-00077-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00114-01]}
address@hidden,Text=[In the standard mode, implementations may only remove
+units from the environment for one of the reasons listed here, or in response
+to an explicit user command to modify the environment. It is not intended that
+the act of compiling a unit is one of the
address@hidden@;@Chg{Version=[2],New=[mechanisms],address@hidden for
+removing units other than those specified by this International Standard.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00214-01]}
address@hidden,Text=[These rules are intended to ensure that an
+implementation never need keep more than one compilation unit with any full
+expanded name. In particular, it is not necessary to be able to have a subunit
+and a child unit with the same name in the environment at one time.]}
+
address@hidden
address@hidden
+
address@hidden
+The rules of the language are enforced across
address@hidden and compilation unit boundaries,
+just as they are enforced within a single compilation unit.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Note that @Chg{Version=[3],New=[Clause],Old=[Section]} @RefSecNum{General}
+requires an implementation to detect illegal compilation units at compile time.
address@hidden
+
address@hidden
+An implementation may support a concept of a @i{library},
+which contains @nt{library_item}s.
+If multiple libraries are supported,
+the implementation has to define how a single environment is
+constructed when a compilation unit is submitted to the compiler.
+Naming conflicts between different libraries might be resolved by
+treating each library as the root of a hierarchy of child library
+units.
address@hidden library],See=(library)}
address@hidden
+Alternatively, naming conflicts could be resolved via some sort of
+hiding rule.
address@hidden
address@hidden
+For example, the implementation might support a command to import
+library Y into library X.
+If a root library unit called LU (that is, Standard.LU) exists in Y,
+then from the point of view of library X,
+it could be called Y.LU.
+X might contain library units that say, @lquotes@;@key[with] Y.LU;@rquotes@;.
address@hidden
+
+A compilation unit containing an instantiation of a separately
+compiled generic unit does not semantically depend on the body
+of the generic unit.
+Therefore, replacing the generic body in the environment
+does not result in the removal of the compilation unit
+containing the instantiation.
address@hidden
+  Therefore, implementations have to be prepared to automatically
+  instantiate generic bodies at link-time, as needed. This might
+  imply a complete automatic recompilation, but it is the intent
+  of the language that generic bodies can be (re)instantiated without
+  forcing all of the compilation units that semantically depend
+  on the compilation unit containing the instantiation to be
+  recompiled.
address@hidden
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00077-01],ARef=[AI95-00114-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 83}
+  Ada 83 allowed implementations to require that the body of a generic unit
+  be available when the instantiation is compiled; that permission is dropped
+  in Ada 95. This isn't really an extension (it doesn't allow Ada users to
+  write anything that they couldn't in Ada 83), but there isn't a more
+  appropriate category, and it does allow users more flexibility when
+  developing programs.]}
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0032],ARef=[AI95-00192-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> The wording was clarified 
to
+  ensure that a @nt{subprogram_body} is not considered a completion of
+  an instance of a generic subprogram.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00214-01]}
+  @ChgAdded{Version=[2],Text=[The permissions to remove a unit from the
+  environment were clarified to ensure that it is never necessary to keep
+  multiple (sub)units with the same full expanded name in the environment.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00217-06]}
+  @ChgAdded{Version=[2],Text=[Units mentioned in a @nt{limited_with_clause}
+  were added to several rules; limited views have the same presence in the
+  environment as the corresponding full views.]}
address@hidden
+
address@hidden and Program Units}
+
address@hidden
address@hidden subclause discusses pragmas related to program units,
+library units, and @nt{compilation}s.]
address@hidden
+
address@hidden
address@hidden unit pragma}
address@hidden, program unit}
+Certain @nt{pragma}s are defined to be @i{program unit pragmas}.
address@hidden, Sec=(to a program unit by a program unit pragma)}
+A @nt{name} given as the argument of a program unit pragma shall resolve to
+denote the declarations or renamings of one or more program
+units that occur immediately within the declarative region or @nt<compilation>
+in which the @nt<pragma> immediately occurs, or it shall resolve to denote
+the declaration of the immediately enclosing program unit (if any);
+the @nt{pragma} applies to the denoted program
+unit(s).
+If there are no @nt{name}s given as arguments,
+the @nt{pragma} applies to the immediately
+enclosing program unit.
address@hidden
+The fact that this is a @ResolutionName means that the @nt{pragma}
+will not apply to declarations from outer declarative regions.
address@hidden
+
address@hidden
+
address@hidden
address@hidden@keepnext@;A program unit pragma shall appear in one of these 
places:
address@hidden
+At the place of a @nt{compilation_unit},
+in which case the @nt<pragma>
+shall immediately follow in the same @nt<compilation> (except for
+other @nt{pragma}s)
+a @address@hidden@!declaration} that is a @nt<address@hidden>,
address@hidden<address@hidden@!declaration>, or @nt<address@hidden>, and
+the @nt<pragma> shall have an argument that is a @nt<name> denoting
+that declaration.
address@hidden
+The @nt{name} has to denote the immediately preceding
address@hidden
address@hidden
+
address@hidden, Kind=[Revised], Ref=[8652/0033], ARef=[AI95-00136-01]}
+Immediately within the @Chg{New=[visible part],Old=[declaration]} of a
+program unit and before any nested address@hidden (but not within a
+generic formal part)], Old=[]}, in which case the argument,
+if any, shall be a @nt{direct_name}
+that denotes the immediately enclosing program unit declaration.
address@hidden
+The argument is optional in this case.
address@hidden
+
+At the place of a declaration
+other than the first,
+of a @nt{declarative_part} or program unit declaration,
+in which case the @nt{pragma} shall have an argument,
+which shall be a @nt{direct_name}
+that denotes one or more of the following (and nothing else):
+a @address@hidden, a @address@hidden@!declaration},
+or a @address@hidden, of the same @nt<address@hidden> or
+program unit declaration.
address@hidden
+If you want to denote a @nt<subprogram_body> that is not a
+completion, or a
address@hidden, for example, you have to put the @nt{pragma}
+inside.
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0132-1]}
address@hidden unit pragma}
address@hidden, library unit}
address@hidden unit pragma], Sec=(library unit pragmas)}
address@hidden, program unit], Sec=(library unit pragmas)}
+Certain program unit pragmas are defined to be
address@hidden unit pragmas}.
address@hidden,New=[If a library unit pragma applies to a program unit,
+the program unit shall be],Old=[The @nt{name}, if
+any, in a library unit pragma shall denote the declaration of]} a library unit.
address@hidden
+This, together with the rules for program unit pragmas above,
+implies that if a library unit pragma applies to a @nt{subprogram_declaration}
+(and similar things), it has to appear immediately after the
address@hidden, whereas if the @nt{pragma} applies to a
address@hidden, a @nt{subprogram_body} that is not a
+completion (and similar things), it has to appear inside, as the first
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden, Kind=[Added], Ref=[8652/0034], ARef=[AI95-00041-01]}
address@hidden,Text=[A library unit pragma that applies to a generic
+unit does not apply to its instances, unless a specific rule for the pragma
+specifies the contrary.]}
address@hidden
+
address@hidden
address@hidden pragma}
address@hidden, configuration}
+Certain @nt{pragma}s are defined to be @i{configuration pragmas};
+they shall appear before the first @nt{compilation_unit}
+of a @nt{compilation}.
address@hidden are generally used to select a partition-wide
+or system-wide option.]
+The @nt<pragma> applies to all @nt{compilation_unit}s
+appearing in the @nt{compilation},
+unless there are none, in which case it applies to all future
address@hidden compiled into the same environment.
address@hidden
+
address@hidden
address@hidden, Kind=[Revised], ARef=[AI95-00212-01]}
+An implementation may @Chg{Version=[2], New=[require that configuration
+pragmas that select partition-wide or system-wide options be compiled],
+Old=[place restrictions on
+configuration pragmas, so long as it allows them]} when the environment
+contains no @nt{library_item}s other than those of the predefined environment.
address@hidden, New=[In this case, the implementation shall still accept
+configuration pragmas in individual compilations that confirm the initially
+selected partition-wide or system-wide options.],Old=[]}
+
address@hidden
+
address@hidden
address@hidden, Kind=[AddedNormal], Ref=[8652/0034], ARef=[AI95-00041-01]}
address@hidden,Text=[When applied to a generic unit, a program unit pragma that
+is not a library unit pragma should apply to each instance of the generic unit
+for which there is not an overriding pragma applied directly to the instance.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[When applied to a generic unit, a program unit pragma that
+is not a library unit pragma should apply to each instance of the generic unit
+for which there is not an overriding pragma applied directly to the 
instance.]}]}
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[2], Kind=[AddedNormal], Ref=[8652/0033], 
ARef=[AI95-00136-01]}
+  @ChgAdded{Version=[2], address@hidden<Corrigendum:> The wording was 
corrected to
+  ensure that a program unit pragma cannot appear in private parts or
+  generic formal parts.]}
+
+  @ChgRef{Version=[2], Kind=[AddedNormal], Ref=[8652/0034],
+  ARef=[AI95-00041-01]} @ChgAdded{Version=[2], address@hidden<Corrigendum:> The
+  wording was clarified to explain the meaning of program unit and library unit
+  pragmas in generic units.]}
+
+  @ChgRef{Version=[2], Kind=[AddedNormal]}
+  @ChgAdded{Version=[2], Text=[The Implementation Advice added by the
+  Corrigendum was moved, as it was not in the normal order. (This changes the
+  paragraph number.) It originally was directly after the new Static Semantics
+  rule.]}
+
+  @ChgRef{Version=[2], Kind=[AddedNormal], ARef=[AI95-00212-01]}
+  @ChgAdded{Version=[2], Type=[Leading],Keepnext=[T],Text=[The permission to
+  place restrictions was clarified to:]}
+  @begin{itemize}
+  @ChgRef{Version=[2], Kind=[AddedNormal]}
+  @ChgAdded{Version=[2], Text=[Ensure that it applies only to partition-wide
+  configuration pragmas, not ones like Assertion_Policy (see
+  @RefSecNum{Pragmas Assert and Assertion_Policy}), which can be different
+  in different units; and]}
+
+  @ChgRef{Version=[2], Kind=[AddedNormal]}
+  @ChgAdded{Version=[2], Text=[Ensure that confirming pragmas are always 
allowed.]}
+  @end{itemize}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0132-1]}
+  @ChgAdded{Version=[3], address@hidden<Correction:> A library unit pragma must
+  apply directly to a library unit, even if no name is given in the pragma.]}
address@hidden
+
+
address@hidden Visibility Rules}
+
address@hidden
address@hidden normal visibility rules do not apply within a
address@hidden or a @nt{context_clause},
+nor within a @nt{pragma} that appears at the place of a compilation unit.
+The special visibility rules for those contexts
+are given here.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00217-06],ARef=[AI95-00312-01]}
address@hidden visible], Sec=(within the
address@hidden of a library unit)}
address@hidden, Sec=(within the
address@hidden of a library unit)}
address@hidden visible], Sec=(within a @nt{with_clause})}
address@hidden, Sec=(within a @nt{with_clause})}
+Within the @nt{parent_unit_name} at the beginning of
address@hidden,New=[an explicit],Old=[a]} @nt{library_item},
+and within a @Chg{Version=[2],address@hidden,
address@hidden, the only declarations
+that are visible are those that address@hidden,New=[ explicit],Old=[]}
address@hidden<library_item>s of the environment,
+and the only declarations that are directly visible are those that
address@hidden,New=[ explicit],Old=[]} root @nt<library_item>s
+of the environment.
address@hidden,New=[Within a @nt{limited_with_clause}, the only declarations
+that are visible are those that are the implicit declaration of the
+limited view of a library package of the environment, and the only
+declarations that are directly visible are those that are the
+implicit declaration of the limited view of a root library package.],
address@hidden
+Notwithstanding the rules of @RefSecNum(Selected Components),
+an expanded name in a @nt{with_clause} may consist of a
address@hidden<prefix> that denotes a generic package and a @nt<selector_name> 
that
+denotes a child of that generic package.
address@hidden(The child is necessarily a generic unit;
+see @RefSecNum{Compilation Units - Library Units}.)]]}
+
address@hidden
+In @lquotes@;@key{package} P.Q.R @key{is} ... @key{end} P.Q.R;@rquotes@;,
+this rule requires P to be a root library unit,
+and Q to be a library unit
+(because those are the things that are directly visible and visible).
+Note that visibility does not apply between the @lquotes@;@address@hidden@;
+and the @lquotes@;;@rquotes@;.
+
+Physically nested declarations are not visible at these places.
+
address@hidden the classification of this note from Reason to Ramification,
+as it certainly isn't a "reason". Besides, there were two reasons, which was
+goofy.}
+Although Standard is visible at these places,
+it is impossible to name it,
+since it is not directly visible,
+and it has no parent.
+
address@hidden,Kind=[Added],ARef=[AI95-00217-06]}
address@hidden,Text=[Only compilation units defining limited views
+can be mentioned in a @nt{limited_with_clause}, while only compilation
+units defining full views (that is, the explicit declarations) can be mentioned
+in a @nt{nonlimited_with_clause}. This resolves the conflict inherent in having
+two compilation units with the same defining name.]}
address@hidden
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00312-01]}
address@hidden,Text=[The @lquotes@;address@hidden@; part
+allows @lquotes@;@key[with] A.B;@rquotes@;
+where A is a generic library package and B is one of its
+(generic) children.
+This is necessary because it is not normally legal to use an expanded
+name to reach inside a generic package.]}
address@hidden
+
address@hidden visible], Sec=(within a @nt{use_clause} in a 
@nt{context_clause})}
address@hidden, Sec=(within a @nt{use_clause} in a @nt{context_clause})}
address@hidden visible], Sec=(within a @nt{pragma} in a @nt{context_clause})}
address@hidden, Sec=(within a @nt{pragma} in a @nt{context_clause})}
+Within a @nt{use_clause} or @nt{pragma}
+that is within a @nt{context_clause},
+each @nt<library_item> mentioned in a previous
address@hidden of the same @nt{context_clause} is visible,
+and each root @nt<library_item> so mentioned is directly visible.
+In addition,
+within such a @nt{use_clause},
+if a given declaration is visible or directly
+visible,
+each declaration that occurs immediately within the given declaration's
+visible part is also visible.
+No other declarations are visible or directly visible.
address@hidden
+Note the word @lquotes@;address@hidden@;.
+For example, if a @nt{with_clause} on a declaration mentions X,
+this does not make X visible in @nt{use_clause}s and @nt{pragma}s
+that are on the body.
+The reason for this rule is
+the one-pass @nt{context_clause}s @MetaRulesName.
+
+Note that the second part of the rule does not
+mention @nt{pragma}s.
address@hidden
+
address@hidden visible], Sec=(within the
address@hidden of a subunit)}
address@hidden, Sec=(within the
address@hidden of a subunit)}
+Within the @nt{parent_unit_name} of a subunit, @nt<library_item>s
+are visible as they are in
+the @nt{parent_unit_name} of a @nt{library_item};
+in addition, the declaration corresponding to each
address@hidden in the environment
+is also visible.
address@hidden
+For a subprogram without a separate @nt<subprogram_declaration>,
+the @nt<body_stub> itself is the declaration.
address@hidden
+
address@hidden visible], Sec=(within a @nt{pragma}
+that appears at the place of a compilation unit)}
address@hidden, Sec=(within a @nt{pragma}
+that appears at the place of a compilation unit)}
+Within a @nt{pragma} that appears at the place of a compilation unit,
+the immediately preceding @nt<library_item> and each of its
+ancestors is visible.
+The ancestor root @nt<library_item> is directly visible.
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00312-01]}
address@hidden,address@hidden
+Notwithstanding the rules of @RefSecNum(Selected Components),
+an expanded name in a @nt{with_clause}, a @nt{pragma} in a @nt{context_clause},
+or a @nt{pragma} that appears at the place of a compilation unit
+may consist of a @nt{prefix} that denotes a generic package and
+a @nt<selector_name> that denotes a child of that generic package.
address@hidden(The child is necessarily a generic unit;
+see @RefSecNum{Compilation Units - Library Units}.)]]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This rule allows @key[with] A.B; and
address@hidden Elaborate(A.B); where A is a
+generic library package and B is one of its (generic) children. This is
+necessary because it is not normally legal to use an expanded
+name to reach inside a generic package.]}
address@hidden
+
address@hidden
+
address@hidden
+The special visibility rules that apply within a
address@hidden or a @nt{context_clause},
+and within a @nt{pragma} that appears at the place of a
address@hidden are clarified.
+
+Note that a @nt{context_clause} is not part of any declarative region.
+
+We considered making the visibility rules within
address@hidden and @nt{context_clause}s follow from the
+context of compilation.
+However, this attempt failed for various reasons.
+For example, it would require @nt{use_clause}s in
address@hidden to be within the declarative region of Standard,
+which sounds suspiciously like a kludge.
+And we would still need a special rule to prevent seeing things
+(in our own @nt{context_clause})
+that were with-ed by our parent, etc.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00217-06]}
+  @ChgAdded{Version=[2],Text=[Added separate visibility rules for
+  @nt{limited_with_clause}s; the existing rules apply only to
+  @nt{nonlimited_with_clause}s.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00312-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that the name of a generic child unit
+  may appear in a @nt{pragma} in a @nt{context_clause}.]}
address@hidden
+
+
address@hidden Execution}
+
address@hidden
address@hidden
address@hidden execution}
address@hidden a program],See=(program execution)}
+An Ada @i{program} consists
+of a set of @address@hidden,
+which can execute in parallel with one another,
+possibly in a separate address space,
+and possibly on a separate computer.]
address@hidden
+
address@hidden
+
address@hidden
address@hidden building}
+A partition is a program or part of a program
+that can be invoked from outside
+the Ada implementation.
address@hidden example, on many systems,
+a partition might be an executable file
+generated by the system linker.]
address@hidden assign}
+The user can @i{explicitly assign} library units to a partition.
+The assignment is done in an implementation-defined manner.
+The compilation units included in a partition are
+those of the explicitly assigned library units,
+as well as other compilation units @i{needed by} those library units.
+The compilation units needed by a given compilation unit are determined
+as follows
+(unless specified otherwise via an implementation-defined @nt{pragma},
+or by some other implementation-defined means):
address@hidden,See=(partition building)}
address@hidden units needed], Sec=(by a compilation unit)}
address@hidden, Sec=(of a compilation unit by another)}
address@hidden
+From a run-time point of view,
+an Ada 95 partition is identical to an Ada 83 program
address@hidden implementations were always allowed to provide inter-program
+communication mechanisms.
+The additional semantics of partitions is that interfaces between
+them can be defined to obey normal language rules
+(as is done in @RefSec{Distributed Systems}),
+whereas interfaces between separate programs had no particular
+semantics.
address@hidden
address@hidden manner of explicitly assigning library units to a partition.}
address@hidden implementation-defined means, if any, of specifying which
+compilation units are needed by a given compilation unit.}
address@hidden
+There are no pragmas that @lquotes@;specify address@hidden@; defined by the
+core language. However, an implementation is allowed to provide such
+pragmas, and in fact @RefSec{Distributed Systems} defines some
+pragmas whose semantics includes reducing the set of
+compilation units described here.
address@hidden
address@hidden
+A compilation unit needs itself;
+
+If a compilation unit is needed, then so are any compilation units
+upon which it depends semantically;
+
+If a @nt{library_unit_declaration} is needed,
+then so is any corresponding
address@hidden;
+
address@hidden,Kind=[Revised],ARef=[AI95-00217-06]}
+If a compilation unit with stubs is needed,
+then so are any corresponding address@hidden,New=[;],Old=[.]}
+
address@hidden
+Note that in the environment, the stubs are replaced with the
+corresponding @ntf{proper_bodies}.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00217-06]}
address@hidden,Text=[If the (implicit) declaration of the limited view
+of a library package is needed, then so is the explicit declaration of the
+library package.]}
+
address@hidden
address@hidden
+  Note that a child unit is not included
+  just because its parent is included @em to include a child,
+  mention it in a @nt{with_clause}.
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00217-06]}
+  @ChgAdded{Version=[2],Text=[A package is included in a partition even if the
+  only reference to it is in a @nt{limited_with_clause}. While this isn't
+  strictly necessary (no objects of types imported from such a unit can be
+  created), it ensures that all incomplete types are eventually completed, and
+  is the least surprising option.]}
address@hidden
+
address@hidden subprogram], Sec=(for a partition)}
+The user can optionally designate
+(in an implementation-defined manner)
+one subprogram as the @i{main subprogram} for the partition.
+A main subprogram, if specified, shall be a subprogram.
address@hidden
+This may seem superfluous,
+since it follows from the definition.
+But we would like to have every error message that might be generated
+(before run time) by an implementation correspond to some
+explicitly stated @lquotes@;address@hidden@; rule.
+
+Of course, this does not mean that the @lquotes@;address@hidden@; rules 
correspond
+one-to-one with an implementation's error messages. For example,
+the rule that says overload resolution @lquotes@;address@hidden@; succeed in 
producing a
+single interpretation would correspond to many error messages in a good
+implementation @em the implementation would want to explain to the user
+exactly why overload resolution failed.
+This is especially true for the syntax rules @em they are considered
+part of overload resolution, but in most cases, one would expect an
+error message based on the particular syntax rule that was violated.
address@hidden
address@hidden manner of designating the main subprogram of a partition.}
address@hidden
+An implementation cannot require the user to specify, say, all of the
+library units to be included.
+It has to support, for example, perhaps the most typical case,
+where the user specifies just one library unit,
+the main program.
+The implementation has to do the work of tracking down all the other ones.
address@hidden
+
address@hidden task}
+Each partition has an anonymous @i{environment address@hidden,
+which is an implicit outermost task whose execution
+elaborates the @nt{library_item}s of the environment
address@hidden, and then calls the main subprogram,
+if there is one.
+A partition's execution is that of its tasks.]
address@hidden
+An environment task has no master;
+all nonenvironment tasks have masters.
+
+An implementation is allowed to support
+multiple concurrent executions of the same partition.
address@hidden
+
address@hidden order of elaboration of library units is determined
+primarily by the @i{elaboration dependences}.]
address@hidden dependence], Sec=(library_item on another)}
address@hidden, Sec=(elaboration)}
+There is an elaboration dependence of a given @nt{library_item} upon
+another if the given @nt{library_item} or any of its subunits depends
+semantically on the other @nt{library_item}.
+In addition, if a given @nt{library_item} or any of its subunits
+has a @nt{pragma} Elaborate or Elaborate_All that
address@hidden,New=[names],Old=[mentions]} another library unit,
+then there is an elaboration dependence of the given
address@hidden upon the body of the other library unit,
+and, for Elaborate_All only, upon
+each @nt{library_item} needed by
+the declaration of the other library unit.
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0107],ARef=[AI95-00180-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00256-01]}
address@hidden,address@hidden@;address@hidden
address@hidden,New=[was],Old=[is]}
+used informally in the above rule; it @Chg{Version=[2],New=[was],Old=[is]}
+not intended to refer to the definition of @i{mentions} in
address@hidden Clauses - With Clauses}.
address@hidden,New=[It was changed to @Lquotes@;address@hidden to make this 
clear.],
+Old=[It would have been better to use
address@hidden@;address@hidden instead of @Lquotes@;address@hidden above.]}]}
+
+See above for a definition of which @nt{library_item}s are @lquotes@;needed 
address@hidden@;
+a given declaration.
+
+Note that elaboration dependences are among @nt{library_item}s,
+whereas the other two forms of dependence are among compilation units.
+Note that elaboration dependence includes semantic dependence.
+It's a little bit sad that pragma Elaborate_Body can't be folded into
+this mechanism.
+It follows from the definition that the elaboration dependence
+relationship is transitive.
+Note that the wording of the rule does not need to take into account
+a semantic dependence of a @nt{library_item} or one of its subunits
+upon a subunit of a different library unit,
+because that can never happen.
address@hidden
+
address@hidden@keepnext@;The environment task for a partition has the following
+structure:
address@hidden
address@hidden @RI{Environment_Task};
+
address@hidden @key[body] @RI{Environment_Task} @key[is]
+    ... (1) address@hidden The environment address@hidden
+            address@hidden (that is, the sequence of address@hidden@RI{s) goes 
here.}
address@hidden
+    ... (2) address@hidden Call the main subprogram, if there is one.}
address@hidden @RI{Environment_Task};
address@hidden
address@hidden
+The name of the environment task is written in italics here to indicate
+that this task is anonymous.
address@hidden
address@hidden
+  The model is different for a @lquotes@;passive address@hidden@;
+  (see @RefSecNum{Partitions}).
+  Either there is no environment task, or its @nt<sequence_of_statements>
+  is an infinite loop rather than a call on a main subprogram.
address@hidden
+
address@hidden@PDefn2{Term=[environment @nt<declarative_part>], Sec=(for the
+environment task of a partition)}
+The environment @nt{declarative_part} at (1) is a sequence of
address@hidden consisting of copies of
+the @nt{library_item}s included in the address@hidden
+The order of elaboration of @nt{library_item}s is
+the order in which they appear in the environment
address@hidden:
address@hidden
+  The order of all included @nt<library_item>s
+  is such that there are no forward elaboration
+  dependences.
+  @begin{Ramification}
+    This rule is written so that if a @nt{library_item}
+    depends on itself, we don't require it to be elaborated
+    before itself. See AI83-00113/12.
+    This can happen only in pathological circumstances.
+    For example, if a library @nt{subprogram_body}
+    has no corresponding @nt{subprogram_declaration},
+    and one of the subunits of the @nt{subprogram_body}
+    mentions the @nt{subprogram_body} in a @nt{with_clause},
+    the @nt{subprogram_body} will depend on itself.
+    For another example, if a @nt{library_unit_body}
+    applies a @nt{pragma} Elaborate_All to its own declaration,
+    then the @nt{library_unit_body} will depend on itself.
+  @end{Ramification}
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  Any included @nt{library_unit_declaration} 
@Chg{Version=[3],New=[for],Old=[to]}
+  which @Chg{Version=[3],New=[aspect],Old=[a @nt{pragma}]}
+  Elaborate_Body @Chg{Version=[3],New=[is True @Redundant[(including when a
+  @nt{pragma} Elaborate_Body applies)]],Old=[applies]}
+  is immediately followed by its @nt{library_unit_body},
+  if included.
address@hidden
+  This implies that the body of such a library unit
+  shall not @lquotes@;address@hidden@; any of its own children,
+  or anything else that depends semantically upon
+  the declaration of the library unit.
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden Elaborate_Body sets
+  aspect Elaborate_Body, see @RefSecNum{Elaboration Control}.]}
address@hidden
+
+  All @nt{library_item}s declared pure occur before any
+  that are not declared pure.
+
+  All preelaborated @nt<library_item>s occur before any
+  that are not preelaborated.
address@hidden
address@hidden
+Normally, if two partitions contain the same compilation unit,
+they each contain a separate @i{copy} of that
+compilation unit.
+See @RefSec{Distributed Systems} for cases where two partitions share
+the same copy of something.
+
+There is no requirement that the main subprogram be elaborated last.
+In fact, it is possible to write a partition in which the main
+subprogram cannot be elaborated last.
address@hidden
address@hidden
+This @nt{declarative_part} has the properties required of all
+environments (see @RefSecNum{The Compilation Process}).
+However, the environment @nt{declarative_part} of a partition will
+typically contain fewer compilation units than the environment
address@hidden used at compile time @em only the @lquotes@;address@hidden@;
+ones are included in the partition.
address@hidden
+
+There shall be a total order of the @nt{library_item}s that obeys the
+above rules.
+The order is otherwise implementation defined.
address@hidden
+The only way to violate this rule is to have
+Elaborate, Elaborate_All, or Elaborate_Body @nt{pragma}s that cause circular 
ordering
+requirements, thus preventing an order that has no forward
+elaboration dependences.
address@hidden
address@hidden order of elaboration of @nt{library_item}s.}
address@hidden
address@hidden a completion], Sec=(library_unit_declaration)}
address@hidden
+Notwithstanding what the RM95 says elsewhere,
+each rule that requires a declaration to have a corresponding
+completion is considered to be a @LinkTimeName
+when the declaration is that of a library unit.
address@hidden
address@hidden
+Such rules may be checked at @lquotes@;link time,@rquotes@; for example.
+Rules requiring the completion to have certain properties,
+on the other hand, are checked at compile time of the completion.
address@hidden
+
+
+The full expanded names of the library units and subunits included in a
+given partition shall be distinct.
+
address@hidden
+This is a @LinkTimeName because making it a @LegalityName
+would violate the @MetaRulesName labeled
address@hidden@;legality determinable via semantic address@hidden@;
address@hidden
+
address@hidden@;The @nt{sequence_of_statements} of the environment task (see (2)
+above) consists of either:
address@hidden
+  A call to the main subprogram,
+  if the partition has one.
+  If the main subprogram has parameters, they are passed;
+  where the actuals come from is implementation defined.
+  What happens to the result of a main function is also
+  implementation defined.
+  @ImplDef{Parameter passing and function return for the main
+  subprogram.}
address@hidden
+
address@hidden@keepnext@;or:
address@hidden
+  A @nt{null_statement}, if there is no main subprogram.
+  @begin{Discussion}
+    For a passive partition, either there is no environment task,
+    or its @nt<sequence_of_statements> is an infinite loop.
+    See @RefSecNum{Partitions}.
+  @end{Discussion}
address@hidden
+
+The mechanisms for building and running partitions are implementation
+defined.
address@hidden might be combined into one operation,
+as, for example, in dynamic linking, or @lquotes@;address@hidden@; systems.]
address@hidden mechanisms for building and running partitions.}
address@hidden
+
address@hidden
address@hidden, Sec=(program)}
+The execution of a program consists of the execution of a set of
+partitions. Further details are implementation defined.
address@hidden, Sec=(partition)}
+The execution of a partition starts with the execution
+of its environment task,
+ends when the environment task terminates,
+and includes the executions of all tasks of the partition.
address@hidden execution of the (implicit) @nt<task_body> of the
+environment task acts as a master
+for all other tasks created as part of the execution of the partition.
+When the environment task completes (normally or abnormally),
+it waits for the termination of all such tasks,
+and then finalizes any remaining objects of the partition.]
address@hidden
+The @lquotes@;further address@hidden@; mentioned above include,
+for example, program termination @em it
+is implementation defined.
+There is no need to define it here;
+it's entirely up to the implementation whether it wants
+to consider the program as a whole to exist beyond the existence of
+individual partitions.
address@hidden
address@hidden details of program execution,
+including program termination.}
address@hidden
address@hidden, Sec=(of a partition)}
address@hidden termination], Sec=(of a partition)}
address@hidden, Sec=(normal)}
address@hidden termination], Sec=(of a partition)}
address@hidden, Sec=(abnormal)}
+The execution of the partition terminates (normally or abnormally) when the
+environment task terminates (normally or abnormally, respectively).
address@hidden
+
address@hidden
+
address@hidden
address@hidden(bounded error),Sec=(cause)}
address@hidden,Sec=(raised by failure of run-time check)}
+Once the environment task has awaited the termination of all other
+tasks of the partition, any further attempt to create a task
+(during finalization) is a bounded error, and may result in
+the raising of Program_Error either upon creation or activation
+of the task.
address@hidden
+If such a task is activated, it is not specified
+whether the task is awaited prior to termination of the
+environment task.
address@hidden
+
address@hidden
address@hidden@;The implementation shall ensure that all compilation units
+included in a partition are consistent with one another,
+and are legal according to the rules of the language.
address@hidden
+The consistency requirement implies that
+a partition cannot contain two versions of the same compilation unit.
+That is,
+a partition cannot contain two different library units with the
+same full expanded name, nor two different bodies for the same
+program unit.
+For example, suppose we compile the following:
address@hidden
address@hidden A @key[is] address@hidden Version 1.}
+    ...
address@hidden A;
+
address@hidden A;
address@hidden B @key[is]
address@hidden B;
+
address@hidden A @key[is] address@hidden Version 2.}
+    ...
address@hidden A;
+
address@hidden A;
address@hidden C @key[is]
address@hidden C;
address@hidden
+
+It would be wrong for a partition containing B and C to contain both
+versions of A.
+Typically, the implementation would require the use of Version 2 of A,
+which might require the recompilation of B.
+Alternatively, the implementation might automatically recompile B
+when the partition is built.
+A third alternative would be an incremental compiler that,
+when Version 2 of A is compiled,
+automatically patches the object code for B to reflect the changes to
+A (if there are any relevant changes @em there might not be any).
+
+An implementation that supported fancy version management
+might allow the use of Version 1 in some circumstances.
+In no case can the implementation allow the use of both versions in
+the same partition
+(unless, of course, it can prove that the two versions are
+semantically identical).
+
+The core language says nothing about inter-partition
+consistency; see also @RefSec{Distributed Systems}.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden partition}
+The kind of partition described in this 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+is known as an @i{active} partition.
+An implementation is allowed to support other kinds of partitions,
+with implementation-defined semantics.
address@hidden semantics of any nonactive partitions supported by the
+implementation.}
address@hidden
address@hidden Systems} defines the concept of passive partitions;
+they may be thought of as a partition without an environment task,
+or as one with a particularly simple form of environment task,
+having an infinite loop rather than a call on a main subprogram
+as its @nt<sequence_of_statements>.
address@hidden
+
+An implementation may restrict the kinds of subprograms it supports
+as main subprograms.
+However, an implementation is required to support all main
+subprograms that are public parameterless library procedures.
address@hidden
+The implementation is required to support main subprograms that are
+procedures declared by @nt{generic_instantiation}s,
+as well as those
+that are children of library units other than Standard.
+Generic units are, of course, not allowed to be main subprograms,
+since they are not subprograms.
+
+Note that renamings are irrelevant to this rule.
+This rules says which subprograms (not views)
+have to be supported.
+The implementation can choose any way it wants for the
+user to indicate which subprogram should be the main subprogram.
+An implementation might allow any name of any view,
+including those declared by renamings.
+Another implementation might require it to be the original name.
+Another implementation still might use the name of the source file or
+some such thing.
address@hidden
+
+If the environment task completes abnormally,
+the implementation may abort any dependent tasks.
address@hidden
+If the implementation does not take advantage of this permission,
+the normal action takes place @em the environment task awaits those
+tasks.
+
+The possibility of aborting them
+is not shown in the @i{Environment_Task} code above,
+because there is nowhere to put an @nt{exception_handler} that can
+handle exceptions raised in both the environment @nt{declarative_part}
+and the main subprogram,
+such that the dependent tasks can be aborted.
+If we put an @nt{exception_handler} in the body of the environment
+task, then it won't handle exceptions that occur during elaboration of
+the environment @nt{declarative_part}.
+If we were to move those things into a nested @nt{block_statement},
+with the @nt{exception_handler} outside that,
+then the @nt{block_statement} would await the library tasks we are
+trying to abort.
+
+Furthermore, this is merely a permission, and is not fundamental to the
+model, so it is probably better to state it separately anyway.
+
+Note that implementations (and tools like debuggers)
+can have modes that provide other behaviors in addition.
address@hidden
address@hidden
+
address@hidden
+An implementation may provide inter-partition
+communication mechanism(s) via special packages and pragmas.
+Standard pragmas for distribution and methods for specifying
+inter-partition communication are defined in @RefSec{Distributed Systems}.
+If no such mechanisms are provided, then each partition is isolated from all
+others, and behaves as a program in and of itself.
address@hidden
+Not providing such mechanisms is equivalent to disallowing multi-partition
+programs.
+
+An implementation may provide mechanisms to facilitate checking the
+consistency of library units elaborated in different partitions;
address@hidden Systems} does so.
address@hidden
+
+Partitions are not required to run in separate address spaces.
+For example, an implementation might support dynamic linking
+via the partition concept.
+
+An order of elaboration of @nt{library_item}s that is consistent with
+the partial ordering defined above does not always ensure that each
address@hidden is elaborated before any other compilation unit
+whose elaboration necessitates that the @nt{library_unit_body} be
+already elaborated.
+(In particular, there is no requirement that the body of a library unit
+be elaborated as soon as possible after the
address@hidden is elaborated,
+unless the pragmas in subclause @RefSecNum{Elaboration Control} are
+used.)
+
+A partition (active or otherwise) need not have a main subprogram.
+In such a case, all the work done by the partition would be done by
+elaboration of various @nt{library_item}s, and by tasks created by that
+elaboration.
+Passive partitions, which cannot have main subprograms,
+are defined in @RefSec{Distributed Systems}.
address@hidden
+The environment task is the outermost semantic level
+defined by the language.
+
+Standard has no private part.
+This prevents strange implementation-dependences involving private
+children of Standard having visibility upon Standard's private part.
+It doesn't matter where the body of Standard appears in the environment,
+since it doesn't do anything.
+See @RefSec{Predefined Language Environment}.
+
+Note that elaboration dependence is carefully defined in such a way that
+if (say) the body of something doesn't exist yet,
+then there is no elaboration dependence upon the nonexistent body.
+(This follows from the fact that @lquotes@;needed address@hidden@; is defined 
that way,
+and the elaboration dependences caused by a @nt{pragma} Elaborate or
+Elaborate_All are defined in terms of @lquotes@;needed address@hidden@;.)
+This property allows us to use the environment concept both at compile
+time and at partition-construction time/run time.
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The concept of partitions is new to Ada 95.
+
+A main subprogram is now optional.
+The language-defined restrictions on main subprograms are relaxed.
address@hidden
+
address@hidden
+Ada 95 uses the term @lquotes@;main address@hidden@; instead of Ada 83's 
@lquotes@;main
address@hidden@; (which was inherited from Pascal).
+This is done to avoid confusion @em a main subprogram is a subprogram, not a
+program.
+The program as a whole is an entirely different thing.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00256-01]}
+  @ChgAdded{Version=[2],Text=[The mistaken use of @lquotes@;address@hidden@;
+  in the elaboration dependence rule was fixed.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00217-06]}
+  @ChgAdded{Version=[2],Text=[The @i<needs> relationship was extended to
+  include limited views.]}
address@hidden
+
address@hidden Control}
+
address@hidden
address@hidden@Defn{elaboration control}
+This subclause defines pragmas that help control
+the elaboration order of @nt{library_item}s.]
address@hidden
+
address@hidden
+The rules governing preelaboration are designed to allow
+it to be done largely by bulk initialization of statically
+allocated storage from information in a @lquotes@;load address@hidden@; 
created by a linker.
+Some implementations may require run-time code to be executed in some
+cases, but we consider these cases rare enough that we need not
+further complicate the rules.
+
+It is important that programs be able to declare data structures that
+are link-time initialized with @nt{aggregate}s, @nt{string_literal}s,
+and concatenations thereof.
+It is important to be able to write link-time evaluated expressions
+involving the First, Last, and Length attributes of such data structures
+(including variables), because they might be initialized with positional
address@hidden or @nt{string_literal}s, and we don't want the user to
+have to count the elements.
+There is no corresponding need for accessing discriminants,
+since they can be initialized with a static constant,
+and then the constant can be referred to elsewhere.
+It is important to allow link-time initialized data structures
+involving discriminant-dependent components.
+It is important to be able to write link-time evaluated expressions
+involving pointers (both access values and addresses)
+to the above-mentioned data structures.
+
+The rules also ensure that no Elaboration_Check need be performed
+for calls on library-level subprograms declared within
+a preelaborated package.
+This is true also of the Elaboration_Check on task activation
+for library level task types declared in a preelaborated package.
+However, it is not true of the Elaboration_Check on instantiations.
+
+A static expression should never prevent a library unit from being
+preelaborable.
+
+
address@hidden
+
address@hidden
address@hidden
address@hidden@Keepnext@;The form of a @nt{pragma} Preelaborate is as follows:
address@hidden
+
address@hidden@key{pragma} @prag(Preelaborate)[(@address@hidden)];'
+
address@hidden
address@hidden unit pragma], Sec=(Preelaborate)}
address@hidden, library unit], Sec=(Preelaborate)}
+A @nt{pragma} Preelaborate is a library unit pragma.
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00161-01]}
address@hidden,Type=[Leading],KeepNext=[T],Text=[The form of a
address@hidden Preelaborable_Initialization is as follows:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,@ChgAdded{Version=[2],
+Text=<@key{pragma} @prag<Preelaborable_Initialization>(@Syn2{direct_name});>}}
address@hidden
+
address@hidden
address@hidden@RootDefn2{Term=[preelaborable], Sec=(of an elaborable construct)}
+An elaborable construct is preelaborable unless its
+elaboration performs any of the following actions:
address@hidden
+A @i{preelaborable} construct can be elaborated
+without using any information that is available only at run time.
+Note that we don't try to prevent exceptions in preelaborable
+constructs; if the implementation wishes to generate code to
+raise an exception, that's OK.
+
+Because there is no flow of control and there are no calls
+(other than to predefined subprograms),
+these run-time properties can actually be detected at compile
+time.
+This is necessary in order to require compile-time enforcement of the
+rules.
address@hidden
address@hidden
+The execution of a @nt{statement} other than a @nt{null_statement}.
address@hidden
+A preelaborable construct can contain @nt{label}s and
address@hidden
address@hidden
+
+A call to a subprogram other than a static function.
+
+The evaluation of a @nt{primary} that is a @nt{name}
+of an object, unless the @nt{name} is a static expression,
+or statically denotes a discriminant of an enclosing type.
address@hidden
+One can evaluate such a @nt{name}, but not as a @nt{primary}.
+For example, one can evaluate an attribute of the object.
+One can evaluate an @nt{attribute_reference},
+so long as it does not denote an object,
+and its @nt{prefix} does not disobey any of these rules.
+For example, Obj'Access, Obj'Unchecked_Access,
+and Obj'Address are generally legal in preelaborated library
+units.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00161-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0028-1]}
+The creation of @Chg{Version=[2],New=[an object @Redundant[(including a
+component)] @Chg{Version=[3],New=[that is initialized by default, if
+its],Old=[of a]} type @Chg{Version=[3],New=[],Old=[that ]}does not have
+preelaborable initialization. Similarly,],
+Old=[a default-initialized object @Redundant[(including
+a component)] of a descendant of a private type,
+private extension, controlled type,
+task type, or protected type with
address@hidden@!declaration}s; similarly]} the evaluation of
+an @nt<address@hidden> with
+an ancestor @nt<address@hidden> denoting a subtype of such a type.
+
address@hidden
+One can declare these kinds of types,
+but one cannot create objects of those types.
+
+It is also nonpreelaborable to create an object if that will cause the
+evaluation of a default expression that will call a user-defined
+function.
+This follows from the rule above forbidding nonnull statements.
address@hidden
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00161-01]}
address@hidden,Text=[Controlled objects are disallowed because most
+implementations will have to take some run-time action during initialization,
+even if the Initialize procedure is null.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00403-01]}
address@hidden,Type=[Leading],address@hidden addition to get conditional 
leading}
+A generic body is
+preelaborable only if elaboration of a corresponding
+instance body would not perform any such actions,
+presuming address@hidden,New=[:],Old=[ the actual for each formal
+private type (or extension) is
+a private type (or extension), and the actual for each
+formal subprogram is a user-defined subprogram.]}
address@hidden contract issue}
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00403-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-0028-1]}
address@hidden,Text=[the actual for address@hidden,
+New=[ discriminated formal derived type,],Old=[]} formal private
address@hidden,New=[, ],Old=[ (]}or
address@hidden,New=[formal private ],address@hidden,New=[],Old=[)]}
+declared within the formal part of the generic unit is
+a @Chg{Version=[3],New=[],Old=[private address@hidden,New=[],Old=[ (or 
extension)]}
+that does not have preelaborable address@hidden,
+New=[, unless @nt<pragma>
+Preelaborable_Initialization has been applied to the formal type],Old=[]};]}
+
address@hidden,Kind=[Added],ARef=[AI95-00403-01]}
address@hidden,Text=[the actual for each formal type is nonstatic;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00403-01]}
address@hidden,Text=[the actual for each formal object is nonstatic; and]}
+
address@hidden,Kind=[Added],ARef=[AI95-00403-01]}
address@hidden,Text=[the actual for each formal subprogram is a
+user-defined subprogram.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00403-01]}
+  @ChgAdded{Version=[2],Text=[This is an @lquotes@;address@hidden
+  rule. The elaboration of a generic unit doesn't perform any of the actions
+  listed above, because its sole effect is to establish that the generic can
+  from now on be instantiated. So the elaboration of the generic itself is not
+  the interesting part when it comes to preelaboration rules. The interesting
+  part is what happens when you elaborate @lquotes@;any address@hidden
+  of the generic. For instance, declaring an object of a limited formal private
+  type might well start tasks, call functions, and do all sorts of
+  nonpreelaborable things. We prevent these situations by assuming that the
+  actual parameters are as badly behaved as possible.]}
address@hidden
address@hidden
+  Without this rule about generics, we would have to forbid
+  instantiations in preelaborated library units,
+  which would significantly reduce their usefulness.
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0035],ARef=[AI95-00002-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0034-1],ARef=[AI05-0243-1]}
address@hidden
address@hidden,New=[A],Old=[If a]} @nt{pragma} Preelaborate (or
address@hidden<pragma> Pure @em see below) @Chg{Version=[3],New=[is used to 
specify that],
+Old=[applies to]}
+a library address@hidden,New=[],Old=[, then it]} is
address@hidden@Chg{Version=[3],New=[, namely that the Preelaborate
address@hidden of the library unit is True; all
+compilation units of the
+library unit are preelaborated],Old=[]}.
address@hidden,New=[],address@hidden
address@hidden
+If a library unit is preelaborated, then its declaration, if any,
+and body, if any, are elaborated
+prior to all nonpreelaborated @nt{library_item}s of the partition.]
address@hidden declaration and body of a preelaborated library
+unit, and all subunits that are elaborated as part of elaborating the library
+unit,], Old=[All compilation units of a preelaborated
+library unit]} shall be address@hidden,New=[
+All
+compilation units of a preelaborated library unit shall depend semantically 
only
+on declared pure or preelaborated @nt{library_item}s.],Old=[]}
address@hidden contract issue}
+In addition to the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}),
address@hidden,New=[these rules also apply],Old=[this rule applies also]}
+in the private part of an instance of a generic unit.
address@hidden,address@hidden
address@hidden
+If a library unit is preelaborated, then its declaration, if any,
+and body, if any, are elaborated
+prior to all nonpreelaborated @nt{library_item}s of the partition.]],
+Old=[In addition, all compilation units of a preelaborated library unit
+shall depend semantically only on
+compilation units of other preelaborated library units.]}
address@hidden
+In a generic body, we assume the worst about
+formal private types and extensions.
+
address@hidden,Kind=[Added],Ref=[8652/0035],ARef=[AI95-00002-01]}
address@hidden,Text=[Subunits of a preelaborated subprogram unit
+do not need
+to be preelaborable. This is needed in order to be consistent with units
+nested in a subprogram body, which do not need to be preelaborable even if
+the subprogram is preelaborated. However, such subunits cannot depend
+semantically on nonpreelaborated units, which is also consistent with
+nested units.]}
address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Preelaborate],
+    address@hidden,Text=[Code execution during elaboration is
+      avoided for a given package.]}]}
+
address@hidden,Kind=[Added],ARef=[AI95-00161-01]}
address@hidden,address@hidden initialization}The following rules
+specify which entities have @i{preelaborable initialization}:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0028-1]}
address@hidden,Text=[The partial view
+of a private type or private extension, a protected type without
address@hidden<entry_declaration>s, a generic formal private type, or a generic 
formal
+derived type, @Chg{Version=[3],New=[has],Old=[have]} preelaborable
+initialization if and only if the @nt<pragma> Preelaborable_Initialization has
+been applied to them. @Redundant[A protected type with @nt{entry_declaration}s
+or a task type never has preelaborable initialization.]]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[A component (including a discriminant) of a record or
+protected type has preelaborable initialization if its declaration includes a
address@hidden<default_expression> whose execution does not perform any actions 
prohibited
+in preelaborable constructs as described above, or if its declaration does not
+include a default expression and its type has preelaborable
+initialization.]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0028-1],ARef=[AI05-0221-1]}
address@hidden,Text=[A derived type has preelaborable initialization
+if its parent type has preelaborable initialization and
address@hidden,New=[],Old=[(in the case of a
+derived record extension) ]}if the noninherited components all have
+preelaborable initialization. However, a @Chg{Version=[3],New=[],
+Old=[user-defined ]}controlled type with an
address@hidden,New=[],Old=[overriding ]}Initialize procedure
address@hidden,New=[that is not a null procedure ],Old=[]}does not
+have preelaborable initialization.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00161-01],ARef=[AI95-00345-01]}
address@hidden,Text=[A view of a type has preelaborable initialization if it
+is an elementary type, an array type whose component type has preelaborable
+initialization, a record type whose components all have preelaborable
+initialization, or an interface type.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00161-01]}
address@hidden,Text=[A @nt<pragma> Preelaborable_Initialization specifies that 
a type has
+preelaborable initialization. This pragma shall appear in the visible part
+of a package or generic package.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00161-01],ARef=[AI95-00345-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0028-1]}
address@hidden,Text=[If the pragma appears in the first list of
address@hidden of a
address@hidden<package_specification>, then the @nt<direct_name> shall denote 
the first
+subtype of a @Chg{Version=[3],New=[composite],Old=[private]}
address@hidden,New=[],Old=[, private extension, or protected type that is not
+an interface type and is without
address@hidden<entry_declaration>s]}, and the type shall be declared 
immediately within
+the same package
+as the @nt<pragma>. If the @nt<pragma> is applied to a private type or a
+private extension, the full view of the type shall have preelaborable
+initialization. If the @nt<pragma> is applied to a protected type,
address@hidden,New=[the protected type shall not have
+entries, and ],Old=[]}each
+component of the protected type shall have preelaborable initialization.
address@hidden,New=[For any other composite type, the type shall have
+preelaborable initialization. ],address@hidden contract issue}In
+addition to the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}), these rules apply
+also in the private part of an instance of a generic unit.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0028-1]}
+  @ChgAdded{Version=[3],Text=[The reason why we need the pragma for private
+  types, private extensions, and protected types is fairly clear: the
+  properties of the full view determine whether the type has preelaborable
+  initialization or not; in order to preserve privacy we need a way to express
+  on the partial view that the full view is well-behaved. The reason why we
+  need the pragma for other composite types is more subtle: a nonnull override
+  for Initialize might occur in the private part, even for a nonprivate type;
+  in order to preserve privacy, we need a way to express on a type declared in
+  a visible part that the private part does not contain any nasty override of
+  Initialize.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00161-01]}
address@hidden,Text=[If the @nt<pragma> appears in a @nt<generic_formal_part>, 
then the
address@hidden<direct_name> shall denote a generic formal private type or a 
generic formal
+derived type declared in the same @nt<generic_formal_part> as the @nt<pragma>.
+In a @nt<generic_instantiation> the corresponding actual type shall have
+preelaborable initialization.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Not only do protected types with
address@hidden
+and task types not have preelaborable initialization, but they cannot have
+pragma Preelaborable_Initialization applied to them.]}
address@hidden
address@hidden
+
address@hidden
+In an implementation, a type declared in a preelaborated 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.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[A type declared in a preelaborated package
+should have the same representation in every elaboration
+of a given version of the package.]}]}
address@hidden
+
address@hidden
address@hidden
address@hidden@keepnext@;The form of a @nt{pragma} Pure is as follows:
address@hidden
+
address@hidden@key{pragma} @prag(Pure)[(@address@hidden)];'
+
address@hidden
address@hidden unit pragma], Sec=(Pure)}
address@hidden, library unit], Sec=(Pure)}
+A @nt{pragma} Pure is a library unit pragma.
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00366-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0035-1]}
address@hidden,Type=[Leading],address@hidden
+A @i{pure} @Chg{Version=[3],New=[compilation unit],address@hidden
+is a preelaborable @Chg{Version=[3],New=[compilation unit],address@hidden whose
+elaboration does not perform any of the following actions:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[the elaboration of a variable declaration;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[the evaluation of an @nt{allocator} of an
+access-to-variable type; for the purposes of this rule, the partial view of a
+type is presumed to have nonvisible components whose default initialization
+evaluates such an @nt{allocator};]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0004-1]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[Such an @nt{allocator} would
+  provide a backdoor way to get a global variable into a pure unit, so it is
+  prohibited. Most such @nt{allocator}s are illegal anyway, as their type is
+  required to have Storage_Size = 0 (see the next two rules). But access
+  parameters and access discriminants don't necessarily disallow 
@nt{allocator}s.
+  However, a call is also illegal here (by the preelaboration rules), so access
+  parameters cannot cause trouble. So this rule is really about prohibiting
+  allocators in discriminant constraints:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden Rec (Acc : @key[access] Integer) @key[is record]
+    C : Character;
address@hidden record];]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Not_Const : @key[constant] Rec (Acc => @key[new] 
Integer'(2)); -- @RI{Illegal in a pure unit}.]}
address@hidden
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0004-1]}
+  @ChgAdded{Version=[2],address@hidden,New=[The second half of the],Old=[This]}
+  rule is needed because aggregates can specify the default initialization
+  of a private type or extension using <> or the ancestor subtype of an
+  extension aggregate. The
+  subtype of a component could use an @nt{allocator} to initialize an access
+  discriminant; the type still could have a pragma Preelaborable_Initialization
+  given. Ada 95 did not allow such private types to have preelaborable
+  initialization, so such a default initialization could not have occurred.
+  Thus this rule is not incompatible with Ada 95.]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0035-1]}
address@hidden,Text=[the elaboration of the declaration of a
address@hidden,New=[nonderived ],Old=[]}named
+access-to-variable type unless the Storage_Size of the type
+has been specified by a static expression with value zero or
+is defined by the language to be zero;]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[A remote access-to-class-wide type
+  (see @RefSecNum{Remote Types Library Units}) has its Storage_Size defined to
+  be zero.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00366-01]}
+  @ChgAdded{Version=[2],Text=[We disallow most named access-to-object types
+  because an @nt{allocator} has a side effect; the pool constitutes variable
+  data. We allow access-to-subprogram types because they
+  don't have @nt{allocator}s. We even allow named access-to-object types if
+  they have an empty predefined pool (they can't have a user-defined pool as
+  System.Storage_Pools is not pure). In this case, most attempts to use an
+  @nt{allocator} are illegal, and any others (in a generic body) will raise
+  Storage_Error.]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0035-1]}
address@hidden,Text=[the elaboration of the declaration of a
address@hidden,New=[nonderived ],Old=[]}named
+access-to-constant type for which the Storage_Size has been specified by an
+expression other than a static expression with value zero.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We allow access-to-constant types so long as
+  there is no user-specified nonzero Storage_Size; if there were a
+  user-specified nonzero Storage_Size restricting the size of the storage
+  pool, allocators would be problematic since the package is supposedly
+  @lquote@;address@hidden, and the allocated size count for the storage pool
+  would represent state.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0035-1]}
address@hidden,Text=[A generic body is pure only if elaboration of a
+corresponding instance body would not perform any such actions presuming any
+composite formal types have nonvisible components whose default initialization
+evaluates an @nt{allocator} of an access-to-variable type.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00366-01]}
address@hidden,Text=[The Storage_Size for an anonymous
+access-to-variable type declared at library level in a library unit that is
+declared pure is defined to be zero.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This makes @nt{allocator}s illegal for such types
+  (see @RefSecNum{Allocators}), making a storage pool unnecessary for these
+  types. A storage pool would represent state.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Note that access discriminants and access
+  parameters are never library-level, even when they are declared in a
+  type or subprogram declared at library-level. That's because they have their
+  own special accessibility rules (see @RefSecNum{Operations of Access 
Types}).]}
address@hidden
+
address@hidden
+
+
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00366-01]}
address@hidden,address@hidden
+A @i{pure} @nt{library_item} is a preelaborable @nt{library_item}
+that does not contain the declaration of any
+variable or named access within a
+subprogram, generic
+subprogram,
+task unit, or protected unit.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00366-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0034-1],ARef=[AI05-0035-1],ARef=[AI05-0243-1]}
address@hidden pure}
+A @nt{pragma} Pure is used to @Chg{Version=[3],New=[specify],Old=[declare]}
+that a library unit is @Chg{Version=[3],address@hidden pure}, namely
+that the Pure address@hidden of the library unit is True; all
+compilation units of the library unit are declared ],Old=[]}pure.
address@hidden,New=[In addition, the limited view
+of any library package is declared pure. The declaration and
+body of a declared pure library unit, and all subunits that are
+elaborated as part of elaborating the library unit, shall be pure.
+All],Old=[If a @nt{pragma} Pure applies to a library unit,
+then its]} compilation units @Chg{Version=[3],New=[of a declared pure
+library unit],Old=[shall be pure, and they]} shall depend semantically
+only on @Chg{Version=[3],New=[],Old=[compilation units of other library units
+that are ]}declared address@hidden,New=[ @nt{library_item}s],
address@hidden,New=[ @PDefn{generic contract issue}
+In addition to the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}), these rules also
+apply in the private part of an instance of a generic unit.],
address@hidden,New=[ Furthermore, the full view of any
+partial view declared in the visible part of @Chg{Version=[3],New=[a declared
+pure],Old=[the]} library unit that has
+any available stream attributes shall support external streaming
+(see @RefSecNum{Stream-Oriented Attributes}).],Old=[]}
address@hidden
address@hidden,Kind=[Deleted],address@hidden is now described normatively}
address@hidden,Text=[A @i{declared-pure} library unit is one to
+which a @nt{pragma} Pure applies.
+Its declaration and body are also said to be declared pure.]}
address@hidden
address@hidden
+A declared-pure package is useful for defining types to be shared
+between partitions with no common address space.
address@hidden
address@hidden
+Note that generic packages are not mentioned
+in the list of things that can contain variable declarations.
+Note that the Ada 95 rules for deferred constants make them
+allowable in library units that are declared pure;
+that isn't true of Ada 83's deferred constants.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00366-01]}
+Anonymous access types
address@hidden,New=[],Old=[(that is, access discriminants and
+access parameters) ]}are allowed.
+
address@hidden,Kind=[Added],ARef=[AI05-0243-1]}
address@hidden,Text=[A limited view is not a library unit, so any rule
+that starts @ldquote@;declared pure library address@hidden does not apply to a
+limited view. In particular, the 3rd and last sentences never apply to limited
+views. However, a limited view is a @nt{library_item}, so rules that discuss
address@hidden@;declared pure @address@hidden do include limited views.]}
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00366-01]}
address@hidden,New=[Ada 95 didn't allow any access types as],
+Old=[The primary reason for disallowing named
+access types is that an @nt{allocator} has a side effect;
+the pool constitutes variable data. We considered somehow allowing
address@hidden access types. However,]} these
+(including access-to-subprogram types)
address@hidden,New=[],Old=[would ]}cause trouble
+for @RefSec{Distributed Systems}, because such types @Chg{Version=[2],New=[],
+Old=[would ]} allow access values in a shared passive
+partition to designate objects in an active partition,
+thus allowing inter-address space address@hidden,New=[ We decided
+to disallow such uses in the relatively rare cases where they cause problems,
+rather than making life harder for the majority of users. Types declared
+in a pure package can be used in remote operations only if they are externally
+streamable. That simply means that there is a means to transport values of the
+type; that's automatically true for nonlimited types that don't have an
+access part. The only tricky part about this is to avoid privacy leakage; that
+was handled by ensuring that any private types (and private
+extensions) declared in a pure package that have available stream attributes
+(which include all nonlimited types by definition) have to be externally
+streamable.],
+Old=[Furthermore, a named access-to-object type without a pool would be a new
+concept, adding complexity from the user's point of view. Finally, the
+prevention of @nt{allocator}s would have to be
+a run-time check, in order to avoid violations of the generic contract
+model.]}
address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Pure],
+    address@hidden,Text=[Side effects are avoided in the
+      subprograms of a given package.]}]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0076-1]}
+  @ChgAdded{Version=[4],Text=[Execution is erroneous if some operation (other
+  than the initialization or finalization of the object) modifies the value of 
a
+  constant object declared at library-level in a pure package.]}
+
+  @begin{Discussion}
+    @ChgRef{Version=[4],Kind=[AddedNormal]}
+    @ChgAdded{Version=[4],Text=[This could be accomplished via a
+    self-referencing pointer or via squirrelling a writable pointer to a
+    controlled object.]}
+  @end{Discussion}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00366-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0219-1]}
+If a library unit is declared pure, then the implementation
+is permitted to omit a call on a library-level
+subprogram of the library unit if the
+results are not needed after the call. @Chg{Version=[2],New=[In addition,
+the implementation],Old=[Similarly, it]} may omit @Chg{Version=[2],New=[],
+Old=[such ]}a address@hidden,New=[ on such a subprogram],Old=[]} and
+simply reuse the results produced by an earlier call on
+the same subprogram, provided that none of the
+parameters @Chg{Version=[2],New=[nor any object accessible via access
+values from the parameters ],address@hidden,New=[have any part that
+is of a type whose full type is an immutably],Old=[are of
+a]} limited type, and the addresses and values of all by-reference
+actual parameters, @Chg{Version=[2],New=[],Old=[and ]}the values of all
+by-copy-in actual parameters, @Chg{Version=[2],New=[and the values of all
+objects accessible via access values from the parameters, ],Old=[]}are
+the same as they were at the earlier call.
address@hidden permission applies even if the subprogram
+produces other side effects when called.]
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00366-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0005-1],ARef=[AI05-0299-1]}
+A declared-pure @nt{library_item} has no variable state.
+Hence, a call on one of its (nonnested) subprograms cannot
address@hidden,New=[normally],address@hidden@;address@hidden
+have side effects. @Chg{Version=[3],New=[Side effects are still possible
+via dispatching calls and via indirect calls through access-to-subprogram
+values. Other mechanisms that might be used to modify variable state
+include],Old=[The only possible side effects from such a call would be
+through]}
+machine code insertions,@Chg{Version=[2],New=[ imported subprograms,
address@hidden,New=[ and ],Old=[]}],Old=[]}unchecked conversion to an access 
type declared within the
address@hidden,New=[; this list is not exhaustive],Old=[, and
+similar address@hidden,New=[ Thus, the permissions described
+in this subclause may apply to a subprogram whose execution has
+side effects.],Old=[]} The compiler may omit a call to such a subprogram
+even if @Chg{Version=[3],New=[],Old=[such]} side effects exist, so the
+writer of such a subprogram has to keep this in mind.
address@hidden
+
address@hidden
+
address@hidden
address@hidden
address@hidden@Keepnext@;The form of a @nt{pragma} Elaborate, Elaborate_All, or
+Elaborate_Body is as follows:
address@hidden
+
address@hidden@key{pragma} @prag(Elaborate)(@address@hidden, @address@hidden);'
+
address@hidden@key{pragma} @prag(Elaborate_All)(@address@hidden, 
@address@hidden);'
+
address@hidden@key{pragma} @prag(Elaborate_Body)[(@address@hidden)];'
+
address@hidden
+A @nt{pragma} Elaborate or Elaborate_All is only allowed within a
address@hidden
address@hidden
+  @lquotes@;Within a @address@hidden@; allows it to be the last
+  item in the @nt{context_clause}.
+  It can't be first, because the @nt{name} has to denote something
+  mentioned earlier.
address@hidden
+
address@hidden unit pragma], Sec=(Elaborate_Body)}
address@hidden, library unit], Sec=(Elaborate_Body)}
+A @nt{pragma} Elaborate_Body is a library unit pragma.
address@hidden
address@hidden
+Hence, a @nt{pragma} Elaborate or Elaborate_All is not
+elaborated, not that it makes any practical difference.
+
+Note that a @nt{pragma} Elaborate or Elaborate_All is neither a program unit
+pragma, nor a library unit pragma.
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden a completion], Sec=(declaration to which a @nt{pragma} 
Elaborate_Body applies)}
+If @Chg{Version=[3],New=[the aspect],Old=[a @nt{pragma}]} Elaborate_Body
address@hidden,New=[is True for],Old=[applies to]} a
address@hidden,New=[ @Redundant[(including when @nt{pragma}
+Elaborate_Body applies)]],Old=[]},
+then the declaration requires a completion @Redundant[(a
+body)address@hidden,address@hidden a completion],
+Sec=(declaration for which aspect Elaborate_Body is True)}],Old=[]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden Elaborate_Body sets the
+  aspect (see below).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00217-06]}
address@hidden,Text=[The @address@hidden of a
address@hidden Elaborate or Elaborate_All shall denote a nonlimited view
+of a library unit.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[These @nt{pragma}s are intended to prevent
+  elaboration check failures. But a limited view does not make anything visible
+  that has an elaboration check, so the @nt{pragma}s cannot do anything useful.
+  Moreover, the @nt{pragma}s would probably reintroduce
+  the circularity that the @nt{limited_with_clause} was intended to break.
+  So we make such uses illegal.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden @nt{pragma} Elaborate specifies that the body of the named 
library
+unit is elaborated before the current @nt{library_item}.
+A @nt{pragma} Elaborate_All specifies that each @nt{library_item} that is
+needed by the named library unit declaration
+is elaborated before the current @address@hidden,New=[],Old=[
+A @nt{pragma} Elaborate_Body specifies that the body
+of the library unit is elaborated immediately after its declaration.]}]
+
address@hidden
+The official statement of the semantics of these @nt{pragma}s is given in
address@hidden Execution}.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Text=[A @nt{pragma} Elaborate_Body sets the Elaborate_Body
+representation aspect of the library unit to which it applies to the value 
True.
address@hidden the Elaborate_Body aspect of a library unit is True, the body of 
the library
+unit is elaborated immediately after its address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[The official statement of the semantics of this
+  aspect is given in @RefSecNum{Program Execution}.]}
address@hidden
address@hidden
+The presence of a @nt{pragma} Elaborate_Body simplifies the removal of
+unnecessary Elaboration_Checks.
+For a subprogram declared immediately within a library unit to which
+a @nt{pragma} Elaborate_Body applies, the only calls that can fail the
+Elaboration_Check are those that occur in the library unit itself,
+between the declaration and body of the called subprogram;
+if there are no such calls
+(which can easily be detected at compile time
+if there are no @ntf{stub}s),
+then no Elaboration_Checks are needed for that subprogram.
+The same is true for Elaboration_Checks on task activations and
+instantiations, and for library subprograms and generic units.
address@hidden
address@hidden
+The fact that the unit of elaboration is the @nt{library_item}
+means that if a @nt{subprogram_body} is not a completion, it is
+impossible for any @nt{library_item} to be elaborated between the
+declaration and the body of such a subprogram.
+Therefore, it is impossible for a call to such a subprogram to fail its
+Elaboration_Check.
address@hidden
address@hidden
+The visibility rules imply that
+each @address@hidden of a @nt{pragma} Elaborate
+or Elaborate_All has to denote a library unit mentioned by a
+previous @nt{with_clause} of the same @nt{context_clause}.
address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Elaborate_Body],
+    address@hidden,Text=[A given package must have a body, and that
+      body is elaborated immediately after the declaration.]}]}
+
address@hidden
+
address@hidden
+A preelaborated library unit is allowed to have nonpreelaborable
+children.
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0035],ARef=[AI95-00002-01]}
+But @Chg{New=[generally ], Old=[]}not nonpreelaborated subunits.
address@hidden(Nonpreelaborated subunits of subprograms are allowed as
+discussed above.)], Old=[]}
address@hidden
+
+A library unit that is declared pure is allowed to have impure
+children.
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0035],ARef=[AI95-00002-01]}
+But @Chg{New=[generally ], Old=[]}not impure subunits.
address@hidden(Impure subunits of subprograms are allowed as discussed above.)],
+Old=[]}
address@hidden
address@hidden
+Pragma Elaborate is mainly for closely related library units,
+such as when two package bodies 'with' each other's declarations.
+In such cases, Elaborate_All sometimes won't work.
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The concepts of preelaborability
+and purity are new to Ada 95.
+The Elaborate_All, Elaborate_Body, Preelaborate,
+and Pure @nt{pragma}s are new to Ada 95.
+
+Pragmas Elaborate are allowed to be mixed in with the other
+things in the @nt{context_clause} @em in Ada 83, they were
+required to appear last.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00366-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  The requirement that a partial view with available stream attributes
+  be externally streamable can cause an incompatibility in rare cases.
+  If there is a limited tagged
+  type declared in a pure package with available attributes, and that
+  type is used to declare a private extension in another pure package,
+  and the full type for the private extension has a component of an
+  explicitly limited record type, a protected type, or a type with
+  access discriminants, then the stream attributes will have to be
+  user-specified in the visible part of the package. That is not a requirement
+  for Ada 95, but this combination seems very unlikely in pure packages.
+  Note that this cannot be an incompatibility for a nonlimited type,
+  as all of the types that are allowed in Ada 95 that would require
+  explicitly defined stream attributes are limited (and thus cannot be used
+  as components in a nonlimited type).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00403-01]}
+  @ChgAdded{Version=[2],address@hidden Correction:] Added wording
+  to cover missing cases for preelaborated generic units. This is
+  incompatible as a preelaborated unit could have used a formal
+  object to initialize a library-level object; that isn't allowed in Ada 2005. 
But such a unit wouldn't really
+  be preelaborable, and Ada 95 compilers can reject such units (as this
+  is a Binding Interpretation), so such units should be very rare.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00161-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b[Amendment Correction:] The concept of preelaborable initialization and
+  @nt{pragma} Preelaborable_Initialization are new. These allow more types
+  of objects to be created in preelaborable units, and fix holes in the
+  old rules.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00366-01]}
+  @ChgAdded{Version=[2],Text=[Access-to-subprogram types and access-to-object
+  types with a Storage_Size of 0 are allowed in pure units. The permission
+  to omit calls was adjusted accordingly (which also fixes a hole in Ada 95, as
+  access parameters are allowed, and changes in the values accessed by them
+  must be taken into account).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00002-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> The wording was changed 
so that
+  subunits of a preelaborated subprogram are also preelaborated.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00217-06]}
+  @ChgAdded{Version=[2],Text=[Disallowed pragma Elaborate and Elaborate_All
+  for packages that are mentioned in a @nt{limited_with_clause}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0028-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Corrected a serious
+  unintended incompatibility with Ada 95 in the new preelaboration wording
+  @em explicit initialization of objects of types that don't have
+  preelaborable initialization was not allowed. Ada 2012 switches
+  back to the Ada 95 rule in these cases. This is unlikely to
+  occur in practice, as it is unlikely that a compiler would have
+  implemented the more restrictive rule (it would fail many ACATS tests
+  if it did).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0035-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added an assume-the-worst
+  rule for generic bodies (else they would never be checked for purity)
+  and added the boilerplate so that the entire generic specification is
+  rechecked. Also fixed wording to have consistent handling for subunits
+  for Pure and Preelaborate. An Ada 95 program could have depended on
+  marking a generic pure that was not really pure, although this
+  would defeat the purpose of the categorization and likely cause
+  problems with distributed programs.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0035-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada address@hidden<Correction:>
+  Adjusted wording so that a subunit can be pure (it is not a
+  @nt<library_item>, but it is a compilation unit).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0035-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Adjusted wording so
+  that the rules for access types only apply to nonderived types
+  (derived types share their storage pool with their parent, so if
+  the parent access type is legal, so is any derived type.)]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[Elaborate_Body is now an aspect,
+  so it can be specified by an @nt{aspect_specification} @em
+  although the pragma is still preferred by the Standard.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0243-1]}
+  @ChgAdded{Version=[3],Text=[Pure and Preelaborate are now aspects,
+  so they can be specified by an @nt{aspect_specification} @em
+  although the pragmas are still preferred by the Standard.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0034-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added wording so that
+  a limited view is always treated as pure, no matter what categorization
+  is used for the originating unit. This was undefined in Ada 2005.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0028-1],ARef=[AI05-0221-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Fixed minor issues with
+  preelaborable initialization (PI): null Initialize procedures do not make
+  a type non-PI; formal types with pragma PI can be assumed to have PI;
+  formal extensions are assumed to not have PI; all composite types
+  can have pragma PI (so that the possibility of hidden Initialize routines
+  can be handled); added discriminants of a derived type are not considered
+  in calculating PI.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0219-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified that the 
implementation
+  permission to omit pure subprogram calls does not apply if any part of the
+  parameters or any designated object has a part that is immutably limited.
+  The old wording just said "limited type", which can change via visibility
+  and thus isn't appropriate for dynamic semantics permissions.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0076-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Explicitly stated that 
modifying
+  a library-level constant in a pure package is erroneous. We don't document
+  this as inconsistent as implementations certainly can still do whatever they
+  were previously doing (no change is required); moreover, this case (and many
+  more) were erroneous in Ada 2005 and before, so we're just restoring the
+  previous semantics.]}
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/11.mss 
b/packages/ada-ref-man/source_2012/11.mss
new file mode 100755
index 0000000..6f3f332
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/11.mss
@@ -0,0 +1,2650 @@
address@hidden(11, Root="ada.mss")
+
address@hidden: 2015/04/03 04:12:42 $}
address@hidden
+
address@hidden: e:\\cvsroot/ARM/Source/11.mss,v $}
address@hidden: 1.93 $}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[clause],Old=[section]} defines
+the facilities for dealing with errors or other
+exceptional situations that arise during program execution.]
address@hidden occurrence}
address@hidden,See=(exception)}
address@hidden (an exception)],See=(raise)}
address@hidden (an exception)],See=(raise)}
address@hidden (an exception)],See=(handle)}
address@hidden<Exception>,
+  Text=<An @i(exception) represents a kind of exceptional situation;
+  an occurrence of such a situation (at run time)
+  is called an @i(exception occurrence).
+  @address@hidden, Sec=(an exception)}
+  To @i{raise} an exception is to abandon normal program execution so
+  as to draw attention to the fact that the corresponding situation has
+  arisen.
+  @PDefn2{Term=[handle], Sec=(an exception)}
+  Performing some actions in response to the arising of an exception
+  is called @i{handling} the exception.
+  ]>}
address@hidden
address@hidden, Sec=(an exception occurrence)}
+...or handling the exception occurrence.
address@hidden
address@hidden
+For example, an exception End_Error might
+represent error situations in which an attempt is made to read beyond
+end-of-file. During the execution of a partition, there might be
+numerous occurrences of this exception.
address@hidden
address@hidden
address@hidden (of an exception)}
+When the meaning is clear from the context,
+we sometimes use @lquotes@;@address@hidden@; as a
+short-hand for @lquotes@;exception address@hidden@;
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0043-1],ARef=[AI05-0258-1]}
address@hidden @nt{exception_declaration} declares a name for an exception.
+An exception @Chg{Version=[3],New=[can be],Old=[is]} raised
address@hidden,New=[explicitly (for example,],Old=[initially either]}
+by a @address@hidden,New=[)],Old=[]}
address@hidden,New=[ implicitly (for example,],Old=[]}
+by the failure of a language-defined address@hidden,New=[)],Old=[]}.
+When an exception arises, control can be transferred to a
+user-provided @nt{exception_handler} at the end of a
address@hidden@address@hidden,
+or it can be propagated to a dynamically enclosing execution.]
address@hidden
+
address@hidden
+We are more explicit about the difference between an exception and an
+occurrence of an exception.
+This is necessary because we now have a type (Exception_Occurrence)
+that represents exception occurrences,
+so the program can manipulate them.
+Furthermore, we say that when an exception is propagated,
+it is the same occurrence that is being propagated
+(as opposed to a new occurrence of the same exception).
+The same issue applies to a re-raise statement.
+In order to understand these semantics,
+we have to make this distinction.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0043-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Generalized the 
introductory
+  description of how an exception can be raised so that it does not appear
+  to cover all of the cases.]}
address@hidden
+
+
address@hidden Declarations}
+
address@hidden
address@hidden
+An @nt{exception_declaration} declares a name for an
+exception.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<exception_declaration>,rhs="@Syn2{defining_identifier_list} : 
@address@hidden,New=<
+   address@hidden>,Old=[]};"}
address@hidden
+
address@hidden
+Each single @nt{exception_declaration} declares a name for a different
+exception. If a generic unit includes an @nt{exception_declaration},
+the @nt{exception_declaration}s implicitly generated by
+different instantiations of the generic unit refer to distinct
+exceptions (but all have the same @nt{defining_identifier}).
+The particular exception denoted by an exception name is determined at
+compilation time and is the same regardless of how many times the
address@hidden is elaborated.
address@hidden
+We considered removing this requirement
+inside generic bodies,
+because it is an implementation burden for implementations
+that wish to share code among several instances.
+In the end, it was decided that it
+would introduce too much implementation dependence.
address@hidden
address@hidden
+Hence, if an @nt{exception_declaration} occurs in a recursive
+subprogram, the exception name denotes the same exception for all
+invocations of the recursive subprogram.
+The reason for this rule is that we allow an exception occurrence to
+propagate out of its declaration's innermost containing master;
+if exceptions were created by their declarations like other entities,
+they would presumably be destroyed upon leaving the master;
+we would have to do something special to prevent them from
+propagating to places where they no longer exist.
address@hidden
address@hidden
+Exception identities are unique across all partitions of a
+program.
address@hidden
+
address@hidden exception}
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,Sec=(raised by failure of run-time check)}
+The @i{predefined} exceptions are the ones declared in the
+declaration of package Standard:
+Constraint_Error, Program_Error,
+Storage_Error, and address@hidden;
+one of them is raised when a language-defined check fails.]
address@hidden
+The exceptions declared in the
+language-defined package IO_Exceptions, for example,
+are not predefined.
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(exception_declaration)}
+The elaboration of an @nt{exception_declaration} has no effect.
+
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+The execution of any construct raises Storage_Error if there is
+insufficient storage for that execution.
address@hidden
+The amount of storage needed for the execution of constructs is
+unspecified.
address@hidden
+Note that any execution whatsoever can raise Storage_Error.
+This allows much implementation freedom in storage management.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of user-defined exception declarations:}
address@hidden
+Singular : @key[exception];
+Error    : @key[exception];
+Overflow, Underflow : @key[exception];
address@hidden
address@hidden
+
address@hidden
address@hidden with Ada 83}
+The exception Numeric_Error is now defined in the Obsolescent
+features Annex, as a rename of Constraint_Error.
+All checks that raise Numeric_Error in Ada 83
+instead raise Constraint_Error in Ada 95.
+To increase upward compatibility,
+we also changed the rules to allow the same exception to be named
+more than once by a given handler.
+Thus,
address@hidden@;@key[when] Constraint_Error | Numeric_Error =>@rquotes@; will 
remain
+legal in Ada 95,
+even though Constraint_Error and Numeric_Error now denote the same
+exception. However, it will not be legal to have
+separate handlers for Constraint_Error and Numeric_Error.
+This change is inconsistent in the rare case that an
+existing program explicitly raises Numeric_Error at a point where
+there is a handler for Constraint_Error;
+the exception will now be caught by that handler.
address@hidden
+
address@hidden
+We explicitly define elaboration for @nt{exception_declaration}s.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a 
@nt{exception_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Handlers}
+
address@hidden
address@hidden response to one or more exceptions is specified by an
address@hidden
address@hidden
+
address@hidden
address@hidden<handled_sequence_of_statements>,rhs="
+     @Syn2{sequence_of_statements}
+  address@hidden
+     @Syn2{exception_handler}
+    address@hidden"}
+
+
address@hidden<exception_handler>,rhs="
+  @key{when} address@hidden:] @Syn2{exception_choice} {| 
@Syn2{exception_choice}} =>
+     @Syn2{sequence_of_statements}"}
+
address@hidden<choice_parameter_specification>,rhs="@Syn2{defining_identifier}"}
+
address@hidden<exception_choice>,rhs="@address@hidden | @key{others}"}
address@hidden
address@hidden
address@hidden@;@address@hidden@; is an abbreviation for 
@lquotes@;@address@hidden@;
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden<choice>, Sec=<of an @nt{exception_handler}>}
+Within this @Chg{Version=[3],New=[clause],Old=[section]}, we sometimes
+abbreviate
address@hidden@;@address@hidden@; to @lquotes@;@address@hidden@;
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI12-0022-1]}
address@hidden,Text=[An @address@hidden of an
address@hidden shall denote an exception.]}
+
address@hidden<cover>, Sec=<of a choice and an exception>}
+A choice with an
address@hidden@nt{name} @i{covers} the named exception.
+A choice with @key{others} covers all exceptions
+not named by previous choices of the same
address@hidden@address@hidden
+Two choices in different @nt<exception_handler>s of the same
address@hidden@address@hidden shall not cover the same
+exception.
address@hidden
+  Two @nt<exception_choice>s of the same @nt<exception_handler> may cover
+  the same exception. For example, given two renaming declarations in
+  separate packages for the same exception, one may nevertheless
+  write, for example,
+  @lquotes@;@key[when] Ada.Text_IO.Data_Error | My_Seq_IO.Data_Error 
=>@rquotes@;.
+
+  An @key{others} choice even covers exceptions that are not
+  visible at the place of the handler.
+  Since exception raising is a dynamic activity,
+  it is entirely possible for an @key{others} handler to handle an
+  exception that it could not have named.
address@hidden
+
+A choice with @key{others} is allowed only for the
+last handler of a @nt{handled_sequence_of_statements}
+and as the only choice of that handler.
+
+An @address@hidden of a choice shall not denote an
+exception declared in a generic formal package.
address@hidden
+This is because the compiler doesn't know the identity of such an
+exception, and thus can't enforce the coverage rules.
address@hidden
address@hidden
+
address@hidden
address@hidden parameter}
+A @nt{choice_parameter_specification} declares a
address@hidden parameter}, which is a constant object of type
+Exception_Occurrence (see @RefSecNum{The Package Exceptions}).
+During the handling of an exception occurrence,
+the choice parameter, if any, of the handler
+represents the exception occurrence that is being handled.
+
address@hidden
+
address@hidden
address@hidden, Sec=(handled_sequence_of_statements)}
+The execution of a @nt<handled_sequence_of_statements> consists
+of the execution of the @nt<address@hidden>.
address@hidden optional handlers are used to handle any exceptions
+that are propagated by the @address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of an exception handler:}
address@hidden
address@hidden
+   Open(File, In_File, "input.txt");   address@hidden see @RefSecNum{File 
Management}]
address@hidden
+   @key[when] E : Name_Error =>
+      Put("Cannot open input file : ");
+      Put_Line(Exception_Message(E));  address@hidden see @RefSecNum{The 
Package Exceptions}]
+      @key[raise];
address@hidden;
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax rule for @nt{exception_handler} is modified to
+allow a @nt{choice_parameter_specification}.
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+Different @Chg{Version=[2],address@hidden,address@hidden<choice>s]}
+of the same @nt<exception_handler> may
+cover the same exception. This allows for
address@hidden@;when Numeric_Error | Constraint_Error =>@rquotes@; even though
+Numeric_Error is a rename of Constraint_Error.
+This also allows one to @lquotes@;address@hidden@; two different I/O packages,
+and then write, for example,
address@hidden@;when Ada.Text_IO.Data_Error | My_Seq_IO.Data_Error =>@rquotes@;
+even though these might both be renames of the same exception.
address@hidden
+
address@hidden
+The syntax rule for @nt{handled_sequence_of_statements} is new.
+These are now used in all the places where handlers
+are allowed.
+This obviates the need to explain
+(in @Chg{Version=[3],New=[Clauses],Old=[Sections]} 5, 6, 7, and 9)
+what portions of the program are handled by the handlers.
+Note that there are more such cases in Ada 95.
+
+The syntax rule for @nt{choice_parameter_specification} is new.
address@hidden
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,New=[Raise Statements and Raise Expressions],Old=[Raise 
Statements]}
+
address@hidden
address@hidden @nt{raise_statement} raises an exception.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00361-01]}
address@hidden<raise_statement>,rhs="@Chg{Version=[2],New=<@key{raise};
+      | @key{raise} @address@hidden address@hidden @address@hidden;>,
+Old=<@key{raise} address@hidden@Syn2{name}];>}"}
+
address@hidden,Kind=[Added],ARef=[AI12-0022-1],ARef=[AI12-0152-1]}
address@hidden,lhs=<@Chg{Version=[4],New=<raise_expression>,Old=<>}>,rhs="@Chg{Version=[4],New=<@key{raise}
 @address@hidden address@hidden @address@hidden>,Old=<>}"}
+
address@hidden,Kind=[Added],ARef=[AI12-0152-1]}
address@hidden,Type=[Leading],Text=[If a @nt{raise_expression} appears
+within the @nt{expression} of one of the following
+contexts, the @nt{raise_expression} shall appear within a pair of parentheses
+within the @nt{expression}:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden;]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden;]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden;]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden;]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden;]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden;]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Text=[Unlike conditional expressions, this doesn't
+  say "immediately surrounded"; the only requirement is that it is somehow
+  within a pair of parentheses that is part of the @nt{expression}. We need
+  this restriction in order that @nt{raise_expression}s cannot be syntactically
+  confused with immediately following constructs (such as
+  @nt{aspect_specification}s).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Text=[We only need to require that a right parenthesis
+  appear somewhere between the @nt{raise_expression} and the surrounding
+  context; that's all we need to specify in order to eliminate the ambiguities.
+  Moreover, we don't care at all where the left parenthesis is (so long as it
+  is legal, of course).]}
+
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Type=[Leading],Text=[For instance, the following is
+  illegal by this rule:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[Obj : Boolean := Func_Call @key[or else raise] TBD_Error 
@key[with] Atomic;]}
address@hidden
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Type=[Leading],Text=[as the "@key[with] Atomic" could
+  be part of the @key[raise_expression] or part of the object declaration.
+  Both of the following are legal:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[Obj : Boolean := Func_Call @key[or else] (@key[raise] 
TBD_Error) @key[with] Atomic;
+Obj : Boolean := (Func_Call @key[or else raise] TBD_Error) @key[with] Atomic;]}
address@hidden
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Type=[Leading],Text=[and if the @key[with] belongs to
+  the @nt{raise_expression}, then both of the following are legal:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[Obj : Boolean := Func_Call @key[or else] (@key[raise] 
TBD_Error @key[with] Atomic);
+Obj : Boolean := (Func_Call @key[or else raise] TBD_Error @key[with] Atomic);]}
address@hidden
+
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Type=[Leading],Text=[This rule only requires
+  parentheses for @nt{raise_expression}s that are
+  part of the "top-level" of an @nt{expression} in one of the named contexts;
+  the @nt{raise_expression} is either the entire @nt{expression}, or part of a
+  chain of logical operations. In practice, the @nt{raise_expression} will
+  almost always be last in interesting top-level @nt{expression}s; anything
+  that follows it could never be executed, so that should be rare.
+  Other contexts such as conditional
+  expressions, qualified expressions, aggregates, and even function calls,
+  provide the needed parentheses. All of the following are legal, no
+  additional parens are needed:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[Pre : Boolean  := (@key[if not] Is_Valid(Param) @key[then 
raise] Not_Valid_Error);
+A : A_Tagged   := (Some_Tagged'(@key[raise] TBD_Error) @key[with] Comp => 'A');
+B : Some_Array := (1, 2, 3, @key[others] => @key[raise] Not_Valid_Error);
+C : Natural    := Func (Val => @key[raise] TBD_Error);]}
address@hidden
+
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Type=[Leading],Text=[Parentheses that are part of
+  the context of the @nt{expression} don't count.
+  For instance, the parentheses around the @nt{raise_expression} are required
+  in the following:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[D : A_Tagged   := ((@key[raise] TBD_Error) @key[with] Comp 
=> 'A');]}
address@hidden
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Text=[as @nt{ancestor_part} is one of the contexts
+  that triggers the rule.]}
+
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Text=[This English-language rule could have been
+  implemented instead by adding nonterminals @ntf{initial_expression} and
+  @ntf{initial_relation}, which are the same as @nt{choice_expression} and
+  @nt{choice_relation} except for the inclusion of membership in
+  @ntf{initial_relation}. Then, @ntf{initial_expresion} could be used in
+  place of @nt{expression} in all of the contexts noted. We did not do that
+  because of the large amount of change required, both to the grammar and
+  to language rules that refer to the grammar. A complete grammar is given
+  in @AILink{AI=[AI12-0152-1],Text=[AI12-0152-1]}.]}
+
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Text=[The use of a @nt{raise_expression} is illegal
+  in each of @nt{modular_type_definition}, @nt{floating_point_definition},
+  @nt{ordinary_fixed_point_definition}, and @nt{decimal_fixed_point_definition}
+  as these uses are required to be static and a @nt{raise_expression} is never
+  static. We include these in this rule so that Ada text has an unambiguous
+  syntax in these cases.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI12-0022-1],ARef=[AI12-0159-1]}
+The @Chg{Version=[4],address@hidden<exception_>@nt{name}],address@hidden, if
+any, @Chg{Version=[4],New=[of],Old=[in]} a @nt{raise_statement}
address@hidden,New=[or @nt{raise_expression} ],Old=[]}shall denote an exception.
address@hidden statement}
+A @nt{raise_statement} with no @address@hidden
+(that is, a @i{re-raise statement})
+shall be within a handler,
+but not within a body enclosed by that handler.
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00361-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0022-1],ARef=[AI12-0152-1]}
address@hidden,Text=[The
address@hidden,address@hidden@nt{expression} or
address@hidden@nt{simple_expression}],address@hidden<expression>]}, if any,
address@hidden,New=[of],Old=[in]} a
address@hidden<raise_statement>@Chg{Version=[4],New=[ or 
@nt{raise_expression}],Old=[,]}
+is expected to be of type String.]}
+
address@hidden,Kind=[Added],ARef=[AI12-0022-1],ARef=[AI12-0159-1]}
address@hidden,Text=[The expected type for a @nt{raise_expression}
+shall be any single type.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00361-01]}
address@hidden,Kind=[Revised],ARef=[AI12-0022-1],ARef=[AI12-0152-1]}
address@hidden, Sec=(an exception)}
+To @i(raise an exception) is to
+raise a new occurrence of that address@hidden,
+as explained in @RefSecNum{Exception Handling}].
address@hidden, Sec=(raise_statement with an exception_name)}
+For the execution of a @nt{raise_statement} with an
address@hidden@nt{name}, the named exception is
address@hidden,New=[ Similarly, for the evaluation of a @nt{raise_expression},
+the named exception is raised.],Old=[]}
address@hidden,address@hidden@Chg{Version=[4],New=[In
+both of these cases, if],Old=[If]} a @SynI<string_>@nt<expression>
address@hidden,New=[or @SynI<string_>@nt<simple_expression> ],Old=[]}is present,
+the @Chg{Version=[4],New=[expression],address@hidden
+is evaluated and its value is associated with the exception 
occurrence.}],Old=[]}
address@hidden, Sec=(re-raise statement)}
+For the execution of a re-raise statement,
+the exception occurrence that caused transfer of control to the
+innermost enclosing handler is raised @Redundant[again].
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00361-01]}
address@hidden,Text=[The definition of Exceptions.Exception_Message
+includes a statement that the string is returned (see
address@hidden Package Exceptions}). We describe the use of the string
+here so that we don't have an unexplained parameter in this subclause.]}
address@hidden
address@hidden
+For a re-raise statement, the implementation does not create a new
+Exception_Occurrence, but instead propagates the same
+Exception_Occurrence value.
+This allows the original cause of the exception to be determined.
address@hidden
address@hidden
+
address@hidden
+  
@ChgRef{Version=[4],Kind=[Added],Aref=[AI12-0062-1],Aref=[AI12-0152-1],ARef=[AI12-0159-1]}
+  @ChgAdded{Version=[4],Text=[If the evaluation of a
+  @SynI<string_>@nt{expression} or @SynI<string_>@nt{simple_expression} raises
+  an exception, that exception is
+  propagated instead of the one denoted by the @SynI<exception_>@nt{name}
+  of the @nt{raise_statement} or @nt{raise_expression}.]}
address@hidden
+
address@hidden
address@hidden@address@hidden of raise statements:}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden Ada.IO_Exceptions.Name_Error;   address@hidden see 
@RefSecNum{Exceptions In address@hidden,New=[
address@hidden Queue_Error @key[with] "Buffer Full"; address@hidden see 
@RefSecNum{Example of Tasking and Synchronization}]],Old=[]}
+
address@hidden;                                address@hidden re-raise the 
current exception]
address@hidden
address@hidden
+
address@hidden
+The fact that the @nt{name} in a @nt{raise_statement} has to denote
+an exception is not clear from RM83.
+Clearly that was the intent,
+since the italicized part of the syntax rules so indicate,
+but there was no explicit rule.
+RM83-1.5(11) doesn't seem to give the italicized parts of the syntax
+any force.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00361-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}The syntax of a
+  @nt{raise_statement} is extended to include a string message. This is more
+  convenient than calling Exceptions.Exception_Message
+  (@address@hidden'Identity, @address@hidden), and
+  should encourage the use of message strings when raising exceptions.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0022-1],ARef=[AI12-0152-1],ARef=[AI12-0159-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada address@hidden<Corrigendum:>
+  The @nt{raise_expression} is new. This construct is necessary to
+  allow conversion of existing specifications to use preconditions and
+  predicates without changing the exceptions raised. It is considered important
+  enough to be added to Ada 2012 rather than waiting for Ada 202x.]}
address@hidden
+
+
address@hidden Handling}
+
address@hidden
address@hidden an exception occurrence is raised,
+normal program execution is abandoned
+and control is transferred to an applicable @nt{exception_handler},
+if any.
address@hidden, Sec=(an exception occurrence)}
+To @i(handle) an exception occurrence is to respond to the
+exceptional event.
address@hidden
+To @i(propagate) an exception occurrence is to raise it again in
+another context; that is,
+to fail to respond to the exceptional event in the present context.]
address@hidden
+In other words, if the execution of a given construct raises an exception,
+but does not handle it,
+the exception is propagated to an enclosing execution
+(except in the case of a @nt{task_body}).
+
address@hidden,address@hidden AI-00023}
+Propagation involves re-raising the same exception address@hidden,
+Old=[(assuming the implementation has not taken advantage of the
address@hidden of @RefSecNum{Raise Statements and Raise Expressions})]}.
+For example, calling an entry of an uncallable task raises
+Tasking_Error; this is not propagation.
address@hidden
address@hidden
+
address@hidden
address@hidden enclosing], Sec=(of one execution by another)}
address@hidden, Sec=(dynamically enclosing)}
+Within a given task, if the
+execution of construct @i{a} is defined by this International Standard
+to consist (in part) of the
+execution of construct @i{b}, then while @i{b} is executing, the
+execution of @i{a} is said to @i(dynamically enclose) the execution of
address@hidden
address@hidden dynamically enclosing}
+The @i(innermost
+dynamically enclosing) execution of a given execution is the
+dynamically enclosing execution that started most recently.
address@hidden
address@hidden, Sec=(one execution by another)}
address@hidden, Sec=(included by another execution)}
+If the execution of @i{a} dynamically encloses that of @i{b},
+then we also say that the execution of @i{b} is
address@hidden in} the execution of @i{a}.
address@hidden
address@hidden
+Examples: The execution of an @nt{if_statement}
+dynamically encloses the evaluation of the @nt{condition} after the
address@hidden (during that evaluation).
+(Recall that @lquotes@;address@hidden@; includes both 
@lquotes@;address@hidden@; and
address@hidden@;address@hidden@;, as well as other executions.)
+The evaluation of a function call dynamically encloses the execution
+of the @nt{sequence_of_statements} of the function @nt{body}
+(during that execution). Note that, due to recursion, several
+simultaneous executions of the same construct can be occurring at once
+during the execution of a particular task.
+
+Dynamically enclosing is not defined across task boundaries;
+a task's execution does not include the execution of any other tasks.
+
+Dynamically enclosing is only defined for executions that are occurring
+at a given moment in time; if an @nt{if_statement} is currently
+executing the @nt{sequence_of_statements} after @key{then}, then
+the evaluation of the @nt{condition} is no longer dynamically
+enclosed by the execution of the @nt{if_statement} (or anything else).
address@hidden
+
address@hidden@Defn2{Term=[raise], Sec=(an exception occurrence)}
+When an exception occurrence is raised by the execution of a given
+construct, the rest of the execution of that construct is @i{abandoned};
+that is, any portions of the execution that have not yet taken place
+are not performed.
+The construct is first completed, and then left, as explained
+in @RefSecNum{Completion and Finalization}.
+Then:
address@hidden
+If the construct is a @nt<task_body>,
+the exception does not propagate further;
address@hidden
+  When an exception is raised by the execution of a
+  @nt{task_body}, there is no dynamically enclosing execution,
+  so the exception does not propagate any further.
+  If the exception occurred during
+  the activation of the task, then the activator raises Tasking_Error,
+  as explained in @RefSec{Task Execution - Task Activation},
+  but we don't define that as propagation; it's a special rule.
+  Otherwise (the exception occurred during the execution of the
+  @nt{handled_sequence_of_statements} of the task),
+  the task silently disappears.
+  Thus, abnormal termination of tasks is not always considered to be an
+  error.
address@hidden
+
+If the construct is the @nt{sequence_of_statements} of a
address@hidden that has a
+handler with a choice covering the exception,
+the occurrence is handled by that handler;
+
address@hidden,
+Sec=(an exception occurrence by an execution, to a dynamically enclosing 
execution)}
+Otherwise, the occurrence is @i{propagated}
+to the innermost dynamically enclosing execution,
+which means that the occurrence is raised again
+in that context.
address@hidden
address@hidden, Sec=(an exception by an execution)}
address@hidden, Sec=(an exception by a construct)}
+As shorthands, we refer to the @i{propagation of an exception},
+and the @i{propagation by a construct},
+if the execution of the construct propagates an exception occurrence.
address@hidden
address@hidden
+
address@hidden, Sec=(an exception occurrence)}
address@hidden, Sec=(handler)}
address@hidden, Sec=(choice_parameter_specification)}
+When an occurrence is @i(handled) by a given handler,
+the @nt{choice_parameter_specification}, if any, is first elaborated,
+which creates the choice parameter and initializes it to the occurrence.
+Then, the @nt{sequence_of_statements} of the
+handler is executed;
+this execution replaces the abandoned portion of the execution of
+the @nt{sequence_of_statements}.
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00318-02]}
+  This @lquotes@;address@hidden@; semantics implies that the handler can
+  do pretty much anything the abandoned sequence could do; for example, in a
+  function, the handler can execute a @Chg{Version=[2],New=[return statement],
+  address@hidden that applies to the function.
address@hidden
address@hidden
+The rules for exceptions raised in library units,
+main subprograms and partitions follow from the normal rules,
+plus the semantics of the environment task
+described in @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden Structure and Compilation Issues} (for example, the
+environment task of a partition elaborates library units and calls
+the main subprogram).
+If an exception is propagated by the main subprogram, it is
+propagated to the environment task, which then terminates abnormally,
+causing the partition to terminate abnormally.
+Although abnormal termination of tasks is not necessarily an error,
+abnormal termination of a partition due to an exception @i{is} an
+error.
address@hidden
address@hidden
+
address@hidden
+Note that exceptions raised in a @nt{declarative_part} of a body
+are not handled by the handlers of the
address@hidden@address@hidden of that body.
address@hidden
+
address@hidden Package Exceptions}
+
address@hidden
address@hidden@keepnext@;The following language-defined library package exists:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00362-01],ARef=[AI95-00400-01],ARef=[AI95-00438-01]}
address@hidden,address@hidden,address@hidden Ada.Streams;
+],address@hidden Ada.Exceptions @address@hidden,New=[
+    @key[pragma] Preelaborate(Exceptions);],Old=[]}
+    @key[type] @AdaTypeDefn{Exception_Id} @key[is] 
@key[private];@Chg{Version=[2],New=[
+    @key[pragma] Preelaborable_Initialization(Exception_Id);],Old=[]}
+    @AdaObjDefn{Null_Id} : @key[constant] Exception_Id;
+    @key[function] @AdaSubDefn{Exception_Name}(Id : Exception_Id) @key[return] 
String;@Chg{Version=[2],New=[
+    @key[function] @AdaSubDefn{Wide_Exception_Name}(Id : Exception_Id) 
@key[return] Wide_String;
+    @key[function] @AdaSubDefn{Wide_Wide_Exception_Name}(Id : Exception_Id)
+        @key[return] Wide_Wide_String;],Old=[]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00362-01]}
+    @key[type] @AdaTypeDefn{Exception_Occurrence} @key[is] @key[limited] 
@key[private];@Chg{Version=[2],New=[
+    @key[pragma] Preelaborable_Initialization(Exception_Occurrence);],Old=[]}
+    @key[type] @AdaTypeDefn{Exception_Occurrence_Access} @key[is] @key[access] 
@key[all] Exception_Occurrence;
+    @AdaObjDefn{Null_Occurrence} : @key[constant] Exception_Occurrence;
+
address@hidden,Kind=[Revised],ARef=[AI95-00329-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+    @key[procedure] @AdaSubDefn{Raise_Exception}(E : @key[in] Exception_Id;
+                              Message : @key[in] String := 
"")@Chg{Version=[3],New=[],Old=[;address@hidden,New=[
+        @Chg{Version=[3],address@hidden,address@hidden 
address@hidden,New=[],Old=[(Raise_Exception)]};],Old=[]}
+    @key[function] @AdaSubDefn{Exception_Message}(X : Exception_Occurrence) 
@key[return] String;
+    @key[procedure] @AdaSubDefn{Reraise_Occurrence}(X : @key[in] 
Exception_Occurrence);
+
address@hidden,Kind=[Revised],ARef=[AI95-00400-01]}
+    @key[function] @AdaSubDefn{Exception_Identity}(X : Exception_Occurrence)
+                                @key[return] Exception_Id;
+    @key[function] @AdaSubDefn{Exception_Name}(X : Exception_Occurrence) 
@key[return] String;
+        address@hidden Same as 
Exception_Name(Exception_Identity(X))address@hidden,New=[
+    @key[function] @AdaSubDefn{Wide_Exception_Name}(X : Exception_Occurrence)
+        @key[return] Wide_String;
+        address@hidden Same as Wide_Exception_Name(Exception_Identity(X)).}
+    @key[function] @AdaSubDefn{Wide_Wide_Exception_Name}(X : 
Exception_Occurrence)
+        @key[return] Wide_Wide_String;
+        address@hidden Same as 
Wide_Wide_Exception_Name(Exception_Identity(X)).}],Old=[]}
+    @key[function] @AdaSubDefn{Exception_Information}(X : 
Exception_Occurrence) @key[return] String;
+
address@hidden,Kind=[Revised],ARef=[AI95-00438-01]}
+    @key[procedure] @AdaSubDefn{Save_Occurrence}(Target : @key[out] 
Exception_Occurrence;
+                              Source : @key[in] Exception_Occurrence);
+    @key[function] @AdaSubDefn{Save_Occurrence}(Source : Exception_Occurrence)
+                             @key[return] 
Exception_Occurrence_Access;@Chg{Version=[2],New=[],Old=[
address@hidden
+   ... address@hidden not specified by the language}
address@hidden Ada.Exceptions;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00438-01]}
address@hidden,Text=[    @key[procedure] Read_Exception_Occurrence
+       (Stream : @key[not null access] Ada.Streams.Root_Stream_Type'Class;
+        Item   : @key[out] Exception_Occurrence);
+    @key[procedure] Write_Exception_Occurrence
+       (Stream : @key[not null access] Ada.Streams.Root_Stream_Type'Class;
+        Item   : @key[in] Exception_Occurrence);]}
+
address@hidden,Kind=[Added],ARef=[AI95-00438-01]}
address@hidden,Text=[    @key[for] Exception_Occurrence'Read @key[use] 
Read_Exception_Occurrence;
+    @key[for] Exception_Occurrence'Write @key[use] 
Write_Exception_Occurrence;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00438-01]}
address@hidden,address@hidden
+   ... address@hidden not specified by the language}
address@hidden Ada.Exceptions;]}
address@hidden
+
+Each distinct exception is represented by a distinct value
+of type Exception_Id.
+Null_Id does not represent any exception,
+and is the default initial value of type Exception_Id.
+Each occurrence of an exception is represented by a
+value of type Exception_Occurrence.
+Null_Occurrence does not represent any exception occurrence,
+and is the default initial value of type Exception_Occurrence.
+
address@hidden,address@hidden be consistent with 8652/0006}
address@hidden@;For @ChgPrefixType{Version=[1],Kind=[Revised],Text=[a
address@hidden@nt{prefix}],Old=[prefix]} E that denotes an exception]},
+the following attribute is defined:
address@hidden
address@hidden<E>, AttrName=<Identity>,
+  Text=[E'Identity returns the unique identity of the exception.
+        The type of this attribute is Exception_Id.]}
address@hidden
+In a distributed program,
+the identity is unique across an entire program,
+not just across a single partition.
+Exception propagation works properly across RPC's.
+An exception can be propagated from one partition to another,
+and then back to the first, where its identity is known.
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00361-01]}
+Raise_Exception raises a new occurrence of the identified
address@hidden,New=[],Old=[ In this case
+Exception_Message returns the Message parameter of Raise_Exception.
+For a @nt{raise_statement} with an @address@hidden,
+Exception_Message returns implementation-defined information
+about the exception occurrence.
+Reraise_Occurrence reraises the specified exception occurrence.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00361-01],ARef=[AI95-00378-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0043-1],ARef=[AI05-0248-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0022-1],ARef=[AI12-0152-1]}
address@hidden,Text=[Exception_Message returns the message associated
+with the given Exception_Occurrence. For an occurrence raised by a call to
+Raise_Exception, the message is the Message parameter passed to 
Raise_Exception.
+For the occurrence raised by a @nt{raise_statement}
address@hidden,New=[or @nt{raise_expression} ],Old=[]}with an
address@hidden@nt{name} and a @address@hidden@Chg{Version=[4],New=[
+or @address@hidden,Old=[]}, the message is
+the @address@hidden@Chg{Version=[4],New=[
+or @address@hidden,Old=[]}. For the occurrence raised by a
address@hidden @Chg{Version=[4],New=[or @nt{raise_expression} ],Old=[]}with
+an @address@hidden but without a @address@hidden@Chg{Version=[4],New=[
+or @address@hidden,Old=[]},
+the message is a string giving implementation-defined information about the
+exception occurrence. @Chg{Version=[3],New=[For an occurrence originally raised
+in some other manner (including by the failure of a language-defined check),
+the message is an unspecified
address@hidden ],Old=[]}In all cases, Exception_Message
+returns a string with lower bound 1.]}
address@hidden information returned by Exception_Message.}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0043-1]}
+  @ChgAdded{Version=[3],Text=[There is @ImplAdviceName about the contents
+  of this string for language-defined checks.]}
address@hidden
address@hidden
address@hidden@Keepnext@;Given an exception E, the @nt{raise_statement}:
address@hidden
address@hidden E;
address@hidden
+
address@hidden@keepnext@;is equivalent to this call to Raise_Exception:
address@hidden
+Raise_Exception(E'Identity, Message => @RI{implementation-defined-string});
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00361-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[Similarly, the
address@hidden:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden E @key[with] "some information";]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[is equivalent to
+this call to Raise_Exception:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[Raise_Exception(E'Identity, Message => "some 
information");]}
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00361-01]}
address@hidden,Text=[Reraise_Occurrence reraises the specified exception
+occurrence.]}
+
address@hidden
address@hidden@keepnext@;The following handler:
address@hidden
address@hidden @key[others] =>
+    Cleanup;
+    @key[raise];
address@hidden
+
address@hidden
address@hidden@keepnext@;is equivalent to this one:
address@hidden
address@hidden
address@hidden X : @key[others] =>
+    Cleanup;
+    Reraise_Occurrence(X);
address@hidden
+
address@hidden
+
+Exception_Identity returns the identity of the exception of the
+occurrence.
+
address@hidden,Kind=[Revised],ARef=[AI95-00400-01]}
+The @Chg{Version=[2],address@hidden@!Exception_Name],Old=[Exception_Name]}
+functions return
+the full expanded name of the exception, in upper case, starting with a root
+library unit. For an exception declared immediately within package Standard,
+the @address@hidden is returned.
+The result is implementation defined if the exception is declared within
+an unnamed @nt{block_statement}.
address@hidden
+  See the @ImplPermName below.
address@hidden
address@hidden
+  This name, as well as each @nt{prefix} of it,
+  does not denote a @nt{renaming_declaration}.
address@hidden
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[The result of @Chg{Version=[2],
address@hidden@address@hidden@!Name],address@hidden@!Name]}
+for @Chg{Version=[2],New=[exceptions],Old=[types]} declared within
+an unnamed @nt{block_statement}.]}
address@hidden
+  Note that we're talking about the name of the exception,
+  not the name of the occurrence.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00400-01]}
address@hidden,Text=[The Exception_Name functions (respectively,
+Wide_Exception_Name) return the same sequence of graphic characters as that
+defined for Wide_Wide_Exception_Name, if all the graphic characters are defined
+in Character (respectively, Wide_Character); otherwise, the sequence of
+characters is implementation defined, but no shorter than that returned by
+Wide_Wide_Exception_Name for the same value of the argument.]}
address@hidden,Kind=[AddedNormal],address@hidden,New=[
+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).],Old=[]}]}
+
address@hidden,Kind=[Added],ARef=[AI95-00378-01],ARef=[AI95-00417-01]}
address@hidden,Text=[The string returned by the Exception_Name,
+Wide_Exception_Name, and Wide_Wide_Exception_Name functions has lower bound 
1.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00378-01]}
+Exception_Information returns implementation-defined information
+about the exception occurrence.
address@hidden,New=[The returned string has lower bound 1.],Old=[]}
address@hidden information returned by Exception_Information.}
+
address@hidden,Kind=[Revised],ARef=[AI95-00241-01],ARef=[AI95-00446-01]}
address@hidden,New=[],Old=[Raise_Exception and ]}Reraise_Occurrence
address@hidden,New=[has],Old=[have]} no effect in the case of
address@hidden,New=[],Old=[Null_Id or ]}Null_Occurrence.
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,New=[Raise_Exception and Exception_Name raise Constraint_Error
+for a Null_Id. Exception_Message, Exception_Name, and Exception_Information
+raise Constraint_Error for a Null_Occurrence. Exception_Identity applied
+to Null_Occurrence returns Null_Id.],
+Old=[Exception_Message, Exception_Identity, Exception_Name, and
+Exception_Information
+raise Constraint_Error for a Null_Id or Null_Occurrence.]}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00241-01]}
address@hidden,Text=[Null_Occurrence can be tested for by comparing
+Exception_Identity(Occurrence) to Null_Id.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00446-01]}
address@hidden,Text=[Raise_Exception was changed so that it always
+raises an exception and thus can be a No_Return procedure. A similar change
+was not made for Reraise_Occurrence, as doing so was determined to be a
+significant incompatibility. It is not unusual to pass an Exception_Occurrence
+to other code to delay raising it. If there was no exception, passing
+Null_Occurrence works fine (nothing is raised). Moreover, as there is no test
+for Null_Occurrence in Ada 95, this is the only way to write such code without
+using additional flags. Breaking this sort of code is unacceptable.]}
address@hidden
+
+The Save_Occurrence procedure copies the Source to the Target.
+The Save_Occurrence function uses an @nt{allocator} of type
+Exception_Occurrence_Access to create a new object,
+copies the Source to this new object,
+and returns an access value designating this new object;
address@hidden result may be deallocated using an instance of
+Unchecked_Deallocation.]
address@hidden
+It's OK to pass Null_Occurrence to the Save_Occurrence
+subprograms;
+they don't raise an exception,
+but simply save the Null_Occurrence.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00438-01]}
address@hidden,Text=[Write_Exception_Occurrence writes a representation
+of an exception occurrence to a stream; Read_Exception_Occurrence reconstructs
+an exception occurrence from a stream (including one written in a different
+partition).]}
address@hidden of these notes (except the first) are moved from below.}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This routines are used to define the stream
+  attributes (see @RefSecNum{Stream-Oriented Attributes}) for
+  Exception_Occurrence.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The identity of the exception,
+  as well as the Exception_Name and Exception_Message,
+  have to be preserved across partitions.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The string returned by Exception_Name
+  or Exception_Message on the result of calling the Read
+  attribute on a given stream has to be the same as the value returned
+  by calling the corresponding function on the exception occurrence
+  that was written into the stream with the Write attribute.
+  The string returned by Exception_Information need not be
+  the same, since it is implementation defined anyway.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is important for supporting writing 
exception occurrences
+  to external files for post-mortem analysis, as well as
+  propagating exceptions across remote subprogram calls
+  in a distributed system
+  (see @RefSecNum{Remote Subprogram Calls}).]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00438-01]}
address@hidden,Text=[The implementation of the Write attribute
+(see @RefSecNum{Stream-Oriented Attributes})
+of Exception_Occurrence shall support writing
+a representation of an exception occurrence
+to a stream; the implementation of the Read attribute
+of Exception_Occurrence shall support reconstructing
+an exception occurrence from a stream (including one written in
+a different partition).]}
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[The identity of the exception,
+  as well as the Exception_Name and Exception_Message,
+  have to be preserved across partitions.]}
+
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[The string returned by Exception_Name
+  or Exception_Message on the result of calling the Read
+  attribute on a given stream has to be the same as the value returned
+  by calling the corresponding function on the exception occurrence
+  that was written into the stream with the Write attribute.
+  The string returned by Exception_Information need not be
+  the same, since it is implementation defined anyway.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[This is important for supporting writing
+  exception occurrences to external files for post-mortem analysis, as well as
+  propagating exceptions across remote subprogram calls
+  in a distributed system
+  (see @RefSecNum{Remote Subprogram Calls}).]}
address@hidden
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraph 16 was
+deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered.}
address@hidden
+
address@hidden
+An implementation of Exception_Name in a space-constrained
+environment may return the
address@hidden@!identifier} instead of the full expanded name.
+
+
+The string returned by Exception_Message may be truncated (to no less
+than 200 characters) by the Save_Occurrence procedure
address@hidden(not the function)],
+the Reraise_Occurrence procedure,
+and the re-raise statement.
address@hidden
+The reason for allowing truncation is to ease implementations.
+The reason for choosing the number 200 is that this is the minimum
+source line length that implementations have to support,
+and this feature seems vaguely related since it's usually a
address@hidden@;address@hidden@;.
+Note that an implementation is allowed to do this truncation even if it
+supports arbitrarily long lines.
address@hidden
address@hidden
+
address@hidden
+Exception_Message (by default) and Exception_Information should produce
+information useful for debugging.
+Exception_Message should be short (about one line),
+whereas 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.
+
+
address@hidden,Kind=[Added],address@hidden,
+Text=[Exception_Information should provide
+information useful for debugging, and should include the Exception_Name
+and Exception_Message.]}]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Exception_Message by default should be short, provide
+information useful for debugging, and should not include the 
Exception_Name.]}]}
+
address@hidden
+It may seem strange to define two subprograms whose semantics is
+implementation defined.
+The idea is that a program can print out debugging/error-logging
+information in a portable way.
+The program is portable in the sense that it will work in any
+implementation; it might print out different information, but the
+presumption is that the information printed out is appropriate for
+debugging/error analysis on that system.
address@hidden
address@hidden
+As an example, Exception_Information might include
+information identifying the location where the exception
+occurred, and, for predefined exceptions, the specific kind of
+language-defined check that failed.
+There is an implementation trade-off here, between how much
+information is represented in an Exception_Occurrence, and how much
+can be passed through a re-raise.
+
+The string returned should be in a form suitable for printing to an
+error log file.
+This means that it might need to contain line-termination control
+characters with implementation-defined I/O semantics.
+The string should neither start nor end with a newline.
+
+If an implementation chooses to provide additional functionality
+related to exceptions and their occurrences,
+it should do so by providing one or more children of
+Ada.Exceptions.
+
+Note that exceptions behave as if declared at library level;
+there is no @lquotes@;natural address@hidden@; for an exception; an exception 
always
+exists. Hence, there is no harm in saving an exception occurrence in
+a data structure, and reraising it later. The reraise has to occur
+as part of the same program execution, so saving an exception
+occurrence in a file, reading it back in from a different
+program execution, and then reraising it is not required to work.
+This is similar to I/O of access types.
+Note that it is possible to use RPC to propagate exceptions across
+partitions.
+
address@hidden@;Here's one way to implement Exception_Occurrence in the private 
part
+of the package. Using this method, an implementation need store only
+the actual number of characters in exception messages. If the user
+always uses small messages, then exception occurrences can be small.
+If the user never uses messages, then exception occurrences can be
+smaller still:
address@hidden
address@hidden Exception_Occurrence(Message_Length : Natural := 200) @key[is]
+    @key[limited] @key[record]
+        Id : Exception_Id;
+        Message : String(1..Message_Length);
+    @key[end] @key[record];
address@hidden
+
address@hidden@;At the point where an exception is raised, an 
Exception_Occurrence
+can be allocated on the stack with exactly the right amount of space
+for the message @em none for an empty message. This is just like
+declaring a constrained object of the type:
address@hidden
+Temp : Exception_Occurrence(10); address@hidden for a 10-character message}
address@hidden
+
+After finding the appropriate handler, the stack can be cut back,
+and the Temp copied to the right place. This is similar to returning
+an unknown-sized object from a function. It is not necessary to
+allocate the maximum possible size for every Exception_Occurrence.
+If, however, the user declares an Exception_Occurrence object,
+the discriminant will be permanently set to 200. The Save_Occurrence
+procedure would then truncate the Exception_Message. Thus, nothing is
+lost until the user tries to save the occurrence. If the user is
+willing to pay the cost of heap allocation, the Save_Occurrence
+function can be used instead.
+
+Note that any arbitrary-sized implementation-defined Exception_Information can
+be handled in a similar way. For example, if the
+Exception_Occurrence includes a stack traceback, a discriminant can
+control the number of stack frames stored. The traceback would be
+truncated or entirely deleted by the Save_Occurrence procedure @em as
+the implementation sees fit.
+
+If the internal representation involves pointers to data structures
+that might disappear, it would behoove the implementation to
+implement it as a controlled type,
+so that assignment can either copy the data structures or else null
+out the pointers.
+Alternatively, if the data structures being pointed at are in a
+task control block,
+the implementation could keep a unique sequence number
+for each task, so it could tell when a task's data structures no longer
+exist.
+
+Using the above method, heap space is never allocated unless the user
+calls the Save_Occurrence function.
+
address@hidden@;An alternative implementation would be to store the message 
strings
+on the heap when the exception is raised. (It could be the global
+heap, or it could be a special heap just for this purpose @em it
+doesn't matter.)  This representation would be used only for choice
+parameters. For normal user-defined exception occurrences, the
+Save_Occurrence procedure would copy the message string into the
+occurrence itself, truncating as necessary. Thus, in this
+implementation, Exception_Occurrence would be implemented as a
+variant record:
address@hidden
address@hidden Exception_Occurrence_Kind @key[is] (Normal, As_Choice_Param);
+
address@hidden Exception_Occurrence(Kind : Exception_Occurrence_Kind := Normal) 
@key[is]
+    @key[limited] @key[record]
+        @key[case] Kind @key[is]
+            @key[when] Normal =>
+                ... address@hidden space for 200 characters}
+            @key[when] As_Choice_Param =>
+                ... address@hidden pointer to heap string}
+        @key[end] @key[case];
+    @key[end] @key[record];
address@hidden
+
+Exception_Occurrences created by the run-time system during exception
+raising would be As_Choice_Param. User-declared ones would be Normal @em the
+user cannot see the discriminant, and so cannot set it to As_Choice_Param.
+The strings in the heap would be freed upon completion of the
+handler.
+
+This alternative implementation corresponds to a heap-based
+implementation of functions returning unknown-sized results.
+
address@hidden@;One possible implementation of Reraise_Occurrence is as follows:
address@hidden
address@hidden Reraise_Occurrence(X : @key[in] Exception_Occurrence) @key[is]
address@hidden
+    Raise_Exception(Identity(X), Exception_Message(X));
address@hidden Reraise_Occurrence;
address@hidden
+
+However, some implementations may wish to retain more information
+across a re-raise @em a stack traceback, for example.
address@hidden
address@hidden
+Note that Exception_Occurrence is a definite subtype.
+Hence, values of type Exception_Occurrence may be written to
+an error log for later analysis, or may be passed
+to subprograms for immediate error analysis.
address@hidden
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00400-01]}
address@hidden,Text=[If an implementation chooses to have a mode in
+which it supports non-Latin-1 characters in identifiers, then it needs to
+define what the above functions return in the case where the name of an
+exception contains such a character.]}
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+  The Identity attribute of exceptions is new, as is the package
+  Exceptions.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00241-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @B[Amendment Correction:] Exception_Identity of an Exception_Occurrence
+  now is defined to return Null_Id for Null_Occurrence, rather than raising
+  Constraint_Error. This provides a simple way to test for Null_Occurrence.
+  We expect that programs that need Constraint_Error raised will be very rare;
+  they can be easily fixed by explicitly testing for Null_Id or by using
+  Exception_Name instead.]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00378-01],ARef=[AI95-00417-01]}
+  @ChgAdded{Version=[2],Text=<@B[Amendment Correction:] We now define the lower
+  bound of the string returned from [[Wide_]Wide_]Exception_Name,
+  Exception_Message, and Exception_Information. This makes working with the
+  returned string easier, and is consistent with many other string-returning
+  functions in Ada. This is technically an inconsistency; if a program
+  depended on some other lower bound for the string returned from one of
+  these functions, it could fail when compiled with Ada 2005. Such code is
+  not portable even between Ada 95 implementations, so it should be very 
rare.>}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00446-01]}
+  @ChgAdded{Version=[2],address@hidden Correction:]
+  Raise_Exception now raises Constraint_Error if passed Null_Id. This means
+  that it always raises an exception, and thus we can apply pragma No_Return to
+  it. We expect that programs that call Raise_Exception with Null_Id will be
+  rare, and programs that do that and expect no exception to be raised will be
+  rarer; such programs can be easily fixed by explicitly testing for Null_Id
+  before calling Raise_Exception.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00400-01],ARef=[AI95-00438-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  Functions Wide_Exception_Name and Wide_Wide_Exception_Name, and procedures
+  Read_Exception_Occurrence and Write_Exception_Occurrence
+  are @Chg{Version=[3],New=[],Old=[newly ]}added
+  to Exceptions. If Exceptions is referenced in a
+  @nt{use_clause}, and an entity @i<E> with the same @nt{defining_identifier}
+  as a new entity in Exceptions is defined in a
+  package that is also referenced in a @nt{use_clause}, the entity @i<E> may no
+  longer be use-visible, resulting in errors. This should be rare and is easily
+  fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00362-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The package Exceptions is preelaborated, and types Exception_Id and
+  Exception_Occurrence have preelaborable initialization, allowing this package
+  to be used in preelaborated units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00361-01]}
+  @ChgAdded{Version=[2],Text=[The meaning of Exception_Message is reworded to
+  reflect that the string can come from a @nt{raise_statement} as well as a
+  call of Raise_Exception.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00400-01]}
+  @ChgAdded{Version=[2],Text=[Added Wide_Exception_Name and
+  Wide_Wide_Exception_Name
+  because identifiers can now contain characters outside of Latin-1.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0043-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added explicit wording
+  that the exception message for language-defined checks is unspecified.
+  The old wording appeared inclusive, but it was not.]}
address@hidden
+
+
address@hidden,Name=[Pragmas Assert and Assertion_Policy]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0274-1]}
address@hidden,Text=[Pragma Assert is used to assert the truth of a
address@hidden,New=[boolean],Old=[Boolean]} expression at
address@hidden,New=[a],Old=[any]} point within a sequence of declarations or
address@hidden,New=[],Old=[ Pragma Assertion_Policy is used to
+control whether such address@hidden are to be ignored by the
+implementation, checked at run-time, or handled in some implementation-defined
+manner.]}]}
+
address@hidden,Kind=[Added],ARef=[AI05-0274-1]}
address@hidden,Text=[Assert pragmas, subtype predicates (see
address@hidden Predicates}), preconditions and postconditions (see
address@hidden and Postconditions}), and type invariants (see
address@hidden Invariants}) are collectively referred to as
address@hidden; their boolean expressions are referred to as @i{assertion
address@hidden@Defn{assertion expressions}]}
+
address@hidden,Kind=[Added],Term=<Predicate>,
+Text=<@ChgAdded{Version=[3],Text=[A predicate is an assertion
+that is expected to be True for all objects of a given
+subtype.]}>}
+
address@hidden,Kind=[Added],Term=<Precondition>,
+Text=<@ChgAdded{Version=[3],Text=[A precondition is an assertion
+that is expected to be True when a given subprogram is
+called.]}>}
+
address@hidden,Kind=[Added],Term=<Postcondition>,
+Text=<@ChgAdded{Version=[3],Text=[A postcondition is an assertion
+that is expected to be True when a given subprogram returns
+normally.]}>}
+
address@hidden [RevisedAdded],InitialVersion=[3], below, but we don't have that 
implemented yet.}
address@hidden,Kind=[Added],Term=<Invariant>,
+Text=<@ChgAdded{Version=[3],address@hidden,New=[An],Old=[A]} invariant
+is an assertion that is expected
+to be True for all objects of a given private type when viewed from outside the
+defining package.]}>}
+
address@hidden,Kind=[Added],Term=<Type Invariant>,
+Text=<@ChgAdded{Version=[4],Text=[See Invariant.]}>}
+
address@hidden,Kind=[Added],Term=<Assertion>,
+Text=<@ChgAdded{Version=[3],Text=[An assertion is a boolean expression that
+appears in any of the following: a @nt{pragma} Assert, a predicate, a
+precondition, a postcondition, an invariant, a constraint, or a null exclusion.
+An assertion is expected to be True at run time at certain specified 
places.]}>}
+
address@hidden,Kind=[Added],ARef=[AI05-0274-1]}
address@hidden,Text=[Pragma Assertion_Policy is used to control whether
+assertions are to be ignored by the implementation, checked at run time, or
+handled in some implementation-defined manner.]}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The form of a
address@hidden Assert is as follows:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[2],@ChgAdded{Version=[2],
address@hidden @prag<Assert>([Check =>] @address@hidden, [Message =>] 
@address@hidden);'}>
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[A @nt{pragma} Assert is allowed at the place where a
address@hidden or a @nt{statement} is allowed.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The form of a
address@hidden Assertion_Policy is as follows:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[2],@ChgAdded[Version=[2],
+Text=<@key{pragma} @prag<Assertion_Policy>(@address@hidden);>]>
+
address@hidden,Kind=[Added],ARef=[AI05-0290-1]}
address@hidden<Version=[3],@ChgAdded[Version=[3],
address@hidden @prag<Assertion_Policy>(@*
+@ @ @ @ @ @ @ @ @ @SynI(assertion_)@Syn2{aspect_mark} => @address@hidden@*
+@ @ @ @ @ {, @SynI(assertion_)@Syn2{aspect_mark} => @address@hidden);]]>
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0290-1]}
address@hidden,address@hidden pragma], Sec=(Assertion_Policy)}
address@hidden, configuration], Sec=(Assertion_Policy)}
+A @nt{pragma} Assertion_Policy address@hidden,New=[ allowed only immediately
+within a @nt{declarative_part}, immediately within a 
@nt{package_specification},
+or as],Old=[]} a configuration pragma.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Text=[The expected type for the
address@hidden@nt{expression} of a @nt{pragma} Assert
+is any boolean type. The expected type for the @address@hidden
+of a @nt{pragma} Assert is type String.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We allow any boolean type to be like
+  @nt{if_statement}s and other conditionals; we only allow String for the
+  message in order to match @nt{raise_statement}s.]}
address@hidden
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0290-1]}
address@hidden,address@hidden,New=[The
address@hidden<assertion_>@nt{aspect_mark} of a @nt{pragma} Assertion_Policy 
shall
+be one of Assert, Static_Predicate, Dynamic_Predicate, Pre, Pre'Class, Post,
+Post'Class, Type_Invariant, Type_Invariant'Class, or some
+implementation defined @nt{aspect_mark}. ],Old=[]}The
address@hidden<policy_>@nt<identifier>@Chg{Version=[3],New=[],Old=[ of a 
@nt{pragma}
+Assertion_Policy]} shall be either Check, Ignore, or 
@Chg{Version=[3],New=[some],Old=[an]}
+implementation-defined @nt{identifier}.]}
address@hidden,Kind=[Revised],InitialVersion=[2],
address@hidden,New=[Implementation-defined
address@hidden<policy_>@nt{identifier}s @Chg{Version=[3],New=[and
address@hidden<assertion_>@nt{aspect_mark}s ],Old=[]}allowed in a @nt{pragma}
+Assertion_Policy.],Old=[]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0290-1]}
address@hidden,Text=[A @nt{pragma} Assertion_Policy
address@hidden,New=[determines for each assertion aspect named in
+the @nt{pragma_argument_association}s whether assertions of the given aspect 
are to
+be enforced by a run-time check. The @SynI<policy_>@nt{identifier} Check
+requires that assertion expressions of the given aspect be checked that they
+evaluate to True at the points specified for the given aspect; the
address@hidden<policy_>@nt{identifier} Ignore requires that the assertion 
expression not
+be evaluated at these points, and the run-time checks not be performed.
address@hidden that for subtype predicate aspects (see @RefSecNum{Subtype 
Predicates}),
+even when the applicable Assertion_Policy is Ignore, the predicate will still 
be
+evaluated as part of membership tests and Valid @nt{attribute_reference}s, and
+if static, will still have an effect on loop iteration over the subtype, and 
the
+selection of @nt{case_statement_alternative}s and @nt{variant}s.]],Old=[is a
+configuration pragma that specifies the assertion policy in effect for the
+compilation units to which it applies. Different policies may apply to 
different
+compilation units within the same partition. The default assertion policy is
+implementation-defined.]}]}
+
address@hidden,Kind=[Added],ARef=[AI05-0290-1]}
address@hidden,Text=[If no @SynI<assertion_>@nt{aspect_mark}s are
+specified in the pragma, the specified policy applies to all assertion
+aspects.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0290-1]}
address@hidden,Text=[A @nt{pragma} Assertion_Policy applies to the named
+assertion aspects in a specific region, and applies to all assertion 
expressions
+specified in that region. A @nt{pragma} Assertion_Policy given in a
address@hidden or immediately within a @nt{package_specification} applies
+from the place of the pragma to the end of the innermost enclosing declarative
+region. The region for a @nt{pragma} Assertion_Policy given as a configuration
+pragma is the declarative region for the entire compilation unit (or units) to
+which it applies.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0290-1]}
address@hidden,Text=[If a @nt{pragma} Assertion_Policy applies to
+a @nt{generic_instantiation}, then
+the @nt{pragma} Assertion_Policy applies to the entire instance.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[This means that an Assertion_Policy pragma that
+  occurs in a scope enclosing the declaration of a generic unit but not also
+  enclosing the declaration of a given instance of that generic unit will not
+  apply to assertion expressions occurring within the given instance.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0290-1]}
address@hidden,Text=[If multiple Assertion_Policy pragmas apply to a
+given construct for a given assertion aspect, the assertion policy is 
determined
+by the one in the innermost enclosing region of a @nt{pragma} Assertion_Policy
+specifying a policy for the assertion aspect. If no such Assertion_Policy 
pragma
+exists, the policy is implementation defined.]}
+
address@hidden,Kind=[AddedNormal],address@hidden,New=[The
+default assertion policy.],Old=[]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The following
+language-defined library package exists:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden,address@hidden Ada.Assertions @key[is]
+   @key[pragma] Pure(Assertions);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaExcDefn{Assertion_Error} : @key<exception>;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<procedure> @AdaSubDefn{Assert}(Check : @key<in> 
Boolean);
+   @key<procedure> @AdaSubDefn{Assert}(Check : @key<in> Boolean; Message : 
@key<in> String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<end> Ada.Assertions;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0290-1]}
address@hidden,Text=[A compilation unit containing a
address@hidden,New=[check for an assertion (including a ],address@hidden
address@hidden,New=[)],Old=[]} has a
+semantic dependence on the Assertions library unit.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Kind=[Deleted],ARef=[AI05-0290-1]}
address@hidden,address@hidden,New=[],Old=[The assertion policy
+that applies to a generic unit also applies to all its instances.]}]}
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0290-1]}
address@hidden,address@hidden,New=[],Old=[An assertion policy
address@hidden policy}specifies how a @nt{pragma} Assert is interpreted by the
+implementation. If the assertion
+policy is Ignore at the point of a @nt{pragma} Assert, the pragma is ignored.]}
+If @Chg{Version=[3],New=[performing checks is required by ],Old=[]}the
address@hidden,New=[Assert ],Old=[]}assertion policy
address@hidden,New=[in effect],Old=[is Check]}
+at the @Chg{Version=[3],New=[place],Old=[point]} of a @nt{pragma} Assert, the
+elaboration of the pragma consists of evaluating the boolean expression, and if
+the result is False, evaluating the Message argument, if any, and raising the
+exception Assertions.Assertion_Error, with a message if the Message
+argument is address@hidden policy],Sec=[Assert address@hidden(Assertion_Error),
+Sec=(raised by failure of assertion)}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[Calling the procedure
+Assertions.Assert without a Message parameter is equivalent to:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<if> Check = False @key<then>
+   @key<raise> Ada.Assertions.Assertion_Error;
address@hidden @key{if};]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[Calling the procedure
+Assertions.Assert with a Message parameter is equivalent to:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<if> Check = False @key<then>
+   @key<raise> Ada.Assertions.Assertion_Error @key<with> Message;
address@hidden @key{if};]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Text=[The procedures Assertions.Assert have these
+effects independently of the assertion policy in effect.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0274-1]}
address@hidden,Text=[It is a bounded error to invoke a potentially
+blocking operation (see @RefSecNum{Protected Subprograms and Protected 
Actions})
+during the evaluation of an assertion expression associated with a call on, or
+return from, a protected operation. If the bounded error is
+detected, Program_Error is raised. If not detected, execution proceeds 
normally,
+but if it is invoked within a protected action, it might result in deadlock or 
a
+(nested) protected action.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Text=[Assertion_Error may be declared by renaming an
+implementation-defined exception from another package.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This permission is intended to allow implementations
+which had an implementation-defined Assert pragma to continue to use their
+originally defined exception. Without this permission, such an implementation
+would be incorrect, as Exception_Name would return the wrong name.]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Text=[Implementations may define their own assertion policies.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0274-1]}
address@hidden,Text=[If the result of a function call in an assertion is
+not needed to determine the value of the assertion expression, an 
implementation
+is permitted to omit the function call. @Redundant[This permission applies even
+if the function has side effects.]]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0274-1]}
address@hidden,Text=[An implementation need not allow the specification
+of an assertion expression if the evaluation of the expression has a side 
effect
+such that an immediate reevaluation of the expression could produce a different
+value. Similarly, an implementation need not allow the specification of an
+assertion expression that is checked as part of a call on or return from a
+callable entity @i<C>, if the evaluation of the expression has a side effect
+such that the evaluation of some other assertion expression associated with the
+same call of (or return from) @i<C> could produce a different value than it
+would if the first expression had not been evaluated.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This allows an implementation to reject such
+  assertions. To maximize portability, assertions should not include 
expressions
+  that contain these sorts of side effects.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The intended effect of the second part of the
+  rule (the part starting with @ldquote@;address@hidden) is that an
+  evaluation of the involved assertion expressions (subtype predicates, type
+  invariants, preconditions and postconditions) in any order yields identical
+  results.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The rule is intended to apply to all of the
+  assertion expressions that are evaluated at the start of call (and similarly
+  for the assertion expressions that are evaluated during the return from a
+  call), but not other assertions actually given in the body, nor between the
+  assertions checked at the start and end of the call. Specifically, a side
+  effect that alters a variable in a function called from a precondition
+  expression that changes the result of a postcondition expression of the same
+  subprogram does @i<not> trigger these rules unless it also changes
+  the value of a reevaluation of the precondition expression.]}
address@hidden
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[4],Text=[Our intent is that any assertion expression that
+  violates this ImplPerm is considered pathological. We definitely want
+  compilers to be able to assume that if you evaluate an assertion expression
+  once and it is True, you don't need to evaluate it again if all you are
+  doing in the mean time is evaluating assertion expressions. We were unable
+  to find wording that had this effect that didn't throw out important other
+  cases (logging, memo functions), so we settled for a strong warning that
+  compilers can reject such pathologies. Perhaps in a future version of
+  Ada we'll be able to tighten this up.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,Text=[Normally, the boolean expression in a @nt{pragma}
+Assert should not call functions that have significant side effects when the
+result of the expression is True, so that the particular assertion policy in
+effect will not affect normal operation of the program.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00286-01]}
address@hidden,address@hidden to Ada 95}
+Pragmas Assert and Assertion_Policy, and package Assertions are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0274-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  There now is an @ImplPermName to reject an assertion expression
+  that calls a function that has a side effect such that an immediate
+  reevalution of the expression could produce a different value.
+  This means that a @nt{pragma} Assert that works in Ada 2005 might be illegal
+  in Ada 2012 in the unlikely event that the compiler detected
+  such an error. This should be unlikely to occur in practice and it
+  is considered a good thing, as the original expression was tricky and
+  probably was not portable (as order of evaluation is unspecified within
+  an expression). Moreover, no compiler is @i<required> to reject such
+  expressions, so there is no need for any compiler to change behavior.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0290-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Assertion_Policy pragmas are now allowed in more places and can specify
+  behavior for individual kinds of assertions.]}
address@hidden
+
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden of Exception Handling}
+
address@hidden
address@hidden@;Exception handling may be used to separate the detection of an 
error
+from the response to that error:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden,New=[],address@hidden Ada.Exceptions;
address@hidden Ada;
address@hidden File_System @key[is]
+    @key[type] File_Handle @key[is] @key[limited] @key[private];
+
+    File_Not_Found : @key[exception];
+    @key[procedure] Open(F : @key[in] @key[out] File_Handle; Name : String);
+        address@hidden raises File_Not_Found if named file does not exist}
+
+    End_Of_File : @key[exception];
+    @key[procedure] Read(F : @key[in] @key[out] File_Handle; Data : @key[out] 
Data_Type);
+        address@hidden raises End_Of_File if the file is not open}
+
+    ...
address@hidden File_System;
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden @key[body] File_System @key[is]
+    @key[procedure] Open(F : @key[in] @key[out] File_Handle; Name : String) 
@key[is]
+    @key[begin]
+        @key[if] File_Exists(Name) @key[then]
+            ...
+        @key[else]
+            @Chg{Version=[2],address@hidden 
],Old=[Exceptions.Raise_Exception(address@hidden,New=[ @key[with] 
],Old=['Identity,
+                                      ]}"File not found: " & Name & 
"."@Chg{Version=[2],New=[],Old=[)]};
+        @key[end] @key[if];
+    @key[end] Open;
+
+    @key[procedure] Read(F : @key[in] @key[out] File_Handle; Data : @key[out] 
Data_Type) @key[is]
+    @key[begin]
+        @key[if] F.Current_Position <= F.Last_Position @key[then]
+            ...
+        @key[else]
+            @key[raise] End_Of_File;
+        @key[end] @key[if];
+    @key[end] Read;
+
+    ...
+
address@hidden File_System;
+
+
address@hidden Ada.Text_IO;
address@hidden Ada.Exceptions;
address@hidden File_System; @key[use] File_System;
address@hidden Ada;
address@hidden Main @key[is]
address@hidden
+    ... address@hidden call operations in File_System}
address@hidden
+    @key[when] End_Of_File =>
+        Close(Some_File);
+    @key[when] Not_Found_Error : File_Not_Found =>
+        Text_IO.Put_Line(Exceptions.Exception_Message(Not_Found_Error));
+    @key[when] The_Error : @key[others] =>
+        Text_IO.Put_Line("Unknown error:");
+        @key[if] Verbosity_Desired @key[then]
+            Text_IO.Put_Line(Exceptions.Exception_Information(The_Error));
+        @key[else]
+            Text_IO.Put_Line(Exceptions.Exception_Name(The_Error));
+            Text_IO.Put_Line(Exceptions.Exception_Message(The_Error));
+        @key[end] @key[if];
+        @key[raise];
address@hidden Main;
address@hidden
+
+
+In the above example, the File_System package contains information about
+detecting certain exceptional situations,
+but it does not specify how to handle those situations.
+Procedure Main specifies how to handle them;
+other clients of File_System might have different handlers,
+even though the exceptional situations arise from the same basic causes.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The sections labeled @lquotes@;Exceptions Raised During address@hidden@;
+are subsumed by this @Chg{Version=[3],New=[subclause],Old=[clause]},
+and by parts of @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden and Synchronization}.
address@hidden
+
address@hidden Checks}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00224-01]}
address@hidden,address@hidden address@hidden pragmas} give
+instructions to an implementation on handling language-defined checks.],Old=[]}
+A @nt{pragma} Suppress gives permission to an
+implementation to omit certain language-defined address@hidden,
+New=[, while a @nt<pragma> Unsuppress revokes the permission to omit 
checks.],Old=[]}.
+
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden check}
address@hidden, Sec=(language-defined)}
address@hidden check],See=(language-defined check)}
address@hidden error}
address@hidden, Sec=(run-time)}
+A @i{language-defined check} (or simply, a @lquotes@;address@hidden@;) is
+one of the situations defined by this International Standard that requires a 
check to
+be made at run time to determine whether some
+condition is true.
address@hidden,Sec=(of a language-defined check)}
+A check @i{fails} when the condition being checked is
address@hidden,New=[False],Old=[false]},
+causing an exception to be raised.
address@hidden
+All such checks are defined under @lquotes@;@address@hidden@;
+in clauses and subclauses throughout the standard.
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00224-01]}
address@hidden@Keepnext@;The address@hidden,New=[s of checking pragmas 
are],Old=[ of a @nt{pragma} Suppress is]} as follows:
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00224-01]}
address@hidden@key{pragma} @prag(Suppress)(@address@hidden,New=<>,Old=( [, [On 
=>] @Syn2{name}])});'
+
address@hidden,Kind=[Added],ARef=[AI95-00224-01]}
address@hidden<Version=[2],@ChgAdded{Version=[2],
+Text=<@key{pragma} @prag(Unsuppress)(@Syn2{identifier});>}>
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00224-01]}
address@hidden pragma], Sec=(Suppress)}
address@hidden, configuration], Sec=(Suppress)}
address@hidden,address@hidden pragma], Sec=(Unsuppress)}
address@hidden, configuration], Sec=(Unsuppress)}],Old=[]}
+A @Chg{Version=[2],New=<checking pragma>,Old=<@nt{pragma} Suppress>} is
+allowed only immediately within a
address@hidden, immediately within a @address@hidden,
+or as a configuration pragma.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00224-01]}
+The @nt{identifier} shall be the name of a check.
address@hidden,New=<>,Old=<The @nt{name} (if present) shall statically denote
+some entity.>}
+
address@hidden,Kind=[Deleted],ARef=[AI95-00224-01]}
address@hidden,Text=<For a @nt{pragma} Suppress that is immediately
+within a @nt{package_specification} and includes a @nt<name>, the @nt<name>
+shall denote an entity (or several overloaded subprograms) declared immediately
+within the @nt{package_specification}.>}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00224-01]}
address@hidden,Text=[A checking pragma applies to the named check in a
+specific region,
+and applies to all entities in that region. A checking pragma given in a
address@hidden<declarative_part> or immediately within a 
@nt<package_specification>
+applies from the place of the @nt<pragma> to the end of the innermost enclosing
+declarative region. The region for a checking pragma given as a configuration
+pragma is the declarative region for the entire compilation unit (or units) to
+which it applies.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00224-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0229-1],ARef=[AI05-0290-1]}
address@hidden,Text=[If a checking pragma applies to a
address@hidden,address@hidden,Old=[generic instantiation]},
+then the checking
+pragma also applies to the @Chg{Version=[3],New=[entire ],Old=[]}instance.
address@hidden,New=[],Old=[ If a checking pragma applies to a call to
+a subprogram that has a @nt<pragma>
+Inline applied to it, then the checking
+pragma also applies to the inlined subprogram body.]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0290-1]}
+  @ChgAdded{Version=[3],Text=[This means that a Suppress pragma that occurs in 
a
+  scope enclosing the declaration of a generic unit but not also enclosing the
+  declaration of a given instance of that generic unit will not apply to
+  constructs within the given instance.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00224-01]}
+A @nt{pragma} Suppress gives permission to an implementation to omit the
+named check @Chg{Version=[2],New=[(or every check in the case of All_Checks) 
for any entities to which it
+applies.],Old=[from the place of the @nt{pragma} to the end of the
+innermost enclosing declarative region, or,
+if the @nt{pragma} is given in a @address@hidden
+and includes a @nt<name>,
+to the end of the scope of the named entity.
+If the @nt{pragma} includes a @nt{name},
+the permission applies only to checks performed on the named entity,
+or, for a subtype, on objects and values of its type.
+Otherwise, the permission applies to all entities.]}
address@hidden check}
+If permission has been given to suppress a given check,
+the check is said to be @i{suppressed}.
address@hidden
+A check is suppressed even if the implementation chooses not to
+actually generate better code.
address@hidden,Sec=(raised by failure of run-time check)}
+This allows the implementation to raise Program_Error,
+for example, if the erroneousness is detected.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00224-01]}
address@hidden,Text=[A @nt{pragma} Unsuppress revokes the permission
+to omit the named check (or every check in the case of All_Checks) given by any
address@hidden Suppress that applies at the point of the @nt{pragma} Unsuppress.
+The permission is revoked for the region to which the @nt{pragma} Unsuppress
+applies. If there is no such permission at the point of a @nt{pragma}
+Unsuppress, then the @nt{pragma} has no effect. A later @nt{pragma} Suppress
+can renew the permission.]}
+
address@hidden@Keepnext@;The following are the language-defined checks:
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden@Redundant[The following checks correspond to situations in which 
the
+exception Constraint_Error is raised upon failure.]
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0036],ARef=[AI95-00176-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00231-01]}
address@hidden
+Access_Check @address@hidden evaluating a dereference (explicit
+or implicit),
+check that the value of the @nt{name} is not @key{null}.
address@hidden,New=[When converting to a subtype that excludes null,
+check that the converted value is not @key{null}.],
+Old=[When passing an actual parameter to a formal access parameter,
+check that the value of the actual parameter is not @key{null}.
address@hidden,New=[When evaluating a @nt{discriminant_association} for an
+access discriminant, check that the value of the discriminant is not 
@key{null}.],
+Old=[]}]}]
+
address@hidden
+Discriminant_Check @address@hidden that the discriminants of a
+composite value
+have the values imposed by a discriminant constraint. Also, when
+accessing a record component, check that it exists for the current
+discriminant values.]
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
address@hidden
+Division_Check @address@hidden that the second operand is not zero
+for the
+operations /, @Chg{Version=[2],address@hidden,Old=[rem]} and
address@hidden,address@hidden,Old=[mod]}.]
+
address@hidden
+Index_Check @address@hidden that the bounds of an array value are
+equal to the
+corresponding bounds of an index constraint. Also, when accessing a
+component of an array object, check for each dimension that the given
+index value belongs to the range defined by the bounds of the array
+object. Also, when accessing a slice of an array object, check that
+the given discrete range is compatible with the range defined by the
+bounds of the array object.]
+
address@hidden
+Length_Check @address@hidden that two arrays have matching
+components,
+in the case of array subtype conversions,
+and logical operators for arrays of boolean components.]
+
address@hidden
+Overflow_Check @address@hidden that a scalar value is within the
+base range of
+its type, in cases where the implementation chooses to raise an
+exception instead of returning the correct mathematical result.]
+
address@hidden
+Range_Check @address@hidden that a scalar value satisfies a range
+constraint.
+Also, for the elaboration of a @nt<subtype_indication>, check that
+the @nt<constraint> (if present) is compatible with the
+subtype denoted by the @nt{subtype_mark}.
+Also, for an @nt<aggregate>, check that an index or
+discriminant value belongs to the corresponding subtype. Also, check
+that when the result of an operation yields an array, the value of
+each component belongs to the component subtype.]
+
address@hidden
+Tag_Check @address@hidden that operand tags in a dispatching call
+are all equal.
+Check for the correct tag on tagged type conversions,
+for an @nt{assignment_statement},
+and when returning a tagged limited object from a function.]
address@hidden
+
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden@Redundant[The following checks correspond to situations in which 
the
+exception Program_Error is raised upon failure.]
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00280]}
address@hidden,address@hidden
+Accessibility_Check @address@hidden the accessibility level of an
+entity or view.]]}
+
address@hidden,Kind=[Added],ARef=[AI95-00280]}
address@hidden,address@hidden
+Allocation_Check @address@hidden an @nt<allocator>, check that the master of
+any tasks to be created by the @nt{allocator} is not yet completed or some
+dependents have not yet terminated, and that the finalization of the
+collection has not started.]]}
+
address@hidden
+Elaboration_Check @address@hidden a subprogram or protected entry is
+called, a task activation is accomplished,
+or a generic instantiation is elaborated, check that the body
+of the corresponding unit has already been elaborated.]
+
address@hidden,Kind=[Deleted],ARef=[AI95-00280]}
address@hidden item is not in alphabetical order}
address@hidden,address@hidden
+Accessibility_Check @address@hidden the accessibility level of an
+entity or view.]]}
+
address@hidden
+
address@hidden@Redundant[The following check corresponds to situations in which 
the
+exception Storage_Error is raised upon failure.]
address@hidden
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+Storage_Check @address@hidden that evaluation of an @nt{allocator}
+does not require
+more space than is available for a storage pool. Check
+that the space available for a task or subprogram has
+not been exceeded.]
address@hidden
+We considered splitting this out into three categories:
+Pool_Check (for @nt{allocator}s), Stack_Check (for stack usage),
+and Heap_Check (for implicit use of the heap @em use of the heap
+other than through an @nt{allocator}).
+Storage_Check would then represent the union of these three.
+However, there seems to be no compelling reason to do this,
+given that it is not feasible to split Storage_Error.
address@hidden
address@hidden
+
address@hidden@Redundant[The following check corresponds to all situations in 
which
+any predefined exception is raised.]
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0290-1]}
address@hidden
+All_Checks @\Represents the union of all checks;
+suppressing All_Checks suppresses all address@hidden,New=[
+other than those associated with assertions. In addition,
+an implementation is allowed (but not required) to behave as if a
+pragma Assertion_Policy(Ignore) applies to any region to which
+pragma Suppress(All_Checks) applies],Old=[]}.
+
address@hidden
+All_Checks includes both language-defined and implementation-defined
+checks.
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[3],Text=[There are additional checks defined in various
+  Specialized Needs Annexes that are not listed here. Nevertheless, they are
+  included in All_Checks and named in a Suppress pragma on implementations that
+  support the relevant annex. Look up @ldquote@;check, address@hidden
+  in the index to find the complete list.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0290-1]}
+  @ChgAdded{Version=[3],Text=[We don't want to say that assertions are
+  suppressed, because we don't want the potential failure of an assertion to
+  cause erroneous execution (see below). Thus they are excluded from the
+  suppression part of the above rule and then handled with an implicit Ignore
+  policy.]}
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)}
+If a given check has been suppressed,
+and the corresponding error situation occurs,
+the execution of the program is erroneous.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00224-01]}
+An implementation is allowed to place restrictions on
address@hidden,New=[checking pragmas, subject only to the requirement that
address@hidden Unsuppress shall allow any
+check names supported by @nt{pragma} Suppress],Old=[Suppress @nt<pragma>s]}.
+An implementation is allowed to add additional check names,
+with implementation-defined semantics.
address@hidden
+When Overflow_Check has been suppressed,
+an implementation may also suppress an unspecified
+subset of the Range_Checks.
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00224-01]}
address@hidden,Text=[The permission to restrict is given
+so the implementation can give an error message when the
+requested suppression is nonsense, such as suppressing a Range_Check
+on a task type.
+It would be verbose and pointless to list all the cases of
+nonsensical language-defined checks in the standard,
+and since the list of checks is open-ended,
+we can't list the restrictions for implementation-defined checks
+anyway.]}
address@hidden
address@hidden check names.}
address@hidden
+For Overflow_Check, the intention is that the
+implementation will suppress any Range_Checks that are implemented in
+the same manner as Overflow_Checks (unless they are free).
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00224-01]}
address@hidden,Text=[An implementation may support an additional
+parameter on
address@hidden Unsuppress similar to the one allowed for @nt{pragma} Suppress
+(see @RefSecNum{Specific Suppression of Checks}). The meaning of
+such a parameter is implementation-defined.]}
address@hidden,Kind=[Added],address@hidden,New=[Existence and
+meaning of second parameter of @nt{pragma} Unsuppress.],Old=[]}]}
address@hidden
+
address@hidden
+The implementation should minimize the code executed for checks
+that have been suppressed.
address@hidden,Kind=[Added],address@hidden,
+Text=[Code executed for checks
+that have been suppressed should be minimized.]}]}
address@hidden
+However, if a given check comes for free (for example, the hardware
+automatically performs the check in parallel with doing useful work)
+or nearly free (for example, the check is a tiny portion of an
+expensive run-time system call), the implementation should not bother to
+suppress the check. Similarly, if the implementation detects the failure at
+compile time and provides a warning message, there is no need to actually
+suppress the check.
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden
+There is no guarantee that a suppressed check is actually removed;
+hence a @nt{pragma} Suppress should be used only for efficiency reasons.
+
address@hidden,Kind=[Added],ARef=[AI95-00224-01]}
address@hidden,Text=[It is possible to give both a @nt{pragma} Suppress
+and Unsuppress for the same check immediately within the same
address@hidden
+In that case, the last @nt{pragma} given determines whether or not the check is
+suppressed. Similarly, it is possible to resuppress a check which has been
+unsuppressed by giving a @nt{pragma} Suppress in an inner declarative region.]}
address@hidden
+
address@hidden
address@hidden@address@hidden,Kind=[Revised],ARef=[AI95-00224-01]}
address@hidden of suppressing @Chg{Version=[2],New=[and unsuppressing 
],Old=[]}checks:}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00224-01]}
address@hidden Suppress(@Chg{Version=[2],New=[Index_Check);
address@hidden Unsuppress(Overflow_Check);],Old=[Range_Check);
address@hidden Suppress(Index_Check, On => Table);]}
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+A @nt{pragma} Suppress is allowed as a configuration pragma.
+A @nt{pragma} Suppress without a @nt<name> is allowed in a
address@hidden
+
+Additional check names are added.
+We allow implementations to define their own checks.
address@hidden
+
address@hidden
+We define the checks in a distributed manner.
+Therefore, the long list of what checks apply to what
+is merely a NOTE.
+
+We have removed the detailed rules about what is allowed
+in a @nt{pragma} Suppress,
+and allow implementations to invent their own.
+The RM83 rules weren't quite right,
+and such a change is necessary anyway in the presence
+of implementation-defined checks.
+
+We make it clear that the difference between a Range_Check
+and an Overflow_Check is fuzzy.
+This was true in Ada 83,
+given RM83-11.6,
+but it was not clear.
+We considered removing Overflow_Check from the language
+or making it obsolescent, just as we did for Numeric_Error.
+However, we kept it for upward compatibility,
+and because it may be useful on machines where range checking
+costs more than overflow checking,
+but overflow checking still costs something.
+Different compilers will suppress different checks when asked to
+suppress Overflow_Check @em
+the nonuniformity in this case is not harmful,
+and removing it would have a serious impact on optimizers.
+
+Under Access_Check,
+dereferences cover the cases of
address@hidden, @nt{indexed_component}, @nt{slice},
+and attribute that are listed in RM83,
+as well as the new @nt{explicit_dereference},
+which was included in @nt{selected_component} in RM83.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00224-01]}
address@hidden,address@hidden to Ada 95}Pragma Unsuppress is new.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00280-01]}
address@hidden,Text=[Allocation_Check was added to support suppressing
+the new check on @nt{allocator}s (see @RefSecNum{Allocators}).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],Ref=[8652/0036],ARef=[AI95-00176-01],ARef=[AI95-00224-01]}
address@hidden,Text=[The description of Access_Check was corrected by the
+Corrigendum to include the discriminant case. This change was then replaced
+by the more general notion of checking conversions to subtypes that exclude
+null in Ada 2005.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00224-01]}
address@hidden,Text=[The On parameter of pragma Suppress was moved to
+Annex J (see @RefSecNum{Specific Suppression of Checks}).
+This feature's effect is inherently nonportable, depending on the
+implementation's model of computation. Compiler surveys demonstrated this,
+showing that implementations vary widely in the interpretation of these
+parameters, even on the same target. While this is relatively harmless for
+Suppress (which is never required to do anything), it would be a significant
+problem for Unsuppress (we want the checks to be made for all implementations).
+By moving it, we avoid needing to define the meaning of Unsuppress with an
+On parameter.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00280-01]}
address@hidden,Text=[The order of the
+Program_Error checks was corrected to be alphabetical.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0290-1]}
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[3],Text=[The effect of a checking pragma no longer
+  applies inside an inlined subprogram body. While this could change the
+  behavior of a program that depends on a check being suppressed in an
+  inlined body, such a program is erroneous and thus no behavior can be
+  depended upon anyway. It's also likely to be very rare. We make this
+  change so that inlining has no effect on the meaning of the subprogram
+  body (since inlining is never 
@Chg{Version=[4],New=[required],Old=[requiring]},
+  this is necessary in order to be
+  able to reason about the body), and so that assertion policies and
+  suppress work the same way for inlining.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden and Optimization}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden@Defn{language-defined check}
address@hidden, Sec=(language-defined)}
address@hidden error}
address@hidden, Sec=(run-time)}
address@hidden
address@hidden
+This @Chg{Version=[3],New=[subclause],Old=[clause]} gives permission to
+the implementation to perform certain @lquotes@;address@hidden@; that
+do not necessarily preserve the canonical semantics.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden semantics}
+The rest of this International Standard (outside this 
@Chg{Version=[3],New=[subclause],Old=[clause]})
+defines the @i{canonical semantics} of the language.
address@hidden canonical semantics of a given (legal) program determines a
+set of possible external effects that can result from the execution of
+the program with given inputs.]
address@hidden
+Note that the canonical semantics is a set of possible behaviors,
+since some reordering, parallelism, and nondeterminism is allowed by
+the canonical semantics.
address@hidden
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+The following parts of the canonical semantics are of particular
+interest to the reader of this @Chg{Version=[3],New=[subclause],Old=[clause]}:
address@hidden
+Behavior in the presence of abnormal objects
+and objects with invalid representations
+(see @RefSecNum{Data Validity}).
+
+Various actions that are defined to occur in an arbitrary order.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Behavior in the presence of a misuse of Unchecked_Deallocation,
+Unchecked_Access, or imported or exported entity
+(see @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden Issues}).
address@hidden
address@hidden
+
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden explained in
address@hidden of an Implementation with the Standard},
+the external effect of a program is defined in terms of its
+interactions with its external environment.
+Hence, the implementation can perform any internal
+actions whatsoever, in any order or in parallel,
+so long as the external effect of the execution of the program is one
+that is allowed by the canonical semantics, or by the rules
+of this @Chg{Version=[3],New=[subclause],Old=[clause]}.]
address@hidden
+Note that an optimization can change the external effect of the program,
+so long as the changed external effect is an external effect that is
+allowed by the semantics.
+Note that the canonical semantics of an erroneous execution allows any
+external effect whatsoever.
+Hence, if the implementation can prove that program execution will be
+erroneous in certain circumstances,
+there need not be any constraints on the machine code executed in those
+circumstances.
address@hidden
address@hidden
+
address@hidden
address@hidden@;The following additional permissions are granted to the
+implementation:
address@hidden
address@hidden permission to avoid raising exceptions}
address@hidden result}
+An implementation need not always
+raise an exception when a language-defined check fails.
+Instead, the operation that failed the check can simply yield
+an @i{undefined result}. The exception need be raised
+by the implementation only if, in the absence of raising it,
+the value of this undefined result would have some effect on
+the external interactions of the program.
+In determining this, the implementation shall not presume that
+an undefined result has a value that belongs to its subtype,
+nor even to the base range of its type, if scalar.
address@hidden removed the raise of the exception, the
+canonical semantics will in general allow the implementation
+to omit the code for the check, and some or all of the operation itself.]
address@hidden
+Even without this permission, an implementation can always
+remove a check if it cannot possibly fail.
address@hidden
address@hidden
+  We express the permission in terms of removing
+  the raise, rather than the operation or the check,
+  as it minimizes the disturbance to the canonical
+  semantics (thereby simplifying reasoning). By allowing
+  the implementation to omit the raise, it thereby does
+  not need to "look" at what happens in the exception handler
+  to decide whether the optimization is allowed.
address@hidden
address@hidden
+The implementation can also omit checks
+if they cannot possibly fail,
+or if they could only fail in erroneous executions.
+This follows from the canonical semantics.
address@hidden
address@hidden
+  @Leading@;This permission is intended to allow normal "dead code removal"
+  optimizations, even if some of the removed code might have failed
+  some language-defined check.
+  However, one may not eliminate the raise of an exception
+  if subsequent code presumes in some way that the check succeeded.
+  For example:
address@hidden
+  @key[if] X * Y > Integer'Last @key[then]
+      Put_Line("X * Y overflowed");
+  @key[end] @key[if];
address@hidden
+  @key[when] @key[others] =>
+      Put_Line("X * Y overflowed");
address@hidden
+  @ChgNote{The following paragraph is missing a number in the original version.
+  To give it a number in the new version, it is marked as an insertion.}
+  @ChgRef{Version=[0],Kind=[Added]}
+  @Chg{New=[],address@hidden@;]}If X*Y does overflow, you may not remove the 
raise of the exception
+  if the code that does the comparison against Integer'Last presumes
+  that it is comparing it with an in-range Integer value, and hence
+  always yields False.
+
+  @Leading@;As another example where a raise may not be eliminated:
address@hidden
+  @key[subtype] Str10 @key[is] String(1..10);
+  @key[type] P10 @key[is] @key[access] Str10;
+  X : P10 := @key[null];
address@hidden
+  @key[if] X.all'Last = 10 @key[then]
+      Put_Line("Oops");
+  @key[end] @key[if];
address@hidden
+  @ChgNote{The following paragraph is missing a number in the original version.
+  To give it a number in the new version, it is marked as an insertion.}
+  @ChgRef{Version=[0],Kind=[Added]}
+  In the above code, it would be wrong to eliminate the
+  raise of Constraint_Error on the "X.all" (since X is null),
+  if the code to evaluate 'Last always yields 10 by presuming
+  that X.all belongs to the subtype Str10, without even "looking."
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden permission to reorder actions}
+If an exception is raised due to the failure
+of a language-defined check,
+then upon
+reaching the corresponding @nt<exception_handler> (or the
+termination of the task, if none), the external interactions
+that have occurred need reflect only that the exception was
+raised somewhere within
+the execution of the @nt<sequence_of_statements> with the handler
+(or the @nt<task_body>), possibly earlier (or later
+if the interactions are independent of the result of the checked
+operation)
+than that defined
+by the canonical semantics, but not within the execution of some
+abort-deferred operation or @i(independent) subprogram
+that does not dynamically enclose the execution of the construct
+whose check failed.
address@hidden subprogram}
+An independent subprogram is one that is
+defined outside the library unit containing the construct whose check
+failed, and @Chg{Version=[3],New=[for which the],Old=[has no]} Inline
address@hidden,New=[aspect is False],address@hidden<pragma> applied to it]}.
address@hidden state of an object}
address@hidden state of an object}
address@hidden of an assignment}
+Any assignment that occurred outside of such abort-deferred
+operations or independent subprograms can be disrupted
+by the raising of the exception,
+causing the object or its parts to become abnormal,
+and certain subsequent uses of the object to be erroneous,
+as explained in @RefSecNum{Data Validity}.
address@hidden
+  We allow such variables to become abnormal so that
+  assignments (other than to atomic variables) can be disrupted
+  due to @lquotes@;address@hidden@; exceptions or instruction scheduling,
+  and so that assignments can be reordered
+  so long as the correct results are produced in the end if
+  no language-defined checks fail.
address@hidden
address@hidden
+  If a check fails, no result dependent on the check may be
+  incorporated in an external interaction. In other words,
+  there is no permission to output meaningless results due
+  to postponing a check.
address@hidden
address@hidden
address@hidden
+We believe it is important to state the
+extra permission to reorder actions
+in terms of what the programmer can expect at run time,
+rather than in terms of what the implementation can assume,
+or what transformations the implementation can perform.
+Otherwise, how can the programmer write reliable programs?
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} has two conflicting goals:
+to allow as much optimization as possible,
+and to make program execution as predictable as possible
+(to ease the writing of reliable programs).
+The rules given above represent a compromise.
+
+Consider the two extremes:
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The extreme conservative rule would be
+to delete this @Chg{Version=[3],New=[subclause],Old=[clause]} entirely.
+The semantics of Ada would be the canonical semantics.
+This achieves the best predictability.
+It sounds like a disaster from the efficiency point of view,
+but in practice, implementations would provide modes
+in which less predictability but more efficiency would be achieved.
+Such a mode could even be the out-of-the-box mode.
+In practice, implementers would provide a compromise based on their
+customer's needs.
+Therefore, we view this as one viable alternative.
+
+The extreme liberal rule would be @lquotes@;the language does not specify the
+execution of a program once a language-defined check has failed;
+such execution can be address@hidden@;
+This achieves the best efficiency.
+It sounds like a disaster from the predictability point of view,
+but in practice it might not be so bad.
+A user would have to assume that exception handlers for exceptions
+raised by language-defined checks are not portable.
+They would have to isolate such code (like all nonportable code),
+and would have to find out, for each implementation of interest,
+what behaviors can be expected.
+In practice, implementations would tend to avoid going so far as to
+punish their customers too much in terms of predictability.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The most important thing about this 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+is that users understand what they can expect at run time,
+and implementers understand what optimizations are allowed.
+Any solution that makes this @Chg{Version=[3],New=[subclause],Old=[clause]}
+contain rules that can interpreted in more than one way is unacceptable.
+
+We have chosen a compromise between the extreme conservative and
+extreme liberal rules.
+The current rule essentially allows arbitrary optimizations within
+a library unit and inlined subprograms reachable from it, but
+disallow semantics-disrupting optimizations across library units
+in the absence of inlined subprograms.
+This allows a library unit to be debugged, and then reused with
+some confidence that the abstraction it manages cannot be
+broken by bugs outside the library unit.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The permissions granted by this @Chg{Version=[3],New=[subclause],Old=[clause]}
+can have an effect on the
+semantics of a program only if the program fails a language-defined check.
address@hidden
+
address@hidden
address@hidden@;RM83-11.6 was unclear.
+It has been completely rewritten here; we hope this version is clearer.
+Here's what happened to each paragraph of RM83-11.6:
address@hidden
+Paragraphs 1 and 2 contain no semantics;
+they are merely pointing out that anything goes if the canonical
+semantics is preserved.
+We have similar introductory paragraphs,
+but we have tried to clarify that these are not granting any 
@lquotes@;address@hidden@;
+permission beyond what the rest of the document allows.
+
+Paragraphs 3 and 4 are reflected in the
address@hidden@;extra permission to reorder address@hidden@;.
+Note that this permission now allows the reordering of assignments in
+many cases.
+
+Paragraph 5 is moved to @RefSec{Operators and Expression Evaluation},
+where operator association is discussed.
+Hence, this is no longer an @lquotes@;extra address@hidden@;
+but is part of the canonical semantics.
+
+Paragraph 6 now follows from the general permission to store
+out-of-range values for unconstrained subtypes.
+Note that the parameters and results of all the predefined operators
+of a type are of the unconstrained subtype of the type.
+
+Paragraph 7 is reflected in the
address@hidden@;extra permission to avoid raising address@hidden@;.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+We moved @Chg{Version=[3],New=[subclause],Old=[clause]}
address@hidden Checks} from after 11.6 to
+before 11.6, in order to preserve the famous number @lquotes@;address@hidden@;
+(given the changes to earlier @Chg{Version=[3],New=[subclauses],Old=[clauses]} 
in
address@hidden,New=[Clause],Old=[Section]} @RefSecNum{Exceptions}).
address@hidden
diff --git a/packages/ada-ref-man/source_2012/12.mss 
b/packages/ada-ref-man/source_2012/12.mss
new file mode 100755
index 0000000..b2651b5
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/12.mss
@@ -0,0 +1,3897 @@
address@hidden(12, Root="ada.mss")
+
address@hidden: 2015/04/03 04:12:42 $}
address@hidden Units}
+
address@hidden: e:\\cvsroot/ARM/Source/12.mss,v $}
address@hidden: 1.97 $}
+
address@hidden
address@hidden unit}
+A @i{generic unit} is a program unit that is either a generic subprogram
+or a generic package.
address@hidden
+A generic unit is a @address@hidden, which can be parameterized,
+and from which corresponding (nongeneric) subprograms or packages can be
+obtained].
+The resulting program units are said to be @i{instances} of the original
+generic unit.
address@hidden,See=(generic unit)}
address@hidden,See=(generic unit)}
address@hidden,See=[generic formal parameter]}
address@hidden<Generic unit>,
+  Text=<A generic unit is a template for a (nongeneric) program unit;
+  the template can be parameterized by objects, types, subprograms, and
+  packages. An instance of a generic unit is created by a
+  @nt(generic_instantiation).
+  The rules of the language are enforced when a generic unit is compiled,
+  using a generic contract model; additional checks are
+  performed upon instantiation to verify the contract is met.
+  That is, the declaration of a generic unit represents a contract
+  between the body of the generic and instances of the generic.
+  Generic units can be used to perform the role that macros
+  sometimes play in other languages.>address@hidden for AI-00024, no mechism 
to correct glossary entries.}
+
address@hidden generic unit is declared by a @nt{generic_declaration}. This form
+of declaration has a @address@hidden@!part} declaring any generic
+formal parameters. An instance of a generic unit is obtained as the
+result of a @nt{generic_instantiation} with appropriate
+generic actual parameters for the generic formal parameters. An
+instance of a generic subprogram is a subprogram. An instance of a
+generic package is a package.
+
+Generic units are templates. As templates they do not have the
+properties that are specific to their nongeneric counterparts. For
+example, a generic subprogram can be instantiated but it cannot be
+called. In contrast, an instance of a generic subprogram is a
+(nongeneric) subprogram; hence, this instance can be called but it
+cannot be used to produce further instances.]
address@hidden
+
address@hidden Declarations}
+
address@hidden
address@hidden @nt{generic_declaration} declares a generic unit, which is 
either a
+generic subprogram or a generic package. A @nt{generic_declaration}
+includes a @nt{generic_formal_part} declaring any generic formal
+parameters. A generic formal parameter can be an object;
+alternatively (unlike a parameter of a subprogram), it can be a type,
+a subprogram, or a package.]
address@hidden
+
address@hidden
address@hidden<generic_declaration>,rhs="@Syn2{generic_subprogram_declaration} 
| @Syn2{generic_package_declaration}"}
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<generic_subprogram_declaration>,rhs="
+     @Syn2{generic_formal_part}  @address@hidden,New=<
+        address@hidden>,Old=[]};"}
+
address@hidden<generic_package_declaration>,rhs="
+     @Syn2{generic_formal_part}  @Syn2{package_specification};"}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],Text=[No syntax change is needed here to allow an
+  @nt{aspect_specification}; a generic package can have an 
@nt{aspect_specification}
+  because a @nt{package_specification} allows an @nt{aspect_specification}.]}
address@hidden
+
address@hidden<generic_formal_part>,rhs="@key{generic} address@hidden | 
@Syn2{use_clause}}"}
+
address@hidden<generic_formal_parameter_declaration>,rhs="
+      @Syn2{formal_object_declaration}
+    | @Syn2{formal_type_declaration}
+    | @Syn2{formal_subprogram_declaration}
+    | @Syn2{formal_package_declaration}"}
address@hidden
+The only form of @nt{subtype_indication} allowed within a
address@hidden is a @nt{subtype_mark}
address@hidden(that is, the @nt{subtype_indication} shall not include an
+explicit @nt{constraint})].
+The defining name of a generic subprogram shall be an @nt{identifier}
address@hidden(not an @nt{operator_symbol})].
address@hidden
+The reason for forbidding @nt{constraint}s in
address@hidden is that it simplifies the elaboration of
address@hidden (since there is nothing to evaluate),
+and that it simplifies the matching rules,
+and makes them more checkable at compile time.
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
address@hidden package}
address@hidden subprogram}
address@hidden procedure}
address@hidden function}
+A @nt{generic_declaration} declares a generic unit @em a
+generic package, generic address@hidden,New=[,],Old=[]}
+or generic function, as appropriate.
+
address@hidden formal}
+An entity is a @i{generic formal} entity if it is declared
+by a @nt<generic_formal_parameter_declaration>. @lquotes@;Generic 
formal,@rquotes@;
+or simply @lquotes@;formal,@rquotes@; is used as a prefix in referring
+to objects, subtypes (and types), functions, procedures and packages,
+that are generic formal entities, as well as to their respective
+declarations.
address@hidden: @lquotes@;generic formal address@hidden@;
+or a @lquotes@;formal integer type address@hidden@;]
address@hidden
+
address@hidden
address@hidden, Sec=(generic_declaration)}
+The elaboration of a @nt{generic_declaration} has no effect.
address@hidden
+
address@hidden
+Outside a generic unit
+a @nt{name} that denotes the @nt{generic_declaration} denotes the
+generic unit.
+In contrast, within the declarative region of the generic unit,
+a @nt{name} that denotes the @nt{generic_declaration} denotes the
+current instance.
address@hidden
+This is stated officially as part of the @lquotes@;current address@hidden@;
+rule in @RefSec{The Context of Overload Resolution}.
+See also @RefSec{Generic Instantiation}.
address@hidden
+
+Within a generic @nt{subprogram_body}, the name of this program unit
+acts as the name of a subprogram. Hence this name can be overloaded,
+and it can appear in a recursive call of the current instance. For the
+same reason, this name cannot appear after the reserved word @key{new}
+in a (recursive) @nt{generic_instantiation}.
+
+A @nt{default_expression} or @nt{default_name} appearing in a
address@hidden is not evaluated during elaboration of the
address@hidden; instead, it is evaluated when used.
+(The usual visibility rules apply to any @nt{name} used in a default:
+the denoted declaration therefore has to be visible at the place of the
+expression.)
address@hidden
+
address@hidden
address@hidden@address@hidden of generic formal parts:}
address@hidden
address@hidden     address@hidden  parameterless }
+
address@hidden
+   Size : Natural;  address@hidden  formal object }
+
address@hidden
+   Length : Integer := 200;          address@hidden formal object with a 
default expression}
+
+   Area   : Integer := Length*Length; address@hidden formal object with a 
default expression}
+
address@hidden
+   @key[type] Item  @key[is] @key[private];                       
address@hidden formal type}
+   @key[type] Index @key[is] (<>);                          address@hidden 
formal type}
+   @key[type] Row   @key[is] @key[array](Index @key[range] <>) @key[of] Item; 
address@hidden formal type}
+   @key[with] @key[function] "<"(X, Y : Item) @key[return] Boolean;    
address@hidden formal subprogram }
address@hidden
+
address@hidden
address@hidden@address@hidden of generic declarations declaring generic 
subprograms
+Exchange and Squaring:}
address@hidden
address@hidden
address@hidden
+   @key[type] Elem @key[is] @key[private];
address@hidden Exchange(U, V : @key[in] @key[out] Elem);
+
address@hidden
+   @key[type] Item @key[is] @key[private];
+   @key[with] @key[function] "*"(U, V : Item) @key[return] Item @key[is] <>;
address@hidden Squaring(X : Item) @key[return] Item;
address@hidden
+
address@hidden
address@hidden@address@hidden of a generic declaration declaring a generic 
package:}
address@hidden
address@hidden
address@hidden
+   @key[type] Item   @key[is] @key[private];
+   @key[type] Vector @key[is] @key[array] (Positive @key[range] <>) @key[of] 
Item;
+   @key[with] @key[function] Sum(X, Y : Item) @key[return] Item;
address@hidden On_Vectors @key[is]
+   @key[function] Sum  (A, B : Vector) @key[return] Vector;
+   @key[function] Sigma(A    : Vector) @key[return] Item;
+   Length_Error : @key[exception];
address@hidden On_Vectors;
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax rule for @nt{generic_formal_parameter_declaration} is modified
+to allow the reserved words @key{tagged} and @key{abstract}, to allow
+formal derived types, and to allow formal packages.
+
address@hidden are allowed in @nt{generic_formal_part}s.
+This is necessary in order to allow a @nt{use_clause} within a formal
+part to provide direct visibility of declarations within a generic
+formal package.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0299-1]}
+The syntax for @nt{generic_formal_parameter_declaration} and
address@hidden is split up into more named categories.
+The rules for these categories are moved to the appropriate
address@hidden,New=[],Old=[clauses and ]}subclauses.
+The names of the categories are changed to be more intuitive and uniform.
+For example, we changed @ntf{generic_parameter_declaration} to
address@hidden, because the thing it declares
+is a generic formal, not a generic.
+In the others, we abbreviate @lquotes@;address@hidden@; to just 
@lquotes@;address@hidden@;.
+We can't do that for @nt{generic_formal_parameter_declaration},
+because of confusion with normal formal parameters of subprograms.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a
+  @nt{generic_subprogram_declaration} (as well as a 
@nt{generic_package_declaration}).
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
address@hidden@Comment{Insert page break so printed RM's look better.}
address@hidden Bodies}
+
address@hidden
address@hidden body}
+The body of a generic unit (a @i{generic body})
address@hidden a template for the instance bodies.
+The syntax of a generic body is identical to that of a nongeneric body].
address@hidden
+We also use terms like @lquotes@;generic function address@hidden@; and
address@hidden@;nongeneric package address@hidden@;
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(generic body)}
+The elaboration of a generic body has no other effect than to
+establish that the generic unit can from then on be instantiated without
+failing the Elaboration_Check.
+If the generic body is a child of a generic package,
+then its elaboration establishes that each corresponding
+declaration nested in an instance of the parent
+(see @RefSecNum{Compilation Units - Library Units})
+can from then on be instantiated without failing the Elaboration_Check.
address@hidden
+
address@hidden
+The syntax of generic subprograms implies that a generic subprogram body
+is always the completion of a declaration.
address@hidden
+
address@hidden
address@hidden@address@hidden of a generic procedure body:}
address@hidden
address@hidden Exchange(U, V : @key[in] @key[out] Elem) @key[is]  
address@hidden see @RefSecNum{Generic Declarations}}
+   T : Elem;  address@hidden  the generic formal type}
address@hidden
+   T := U;
+   U := V;
+   V := T;
address@hidden Exchange;
address@hidden
+
address@hidden
address@hidden@address@hidden of a generic function body:}
address@hidden
address@hidden
address@hidden Squaring(X : Item) @key[return] Item @key[is]  address@hidden  
see @RefSecNum{Generic Declarations}}
address@hidden
+   @key[return] X*X;  address@hidden  the formal operator "*"}
address@hidden Squaring;
address@hidden
+
address@hidden
address@hidden@address@hidden of a generic package body:}
address@hidden
address@hidden
address@hidden @key[body] On_Vectors @key[is]  address@hidden  see 
@RefSecNum{Generic Declarations}}
+
+   @key[function] Sum(A, B : Vector) @key[return] Vector @key[is]
+      Result : Vector(A'Range); address@hidden  the formal type Vector}
+      Bias   : @key[constant] Integer := B'First - A'First;
+   @key[begin]
+      @key[if] A'Length /= B'Length @key[then]
+         @key[raise] Length_Error;
+      @key[end] @key[if];
+
+      @key[for] N @key[in] A'Range @key[loop]
+         Result(N) := Sum(A(N), B(N + Bias)); address@hidden the formal 
function Sum}
+      @key[end] @key[loop];
+      @key[return] Result;
+   @key[end] Sum;
+
+   @key[function] Sigma(A : Vector) @key[return] Item @key[is]
+      Total : Item := A(A'First); address@hidden  the formal type Item}
+   @key[begin]
+      @key[for] N @key[in] A'First + 1 .. A'Last @key[loop]
+         Total := Sum(Total, A(N)); address@hidden  the formal function Sum}
+      @key[end] @key[loop];
+      @key[return] Total;
+   @key[end] Sigma;
address@hidden On_Vectors;
address@hidden
address@hidden
+
+
address@hidden@Comment{For ISO version of Ada 2012 Standard}
address@hidden Instantiation}
+
address@hidden
address@hidden@Defn2{Term=[instance], Sec=(of a generic unit)}
+An instance of a generic unit is declared by a
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden contract model}
address@hidden model of generics}
+The legality of an instance should be determinable without looking at
+the generic body.
+Likewise, the legality of a generic body should be determinable without
+looking at any instances.
+Thus, the @nt{generic_declaration} forms a contract between the body and
+the instances; if each obeys the rules with respect to the
address@hidden, then no legality problems will arise.
+This is really a special case of the
address@hidden@;legality determinable via semantic address@hidden@;
address@hidden (see @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden Structure and Compilation Issues}),
+given that a @nt{generic_instantiation} does not depend semantically
+upon the generic body, nor vice-versa.
+
+Run-time issues are another story.
+For example, whether parameter passing is by copy or by reference is
+determined in part by the properties of the generic actuals,
+and thus cannot be determined at compile time of the generic body.
+Similarly, the contract model does not apply to @LinkTimeTitle.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00218-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<generic_instantiation>,rhs="
+     @key{package} @Syn2{defining_program_unit_name} @key{is}
+         @key{new} @address@hidden address@hidden@Chg{Version=[3],New=<
+            address@hidden>,Old=[]};
+   | @Chg{Version=[2],New=<address@hidden
+     >,Old=<>address@hidden @Syn2{defining_program_unit_name} @key{is}
+         @key{new} @address@hidden address@hidden@Chg{Version=[3],New=<
+            address@hidden>,Old=[]};
+   | @Chg{Version=[2],New=<address@hidden
+     >,Old=<>address@hidden @Syn2{defining_designator} @key{is}
+         @key{new} @address@hidden address@hidden@Chg{Version=[3],New=<
+            address@hidden>,Old=[]};"}
+
+
address@hidden<generic_actual_part>,rhs="
+   (@Syn2{generic_association} {, @Syn2{generic_association}})"}
+
address@hidden<generic_association>,rhs="
+   address@hidden@Syn2{selector_name} =>] 
@Syn2{explicit_generic_actual_parameter}"}
+
address@hidden<explicit_generic_actual_parameter>,rhs="@Syn2{expression} | 
@address@hidden
+   | @address@hidden | @address@hidden | @Syn2{subtype_mark}
+   | @address@hidden"}
+
address@hidden
address@hidden association}
address@hidden association}
+A @nt{generic_association} is @i{named} or @i{positional}
+according to whether or not the 
@address@hidden@address@hidden@nt<address@hidden>
+is specified. Any positional associations shall precede any
+named associations.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0004-1]}
address@hidden actual parameter}
address@hidden actual}
address@hidden
+The @i{generic actual parameter} is either the
address@hidden given in a
address@hidden,address@hidden@!association}],address@hidden@address@hidden
+for each formal,
+or the corresponding @address@hidden or @address@hidden if no
address@hidden,address@hidden@!association}],address@hidden@address@hidden
+is given for the formal.
+When the meaning is clear from context,
+the term @lquotes@;generic actual,@rquotes@; or simply 
@lquotes@;actual,@rquotes@; is used as a synonym for
address@hidden@;generic actual address@hidden@;
+and also for the view denoted by one, or the value of one.
address@hidden
+
address@hidden
+In a @nt<generic_instantiation> for a particular kind of program
+unit @Redundant[(package, procedure, or function)],
+the @nt<name> shall denote a generic
+unit of the corresponding kind @Redundant[(generic package,
+generic procedure, or generic
+function, respectively)].
+
address@hidden,Kind=[Revised],ARef=[AI05-0118-1]}
+The @address@hidden of
address@hidden,New=[ named],Old=[]}
address@hidden shall denote a
address@hidden
+of the generic unit being instantiated.
+If two or more formal subprograms have the same defining name, then
+named associations are not allowed for the corresponding
+actuals.
+
address@hidden,Kind=[Added],ARef=[AI05-0118-1]}
address@hidden,Text=[The @nt{generic_formal_parameter_declaration}
+for a positional @nt{generic_association} is the parameter with the
+corresponding position in the @nt{generic_formal_part} of the
+generic unit being instantiated.]}
+
+A @nt{generic_instantiation} shall contain at
+most one @nt<generic_association> for each formal.
+Each formal without an association shall have a
address@hidden or @nt{subprogram_default}.
+
+In a generic unit @LegalityName@;s
+are enforced at compile time of the
address@hidden and generic body,
+given the properties of the formals.
+In the visible part and formal part of an instance,
address@hidden@;s are enforced at
+compile time of the @nt{generic_instantiation},
+given the properties of the actuals.
+In other parts of an instance, @LegalityName@;s
+are not enforced;
+this rule does not apply when a given rule
+explicitly specifies otherwise.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+Since rules are checked using the properties of the formals,
+and since these properties do not always carry over to the actuals,
+we need to check the rules again in the visible part of the instance.
+For example, only if a tagged type is limited may
+an extension of it have limited components in
+the @Chg{Version=[2],address@hidden,address@hidden<extension_part>]}.
+A formal tagged limited type
+is limited, but the actual might be nonlimited. Hence
+any rule that requires a tagged type to be limited
+runs into this problem.
+Such rules are rare; in most cases, the rules for matching of formals
+and actuals guarantee that if the rule is obeyed in the generic unit,
+then it has to be obeyed in the instance.
+
address@hidden,Kind=[Added],ARef=[AI05-0005-1]}
address@hidden,Text=[Ada 2012 addendum: Such @LegalityTitle are not
+as rare as the authors of Ada 95 hoped; there are more than 30 of them known
+at this point. They are indexed under "generic contract issue" and
+are associated with the boilerplate "In addition to the places where
address@hidden normally apply...". Indeed, there is only one known rule
+where rechecking in the specification is needed and where rechecking in the
+private part is @i<not> wanted (it is in @RefSecNum{Derived Types and Classes},
+but even it needs rechecking when tagged types are involved).]}
address@hidden
address@hidden
address@hidden@;The @lquotes@;address@hidden@; of the formals are determined
+without knowing anything about the actuals:
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0095],ARef=[AI95-00034-01]}
+A formal derived subtype is constrained if and only if the ancestor
+subtype is constrained.
+A formal array type is constrained if and only if the declarations
address@hidden,Old=[says]}
address@hidden A formal private type is constrained if it does not have a
+discriminant part.],Old=[]}
+Other formal subtypes are unconstrained,
+even though they might be constrained in an instance.
+
+A formal subtype can be indefinite,
+even though the copy might be definite in an instance.
+
+A formal object of mode @key[in] is not a static constant;
+in an instance, the copy is static if the actual is.
+
+A formal subtype is not static,
+even though the actual might be.
+
+Formal types are specific,
+even though the actual can be class-wide.
+
+The subtype of a formal object of mode @key[in out]
+is not static.
+(This covers the case of AI83-00878.)
+
+The subtype of a formal parameter of
+a formal subprogram does not
+provide an applicable index constraint.
+
address@hidden,Kind=[Revised],ARef=[AI05-0239-1]}
+The profile of a formal subprogram is not @Chg{Version=[3],New=[subtype 
conformant],Old=[subtype-conformant]}
+with any other profile.
address@hidden conformance}
+
+A generic formal function is not static.
address@hidden
address@hidden
address@hidden
address@hidden@;The exceptions to the above rule about when legality rules are
+enforced fall into these categories:
address@hidden
address@hidden@;Some rules are checked in the generic declaration, and then 
again
+in both the visible and private parts of the instance:
address@hidden
+The parent type of a record extension has to be specific
+(see @RefSecNum{Type Extensions}).
+This rule is not checked in the instance body.
+
+The parent type of a private extension has to be specific
+(see @RefSecNum{Private Types and Private Extensions}).
+This rule is not checked in the instance body.
+
address@hidden,Kind=[Revised],ARef=[AI95-00402-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0093-1]}
+A type with an access discriminant @Chg{Version=[2],New=[with a
address@hidden ],Old=[]}has to be @Chg{Version=[3],New=[immutably
+limited. In the generic body, the definition of immutably limited is adjusted
+in an assume-the-worst manner (thus the rule is checked that way)],Old=[a
+descendant of @Chg{Version=[2],New=[an explicitly limited record type],Old=[a
+type declared with @key[limited]]}, or be a task or protected
+type. This rule is irrelevant in the instance body]}.
+
+In the declaration of a record extension,
+if the parent type is nonlimited, then each of the
+components of the @nt{record_extension_part} have to be nonlimited
+(see @RefSecNum{Type Extensions}).
+In the generic body, this rule is checked in an assume-the-worst
+manner.
+
+A preelaborated library unit has to be preelaborable
+(see @RefSecNum{Elaboration Control}).
+In the generic body, this rule is checked in an assume-the-worst
+manner.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00402-01]}
address@hidden,NoPrefix=[T],Text=[The corrections made by the
+Corrigendum added a number of such rules, and the Amendment added many more.
+There doesn't seem to be much value in repeating all of these rules here (as
+of this writing, there are roughly 33 such rules).
+As noted below, all such rules are indexed in the AARM.]}
+
address@hidden rule],Sec=(checking in generic units)}
+For the accessibility rules,
+the formals have nothing to say about the property in question.
+Like the above rules, these rules are checked in the generic declaration,
+and then again in both the visible and private parts of
+the instance.
+In the generic body, we have explicit rules that essentially
+assume the worst (in the cases of type extensions and
+access-to-subprogram types),
+and we have run-time checks
+(in the case of access-to-object types).
+See @RefSecNum{Type Extensions},
address@hidden of Access Types},
+and @RefSecNum{Type Conversions}.
+
address@hidden@;We considered run-time checks for access-to-subprogram types as 
well.
+However, this would present difficulties for
+implementations that share generic bodies.
+
+The rules requiring @lquotes@;address@hidden@; values for static expressions 
are
+ignored when the expected type for the expression is a descendant of a
+generic formal type other than a generic formal derived type,
+and do not apply in an instance.
+
+The rule forbidding two explicit homographs in the same declarative
+region does not apply in an instance of a generic unit,
+except that it @i{does} apply in the declaration of a record extension
+that appears in the visible part of an instance.
+
address@hidden@;Some rules do not apply at all in an instance,
+not even in the visible part:
address@hidden
address@hidden are not normally allowed to be multiply nested,
+but they can be in instances.
address@hidden
address@hidden
+
address@hidden contract issue}
+Each rule that is an exception is marked with
address@hidden@;generic contract issue;@rquotes@; look that up in the index to 
find them all.
address@hidden
address@hidden
+The @LegalityName@;s are the ones labeled @LegalityTitle.
+We are talking about all @LegalityName@;s in the entire language here.
+Note that, with some exceptions,
+the legality of a generic unit is checked even if there are no
+instantiations of the generic unit.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The @LegalityName@;s are described here, and
+the overloading rules were described earlier in this 
@Chg{Version=[3],New=[subclause],Old=[clause]}.
+Presumably, every @StaticSemName is sucked in by one of those.
+Thus, we have covered all the compile-time rules of the language.
+There is no need to say anything special about the @LinkTimeName@;s
+or the @RunTimeName@;s.
address@hidden
address@hidden
+Here is an example illustrating how this rule is checked:
address@hidden@;In the declaration of a record extension,
+if the parent type is nonlimited, then each of the
+components of the @nt{record_extension_part} shall be address@hidden@;
address@hidden
address@hidden
+    @key[type] Parent @key[is] @key[tagged] @key[private];
+    @key[type] Comp @key[is] @key[limited] @key[private];
address@hidden G1 @key[is]
+    @key[type] Extension @key[is] @key[new] Parent @key[with]
+        @key[record]
+            C : Comp; address@hidden Illegal!}
+        @key[end] @key[record];
address@hidden G1;
address@hidden
+
address@hidden,address@hidden AI-00114}
+The parent type is nonlimited, and the component type is limited,
+which is illegal.
+It doesn't matter that @Chg{New=[],Old=[an ]}one could imagine writing an
+instantiation with the actual for Comp being nonlimited @em we never get to
+the instance, because the generic itself is illegal.
+
address@hidden@;On the other hand:
address@hidden
address@hidden
+    @key[type] Parent @key[is] @key[tagged] @key[limited] @key[private]; 
address@hidden Parent is limited.}
+    @key[type] Comp @key[is] @key[limited] @key[private];
address@hidden G2 @key[is]
+    @key[type] Extension @key[is] @key[new] Parent @key[with]
+        @key[record]
+            C : Comp; address@hidden OK.}
+        @key[end] @key[record];
address@hidden G2;
+
address@hidden Limited_Tagged @key[is] @key[tagged] @key[limited] @key[null] 
@key[record];
address@hidden Non_Limited_Tagged @key[is] @key[tagged] @key[null] @key[record];
+
address@hidden Limited_Untagged @key[is] @key[limited] @key[null] @key[record];
address@hidden Non_Limited_Untagged @key[is] @key[null] @key[record];
+
address@hidden Good_1 @key[is] @key[new] G2(Parent => Limited_Tagged,
+                         Comp => Limited_Untagged);
address@hidden Good_2 @key[is] @key[new] G2(Parent => Non_Limited_Tagged,
+                         Comp => Non_Limited_Untagged);
address@hidden Bad  @key[is] @key[new] G2(Parent => Non_Limited_Tagged,
+                         Comp => Limited_Untagged); address@hidden Illegal!}
address@hidden
+
+The first instantiation is legal,
+because in the instance the parent is limited,
+so the rule is not violated.
+Likewise, in the second instantiation,
+the rule is not violated in the instance.
+However, in the Bad instance,
+the parent type is nonlimited,
+and the component type is limited,
+so this instantiation is illegal.
address@hidden
address@hidden
+
address@hidden
+A @nt{generic_instantiation} declares an instance;
+it is equivalent to the instance declaration (a @address@hidden
+or @address@hidden) immediately followed by the instance body,
+both at the place of the instantiation.
address@hidden
+The declaration and the body of the instance are not @lquotes@;address@hidden@;
+in the technical sense, even though you can't see them in the program text.
+Nor are declarations within an instance @lquotes@;address@hidden@;
+(unless they are implicit by other rules).
+This is necessary because implicit declarations have special semantics
+that should not be attached to instances.
+For a generic subprogram,
+the profile of a @nt{generic_instantiation} is that of the instance
+declaration, by the stated equivalence.
address@hidden
address@hidden
address@hidden part], Sec=(of an instance)}
address@hidden part], Sec=(of a package)}
+The visible and private parts of a package instance are defined in
address@hidden Specifications and Declarations}
+and @RefSec{Formal Packages}.
+The visible and private parts of a subprogram instance are defined in
address@hidden of Declarations}.
address@hidden
+
+The instance is a copy of the text of the template.
address@hidden use of a formal parameter
+becomes (in the copy) a use of the actual, as explained below.]
address@hidden instance}
address@hidden instance}
address@hidden instance}
address@hidden instance}
address@hidden, Sec=(of a generic package)}
address@hidden, Sec=(of a generic subprogram)}
address@hidden, Sec=(of a generic procedure)}
address@hidden, Sec=(of a generic function)}
+An instance of a generic package is a package,
+that of a generic procedure is a procedure, and that of a generic
+function is a function.
address@hidden
+An instance is a package or subprogram
+(because we say so),
+even though it contains a copy of the @nt{generic_formal_part},
+and therefore doesn't look like one.
+This is strange, but it's OK, since the syntax rules are overloading
+rules, and therefore do not apply in an instance.
address@hidden
address@hidden
+We use a macro-expansion model, with some explicitly-stated
+exceptions (see below).
+The main exception is that the interpretation of each construct in a
+generic unit
+(especially including the denotation of each name)
+is determined when the declaration and body of the generic unit
+(as opposed to the instance) are compiled,
+and in each instance this interpretation is (a copy of) the template
+interpretation.
+In other words, if a construct is interpreted as a @nt{name} denoting
+a declaration D, then in an instance, the copy of the construct will
+still be a name, and will still denote D (or a copy of D).
+From an implementation point of view,
+overload resolution is performed on the template,
+and not on each copy.
+
+We describe the substitution of generic actual parameters by saying
+(in most cases) that the copy of each generic formal parameter
+declares a view of the actual.
+Suppose a name in a generic unit denotes a
address@hidden
+The copy of that name in an instance will denote the copy of that
address@hidden in the instance.
+Since the @nt{generic_formal_parameter_declaration} in the instance
+declares a view of the actual,
+the name will denote a view of the actual.
+
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
+Other properties of the copy (for example, staticness,
address@hidden,New=[categories],Old=[classes]} to
+which types belong) are recalculated for each instance;
+this is implied by the fact that it's a copy.
+
address@hidden,Kind=[Revised],ARef=[AI95-00317-01]}
+Although the @nt{generic_formal_part} is included in an instance,
+the declarations in the @nt{generic_formal_part} are only visible
+outside the instance in the case of a generic formal package whose
address@hidden @Chg{Version=[2],New=[includes one or more
+<> indicators],Old=[is (<>)]}
address@hidden see @RefSecNum{Formal Packages}.
address@hidden
+
+The interpretation
+of each construct within a generic declaration or body is determined
+using the overloading rules
+when that generic declaration or body is compiled.
+In an instance, the interpretation of each (copied) construct is the
+same,
+except in the case of a name that denotes the
address@hidden
+or some declaration within the generic unit;
+the corresponding name in the instance then denotes the corresponding copy
+of the denoted declaration.
+The overloading rules do not apply in the instance.
address@hidden
+See @RefSec{The Context of Overload Resolution} for definitions of
address@hidden@;address@hidden@; and @lquotes@;overloading address@hidden@;
+
+Even the @nt{generic_formal_parameter_declaration}s have corresponding
+declarations in the instance,
+which declare views of the actuals.
+
+Although the declarations in the instance are copies of those in the
+generic unit, they often have quite different properties,
+as explained below.
+For example a constant declaration in the generic unit might declare
+a nonstatic constant, whereas the copy of that declaration might
+declare a static constant.
+This can happen when the staticness depends on some generic formal.
+
+This rule is partly a ramification of the @lquotes@;current address@hidden@;
+rule in @RefSec{The Context of Overload Resolution}.
+Note that that rule doesn't cover the @nt{generic_formal_part}.
+
+Although the overloading rules are not observed in the instance,
+they are, of course, observed in the @ntf{_instantiation} in order to
+determine the interpretation of the constituents of the
address@hidden
+
+Since children are considered to occur within their parent's
+declarative region, the above rule applies to a name that denotes a
+child of a generic unit, or a declaration inside such a child.
+
+Since the @SyntaxName@;s are overloading rules,
+it is possible (legal) to violate them in an instance.
+For example, it is possible for an instance body to occur in a
address@hidden, even though the @SyntaxName@;s forbid bodies
+in @nt{package_specification}s.
address@hidden
+
+In an instance,
+a @nt{generic_formal_parameter_declaration} declares a view
+whose properties are identical to those of the actual,
+except as specified in
address@hidden Objects} and @RefSec{Formal Subprograms}.
+Similarly, for a declaration within
+a @nt{generic_formal_parameter_declaration},
+the corresponding declaration in an instance declares a view whose
+properties are identical to the corresponding declaration within the
+declaration of the actual.
address@hidden
+  In an instance,
+  there are no @lquotes@;address@hidden@; of types and subtypes
+  that come from the formal.
+  The primitive operations of the type come from the
+  formal, but these are declarations in their own right,
+  and are therefore handled separately.
+
+  Note that certain properties that come from the actuals are
+  irrelevant in the instance.
+  For example, if an actual type is of a class deeper in the
+  derived-type hierarchy than the formal,
+  it is impossible to call the additional operations of the deeper class
+  in the instance,
+  because any such call would have to be a copy of some corresponding call
+  in the generic unit,
+  which would have been illegal.
+  However, it is sometimes possible to reach into the specification of
+  the instance from outside, and notice such properties.
+  For example, one could pass an object declared in the instance
+  specification to one of the additional operations of the deeper type.
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+  A @nt{formal_type_declaration} can contain
+  @nt{discriminant_specification}s,
+  a @nt{formal_subprogram_declaration} can contain
+  @Chg{Version=[2],address@hidden,address@hidden, and
+  a @nt{formal_package_declaration} can contain many kinds of
+  declarations.
+  These are all inside the generic unit, and have corresponding
+  declarations in the instance.
+
+  This rule implies, for example, that if a subtype in a generic unit
+  is a subtype of a generic formal subtype,
+  then the corresponding subtype in the instance is a subtype of the
+  corresponding actual subtype.
+
+  For a @nt{generic_instantiation},
+  if a generic actual is a static @Redundant[(scalar or string)] subtype,
+  then each use of the corresponding formal parameter within the
+  specification of the instance is considered to be static.
+  (See AI83-00409.)
+
+  Similarly, if a generic actual is a static expression and
+  the corresponding formal parameter has a
+  static @Redundant[(scalar or string)] subtype,
+  then each use of the formal parameter in the specification of the
+  instance is considered to be static.
+  (See AI83-00505.)
+
+  @leading@;If a primitive subprogram of a type derived from a generic formal
+  derived tagged type is not overriding (that is, it is a new
+  subprogram), it is possible for the copy of that subprogram in
+  an instance to override a subprogram inherited from the actual.
+  For example:
address@hidden
address@hidden T1 @key[is] @key[tagged] @key[record] ... @key[end] @key[record];
+
address@hidden
+    @key[type] Formal @key[is] @key[new] T1;
address@hidden G @key[is]
+    @key[type] Derived_From_Formal @key[is] @key[new] Formal @key[with] 
@key[record] ... @key[end] @key[record];
+    @key[procedure] Foo(X : @key[in] Derived_From_Formal); address@hidden Does 
not override anything.}
address@hidden G;
+
address@hidden T2 @key[is] @key[new] T1 @key[with] @key[record] ... @key[end] 
@key[record];
address@hidden Foo(X : @key[in] T2);
+
address@hidden Inst @key[is] @key[new] G(Formal => T2);
address@hidden
+
+In the instance Inst,
+the declaration of Foo for Derived_From_Formal
+overrides the Foo inherited from T2.
address@hidden
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+For formal types,
+an implementation that shares the code among multiple instances of the
+same generic unit needs to beware that things like parameter passing
+mechanisms (by-copy vs. by-reference) and
address@hidden@nt{aspect_clause}s],address@hidden are
+determined by the actual.
address@hidden
+
address@hidden declarations are also copied,
+and a name that denotes an implicit declaration in the generic
+denotes the corresponding copy in the instance.
+However, for a type declared within the visible part of the
+generic, a whole new set of primitive subprograms
+is implicitly declared for use outside the instance,
+and may differ from the copied set if the properties of the
+type in some way depend on the properties of some actual type
+specified in the instantiation.
+For example, if the type in the generic is derived
+from a formal private type, then in the instance the type
+will inherit subprograms from the corresponding actual type.
+
address@hidden
+These new implicit declarations occur immediately after the type
+declaration in the instance, and override
+the copied ones. The copied ones
+can be called only from within the instance; the new
+ones can be called only from outside the instance, although
+for tagged types, the
+body of a new one can be executed by a call to an old one.]
address@hidden
+This rule is stated officially in @RefSec{Visibility}.
address@hidden
address@hidden
+The new ones follow from the class(es) of the formal types.
+For example, for a type T derived from a generic formal private type,
+if the actual is Integer, then the copy of T in the instance has a
+"+" primitive operator,
+which can be called from outside the instance
+(assuming T is declared in the visible part of the instance).
+
+AI83-00398.
+
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
+Since an actual type is always in the
address@hidden,New=[category],Old=[class]} determined for
+the formal, the new subprograms hide all of the copied ones,
+except for a declaration of "/=" that corresponds to an explicit
+declaration of "=".
+Such "/=" operators are special, because unlike other implicit
+declarations of primitive subprograms, they do not appear by virtue
+of the class, but because of an explicit declaration of "=".
+If the declaration of "=" is implicit (and therefore overridden
+in the instance), then a corresponding implicitly declared "/="
+is also overridden.
+But if the declaration of "=" is explicit (and therefore not overridden
+in the instance), then a corresponding implicitly declared "/="
+is not overridden either,
+even though it's implicit.
+
+Note that the copied ones can be called from inside the instance, even
+though they are hidden from all visibility,
+because the names are resolved in the generic unit @em visibility
+is irrelevant for calls in the instance.
address@hidden
+
address@hidden the visible part of an instance, an explicit declaration
+overrides an implicit declaration if they are homographs,
+as described in @RefSecNum{Visibility}.]
+On the other hand, an explicit declaration in
+the private part of an instance overrides an implicit
+declaration in the instance, only if the corresponding explicit
+declaration in the generic overrides a corresponding
+implicit declaration in the generic.
+Corresponding rules apply to the other kinds of overriding
+described in @RefSecNum{Visibility}.
address@hidden
address@hidden@;For example:
address@hidden
address@hidden Ancestor @key[is] @key[tagged] @key[null] @key[record];
+
address@hidden
+    @key[type] Formal @key[is] @key[new] Ancestor @key[with] @key[private];
address@hidden G @key[is]
+    @key[type] T @key[is] @key[new] Formal @key[with] @key[null] @key[record];
+    @key[procedure] P(X : @key[in] T); address@hidden (1)}
address@hidden
+    @key[procedure] Q(X : @key[in] T); address@hidden (2)}
address@hidden G;
+
address@hidden Actual @key[is] @key[new] Ancestor @key[with] @key[null] 
@key[record];
address@hidden P(X : @key[in] Actual);
address@hidden Q(X : @key[in] Actual);
+
address@hidden Instance @key[is] @key[new] G(Formal => Actual);
address@hidden
+
+In the instance, the copy of P at (1) overrides Actual's P,
+whereas the copy of Q at (2) does not override anything;
+in implementation terms, it occupies a separate slot in
+the type descriptor.
address@hidden
address@hidden
+The reason for this rule is so a programmer writing an
address@hidden need not look at the private part of the generic in
+order to determine which subprograms will be overridden.
address@hidden
address@hidden
+
address@hidden
+Recursive generic instantiation is not allowed in the following
+sense: if a given generic unit includes an instantiation of a second
+generic unit, then the instance generated by this instantiation shall
+not include an instance of the first generic unit
address@hidden(whether this instance is generated directly, or indirectly
+by intermediate instantiations)].
address@hidden
+Note that this rule is not a violation of the generic contract model,
+because it is not a @LegalityName.
+Some implementations may be able to check this rule at compile time,
+but that requires access to all the bodies,
+so we allow implementations to check the rule at link time.
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(generic_instantiation)}
+For the elaboration of a @nt{generic_instantiation},
+each @nt{generic_association} is first evaluated.
+If a default is used,
+an implicit @nt{generic_association} is assumed for this rule.
+These evaluations are done in an arbitrary order, except that the
+evaluation for a default actual takes place after the evaluation
+for another actual if the default includes a @nt{name}
+that denotes the other address@hidden order],Sec=[allowed]}
+Finally, the instance declaration and body are elaborated.
address@hidden
+Note that if the evaluation of a default depends on some side effect
+of some other evaluation,
+the order is still arbitrary.
address@hidden
+
address@hidden, Sec=(generic_association)}
+For the evaluation of a @nt{generic_association}
+the generic actual parameter is evaluated.
+Additional actions are performed in the case of a formal object of
+mode @key{in} (see @RefSecNum{Formal Objects}).
address@hidden
+Actually, the actual is evaluated only if evaluation is defined for that
+kind of construct @em we don't actually @lquotes@;address@hidden@; 
@nt{subtype_mark}s.
address@hidden
address@hidden
+
address@hidden
+If a formal type is not tagged, then the type is treated as
+an untagged type within the generic body.
+Deriving from such a type in a generic body is permitted;
+the new type does not get a new tag value,
+even if the actual is tagged.
+Overriding operations for such a derived type cannot be dispatched to
+from outside the instance.
address@hidden
+If two overloaded subprograms declared in a generic package
+specification differ only by the (formal) type of their parameters and
+results, then there exist legal instantiations for which all calls of
+these subprograms from outside the instance are ambiguous. For example:
address@hidden
address@hidden
+   @key[type] A @key[is] (<>);
+   @key[type] B @key[is] @key[private];
address@hidden G @key[is]
+   @key[function] Next(X : A) @key[return] A;
+   @key[function] Next(X : B) @key[return] B;
address@hidden G;
+
address@hidden P @key[is] @key[new] G(A => Boolean, B => Boolean);
address@hidden All calls of P.Next are ambiguous.}
address@hidden
address@hidden
address@hidden
address@hidden@;The following example illustrates some of the subtleties of the
+substitution of formals and actuals:
address@hidden
address@hidden
+    @key[type] T1 @key[is] @key[private];
+    address@hidden A predefined "=" operator is implicitly declared here:}
+    address@hidden function "="(Left, Right : T1) return Boolean;}
+    address@hidden Call this "="@-{1}.}
address@hidden G @key[is]
+    @key[subtype] S1 @key[is] T1; address@hidden So we can get our hands on 
the type from}
+                      address@hidden outside an instance.}
+    @key[type] T2 @key[is] @key[new] T1;
+    address@hidden An inherited "=" operator is implicitly declared here:}
+    address@hidden function "="(Left, Right : T2) return Boolean;}
+    address@hidden Call this "="@-{2}.}
+
+    T1_Obj : T1 := ...;
+    Bool_1 : Boolean := T1_Obj = T1_Obj;
+
+    T2_Obj : T2 := ...;
+    Bool_2 : Boolean := T2_Obj = T2_Obj;
address@hidden G;
+...
+
address@hidden P @key[is]
+    @key[type] My_Int @key[is] @key[new] Integer;
+    address@hidden A predefined "=" operator is implicitly declared here:}
+    address@hidden function "="(Left, Right : My_Int) return Boolean;}
+    address@hidden Call this "="@-{3}.}
+    @key[function] "="(X, Y : My_Int) @key[return] Boolean;
+    address@hidden Call this "="@-{4}.}
+    address@hidden "="@-{3} is hidden from all visibility by "="@-{4}.}
+    address@hidden Nonetheless, "="@-{3} can @lquotes@;address@hidden@; in 
certain circumstances.}
address@hidden P;
address@hidden P;
+...
address@hidden I @key[is] @key[new] G(T1 => My_Int); address@hidden "="@-{5} is 
declared in I (see below).}
address@hidden I;
+
+Another_T1_Obj : S1 := 13; address@hidden Can't denote T1, but S1 will do.}
+Bool_3 : Boolean := Another_T1_Obj = Another_T1_Obj;
+
+Another_T2_Obj : T2 := 45;
+Bool_4 : Boolean := Another_T2_Obj = Another_T2_Obj;
+
+Double : T2 := T2_Obj + Another_T2_Obj;
address@hidden
+
+In the instance I, there is a copy of "="@-{1} (call it "="@-{1i}) and
+"="@-{2} (call it "="@-{2i}).
+The "="@-{1i} and "="@-{2i} declare views of the predefined "=" of My_Int
+(that is, "="@-{3}).
+In the initialization of Bool_1 and Bool_2 in the generic unit G,
+the names "=" denote "="@-{1} and "="@-{2}, respectively.
+Therefore, the copies of these names in the instances
+denote "="@-{1i} and "="@-{2i}, respectively.
+Thus, the initialization of I.Bool_1 and I.Bool_2 call the predefined
+equality operator of My_Int;
+they will not call "="@-{4}.
+
+The declarations "="@-{1i} and "="@-{2i} are hidden from all
+visibility.
+This prevents them from being called from outside the instance.
+
+The declaration of Bool_3
+calls "="@-{4}.
+
+The instance I also contains implicit declarations of the primitive
+operators of T2, such as "=" (call it "="@-{5}) and "+".
+These operations cannot be called from within the instance,
+but the declaration of Bool_4 calls "="@-{5}.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of generic instantiations (see
address@hidden Declarations}):}
address@hidden
address@hidden()@tabset(P49)
address@hidden Swap @key[is] @key[new] Exchange(Elem => Integer);
address@hidden Swap @key[is] @key[new] Exchange(Character);  @address@hidden  
Swap is overloaded }
address@hidden Square @key[is] @key[new] Squaring(Integer); @address@hidden  
"*" of Integer used by default}
address@hidden Square @key[is] @key[new] Squaring(Item => Matrix, "*" => 
Matrix_Product);
address@hidden Square @key[is] @key[new] Squaring(Matrix, Matrix_Product); 
address@hidden same as previous    }
+
address@hidden Int_Vectors @key[is] @key[new] On_Vectors(Integer, Table, "+");
address@hidden
+
address@hidden
address@hidden@address@hidden of uses of instantiated units:}
address@hidden
address@hidden
+Swap(A, B);
+A := Square(A);
+
+T : Table(1 .. 5) := (10, 20, 30, 40, 50);
+N : Integer := Int_Vectors.Sigma(T);  address@hidden  150 (see @RefSec{Generic 
Bodies} for the body of Sigma)}
+
address@hidden Int_Vectors;
+M : Integer := Sigma(T);  address@hidden  150}
address@hidden
address@hidden
+
address@hidden
address@hidden with Ada 83}
+In Ada 83, all explicit actuals are evaluated before all defaults,
+and the defaults are evaluated in the order of the formal
+declarations.
+This ordering requirement is relaxed in Ada 95.
address@hidden
+
address@hidden
address@hidden with Ada 83}
+We have attempted to remove every violation of the contract model.
+Any remaining contract model violations should be considered bugs in
+the RM95.
+The unfortunate property of reverting to the predefined operators of
+the actual types is retained for upward compatibility.
+(Note that fixing this would require subtype conformance rules.)
+However, tagged types do not revert in this sense.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax rule for @nt{explicit_generic_actual_parameter} is modified to 
allow a
address@hidden@nt{name}.
address@hidden
+
address@hidden
+The fact that named associations cannot be used for two formal
+subprograms with the same defining name is moved to AARM-only material,
+because it is a ramification of other rules, and because it is not of
+interest to the average user.
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+The rule that
address@hidden@;An explicit @nt{explicit_generic_actual_parameter} shall not be 
supplied more
+than once for a given @Chg{Version=[2],New=[generic formal parameter],
address@hidden@rquotes@;
+seems to be missing from RM83, although it was clearly the intent.
+
+In the explanation that the instance is a copy of the template,
+we have left out RM83-12.3(5)'s @lquotes@;apart from the generic formal
address@hidden@;, because it seems that things in the formal part still need to
+exist in instances.
+This is particularly true for generic formal packages,
+where you're sometimes allowed to reach in and denote the formals of
+the formal package from outside it.
+This simplifies the explanation of what each name in an instance
+denotes: there are just two cases: the declaration can be inside or
+outside (where inside needs to include the generic unit itself).
+Note that the RM83 approach of listing many cases (see RM83-12.5(5-14))
+would have become even more unwieldy with the addition of generic formal
+packages, and the declarations that occur therein.
+
+We have corrected the definition of the elaboration of a
address@hidden (RM83-12.3(17)); we don't elaborate
+entities, and the instance is not @lquotes@;address@hidden@;
+
+In RM83, there is a rule saying the formal and actual shall match, and
+then there is much text defining what it means to match.
+Here, we simply state all the latter text as rules.
+For example, @lquotes@;A formal foo is matched by an actual greenish 
address@hidden@;
+becomes @lquotes@;For a formal foo, the actual shall be a greenish 
address@hidden@;
+This is necessary to split the @ResolutionName@;s
+from the @LegalityName@;s.
+Besides, there's really no need to define the concept of matching for
+generic parameters.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00218-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  An @nt{overriding_indicator} (see
+  @RefSecNum{Overriding Indicators}) is allowed on a subprogram 
instantiation.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a 
@nt{generic_instantiation}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0118-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a definition for
+  positional parameters, as this is missing from Ada 95 and Ada 2005.]}
address@hidden
+
+
address@hidden Objects}
+
address@hidden
address@hidden@Defn{generic formal object}
address@hidden object, generic}
+A generic formal object can be used to pass a value or variable
+to a generic unit.]
address@hidden
+
address@hidden
+A generic formal object of mode @key{in} is like a constant
+initialized to the value of the @nt{explicit_generic_actual_parameter}.
+
+A generic formal object of mode @key{in out} is like a renaming
+of the @nt{explicit_generic_actual_parameter}.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00423-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0005-1],ARef=[AI05-0183-1]}
address@hidden<formal_object_declaration>,rhs="
+    @Syn2{defining_identifier_list} : @Syn2{mode} 
@Chg{Version=[2],New=<address@hidden >,Old=<>address@hidden [:= 
@address@hidden,New=<
+        address@hidden>,Old=[]};@Chg{Version=[2],New=<
+  @Chg{Version=[3],New=[|],Old=[ ]}  @Syn2{defining_identifier_list} : 
@Syn2{mode} @Syn2{access_definition} [:= @address@hidden,New=<
+        address@hidden>,Old=[]};>,Old=<>}"}
address@hidden
+
address@hidden
address@hidden type],
+  Sec=(generic formal object default_expression)}
+The expected type for the @nt{default_expression}, if any, of a formal
+object is the type of the formal object.
+
+
address@hidden type], Sec=(generic formal in object actual)}
+For a generic formal object of mode @key[in],
+the expected type for the actual is the type of the formal.
+
address@hidden,Kind=[Revised],ARef=[AI95-00423-01]}
+For a generic formal object of mode @key[in out],
+the type of the actual shall resolve to the type @Chg{Version=[2],
+New=[determined by the @nt{subtype_mark}, or for a
address@hidden with an @nt{access_definition}, to a specific
+anonymous access type. If the anonymous access type is an access-to-object 
type,
+the type of the actual shall
+have the same designated type as that of the @nt{access_definition}.
+If the anonymous access type is an access-to-subprogram type, the type
+of the actual shall have a designated profile which
+is type conformant with that of the @nt{access_definition}.
address@hidden conformance],Sec=(required)}],Old=[of the formal.]}
address@hidden
+See the corresponding rule for @nt{object_renaming_declaration}s for a
+discussion of the reason for this rule.
address@hidden
+
address@hidden
+
address@hidden
+If a generic formal object has a @nt{default_expression},
+then the mode shall be @key{in}
address@hidden(either explicitly or by default)];
+otherwise, its mode shall be either @key{in} or @key{in out}.
address@hidden
+Mode @key{out} is not allowed for generic formal objects.
address@hidden
+
+For a generic formal object of mode @key{in}, the actual shall be an
address@hidden
+For a generic formal object of mode @key{in out}, the actual shall be
+a @nt{name} that denotes a variable for which renaming is allowed
+(see @RefSecNum{Object Renaming Declarations}).
address@hidden
+The part of this that requires an @nt{expression} or @nt{name} is a
address@hidden,
+but that's too pedantic to worry about.
+(The part about denoting a variable, and renaming being allowed,
+is most certainly @i{not} a @ResolutionName.)
address@hidden
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00287-01],ARef=[AI95-00423-01]}
address@hidden,Type=[Leading],address@hidden leading}
address@hidden,New=[In the case where the type of the formal is defined by an
address@hidden, the type of the actual and the type of the formal:],
+Old=[The type of a generic formal object of mode
address@hidden shall be nonlimited.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00423-01]}
+  @ChgAdded{Version=[2],Text=[shall both be access-to-object types with
+  statically matching designated subtypes and with both or neither being
+  access-to-constant types; or
+  @PDefn2{Term=[statically matching],Sec=(required)}]}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00423-01]}
+  @ChgAdded{Version=[2],Text=[shall both be access-to-subprogram types with
+  subtype conformant designated profiles.
+  @Defn2{Term=[subtype conformance],Sec=(required)}]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00423-01]}
address@hidden,Type=[Leading],Text=[For a
address@hidden with a @nt{null_exclusion} or an
address@hidden that has a @nt{null_exclusion}:]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[if the actual matching the
+  @nt{formal_object_declaration} denotes the generic formal object
+  of another generic unit @i{G}, and the instantiation containing the actual
+  occurs within the body
+  of @i{G} or within the body of a generic unit declared within the declarative
+  region of @i{G}, then the declaration of the formal object of @i{G}
+  shall have a @nt{null_exclusion};]}
+
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[otherwise, the subtype of the actual
+  matching the @nt{formal_object_declaration} shall exclude null.
+  @PDefn{generic contract issue}
+  In addition to the places where @LegalityTitle normally apply
+  (see @RefSecNum{Generic Instantiation}),
+  this rule applies also in the private part of an
+  instance of a generic unit.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00287-01],ARef=[AI95-00423-01]}
+  @Chg{Version=[2],New=[This rule prevents @lquotes@;address@hidden
+  @b<Null> must never be the value of an object with an explicit
+  @nt{null_exclusion}. The first bullet is an assume-the-worst rule
+  which prevents trouble in generic bodies (including bodies of child
+  units) when the subtype of the formal object excludes null implicitly.],
+  Old=[Since a generic formal object is like a
+  constant of mode @key{in} initialized to the value of the actual,
+  a limited type would not make sense, since initializing a constant is
+  not allowed for a limited type.
+  That is, generic formal objects of mode @key{in} are passed by copy,
+  and limited types are not supposed to be copied.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00255-01],ARef=[AI95-00423-01]}
+A @nt{formal_object_declaration} declares a generic formal object.
+The default mode is @key{in}.
address@hidden subtype], Sec=(of a generic formal object)}
+For a formal object of mode @key{in},
+the nominal subtype is the one denoted by the
address@hidden @Chg{Version=[2],New=[or @nt{access_definition} ],Old=[]}in
+the declaration of the formal.
address@hidden, Sec=(subtype)}
+For a formal object of mode @key{in out}, its type
+is determined by the @nt<subtype_mark> @Chg{Version=[2],
+New=[or @nt{access_definition} ],Old=[]}in the declaration;
+its nominal subtype is nonstatic, even if the
address@hidden<subtype_mark> denotes a static address@hidden,
+New=[; for a composite type, its nominal subtype is unconstrained if the first
+subtype of the type is address@hidden, even if the @nt{subtype_mark}
+denotes a constrained subtype]],Old=[]}.
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00255-01]}
+  @ChgAdded{Version=[2],Text=[We require that the subtype is
+  unconstrained because a formal @key{in out} acts like a renaming, and
+  thus the given subtype is ignored for purposes of matching; any value of
+  the type can be passed. Thus we can assume only that the object is
+  constrained if the first subtype is constrained (and thus there can be
+  no unconstrained subtypes for the type). If we didn't do this, it
+  would be possible to
+  rename or take 'Access of components that could disappear due to an
+  assignment to the whole object.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00423-01]}
+  @ChgAdded{Version=[2],Text=[The two @lquotes@;even address@hidden clauses are
+  OK even though they don't mention @nt{access_definition}s; an access subtype
+  can neither be a static subtype nor be a composite type.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00269-01]}
address@hidden,address@hidden constant declaration],
+  Sec=(corresponding to a formal object of mode @key[in])}],Old=[]}
address@hidden constant],
+  Sec=(corresponding to a formal object of mode @key[in])}
address@hidden object}
+In an instance,
+a @nt{formal_object_declaration} of mode @key{in}
address@hidden,New=[is a @i<full constant declaration> and ],
+Old=[]}declares a new stand-alone constant
+object whose initialization expression is the actual,
+whereas a @nt{formal_object_declaration} of mode @key{in out}
+declares a view whose properties are identical to those of the actual.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
+These rules imply that generic formal objects of mode @key{in} are
+passed by address@hidden,New=[ (or are built-in-place for
+a limited type)],Old=[]},
+whereas generic formal objects of mode @key{in out} are passed by
+reference.
+
+Initialization and finalization happen for the constant declared by
+a @nt{formal_object_declaration} of mode @key{in} as for any constant;
+see @RefSec{Object Declarations}
+and @RefSec{Assignment and Finalization}.
+
address@hidden, Sec=(of a generic formal object)}
+In an instance,
+the subtype of a generic formal object of mode
address@hidden is as for the equivalent constant.
+In an instance,
+the subtype of a generic formal object of mode @key{in out}
+is the subtype of the corresponding generic actual.
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(generic_association for a formal
+object of mode @key{in})}
address@hidden operation], Sec=(during evaluation of a
address@hidden for a formal object of mode @key{in})}
+For the evaluation of a @nt{generic_association}
+for a formal object of mode @key{in},
+a constant object is created, the value of the actual parameter
+is converted to the nominal subtype of the formal object,
+and assigned to the address@hidden, including any value adjustment @em
+see @RefSecNum{Assignment and Finalization}].
address@hidden subtype conversion],Sec=(generic formal object of mode @key[in])}
address@hidden
+This includes evaluating the actual
+and doing a subtype conversion,
+which might raise an exception.
address@hidden
address@hidden
+The rule for evaluating a @nt<generic_association> for a formal
+object of mode @key{in out} is covered by
+the general Dynamic Semantics rule in @RefSecNum{Generic Instantiation}.
address@hidden
address@hidden
+
address@hidden
+The constraints that apply to a generic formal object of mode @key{in
+out} are those of the corresponding generic actual parameter (not
+those implied by the @nt{subtype_mark} that appears in the
address@hidden).
+Therefore, to avoid confusion, it is recommended that the name of a
+first subtype
+be used for the declaration of such a formal object.
address@hidden
+Constraint checks are done at instantiation time for formal objects of
+mode @key{in},
+but not for formal objects of mode @key{in out}.
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+In Ada 83, it is forbidden to pass a (nongeneric) formal parameter
+of mode @key{out}, or a subcomponent thereof, to a generic formal
+object of mode @key{in out}.
+This restriction is removed in Ada 95.
address@hidden
+
address@hidden
+We make @lquotes@;@address@hidden@; explicit in the syntax.
+RM83 refers to the mode without saying what it is.
+This is also more uniform with the way (nongeneric) formal parameters
+are defined.
+
+We considered allowing mode @key{out} in Ada 95,
+for uniformity with (nongeneric) formal parameters.
+The semantics would be identical for modes @key{in out} and
address@hidden
+(Note that generic formal objects of mode @key{in out} are passed by
+reference. Note that for (nongeneric) formal parameters that are
+allowed to be passed by reference, the semantics of @key{in out} and
address@hidden is the same. The difference might serve as documentation.
+The same would be true for generic formal objects, if @key{out} were
+allowed, so it would be consistent.)
+We decided not to make this change, because it does not produce any
+important benefit, and any change has some cost.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  A generic formal @key{in} object can have
+  a limited type. The actual for such an object must be built-in-place
+  via a @nt{function_call} or @nt{aggregate}, see @RefSecNum{Limited Types}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00423-01]}
+  @ChgAdded{Version=[2],Text=[A generic formal object can have
+  a @nt{null_exclusion} or an anonymous access type.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00255-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that the nominal subtype of a
+  composite formal @key{in out} object is unconstrained if the first subtype
+  of the type is unconstrained.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00269-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that a formal @key{in} object can
+  be static when referenced from outside of the instance (by declaring
+  such an object to be a full constant declaration).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a 
@nt{formal_object_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden Types}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
address@hidden generic formal subtype can be used to pass to a generic unit
+a subtype whose type is in a certain @Chg{Version=[2],New=[category],
+Old=[class]} of types.]
address@hidden
+We considered having intermediate syntactic categories
address@hidden,
address@hidden, and
address@hidden,
+to be more uniform with the syntax rules for non-generic-formal
+types.
+However, that would make the rules for formal types slightly more
+complicated, and it would cause confusion,
+since @nt{formal_discrete_type_definition} would not fit into the
+scheme very well.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0213-1]}
address@hidden<formal_type_declaration>,rhs="
+    @Chg{Version=[3],New=[  @Syn2{formal_complete_type_declaration}
+    | @Syn2{formal_incomplete_type_declaration}],Old=<@key{type} 
@address@hidden @key{is} @Syn2{formal_type_definition};>}"}
+
address@hidden,Kind=[Added],ARef=[AI05-0183-1],ARef=[AI05-0213-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<formal_complete_type_declaration>,Old=<>}>,rhs="@Chg{Version=[3],New=<
+    @key{type} @address@hidden @key{is} @Syn2{formal_type_definition}
+        address@hidden;>,Old=<>}"}
+
address@hidden,Kind=[Added],ARef=[AI05-0213-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<formal_incomplete_type_declaration>,Old=<>}>,rhs="@Chg{Version=[3],New=<
+    @key{type} @address@hidden address@hidden tagged}];>,Old=<>}"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00251-01]}
address@hidden<formal_type_definition>,rhs="
+      @Syn2{formal_private_type_definition}
+    | @Syn2{formal_derived_type_definition}
+    | @Syn2{formal_discrete_type_definition}
+    | @Syn2{formal_signed_integer_type_definition}
+    | @Syn2{formal_modular_type_definition}
+    | @Syn2{formal_floating_point_definition}
+    | @Syn2{formal_ordinary_fixed_point_definition}
+    | @Syn2{formal_decimal_fixed_point_definition}
+    | @Syn2{formal_array_type_definition}
+    | @address@hidden,New=[
+    | @Syn2{formal_interface_type_definition}],Old=[]}"}
address@hidden
+
address@hidden
address@hidden actual subtype}
address@hidden subtype}
address@hidden actual type}
address@hidden type}
+For a generic formal subtype, the actual shall be
+a @nt{subtype_mark};
+it denotes the @i{(generic) actual subtype}.
address@hidden
+When we say simply @lquotes@;address@hidden@; or @lquotes@;address@hidden@; 
(for a generic
+formal that denotes a subtype) we're talking about the subtype, not
+the type, since a name that denotes a @nt{formal_type_declaration}
+denotes a subtype, and the corresponding actual also denotes a
+subtype.
address@hidden
address@hidden
+
address@hidden
address@hidden formal type}
address@hidden type}
address@hidden formal subtype}
address@hidden subtype}
+A @nt{formal_type_declaration} declares a @i{(generic) formal type},
+and its first subtype, the @i{(generic) formal subtype}.
address@hidden
+A subtype (other than the first subtype)
+of a generic formal type is not a generic formal subtype.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0213-1]}
address@hidden,address@hidden category for a formal type}
address@hidden determined for a formal type}],
address@hidden class for a formal type}
address@hidden determined for a formal type}]}
+The form of a @nt{formal_type_definition} @i{determines a
address@hidden,New=[category (of types)],Old=[class]}} to which the
+formal type belongs.
+For a @nt{formal_private_type_definition} the reserved words
address@hidden and @key{limited} indicate the @Chg{Version=[2],New=[category of 
types],Old=[class]}
+(see @RefSecNum{Formal Private and Derived Types})address@hidden,New=[
+The reserved word @key{tagged} also plays this role in the case of a
address@hidden,Old=[]}
+For a @nt{formal_derived_type_definition} the
address@hidden,New=[category of types],Old=[class]} is
+the derivation class rooted at the ancestor type.
+For other formal types,
+the name of the syntactic category indicates the
address@hidden,New=[category of types],Old=[class]};
+a @nt{formal_discrete_type_definition} defines a discrete type,
+and so on.
address@hidden
+This rule is clearer with the flat syntax rule for
address@hidden given above.
+Adding @ntf{formal_integer_type_definition} and others would make this
+rule harder to state clearly.
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00442-01]}
address@hidden,Text=[We use @lquotes@;address@hidden rather than
address@hidden@;address@hidden above, because the requirement that classes are
+closed under derivation is not important here. Moreover, there are
+interesting categories that are not closed under derivation. For instance,
+limited and interface are categories that do not form classes.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
+The actual type shall be in the @Chg{Version=[2],New=[category],Old=[class]}
+determined for the formal.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
+For example, if the @Chg{Version=[2],New=[category],Old=[class]} determined
+for the formal is the @Chg{Version=[2],New=[category],Old=[class]} of all
+discrete types, then the actual has to be discrete.
+
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
+Note that this rule does not require the actual to belong to every
address@hidden,New=[category],Old=[class]} to which the formal belongs.
+For example, formal private types are in the
address@hidden,New=[category],Old=[class]} of composite types,
+but the actual need not be composite.
+Furthermore, one can imagine an infinite number of @Chg{Version=[2],
+New=[categories],Old=[classes]} that are just
+arbitrary sets of types @Chg{Version=[2],New=[],Old=[that obey the
+closed-under-derivation rule,
+and are therefore technically classes]}
+(even though we don't give them names,
+since they are uninteresting).
+We don't want this rule to apply to @i{those}
address@hidden,New=[categories],Old=[classes]}.
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01],ARef=[AI95-00442-01]}
address@hidden@;address@hidden@; is not @Chg{Version=[2],New=[an],Old=[a]}
address@hidden@;address@hidden@; @Chg{Version=[2],New=[category],Old=[class]},
+but @lquotes@;address@hidden@; is;
+it is legal to pass a nonlimited type to a limited formal type,
+but not the other way around.
+The reserved word @Chg{Version=[2],address@hidden,address@hidden really 
represents a
address@hidden,New=[category],Old=[class]} containing
+both limited and nonlimited types.
address@hidden@;address@hidden@; is not a @Chg{Version=[2],New=[category for 
this purpose],
+Old=[class]}; a generic formal private type accepts
+both private and nonprivate actual types.
+
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
+It is legal to pass a class-wide subtype as the actual
+if it is in the right @Chg{Version=[2],New=[category],Old=[class]},
+so long as the formal has unknown discriminants.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0037],ARef=[AI95-00043-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00233-01],ARef=[AI95-00442-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0029-1]}
address@hidden formal type also belongs to each
address@hidden,New=[category],Old=[class]} that contains
+the determined @Chg{Version=[2],New=[category],Old=[class]}.]
+The primitive subprograms of the type are as for any
+type in the determined @Chg{Version=[2],New=[category],Old=[class]}. For a
+formal type other than a formal
+derived type, these are the predefined operators of the address@hidden
+For an elementary formal type, the predefined operators are implicitly declared
+immediately after the declaration of the formal type. For a composite formal
+type, the predefined operators are implicitly declared either immediately after
+the declaration of the formal type, or later
address@hidden,New=[immediately within the declarative region in which the
+type is declared],Old=[in its immediate scope]} according
+to the rules of @RefSecNum(Private Operations).],
+Old=[; they are implicitly declared immediately after the declaration
+of the formal type.]} In an instance, the copy of such an
+implicit declaration declares a view of the predefined operator
+of the actual type, even if this operator has been overridden for
+the actual address@hidden,New=[ and even if it is never declared
+for the actual type],Old=[]}.
address@hidden rules specific to formal derived types are given
+in @RefSecNum{Formal Private and Derived Types}.]
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
+All properties of the type are as for any type in the 
@Chg{Version=[2],New=[category],Old=[class]}.
+Some examples:
+The primitive operations available are as defined by the language for each
address@hidden,New=[category],Old=[class]}.
+The form of @nt{constraint} applicable to a formal type in a
address@hidden depends on the @Chg{Version=[2],New=[category],Old=[class]} of 
the type as for a
+nonformal type.
+The formal type is tagged if and only if it is declared as a tagged
+private type, or as a type derived from a (visibly) tagged type.
+(Note that the actual type might be tagged even if the formal type is
+not.)
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0029-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The somewhat
+  cryptic phrase @ldquote@;even if it is never address@hidden@; is
+  intended to deal with the following oddity:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Q @key[is]
+    @key[type] T @key[is limited private];
address@hidden
+    @key[type] T @key[is range] 1 .. 10;
address@hidden Q;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+    @key[type] A @key[is array] (Positive @key[range] <>) @key[of] T;
address@hidden Q.G @key[is]
+    A1, A2 : A (1 .. 1);
address@hidden
+    B : Boolean := A1 = A2;
address@hidden Q.G;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Q.G;
address@hidden R @key[is]
+   @key[type] C @key[is array] (Positive @key[range] <>) @key[of] Q.T;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[package] I @key[is new] Q.G (C); address@hidden 
Where is the predefined "=" for C?}
address@hidden R;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[An "=" is available for the formal type A in the
+private part of Q.G. However, no "=" operator is ever declared for type C,
+because its component type Q.T is limited. Still, in the instance I the name
+"=" declares a view of the "=" for C which exists-but-is-never-declared.]}
address@hidden
address@hidden
+
+
address@hidden
+Generic formal types, like all types, are not named.
+Instead, a @nt{name} can denote a generic formal subtype.
+Within a generic unit, a generic formal type is considered as being
+distinct from all other (formal or nonformal) types.
address@hidden
+This follows from the fact that each @nt{formal_type_declaration}
+declares a type.
address@hidden
+
+A @nt{discriminant_part} is allowed only for certain kinds of types,
+and therefore only for certain kinds of generic formal types.
+See @RefSecNum{Discriminants}.
address@hidden
+The term @lquotes@;formal floating point address@hidden@; refers to a type 
defined by a
address@hidden
+It does not include
+a formal derived type whose ancestor is floating point.
+Similar terminology applies to the other kinds of
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of generic formal types:}
address@hidden
address@hidden Item @key[is] @key[private];
address@hidden Buffer(Length : Natural) @key[is] @key[limited] @key[private];
+
address@hidden Enum  @key[is] (<>);
address@hidden Int   @key[is] @key[range] <>;
address@hidden Angle @key[is] @key[delta] <>;
address@hidden Mass  @key[is] @key[digits] <>;
+
address@hidden Table @key[is] @key[array] (Enum) @key[of] Item;
address@hidden
+
address@hidden
address@hidden@address@hidden of a generic formal part declaring a
+formal integer type:}
address@hidden
address@hidden
address@hidden
+   @key[type] Rank @key[is] @key[range] <>;
+   First  : Rank := Rank'First;
+   Second : Rank := First + 1;  address@hidden  the operator "+" of the type 
Rank  }
address@hidden
address@hidden
+
address@hidden
+RM83 has separate sections @lquotes@;Generic Formal address@hidden@; and 
@lquotes@;Matching Rules for
+Formal address@hidden@; (for various X's) with most of the text
+redundant between the two.
+We have combined the two in order to reduce the redundancy.
+In RM83, there is no @lquotes@;Matching Rules for Formal address@hidden@; 
section; nor is
+there a @lquotes@;Generic Formal Y address@hidden@; section (for Y = Private, 
Scalar, Array,
+and Access).
+This causes, for example, the duplication across all the @lquotes@;Matching
+Rules for Y address@hidden@; sections of the rule that the actual passed to a
+formal type shall be a subtype;
+the new organization avoids that problem.
+
+The matching rules are stated more concisely.
+
+We no longer consider the multiplying
+operators that deliver a result of type @i{universal_fixed} to be
+predefined for the various types; there is only one of each in
+package Standard. Therefore, we need not mention them here as RM83
+had to.
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0037],ARef=[AI95-00043-01],ARef=[AI95-00233-01]}
+  @ChgAdded{Version=[2],Text=[Corrigendum 1 corrected the wording to properly
+  define the location where operators are defined for formal array types.
+  The wording here was inconsistent with that in @RefSec{Private Operations}.
+  For the Amendment, this wording was corrected again, because it didn't
+  reflect the Corrigendum 1 revisions in @RefSecNum{Private Operations}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Text=[Formal interface types are defined; see
+  @RefSec{Formal Interface Types}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[We use @lquotes@;determines a address@hidden
+  rather than class, since not all interesting properties form a class.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in a 
@nt{formal_type_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0029-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction>: Updated the wording to
+  acknowledge the possibility of operations that are never declared for an
+  actual type but still can be used inside of a generic unit.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0213-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[Formal incomplete types are added; these
+  are documented as an extension in the next subclause.]}
address@hidden
+
+
address@hidden Private and Derived Types}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0213-1]}
address@hidden@Chg{Version=[2],New=[In its most general form, the category],
+Old=[The class]}
+determined for a formal private type @Chg{Version=[2],New=[is all types,
+but @Chg{Version=[3],New=[the category],Old=[it]} can be restricted to
+only nonlimited types or to only tagged types],
+Old=[can be either limited or nonlimited, and either tagged or untagged;
+no more specific class is known for such a address@hidden,New=[
+Similarly, the category for a formal incomplete type is all types but the
+category can be restricted to only tagged types; unlike other formal types,
+the actual type does not need to be able to be frozen (see @RefSecNum{Freezing 
Rules}).],Old=[]}
+The @Chg{Version=[2],New=[category],Old=[class]} determined for a formal
+derived type is the derivation class rooted at the ancestor type.]
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0213-1]}
+  @ChgAdded{Version=[2],Text=[The first @Chg{Version=[3],New=[two rules
+  are],Old=[rule is]} given normatively below,
+  and the @Chg{Version=[3],New=[third],Old=[second]} rule is given normatively
+  in @RefSecNum{Formal Types}; they are repeated here to give a capsule
+  summary of what this subclause is about.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0213-1]}
+  @ChgAdded{Version=[3],Text=[Since the actual of a formal incomplete type
+  does not need to be able to be frozen, the actual can be an incomplete
+  type or a partial view before its completion.]}
address@hidden
address@hidden
+
address@hidden
address@hidden<formal_private_type_definition>,
+  rhs="address@hidden @key{tagged}] address@hidden @key{private}"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00251-01],ARef=[AI95-00419-01],ARef=[AI95-00443-01]}
address@hidden<formal_derived_type_definition>,
+  rhs="@Chg{Version=[2],New=[
+     ],address@hidden @Chg{Version=[2],New=<address@hidden | 
@key{synchronized}] >,address@hidden @Syn2{subtype_mark} 
address@hidden,New=<address@hidden @Syn2{interface_list}]>,Old=<>address@hidden 
@key{private}]"}
address@hidden
+
address@hidden
+If a generic formal type declaration has a @nt{known_discriminant_part},
+then it shall not include a
address@hidden for a discriminant.
address@hidden
+Consequently,
+a generic formal subtype
+with a @nt{known_discriminant_part} is an indefinite subtype, so
+the declaration of a stand-alone variable has to provide a constraint
+on such a subtype, either explicitly, or by its initial value.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00401-01],ARef=[AI95-00419-01],ARef=[AI95-00443-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0237-1]}
address@hidden subtype], Sec=(of a formal derived type)}
address@hidden extension}
+The @i(ancestor subtype) of a formal derived type is the
+subtype denoted by the @nt<subtype_mark> of
+the @nt<formal_derived_type_definition>.
+For a formal derived type declaration,
+the reserved words @key{with private} shall appear if and only
+if the ancestor type is a tagged type; in this case
+the formal derived type is a private extension of the
+ancestor type and the ancestor shall not be a class-wide
+type.
address@hidden, @Chg{Version=[2],New=[an @nt{interface_list} or ],Old=[]}
+the optional reserved @Chg{Version=[2],New=[words],Old=[word]} @key{abstract}
address@hidden,New=[or @key{synchronized} ],Old=[]}shall
+appear only if the ancestor type is a tagged address@hidden,
+New=[ The reserved word @key{limited} or @key{synchronized} shall appear
+only if the ancestor type @Redundant[and any progenitor types] are limited 
types.
+The reserved word @key{synchronized} shall appear (rather than @key{limited}) 
if
+the ancestor type or any of the progenitor types are
+synchronized interfaces.],address@hidden,New=[ The ancestor type shall be a 
limited interface if the reserved
+word @key{synchronized} appears.],Old=[]}
+
address@hidden
+We use the term @lquotes@;address@hidden@; here instead of 
@lquotes@;address@hidden@;
+because the actual can be any descendant of the ancestor,
+not necessarily a direct descendant.
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00419-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
address@hidden,Text=[We require the ancestor type to be limited when
address@hidden appears so that we avoid
address@hidden,New=[oddities],Old=[oddies]} like limited integer types.
+Normally, @key{limited} means @lquotes@;match address@hidden for a generic
+formal, but it was felt that allowing limited elementary types to be declared
+was just too weird. Integer still matches a formal limited private type;
+it is only a problem when the type is known to be elementary.
+Note that the progenitors are required to be limited by rules in
address@hidden Types}, thus that part of the rule is redundant.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00443-01]}
address@hidden,Text=[We require that @key{synchronized} appear if the
+ancestor or any
+of the progenitors are synchronized, so that property is explicitly given
+in the program text @en it is not automatically inherited from the ancestors.
+However, it can be given even if neither the ancestor nor the progenitors
+are synchronized.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00251-01],ARef=[AI95-00401-01],ARef=[AI95-00443-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0087-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0036-1]}
address@hidden,Text=[The actual type for a formal derived type
+shall be a descendant of @Redundant[the ancestor type and] every progenitor of
+the formal type. @Chg{Version=[3],New=[If the formal type is nonlimited,
+the actual type shall be nonlimited. @Chg{Version=[4],New=[The actual type for
+a formal derived type shall be tagged if and only if the formal derived type
+is a private extension. ],Old=[]}],Old=[]}If the reserved word
address@hidden appears
+in the declaration of the formal derived type, the actual
+type shall be a synchronized tagged type.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The actual type has to be a descendant of the
+  ancestor type, in order that it be in the correct class. Thus, that part
+  of the rule is redundant.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[For a nonformal private extension, we
+  require the partial view to be synchronized if the full view is synchronized
+  tagged. This does not apply to a formal private extension @em it is OK if
+  the formal is not synchronized. Any attempt to extend the formal
+  type will be rechecked in the instance, where the rule disallowing
+  extending a @Chg{Version=[3],New=[synchronized],Old=[sychronized]}
+  noninterface type will be enforced. This is
+  consistent with the @lquotes@;no hidden address@hidden rule also
+  applying only to nonformal private extensions, as well as the rule that
+  a limited nonformal private extension implies a limited full type.
+  Formal private extensions are exempted from all these rules to
+  enable the construction of generics that can be used with the widest
+  possible range of types. In particular, an indefinite tagged
+  limited formal private type can match any @lquotes@;address@hidden
+  actual tagged type.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0087-1]}
+  @ChgAdded{Version=[3],Text=[A type (including formal types) derived from a
+  limited interface could be nonlimited; we do not want a limited type derived
+  from such an interface to match a nonlimited formal derived type.
+  Otherwise, we could assign limited objects. Thus, we have to explicitly
+  ban this case.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0036-1]}
+  @ChgAdded{Version=[4],Text=[If we allowed actual types that differ from
+  the kind of the formal derived type, we could allow type conversions that
+  would not be allowed outside of the generic. That would be particularly
+  problematical if the actual is a tagged type with extension components;
+  we could have created an object of the type that is missing those components
+  by converting from the ancestor type to a formal derived type that
+  is not an extension.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0213-1]}
+If @Chg{Version=[3],New=[a],Old=[the]} address@hidden,New=[ private or
+derived],Old=[]} subtype is definite, then the actual subtype shall
+also be definite.
address@hidden
+On the other hand, for an indefinite formal subtype,
+the actual can be either definite or indefinite.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0213-1]}
address@hidden,Text=[A @nt{formal_incomplete_type_declaration} declares
+a formal incomplete type. The only view of a formal incomplete type is an
+incomplete view. @Redundant[Thus, a formal incomplete type is subject to the 
same
+usage restrictions as any other incomplete type @em see @RefSecNum{Incomplete 
Type Declarations}.]]}
+
address@hidden@;For a generic formal derived type with no 
@nt<discriminant_part>:
address@hidden(Itemize)
+  If the ancestor subtype is constrained,
+  the actual subtype shall be constrained,
+  and shall be statically compatible with the ancestor;
address@hidden
+  In other words, any constraint on the ancestor subtype is considered
+  part of the @lquotes@;address@hidden@;
address@hidden
+
+  If the ancestor subtype is an unconstrained access
+  or composite subtype,
+  the actual subtype shall be unconstrained.
address@hidden
+  This rule ensures that if a composite constraint is allowed on the
+  formal, one is also allowed on the actual.
+  If the ancestor subtype is an unconstrained scalar subtype,
+  the actual is allowed to be constrained, since a scalar constraint
+  does not cause further constraints to be illegal.
address@hidden
+
+  If the ancestor subtype is an unconstrained discriminated subtype, then
+  the actual shall have the same number of discriminants, and each
+  discriminant of the actual shall correspond to a discriminant of the
+  ancestor, in the sense of @RefSecNum{Discriminants}.
+
address@hidden
+  This ensures that if a discriminant constraint is given on
+  the formal subtype, the corresponding constraint in the instance
+  will make sense, without additional run-time checks.
+  This is not necessary for arrays, since the bounds cannot be overridden
+  in a type extension. An @nt<unknown_discriminant_part> may be used
+  to relax these matching requirements.
address@hidden
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],Text=[If the ancestor subtype is an access subtype, the
+  actual subtype shall exclude null if and only if the ancestor subtype
+  excludes null.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We require that the
+  @lquotes@;excludes address@hidden property match, because it would be 
difficult
+  to write a correct generic for a formal access type without knowing this
+  property. Many typical algorithms and techniques will not work for a
+  subtype that excludes null (setting an unused component to @key{null},
+  default-initialized objects, and so on). We want this sort of requirement to
+  be reflected in the contract of the generic.]}
+
address@hidden
+
address@hidden(Itemize)
+
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0213-1]}
+The declaration of a formal derived type shall not have a
address@hidden
+For a generic formal private @Chg{Version=[3],New=[or incomplete ],Old=[]}type
+with a @nt{known_discriminant_part}:
address@hidden
+The actual type shall be a type with the same number of discriminants.
+
+The actual subtype shall be unconstrained.
+
+The subtype of each discriminant of the
+actual type shall statically match the subtype of the corresponding
+discriminant of the formal type.
address@hidden matching],Sec=(required)}
address@hidden
+We considered defining the first and third rule to be called
address@hidden@;subtype address@hidden@; for @nt{discriminant_part}s.
+We rejected that idea, because it would require implicit (inherited)
address@hidden, which seemed like too much mechanism.
address@hidden
address@hidden
+
address@hidden a generic formal type with an
address@hidden,
+the actual may, but need not, have discriminants,
+and may be definite or indefinite.]
+
address@hidden,Kind=[Added],ARef=[AI12-0095-1]}
address@hidden,Text=[When enforcing @LegalityTitle@;, for the purposes of
+determining within a generic body whether a type is unconstrained in any 
partial
+view, a discriminated subtype is considered to have a constrained partial view
+if it is a descendant of an untagged generic formal private or derived type.]}
+
address@hidden
+
address@hidden
address@hidden@;@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00442-01]}
+The @Chg{Version=[2],New=[category],Old=[class]} determined for a formal
+private type is as follows:
address@hidden,Kind=[Revised]}
address@hidden@Tabset(P32)
address@hidden
address@hidden(Type Definition) @address@hidden(Determined 
@Chg{Version=[2],New=[Category],Old=[Class]})@*
address@hidden private} @\the @Chg{Version=[2],New=[category],Old=[class]} of 
all types
address@hidden @\the @Chg{Version=[2],New=[category],Old=[class]} of all 
nonlimited types
address@hidden limited private} @\the 
@Chg{Version=[2],New=[category],Old=[class]} of all tagged types
address@hidden private} @\the @Chg{Version=[2],New=[category],Old=[class]} of 
all nonlimited tagged types
address@hidden
+
address@hidden presence of the reserved word @key{abstract} determines
+whether the actual type may be abstract.]
+
address@hidden,Kind=[Added],ARef=[AI05-0213-1]}
address@hidden,Text=[The category determined for a formal incomplete type is the
+category of all types, unless the @nt{formal_type_declaration}
+includes the reserved word @key[tagged]; in this case, it is the
+category of all tagged types.]}
+
+A formal private or derived type is a private or derived type,
+respectively.
+A formal derived tagged type is a private extension.
address@hidden formal private or derived type is abstract if the reserved
+word @key(abstract) appears in its declaration.]
+
address@hidden,Kind=[Revised],ARef=[AI95-00233-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0110-1]}
address@hidden,New=[For a formal derived type, the characteristics],Old=[If
+the ancestor type is a composite type that is not an array type, the formal 
type
+inherits components from the ancestor type]} (including
address@hidden,New=[components, but excluding ],Old=[]}discriminants if
address@hidden,New=[there is ],Old=[]}a new
address@hidden<discriminant_part>@Chg{Version=[3],New=[],Old=[ is not 
specified]}),
address@hidden,New=[predefined operators,
+and inherited user-defined primitive subprograms are determined
+by its ancestor type and its progenitor types (if any), in the
+same way that those of],Old=[as for]}
+a derived type
address@hidden,New=[are determined by those of its parent type and its
+progenitor types],Old=[defined by a @nt<derived_type_definition>]}
+(see @RefSecNum(Derived Types and Classes)@Chg{Version=[2],New=[ and
address@hidden Operations}],Old=[]}).
+
+
address@hidden,Kind=[Revised],Ref=[8652/0038],ARef=[AI95-00202]}
address@hidden,Kind=[Revised],ARef=[AI95-00233-01],ARef=[AI95-00401-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0029-1],ARef=[AI05-0110-1]}
address@hidden,New=[],Old=[For a formal derived type,
+the predefined operators and inherited user-defined subprograms are determined
+by the ancestor address@hidden,New=[ and any progenitor types],Old=[]}, and
+are implicitly declared at the earliest place, if any,
address@hidden,New=[immediately within the declarative region in which],
+Old=[within the immediate scope of]} the formal
address@hidden,New=[ is declared],Old=[]}, where the corresponding
+primitive subprogram of the ancestor @Chg{Version=[2],New=[or progenitor
+],Old=[]}is visible (see @RefSecNum{Private Operations}). ]}In an instance,
+the
+copy of @Chg{Version=[3],New=[],Old=[such ]}an implicit declaration
address@hidden,New=[of a primitive subprogram of a formal derived type ],
+Old=[]}declares a view of the corresponding
+primitive subprogram of the address@hidden@Chg{Version=[2], New=[ or
+progenitor],Old=[]} of the formal derived type],Old=[]}, even if this primitive
+has been overridden for the actual address@hidden,New=[ and even if it is
+never declared for the actual type],Old=[]}. @Chg{New=[When the
address@hidden, New=[ or progenitor],Old=[]} of the formal derived
+type is itself a formal type, the copy of the implicit declaration declares a
+view of the corresponding copied operation of the address@hidden,
+New=[ or progenitor],Old=[]}.],Old=[]} @Redundant[In the case of a formal
+private extension, however, the tag of the formal type is that of the actual
+type, so if the tag in a call is statically determined to be that of the formal
+type, the body executed will be that corresponding to the actual type.]
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00401-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0239-1]}
+The above rule defining the properties of primitive subprograms in an
+instance applies even if the subprogram has been overridden or
+hidden for the actual type.
+This rule is necessary for untagged types,
+because their primitive subprograms might have been overridden by
+operations that are not @Chg{Version=[3],New=[subtype 
conformant],Old=[subtype-conformant]} with the operations
+defined for the class.
+For tagged types, the rule still applies, but the primitive
+subprograms will dispatch to the appropriate implementation based on
+the type and tag of the operands.
+Even for tagged types, the formal parameter names and
address@hidden are determined
+by those of the primitive subprograms of the specified
+ancestor address@hidden,New=[ (or progenitor type, for subprograms
+inherited from an interface type)],Old=[]}.
address@hidden
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0030-1]}
+  @ChgAdded{Version=[4],Text=[The availability of stream attributes is not
+  formally a characteristic of a type, but it is still determined by the
+  ancestor type for a formal derived type in the same way as the 
characteristics
+  are. Availability is rechecked in the instance specification.]}
address@hidden
address@hidden,address@hidden be consistent with 8652/0006}
address@hidden@;For @ChgPrefixType{Version=[1],Kind=[Revised],Text=[a
address@hidden@nt{prefix}],Old=[prefix]} S that denotes a formal indefinite 
subtype]},
+the following attribute is defined:
address@hidden
address@hidden,Kind=(Revised),ChginAnnex=[T],Leading=[F],
+Prefix=<S>, AttrName=<Definite>,ARef=[AI05-0264-1],InitialVersion=[0],
+  Text=[S'Definite yields True if the actual subtype corresponding
+    to S is definite; address@hidden,New=[,],Old=[]} it yields False. The 
value of this
+    attribute is of the predefined type Boolean.]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+Whether an actual subtype is definite or indefinite may
+have a major effect on the algorithm used in a generic.
+For example, in a generic I/O package, whether to use fixed-length or
+variable-length records could depend on whether the actual is
+definite or indefinite.
+This attribute is essentially a replacement for the Constrained
address@hidden,New=[,],Old=[]}
+which is now considered obsolete.
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00158-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0071-1]}
address@hidden,Type=[Leading],Text=[In the case where a formal type
address@hidden,New=[has],Old=[is tagged with]} unknown discriminants,
+and the actual type is a class-wide type @i<T>'Class:]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00158-01]}
address@hidden,Text=[For the purposes of defining the primitive
+operations of the formal type, each of the primitive operations of the actual
+type is considered to be a subprogram (with an intrinsic calling convention @em
+see @RefSecNum{Conformance Rules}) whose body consists of a dispatching call
+upon the corresponding operation of @i<T>, with its formal parameters as the
+actual parameters. If it is a function, the result of the dispatching call is
+returned.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00158-01]}
address@hidden,Text=[If the corresponding operation of @i<T>
+has no controlling formal
+parameters, then the controlling tag value is determined by the
+context of the call, according to the rules for tag-indeterminate
+calls (see @RefSecNum{Dispatching Operations of Tagged Types} and
address@hidden Statements}). In the case where the tag would be
+statically determined to be that of the formal type, the call raises
+Program_Error. If such a function is renamed, any call on the
+renaming raises Program_Error.
address@hidden,Sec=(raised by failure of run-time check)}]}
+
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[As it states in @RefSecNum{Conformance Rules},
+the convention of an inherited subprogram
+of a generic formal tagged type with unknown discriminants is intrinsic.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[In the case of a corresponding
+primitive of T with no controlling
+formal parameters, the context of the call provides the controlling
+tag value for the dispatch. If no tag is provided by context,
+Program_Error is raised rather than resorting to a nondispatching
+call. For example:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key{type} NT(<>) @key{is new} T @key{with private};
+    -- @RI[Assume T has operation "address@hidden Empty @key{return} T;@RI["]
address@hidden G @key{is}
+   @key{procedure} Test(X : @key{in out} NT);
address@hidden G;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden body} G @key{is}
+   @key{procedure} Test(X : @key{in out} NT) @key{is}
+   @key{begin}
+      X := Empty;  -- @RI[Dispatching based on X'Tag takes]
+                   -- @RI[place if actual is class-wide.]
+      @key{declare}
+          Y : NT := Empty;
+                   -- @RI[If actual is class-wide, this raises Program_Error]
+                   -- @RI[as there is no tag provided by context.]
+      @key{begin}
+          X := Y;  -- @RI[We never get this far.]
+      @key{end};
+   @key{end} Test;
address@hidden G;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden T1 @key{is new} T @key{with null record};
address@hidden I @key{is new} G(T1'Class);]}
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden@;@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00442-01]}
+In accordance with the general rule that the actual type shall
+belong to the @Chg{Version=[2],New=[category],Old=[class]} determined for the 
formal
+(see @RefSec(Formal Types)):
address@hidden(itemize)
+  If the formal type is nonlimited, then so shall be the actual;
+
+  For a formal derived type, the actual shall be in the class rooted
+  at the ancestor subtype.
address@hidden(itemize)
+
+The actual type can be abstract only if the formal type is abstract
+(see @RefSecNum{Abstract Types and Subprograms}).
address@hidden
+This is necessary to avoid contract model problems,
+since one or more of its primitive subprograms are abstract;
+it is forbidden to create objects of the type,
+or to declare functions returning the type.
address@hidden
address@hidden
+On the other hand, it is OK to pass a nonabstract actual to an abstract
+formal @em @key[abstract] on the formal indicates that the actual might
+be abstract.
address@hidden
+
+If the formal has a @nt{discriminant_part},
+the actual can be either definite or indefinite.
+Otherwise, the actual has to be definite.
address@hidden
+
address@hidden
address@hidden with Ada 83}
+Ada 83 does not have
address@hidden, so it allows indefinite
+subtypes to be passed to definite formals,
+and applies a legality rule to the instance body.
+This is a contract model violation.
+Ada 95 disallows such cases at the point of the instantiation.
+The workaround is to add (<>)
+as the @nt{discriminant_part} of
+any formal subtype if it is intended
+to be used with indefinite actuals.
+If that's the intent, then there can't be anything
+in the generic body that would require a definite subtype.
+
+The check for discriminant subtype matching is changed from a
+run-time check to a compile-time check.
address@hidden
+
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01],ARef=[AI95-00401-01],ARef=[AI95-00419-01],ARef=[AI95-00443-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  A generic formal derived type can include progenitors (interfaces) as well
+  as a primary ancestor. It also may include @key{limited} to indicate that
+  it is a limited type, and @key{synchronized} to indicate that it is a
+  synchronized type.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0038],ARef=[AI95-00202-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected wording to 
define the
+  operations that are inherited when the ancestor of a formal type is itself
+  a formal type to avoid anomalies.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00158-01]}
+  @ChgAdded{Version=[2],Text=[Added a semantic description of the meaning
+  of operations of an actual class-wide type, as such a type does not have
+  primitive operations of its own.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],Text=[Added a matching rule for access subtypes that
+  exclude null.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00233-01]}
+  @ChgAdded{Version=[2],Text=[The wording for the declaration of implicit
+  operations is corrected to be consistent with @RefSecNum{Private Operations}
+  as modified by Corrigendum 1.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[We change to
+  @lquotes@;determines a address@hidden as that is the new terminology
+  (it avoids confusion, since not all interesting properties form a class).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0087-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Added wording to
+  prevent a limited type from being passed to a nonlimited formal
+  derived type. While this was allowed, it would break the contract
+  for the limited type, so hopefully no programs actually depend on that.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0213-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Formal incomplete types are a new kind of generic formal; these can
+  be instantiated with incomplete types and unfrozen private types.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0029-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Updated the wording to
+  acknowledge the possibility of operations that are never declared for an
+  actual type but still can be used inside of a generic unit.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0071-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Fixed hole that failed
+  to define what happened for "=" for an untagged private type whose
+  actual is class-wide.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0110-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Revised the wording for
+  inheritance of characteristics and operations of formal derived types
+  to be reuse the rules as defined for derived types; this should eliminate
+  holes in the wording which have plagued us since Ada 95 was defined
+  (it has been "corrected" four previous times).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0237-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added missing rule for the
+  ancestors of formal derived types. The added rule would formally be
+  incompatible, but since it would be impossible to instantiate any such
+  generic, this cannot happen outside of test suites and thus is not
+  documented as an incompatibility.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0036-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Added a requirement that a tagged type only match a formal derived type
+  that is a private extension. This is necessary to prevent type conversions
+  that would not be allowed outside of the generic. We expect that this will
+  be rare, as it only can happen if the formal derived type does not
+  accurately describe the actual type; in most such cases, extension will be
+  desired and a private extension used so that is allowed.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0095-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> The assume the worst rule
+  for determining within a generic body whether a type is unconstrained in any
+  partial view was moved here. While AI05-0041-1 added it to
+  @RefSecNum{Operations of Access Types}, it's also needed (at least) in
+  @RefSecNum{Type Conversions} and @RefSecNum{Parameter Associations}. Thus,
+  it was moved here so that it applies generally.]}
address@hidden
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Scalar Types}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
+A @i{formal scalar type} is one defined by any of the
address@hidden in this subclause.
address@hidden @Chg{Version=[2],New=[category],Old=[class]} determined for a
+formal scalar type is @Chg{Version=[2],New=[the category of all 
],Old=[]}discrete,
+signed integer, modular, floating point, ordinary fixed point, or
address@hidden,New=[ types],Old=[]}.]
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[The second rule follows from the rule in
+  @RefSecNum{Formal Types} that says that the category is determined by the
+  one given in the name of the syntax production. The effect of the rule
+  is repeated here to give a capsule
+  summary of what this subclause is about.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[The @lquotes@;category of a address@hidden
+  includes any classes that the type belongs to.]}
address@hidden
address@hidden
+
+
address@hidden
address@hidden<formal_discrete_type_definition>,rhs="(<>)"}
+
+
address@hidden<formal_signed_integer_type_definition>,rhs="@key{range} <>"}
address@hidden<formal_modular_type_definition>,rhs="@key{mod} <>"}
+
+
address@hidden<formal_floating_point_definition>,rhs="@key{digits} <>"}
+
+
address@hidden<formal_ordinary_fixed_point_definition>,rhs="@key{delta} <>"}
address@hidden<formal_decimal_fixed_point_definition>,rhs="@key{delta} <> 
@key{digits} <>"}
address@hidden
+
address@hidden
+The actual type for a formal scalar type
+shall not be a nonstandard numeric type.
address@hidden
+This restriction is necessary because nonstandard numeric
+types have some number of restrictions on their use, which could cause
+contract model problems in a generic body. Note that nonstandard
+numeric types can be passed to formal derived and formal private
+subtypes, assuming they obey all the other rules, and assuming the
+implementation allows it (being nonstandard means the implementation
+might disallow anything).
address@hidden
address@hidden
+
address@hidden
+The actual type shall be in the class of types implied
+by the syntactic category of the formal type definition
+(see @RefSec(Formal Types)). For example, the actual for a
address@hidden<formal_modular_type_definition> shall be a modular type.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[We change to
+  @lquotes@;determines a address@hidden as that is the new terminology
+  (it avoids confusion, since not all interesting properties form a class).]}
address@hidden
+
+
address@hidden Array Types}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
address@hidden @Chg{Version=[2],New=[category],Old=[class]} determined for a
+formal array type is the @Chg{Version=[2],New=[category],Old=[class]} of all 
array types.]
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[This rule follows from the rule in
+  @RefSecNum{Formal Types} that says that the category is determined by the
+  one given in the name of the syntax production. The effect of the rule
+  is repeated here to give a capsule
+  summary of what this subclause is about.]}
address@hidden
address@hidden
+
address@hidden
address@hidden<formal_array_type_definition>,rhs="@Syn2{array_type_definition}"}
address@hidden
+
address@hidden
+The only form of @nt{discrete_subtype_definition} that is allowed within the
+declaration of a
+generic formal (constrained) array subtype is a @nt{subtype_mark}.
address@hidden
+The reason is the same as for forbidding @nt{constraint}s in
address@hidden (see @RefSecNum{Generic Declarations}).
address@hidden
+
address@hidden@;For a formal array subtype, the actual subtype shall satisfy the
+following conditions:
address@hidden
+The formal array type and the actual array type shall have the same
+dimensionality; the formal subtype and the actual subtype shall be
+either both constrained or both unconstrained.
+
+For each index position, the index types shall be the same,
+and the index subtypes (if unconstrained),
+or the index ranges (if constrained), shall statically match
+(see @RefSecNum{Statically Matching Constraints and Subtypes}).
address@hidden matching],Sec=(required)}
+
+The component subtypes of the formal and
+actual array types shall statically match.
address@hidden matching],Sec=(required)}
+
+If the formal type has aliased components,
+then so shall the actual.
address@hidden
+On the other hand, if the formal's components are not aliased,
+then the actual's components can be either aliased or not.
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of formal array types:}
address@hidden
address@hidden  given the generic package }
+
address@hidden
+   @key[type] Item   @key[is] @key[private];
+   @key[type] Index  @key[is] (<>);
+   @key[type] Vector @key[is] @key[array] (Index @key[range] <>) @key[of] Item;
+   @key[type] Table  @key[is] @key[array] (Index) @key[of] Item;
address@hidden P @key[is]
+   ...
address@hidden P;
+
address@hidden  and the types }
+
address@hidden Mix    @key[is] @key[array] (Color @key[range] <>) @key[of] 
Boolean;
address@hidden Option @key[is] @key[array] (Color) @key[of] Boolean;
+
address@hidden  then Mix can match Vector and Option can match Table }
+
address@hidden R @key[is] @key[new] P(Item   => Boolean, Index => Color,
+                   Vector => Mix,     Table => Option);
+
address@hidden  Note that Mix cannot match Table and Option cannot match Vector}
address@hidden
address@hidden
+
address@hidden
address@hidden with Ada 83}
+The check for matching of component subtypes and index subtypes or
+index ranges is changed from a
+run-time check to a compile-time check.
+The Ada 83 rule that @lquotes@;If the component type is not a scalar type,
+then the component subtypes shall be either both constrained or both
address@hidden@; is removed, since it is subsumed by static matching.
+Likewise, the rules requiring that component types be
+the same is subsumed.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[We change to
+  @lquotes@;determines a address@hidden as that is the new terminology
+  (it avoids confusion, since not all interesting properties form a class).]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden Access Types}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00442-01]}
address@hidden @Chg{Version=[2],New=[category],Old=[class]} determined for a
+formal access type is the @Chg{Version=[2],New=[category],Old=[class]} of all 
access types.]
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[This rule follows from the rule in
+  @RefSecNum{Formal Types} that says that the category is determined by the
+  one given in the name of the syntax production. The effect of the rule
+  is repeated here to give a capsule
+  summary of what this subclause is about.]}
address@hidden
address@hidden
+
address@hidden
address@hidden<formal_access_type_definition>,rhs="@Syn2{access_type_definition}"}
address@hidden
+
address@hidden
+For a formal access-to-object type,
+the designated subtypes of the formal and actual types shall
+statically match.
address@hidden matching],Sec=(required)}
+
address@hidden,Kind=[Revised],ARef=[AI95-00231-01]}
+If and only if the @nt{general_access_modifier} @key{constant} applies
+to the formal,
+the actual shall be an access-to-constant type.
+If the @nt{general_access_modifier} @key{all} applies to the
+formal, then the actual shall be a general access-to-variable type
+(see @RefSecNum{Access Types})address@hidden,New=[ If and only
+if the formal subtype excludes null, the actual subtype shall exclude 
null.],Old=[]}
address@hidden
+If no @ntf{_modifier} applies to the formal, then
+the actual type may be either a pool-specific or a general
+access-to-variable type.
address@hidden
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0109],ARef=[AI95-00025-01]}
address@hidden,Text=[Matching an access-to-variable to a formal
+access-to-constant type cannot be allowed. If it were allowed, it would
+be possible to create an access-to-variable value designating a constant.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00231-01]}
address@hidden,Text=[We require that the @lquotes@;excludes address@hidden
+property match, because it would be difficult to write a correct generic for a
+formal access type without knowing this property. Many typical algorithms and
+techniques will not work for a subtype that excludes null (setting an unused
+component to @key{null}, default-initialized objects, and so on). Even
+Ada.Unchecked_Deallocation would fail for a subtype that excludes null. Most
+generics would end up with comments saying that they are not intended to work
+for subtypes that exclude null. We would rather that this sort of requirement
+be reflected in the contract of the generic.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0239-1],ARef=[AI05-0288-1]}
+For a formal access-to-subprogram subtype,
+the designated profiles of the formal and the actual
+shall be @Chg{Version=[3],New=[subtype conformant],Old=[mode-conformant,
+and the calling convention of the actual shall be @i{protected}
+if and only if that of the formal is @i{protected}]}.
address@hidden,address@hidden conformance],Sec=(required)}],
address@hidden conformance],Sec=(required)}]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0288-1]}
+  @ChgDeleted{Version=[3],Text=[We considered requiring subtype conformance
+  here, but mode conformance is more flexible, given that there is no way in
+  general to specify the convention of the formal.]}
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of formal access types:}
address@hidden
address@hidden  the formal types of the generic package }
+
address@hidden
+   @key[type] Node @key[is] @key[private];
+   @key[type] Link @key[is] @key[access] Node;
address@hidden P @key[is]
+   ...
address@hidden P;
+
address@hidden  can be matched by the actual types }
+
address@hidden Car;
address@hidden Car_Name @key[is] @key[access] Car;
+
address@hidden Car @key[is]
+   @key[record]
+      Pred, Succ : Car_Name;
+      Number     : License_Number;
+      Owner      : Person;
+   @key[end] @key[record];
+
address@hidden  in the following generic instantiation }
+
address@hidden R @key[is] @key[new] P(Node => Car, Link => Car_Name);
address@hidden
address@hidden
+
address@hidden
address@hidden with Ada 83}
+The check for matching of designated subtypes is changed from a
+run-time check to a compile-time check.
+The Ada 83 rule that @lquotes@;If the
+designated type is other than a scalar type, then the designated
+subtypes shall be either both constrained or both address@hidden@; is
+removed, since it is subsumed by static matching.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Formal access-to-subprogram subtypes and formal general access
+types are new concepts.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00231-01]}
+  @ChgAdded{Version=[2],Text=[Added a matching rule for subtypes that exclude
+  null.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[We change to
+  @lquotes@;determines a address@hidden as that is the new terminology
+  (it avoids confusion, since not all interesting properties form a class).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0288-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  @b<Correction:> Matching of formal access-to-subprogram types now uses
+  subtype conformance rather than mode conformance, which is needed to
+  plug a hole. This could cause some instantiations legal in Ada 95 and
+  Ada 2005 to be rejected in Ada 2012. We believe that formal
+  access-to-subprogram types occur rarely, and actuals that are not
+  subtype conformant are rarer still, so this should not happen often.
+  (In addition, one popular compiler has a bug that causes such instances
+  to be rejected, so no code compiled with that compiler could have an
+  incompatibility.)]}
address@hidden
+
+
address@hidden,Name=[Formal Interface Types]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01],ARef=[AI95-00442-01]}
address@hidden,address@hidden category determined for a formal
+interface type is the category of all interface types.]]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],Text=[This rule follows from the rule in
+  @RefSecNum{Formal Types} that says that the category is determined by the
+  one given in the name of the syntax production. The effect of the rule
+  is repeated here to give a capsule
+  summary of what this subclause is about.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Here we're taking advantage
+  of our switch in terminology from @lquotes@;determined address@hidden to
+  @lquotes@;determined address@hidden; by saying @lquotes@;address@hidden
+  rather than @lquotes@;address@hidden, we
+  require that any actual type be an interface type, not just some type
+  derived from an interface type.]}
address@hidden
+
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251-01]}
address@hidden,lhs=<@Chg{Version=[2],New=<formal_interface_type_definition>,Old=<>}>,
+rhs="@Chg{Version=[2],New=<@Syn2{interface_type_definition}>,Old=<>}"}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00251],ARef=[AI95-00401]}
address@hidden,Text=[The actual type shall be a descendant of every
+progenitor of the formal type.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00345]}
address@hidden,Text=[The actual type shall be a limited, task,
+protected, or synchronized interface
+if and only if the formal type is also, respectively, a limited, task,
+protected, or synchronized interface.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We require the kind of interface type to match
+  exactly because without that it is almost impossible to properly implement
+  the interface.]}
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,address@hidden Root_Work_Item @key{is tagged private};]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,address@hidden
+   @key{type} Managed_Task @key{is task interface};
+   @key{type} Work_Item(<>) @key{is new} Root_Work_Item @key{with private};
address@hidden Server_Manager @key{is}
+   @key{task type} Server @key{is new} Managed_Task @key{with}
+      @key{entry} Start(Data : @key{in out} Work_Item);
+   @key{end} Server;
address@hidden Server_Manager;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,Text=[This generic allows an application to establish a
+standard interface that all tasks need to implement so they can be managed
+appropriately by an application-specific scheduler.]}
+
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01],ARef=[AI95-00345-01],ARef=[AI95-00401-01],ARef=[AI95-00442-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The formal interface type is new.]}
address@hidden
+
+
address@hidden Subprograms}
+
address@hidden
address@hidden@Defn{generic formal subprogram}
address@hidden subprogram, generic}
+Formal subprograms can be used to pass callable entities to a generic
+unit.]
address@hidden
+
address@hidden
+Generic formal subprograms are like renames of the 
@nt{explicit_generic_actual_parameter}.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00260-02]}
address@hidden<formal_subprogram_declaration>,rhs="@Chg{Version=[2],
+New=<@Syn2{formal_concrete_subprogram_declaration}
+    | @Syn2{formal_abstract_subprogram_declaration}>,
+Old=<@key{with} @Syn2{subprogram_specification} address@hidden 
@Syn2{subprogram_default}];>}"}
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0183-1]}
address@hidden,lhs=<@Chg{Version=[2],New=<formal_concrete_subprogram_declaration>,Old=<>}>,
+rhs="@Chg{Version=[2],New=<
+     @key{with} @Syn2{subprogram_specification} address@hidden 
@address@hidden,New=<
+        address@hidden>,Old=[]};>,Old=<>}"}
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0183-1]}
address@hidden,lhs=<@Chg{Version=[2],New=<formal_abstract_subprogram_declaration>,Old=<>}>,
+rhs="@Chg{Version=[2],New=<
+     @key{with} @Syn2{subprogram_specification} @key{is abstract} 
address@hidden@Chg{Version=[3],New=<
+        address@hidden>,Old=[]};>,Old=<>}"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00348-01]}
address@hidden<subprogram_default>,rhs="@Syn2{default_name} | 
<>@Chg{Version=[2],New=< | @key{null}>,Old=<>}"}
+
address@hidden<default_name>,rhs="@Syn2{name}"}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00260-02],ARef=[AI95-00348-01]}
address@hidden,Text=[A @nt{subprogram_default} of @key{null} shall not
+be specified for a formal function or for a
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[There are no null functions because the return
+value has to be constructed somehow. We don't allow null for abstract formal
+procedures, as the operation is dispatching. It doesn't seem appropriate (or
+useful) to say that the implementation of something is null in the formal
+type and all possible descendants of that type. This also would define a
+dispatching operation that doesn't correspond to a slot in the tag of the
+controlling type, which would be a new concept. Finally, additional rules
+would be needed to define the meaning of a dispatching null procedure (for
+instance, the convention of such a subprogram should be intrinsic, but that's
+not what the language says). It doesn't seem worth the effort.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden
address@hidden profile], Sec=(formal subprogram default_name)}
+The expected profile for the @nt<default_name>, if any, is that of the
+formal subprogram.
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  This rule, unlike others in this
+  @Chg{Version=[3],New=[subclause],Old=[clause]}, is observed at compile
+  time of the @nt{generic_declaration}.
+
+  The evaluation of the @nt{default_name} takes place during the
+  elaboration of each instantiation that uses the default, as defined
+  in @RefSec{Generic Instantiation}.
address@hidden
+
address@hidden profile], Sec=(formal subprogram actual)}
+For a generic formal subprogram,
+the expected profile for the actual is that of the formal subprogram.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0239-1]}
+The profiles of the formal and any named default shall be
address@hidden,New=[mode conformant],Old=[mode-conformant]}.
address@hidden conformance],Sec=(required)}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This rule, unlike others in this 
@Chg{Version=[3],New=[subclause],Old=[clause]},
+is checked at compile time of the @nt{generic_declaration}.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0239-1]}
+The profiles of the formal and actual shall be
address@hidden,New=[mode conformant],Old=[mode-conformant]}.
address@hidden conformance],Sec=(required)}
+
address@hidden,Kind=[Added],ARef=[AI95-00423-01]}
address@hidden,Type=[Leading],Text=[For a parameter or result subtype of
+a @nt{formal_subprogram_declaration} that has an explicit 
@nt{null_exclusion}:]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[if the actual matching the
+  @nt{formal_subprogram_declaration} denotes a generic formal object of
+  another generic unit @i{G}, and the instantiation containing the actual
+  that occurs within the body of a generic unit @i{G} or within the body of a
+  generic unit declared within the declarative region of
+  the generic unit @i{G}, then the corresponding parameter or result type of
+  the formal subprogram of @i{G} shall have a @nt{null_exclusion};]}
+
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[otherwise, the subtype of the corresponding
+  parameter or result type of the actual matching the
+  @nt{formal_subprogram_declaration} shall exclude null.
+  @PDefn{generic contract issue}
+  In addition to the places where @LegalityTitle normally apply
+  (see @RefSecNum{Generic Instantiation}),
+  this rule applies also in the private part of an
+  instance of a generic unit.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[This rule prevents
+  @lquotes@;address@hidden
+  @b<Null> must never be the value of a parameter or result with an explicit
+  @nt{null_exclusion}. The first bullet is an assume-the-worst rule
+  which prevents trouble in generic bodies (including bodies of child generics)
+  when the formal subtype excludes null implicitly.]}
address@hidden
+
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0296-1]}
address@hidden,Text=[If a formal parameter of a
address@hidden@address@hidden@!declaration} is of a
+specific tagged type @i<T> or of an anonymous access type designating a
+specific tagged type @i<T>, @i<T> is called a @i<controlling type> of the
address@hidden@address@hidden@!declaration}. Similarly, if the result
+of a @address@hidden@address@hidden for a function is of
+a specific tagged type @i<T> or of an anonymous access type designating a
+specific tagged type @i<T>, @i<T> is called a controlling type of
+the @address@hidden@address@hidden A
address@hidden@address@hidden@!declaration} shall have exactly
+one controlling address@hidden,New=[, and that type shall not be
+incomplete],Old=[]}.
address@hidden type],Sec=[of a @nt{formal_abstract_subprogram_declaration}]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The specific tagged type could be any of
+  a formal tagged private type,
+  a formal derived type, a formal interface type,
+  or a normal tagged type. While the last case doesn't
+  seem to be very useful, there isn't any good reason for disallowing it.
+  This rule ensures that the operation is a dispatching operation of some
+  type, and that we unambiguously know what that type is.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We informally call a subprogram declared by
+  a @address@hidden@address@hidden an
+  @i{abstract formal subprogram},
+  but we do not use this term in normative wording.
+  @Defn{abstract formal subprogram}
+  (We do use it often in these notes.)]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,Text=[The actual subprogram for a
address@hidden@address@hidden@!declaration} shall be a
+dispatching operation of the controlling type or of the actual type
+corresponding to the controlling type.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We mean the controlling type of the
+  @address@hidden@address@hidden, of course.
+  Saying that gets unwieldy and redundant (so says at least one reviewer,
+  anyway).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[This means that the actual is
+  either a primitive operation of the
+  controlling type, or an abstract formal subprogram. Also note that this
+  prevents the controlling type from being class-wide (with one exception
+  explained below), as only specific types have primitive operations (and a
+  formal subprogram eventually has to have an actual that is a primitive of
+  some type). This could happen in a case like:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key{type} T(<>) @key{is tagged private};
+   @key{with procedure} Foo (Obj : @key{in} T) @key{is abstract};
address@hidden P ...]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden New_P @key{is new} P (Something'Class, 
Some_Proc);]}
address@hidden
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The instantiation here is always illegal,
+  because Some_Proc could never be a primitive operation of Something'Class
+  (there are no such operations). That's good, because we want calls to Foo
+  always to be dispatching calls.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[Since it is possible for a formal
+  tagged type to be instantiated with a class-wide type, it is possible for the
+  (real) controlling type to be class-wide in one unusual case:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key{type} NT(<>) @key{is new} T @key{with private};
+   -- @RI[Presume that T has the following primitive operation:]
+   -- @key{with procedure} Bar (Obj : @key{in} T);
address@hidden Gr ...]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden body} Gr @key{is}
+   @key{package} New_P2 @key{is new} P (NT, Foo => Bar);
address@hidden Gr;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden New_Gr @key{is new} Gr (Something'Class);]}
address@hidden
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The instantiation of New_P2 is legal, since
+  Bar is a dispatching operation of the actual type of the controlling type
+  of the abstract formal subprogram Foo. This is not a problem, since the
+  rules given in @RefSecNum{Formal Private and Derived Types} explain how
+  this routine dispatches even though its parameter is class-wide.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Note that this legality rule never needs to be
+  rechecked in an instance (that contains a nested instantiation). The rule
+  only talks about the actual type of the instantiation; it does not require
+  looking further; if the actual type is in fact a formal type, we do not
+  intend looking at the actual for that formal.]}
address@hidden
address@hidden
+
address@hidden
+A @nt{formal_subprogram_declaration} declares a generic formal subprogram.
+The types of the formal parameters and result, if any, of
+the formal subprogram are
+those determined by the @nt<subtype_mark>s given in
+the @nt{formal_subprogram_declaration}; however, independent of
+the particular subtypes that are denoted by the @nt<subtype_mark>s,
+the nominal subtypes of the formal parameters and result, if any,
+are defined to be nonstatic, and unconstrained if
+of an array type @Redundant[(no applicable index constraint
+is provided in a call on a formal subprogram)].
+In an instance,
+a @nt{formal_subprogram_declaration} declares a view
+of the actual.
+The profile of this view takes its subtypes
+and calling convention
+from the original profile of the actual entity,
+while taking the formal parameter
address@hidden and @address@hidden from the profile given in the
address@hidden@address@hidden The
+view is a function or procedure, never an entry.
address@hidden
+This rule is intended to be the same as the one for
+renamings-as-declarations, where the @nt{formal_subprogram_declaration}
+is analogous to a renaming-as-declaration,
+and the actual is analogous to the renamed view.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0071-1],ARef=[AI05-0131-1]}
address@hidden,Type=[Leading],Text=[If a @nt{subtype_mark} in the profile
+of the @nt{formal_subprogram_declaration} denotes a formal private or formal
+derived type and the actual type for this formal type is a class-wide type
address@hidden'Class, then for the purposes of resolving the corresponding 
actual
+subprogram at the point of the instantiation, certain implicit declarations may
+be available as possible resolutions as follows:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[For each primitive subprogram of @i{T} that is
+  directly visible at the point of the instantiation, and that has at least one
+  controlling formal parameter, a corresponding implicitly declared subprogram
+  with the same defining name, and having the same profile as the primitive
+  subprogram except that @i{T} is systematically replaced by @i{T}'Class in the
+  types of its profile, is potentially use-visible. The body of such a
+  subprogram is as defined in @RefSecNum{Formal Private and Derived Types} for
+  primitive subprograms of a formal type when the actual type is
+  address@hidden use-visible}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0071-1],ARef=[AI05-0131-1]}
+  @ChgAdded{Version=[3],Text=[This gives the same capabilities to formal
+  subprograms as those that primitive operations of the formal type have
+  when the actual type is class-wide. We do not want to discourage the use of
+  explicit declarations for (formal) subprograms!]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0071-1],ARef=[AI05-0131-1]}
+  @ChgAdded{Version=[3],Text=[Although the above wording seems to require
+  constructing implicit versions of all of the primitive subprograms of type
+  @i{T}, it should be clear that a compiler only needs to consider those that
+  could possibly resolve to the corresponding actual subprogram. For instance,
+  if the formal subprogram is a procedure with two parameters, and the actual
+  subprogram name is Bar (either given explicitly or by default), the compiler
+  need not consider primitives that are functions, that have the wrong number 
of
+  parameters, that have defining names other than Bar, and so on; thus it does
+  not need to construct implicit declarations for those primitives.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0071-1],ARef=[AI05-0131-1]}
+  @ChgAdded{Version=[3],Text=[Functions that only have a controlling result
+  and do not have a controlling parameter of @i<T> are not covered by this
+  rule, as any call would be required to raise Program_Error by
+  @RefSecNum{Formal Private and Derived Types}. It is better to detect the
+  error earlier than at run time.]}
address@hidden
+
+If a generic unit has a @nt<subprogram_default> specified by a box, and
+the corresponding actual parameter is omitted, then it is equivalent to
+an explicit actual parameter that is a usage name identical to the
+defining name of the formal.
+
address@hidden,Kind=[Added],ARef=[AI95-00348-01]}
address@hidden,Text=[If a generic unit has a @nt{subprogram_default}
+specified by the reserved word @key{null}, and the corresponding actual
+parameter is omitted, then it is equivalent to an explicit actual parameter
+that is a null procedure having the profile given in the
address@hidden@address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,Text=[The subprogram declared by a
address@hidden@address@hidden@!declaration} with a controlling type @i<T>
+is a dispatching operation of type @i<T>.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This is necessary to trigger all of the
+dispatching operation
+rules. It otherwise would not be considered a dispatching operation, as
+formal subprograms are never primitive operations.]}
address@hidden
+
address@hidden
+
address@hidden
+The matching rules for formal subprograms state requirements that are
+similar to those applying to @nt{subprogram_renaming_declaration}s
+(see @RefSecNum{Subprogram Renaming Declarations}).
+In particular, the name of a parameter of the formal subprogram need not
+be the same as that of the corresponding parameter of the actual
+subprogram;
+similarly, for these parameters, @nt{default_expression}s need not
+correspond.
+
+The constraints that apply to a parameter of a formal subprogram are
+those of the corresponding formal parameter of the matching actual
+subprogram (not those implied by the corresponding @nt{subtype_mark} in
+the @ntf{_specification} of the formal subprogram). A similar remark
+applies to the result of a function. Therefore, to avoid confusion, it
+is recommended that the @nt{name} of a first subtype
+be used in any declaration of a formal subprogram.
+
+The subtype specified for a formal parameter of a generic formal
+subprogram can be any visible subtype, including a generic formal
+subtype of the same @nt{generic_formal_part}.
+
+A formal subprogram is matched by an attribute of a type if the
+attribute is a function with a matching specification.
+An enumeration literal of a given type matches a parameterless formal
+function whose result type is the given type.
+
+A @nt{default_name} denotes an entity that is visible or directly
+visible at the place of the @nt{generic_declaration};
+a box used as a default is equivalent to a name that denotes an
+entity that is directly visible at the place of the
address@hidden
address@hidden
+Visibility and name resolution are applied to the equivalent explicit
+actual parameter.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00260-02]}
+The actual subprogram cannot be address@hidden,New=[ unless
+the formal subprogram is a @address@hidden@address@hidden,
+Old=[]} (see @RefSecNum{Abstract Types and Subprograms}).
+
address@hidden,Kind=[Added],ARef=[AI95-00260-02]}
address@hidden,Text=[The subprogram declared by a
address@hidden@address@hidden@!declaration} is an abstract subprogram.
+All calls on a subprogram declared by a
address@hidden@address@hidden@!declaration} must be dispatching calls.
+See @RefSecNum{Abstract Types and Subprograms}.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00348-01]}
address@hidden,Text=[A null procedure as a subprogram default has
+convention Intrinsic (see @RefSecNum{Conformance Rules}).]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[This is an implicitly declared subprogram,
+so it has convention Intrinsic as defined in @RefSecNum{Conformance Rules}.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden@address@hidden of generic formal subprograms:}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00433-01]}
address@hidden @key[function] "+"(X, Y : Item) @key[return] Item @key[is] <>;
address@hidden @key[function] Image(X : Enum) @key[return] String @key[is] 
Enum'Image;
address@hidden @key[procedure] Update @key[is] 
Default_Update;@Chg{Version=[2],New=[
address@hidden @key[procedure] Pre_Action(X : @key[in] Item) @key[is null];  
address@hidden defaults to no action]
address@hidden @key[procedure] Write(S    : @key[not null access] 
Root_Stream_Type'Class;
+                     Desc : Descriptor)
+                     @b<is abstract> Descriptor'Write;  address@hidden see 
@RefSecNum{Stream-Oriented Attributes}]
address@hidden Dispatching operation on Descriptor with default]],Old=[]}
+
address@hidden  given the generic procedure declaration }
+
address@hidden
+   @key[with] @key[procedure] Action (X : @key[in] Item);
address@hidden Iterate(Seq : @key[in] Item_Sequence);
+
address@hidden  and the procedure }
+
address@hidden Put_Item(X : @key[in] Item);
+
address@hidden  the following instantiation is possible }
+
address@hidden Put_List @key[is] @key[new] Iterate(Action => Put_Item);
address@hidden
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00260-02]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The @nt{formal_abstract_subprogram_declaration} is new. It allows
+  the passing of dispatching operations to generic units.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00348-01]}
+  @ChgAdded{Version=[2],Text=[
+  The formal subprogram default of @key{null} is new. It allows the default
+  of a generic procedure to do nothing, such as for passing a debugging
+  routine.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00423-01]}
+  @ChgAdded{Version=[2],Text=[Added matching rules for @nt{null_exclusion}s.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0296-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}It
+  is now illegal to declare a formal abstract subprogram whose controlling
+  type is incomplete. It was never intended to allow that, and such a type
+  would have to come from outside of the generic unit in Ada 2005, so it is
+  unlikely to be useful. Moreover, a dispatching call on the subprogram
+  is likely to fail in many implementations. So it is very unlikely that any
+  code will need to be changed because of this new rule.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0071-1],ARef=[AI05-0131-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada address@hidden<Correction:>
+  Added construction of implicit subprograms for primitives of class-wide 
actual
+  types, to make it possible to import subprograms via formal subprograms as
+  well as by implicit primitive operations of a formal type. (This is a
+  @b<Correction> as it is very important for the usability of indefinite
+  containers when instantiated with class-wide types; thus we want Ada 2005
+  implementations to support it.)]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],Text=[An optional @nt{aspect_specification} can be
+  used in a @nt{formal_concrete_subprogram_declaration} and a
+  @nt{formal_abstract_subprogram_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
+
address@hidden Packages}
+
address@hidden
address@hidden@Defn{generic formal package}
address@hidden package, generic}
+Formal packages can be used to pass packages to a generic unit.
+The @nt{formal_package_declaration} declares that the formal package
+is an instance of a given generic package.
+Upon instantiation, the actual package has to be an instance
+of that generic package.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden<formal_package_declaration>,rhs="
+    @key{with} @key{package} @Syn2{defining_identifier} @key{is} @key{new} 
@address@hidden  @address@hidden,New=<
+        address@hidden>,Old=[]};"}
+
address@hidden,Kind=[Revised],ARef=[AI95-00317-01]}
address@hidden<formal_package_actual_part>,rhs="
+    @Chg{Version=[2],New=`(address@hidden =>] <>)
+  | address@hidden
+  | (@Syn2{formal_package_association} {, @Syn2{formal_package_association}} 
[, @key{others} => <>])',
+Old=[(<>) | address@hidden"}
+
address@hidden,Kind=[Added],ARef=[AI95-00317-01]}
address@hidden,lhs=<@Chg{Version=[2],New=<formal_package_association>,Old=<>}>,
+rhs="@Chg{Version=[2],New={
+    @Syn2{generic_association}
+  | @address@hidden => <>},Old={}}"}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00317-01]}
address@hidden,Text=[Any positional @nt{formal_package_association}s
+shall precede any named @nt{formal_package_association}s.]}
address@hidden
address@hidden
+
address@hidden
address@hidden, Sec=(for a formal package)}
+The @i(generic_package_)@nt<name> shall denote a generic package
+(the @i(template) for the formal package);
+the formal package is an instance of the template.
+
address@hidden,Kind=[Added],ARef=[AI05-0025-1]}
address@hidden,Text=[The @i(generic_formal_parameter_)@nt{selector_name}
+of a @nt{formal_package_association} shall
+denote a @nt{generic_formal_parameter_declaration} of the template. If two or
+more formal subprograms of the template have the same defining name, then named
+associations are not allowed for the corresponding actuals.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00398-01]}
address@hidden,address@hidden this is renumbered by the above}
address@hidden,Text=[A @nt<formal_package_actual_part> shall contain
+at most one @nt<formal_package_association> for each formal parameter. If the
address@hidden<formal_package_actual_part> does not include
address@hidden@key[others] => <>@rquotes, each
+formal parameter without an association shall have a @nt<default_expression>
+or @nt<subprogram_default>.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0200-1]}
address@hidden,Text=[The rules for matching between
address@hidden and the generic formals of the template are as
+follows:]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[If all of the @nt{formal_package_association}s 
are
+  given by generic associations, the @nt{explicit_generic_actual_parameter}s of
+  the @nt{formal_package_association}s shall be legal for an instantiation of 
the
+  template.]}
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[If a @nt{formal_package_association} for a formal
+  type @i<T> of the template is given by <>, then the
+  @nt{formal_package_association} for any other
+  @nt{generic_formal_parameter_declaration} of
+  the template that mentions @i<T> directly or indirectly must be
+  given by <> as well.]}
+
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0200-1]}
+  @ChgAdded{Version=[3],Text=[The above rule is simple to state, though it does
+  not reflect the fact that the formal package functions like an instantiation
+  of a special kind, where each box association for a
+  @nt{generic_formal_parameter_declaration} @i<F> is replaced with a new entity
+  @i<F>' that has the same characteristics as @i<F>: if @i<F> is a formal
+  discrete type then @i<F>' is a discrete type, if @i<F> is a formal subprogram
+  then @i<F>' is a subprogram with a similar signature, etc. In practice this 
is
+  achieved by making the association into a copy of the declaration of the
+  generic formal.]}
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00317-01]}
address@hidden@;The actual shall be an instance of the template.
+If the @nt<formal_package_actual_part> is (<>)@Chg{Version=[2],
+New=[ or (@key{others} => <>)],Old=[]},
address@hidden the actual may be any instance of the template]; otherwise,
address@hidden,New=[certain of the actual parameters],
+Old=[each actual parameter]}
+of the actual instance shall match the corresponding
+actual @Chg{Version=[2],New=[parameters],Old=[parameter]}
+of the formal address@hidden,New=[, determined],
+Old=[ @Redundant[(whether the
+actual parameter is given explicitly or by default)],]} as follows:
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00317-01]}
address@hidden,Text=[If the @address@hidden@address@hidden
+includes @nt{generic_association}s as well as associations with <>,
+then only the actual parameters specified explicitly with
address@hidden are required to match;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00317-01]}
address@hidden,Text=[Otherwise, all actual parameters shall
address@hidden, whether any actual parameter is given explicitly
+or by default].]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00317-01]}
address@hidden,Type=[Leading],Text=[The rules for matching of
+actual parameters between the actual instance and the formal package
+are as follows:]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00317-01]}
+For a formal object of mode @address@hidden,New=[,],Old=[]} the
+actuals match if they are
+static expressions with the same value, or if they statically denote
+the same constant,
+or if they are both the literal @key[null].
address@hidden
+  We can't simply require full conformance between the two
+  actual parameter expressions, because the two
+  expressions are being evaluated at different times.
address@hidden
+
+For a formal subtype, the actuals match if they denote
+statically matching subtypes.
address@hidden matching],Sec=(required)}
+
+For other kinds of formals, the actuals match if they statically
+denote the same entity.
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0039],ARef=[AI95-00213-01]}
address@hidden,Text=[For the purposes of matching, any actual parameter
+that is the name
+of a formal object of mode @key{in} is replaced by the formal object's actual
+expression (recursively).]}
address@hidden
+
address@hidden
+A @nt{formal_package_declaration} declares a generic formal package.
+
address@hidden,Kind=[Revised],ARef=[AI95-00317-01]}
address@hidden part], Sec=(of a formal package)}
+The visible part of a formal package includes
+the first list of @nt{basic_declarative_item}s of the
address@hidden@!specification}.
+In addition, @Chg{Version=[2],New=[for each actual parameter that is
+not required to match, a copy of the
+declaration of the corresponding formal parameter of the template is
+included in the visible part of the formal package. If the copied
+declaration is for a formal type, copies of the implicit declarations
+of the primitive subprograms of the formal type are also included in
+the visible part of],
+Old=[if the @address@hidden@address@hidden is (<>),
+it also includes the @address@hidden@!part} of the template
+for]} the formal package.
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00317-01]}
+If the @nt<formal_package_actual_part> is (<>),
+then the declarations that occur immediately within the
address@hidden<generic_formal_part> of the template for the formal package
+are visible outside the formal package,
+and can be denoted by expanded names outside the formal
address@hidden,New=[If only some of the actual parameters are
+given by <>, then the declaration corresponding to those parameters (but
+not the others) are made visible.],Old=[]}
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+We always want either the actuals
+or the formals of an instance to be
address@hidden,New=[nameable],Old=[namable]} from outside, but never both.
+If both were @Chg{Version=[3],New=[nameable],Old=[namable]}, one would get
+some funny anomalies since
+they denote the same entity, but, in the case of types at least,
+they might have different and inconsistent sets of primitive operators
+due to predefined operator @lquotes@;address@hidden@; Formal derived types
+exacerbate the difference. We want the implicit declarations
+of the @nt<generic_formal_part> as well as the explicit
+declarations, so we get operations on the formal types.
address@hidden
address@hidden
+A generic formal package is a package, and is an instance.
+Hence, it is possible to pass a generic formal package
+as an actual to another generic formal package.
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00317-01]}
address@hidden,Text=[
+For the purposes of matching, if the actual instance @i<A> is itself a
+formal package, then the actual parameters of @i<A> are those specified
+explicitly or implicitly in the @nt{formal_package_actual_part} for @i<A>, 
plus,
+for those not specified, the copies of the formal parameters of the
+template included in the visible part of @i<A>.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,Type=[Leading],Keepnext=[T],address@hidden of a generic
+package with formal package parameters:}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Ordered_Maps;  address@hidden see 
@RefSecNum{The Generic Package Containers.Ordered_Maps}]
address@hidden
+   @key[with package] Mapping_1 @key[is new] Ada.Containers.Ordered_Maps(<>);
+   @key[with package] Mapping_2 @key[is new] Ada.Containers.Ordered_Maps
+                                    (Key_Type => Mapping_1.Element_Type,
+                                     @key[others] => <>);
address@hidden Ordered_Join @key[is]
+   address@hidden Provide a "join" between two mappings]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[subtype] Key_Type @key[is] Mapping_1.Key_Type;
+   @key[subtype] Element_Type @key[is] Mapping_2.Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] Lookup(Key : Key_Type) @key[return] 
Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ...
address@hidden Ordered_Join;]}
address@hidden
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden,Kind=[AddedNormal],ARef=[AI95-00433-01]}
address@hidden,Type=[Leading],Keepnext=[T],address@hidden of
+an instantiation of a package with formal packages:}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Ordered_Maps;
address@hidden Symbol_Package @key[is]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] String_Id @key[is] ...]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] Symbol_Info @key[is] ...]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[package] String_Table @key[is new] 
Ada.Containers.Ordered_Maps
+           (Key_Type => String,
+            Element_Type => String_Id);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[package] Symbol_Table @key[is new] 
Ada.Containers.Ordered_Maps
+           (Key_Type => String_Id,
+            Element_Type => Symbol_Info);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[package] String_Info @key[is new] 
Ordered_Join(Mapping_1 => String_Table,
+                                           Mapping_2 => Symbol_Table);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   Apple_Info : @key[constant] Symbol_Info := 
String_Info.Lookup("Apple");]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Symbol_Package;]}
+
address@hidden
address@hidden
+
+
+
address@hidden
+  @Defn{extensions to Ada 83}
+  Formal packages are new to Ada 95.
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00317-01],ARef=[AI95-00398-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  It's now allowed to mix actuals of a formal package that are specified
+  with those that are not specified.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0039],ARef=[AI95-00213-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the description 
of
+  formal package matching to say that formal parameters are always replaced by
+  their actual parameters (recursively). This matches the actual practice of
+  compilers, as the ACATS has always required this behavior.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00317-01]}
+  @ChgAdded{Version=[2],Text=[The description of which operations are
+  visible in a formal package has been clarified. We also specify how matching
+  is done when the actual is a formal package.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0025-1],ARef=[AI05-0200-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Added missing rules for parameters of generic formal package that
+  parallel those in @RefSecNum{Generic Instantiation}, as well as some
+  specific to <> parameters. These are technically incompatibilities because
+  generic formal package parameters that Ada 95
+  and Ada 2005 would have considered legal now have to be rejected. But this
+  should not be an issue in practice as such formal parameters could not have
+  matched any actual generics. And it is quite likely that implementations
+  already enforce some of these rules.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  An optional @nt{aspect_specification} can be used in
+  a @nt{formal_package_declaration}.
+  This is described in @RefSecNum{Aspect Specifications}.]}
address@hidden
+
+
address@hidden of a Generic Package}
+
address@hidden
+The following example provides a possible formulation of stacks by means
+of a generic package.
+The size of each stack and the type of the stack elements are provided
+as generic formal parameters.
address@hidden
+
address@hidden
address@hidden
address@hidden, Kind=[Deleted]}
address@hidden,Text=<@ @;@comment{Empty paragraph to hang junk paragraph number 
from original RM}>]
address@hidden
address@hidden
+   Size : Positive;
+   @key[type] Item @key[is] @key[private];
address@hidden Stack @key[is]
+   @key[procedure] Push(E : @key[in]  Item);
+   @key[procedure] Pop (E : @key[out] Item);
+   Overflow, Underflow : @key[exception];
address@hidden Stack;
+
address@hidden @key[body] Stack @key[is]
+
+   @key[type] Table @key[is] @key[array] (Positive @key[range] <>) @key[of] 
Item;
+   Space : Table(1 .. Size);
+   Index : Natural := 0;
+
+   @key[procedure] Push(E : @key[in] Item) @key[is]
+   @key[begin]
+      @key[if] Index >= Size @key[then]
+         @key[raise] Overflow;
+      @key[end] @key[if];
+      Index := Index + 1;
+      Space(Index) := E;
+   @key[end] Push;
+
+   @key[procedure] Pop(E : @key[out] Item) @key[is]
+   @key[begin]
+      @key[if] Index = 0 @key[then]
+         @key[raise] Underflow;
+      @key[end] @key[if];
+      E := Space(Index);
+      Index := Index - 1;
+   @key[end] Pop;
+
address@hidden Stack;
address@hidden
+
address@hidden
address@hidden@Keepnext@;Instances of this generic package can be obtained as 
follows:
address@hidden
address@hidden
address@hidden Stack_Int  @key[is] @key[new] Stack(Size => 200, Item => 
Integer);
address@hidden Stack_Bool @key[is] @key[new] Stack(100, Boolean);
address@hidden
+
address@hidden
address@hidden@Keepnext@;Thereafter, the procedures of the instantiated 
packages can be called as
+follows:
address@hidden
address@hidden
+Stack_Int.Push(N);
+Stack_Bool.Push(True);
address@hidden
+
address@hidden
address@hidden@Keepnext@;Alternatively, a generic formulation of the type Stack 
can be given as
+follows (package body omitted):
address@hidden
address@hidden
address@hidden
+   @key[type] Item @key[is] @key[private];
address@hidden On_Stacks @key[is]
+   @key[type] Stack(Size : Positive) @key[is] @key[limited] @key[private];
+   @key[procedure] Push(S : @key[in] @key[out] Stack; E : @key[in]  Item);
+   @key[procedure] Pop (S : @key[in] @key[out] Stack; E : @key[out] Item);
+   Overflow, Underflow : @key[exception];
address@hidden
+   @key[type] Table @key[is] @key[array] (Positive @key[range] <>) @key[of] 
Item;
+   @key[type] Stack(Size : Positive) @key[is]
+      @key[record]
+         Space : Table(1 .. Size);
+         Index : Natural := 0;
+      @key[end] @key[record];
address@hidden On_Stacks;
address@hidden
+
address@hidden
address@hidden@Keepnext@;In order to use such a package, an instance has to be 
created and
+thereafter stacks of the corresponding type can be declared:
address@hidden
address@hidden
address@hidden
+   @key[package] Stack_Real @key[is] @key[new] On_Stacks(Real); @key[use] 
Stack_Real;
+   S : Stack(100);
address@hidden
+   ...
+   Push(S, 2.54);
+   ...
address@hidden;
address@hidden
address@hidden
diff --git a/packages/ada-ref-man/source_2012/13a.mss 
b/packages/ada-ref-man/source_2012/13a.mss
new file mode 100755
index 0000000..fb25eec
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/13a.mss
@@ -0,0 +1,5165 @@
address@hidden(13, Root="ada.mss")
+
address@hidden: 2015/04/03 04:12:42 $}
address@hidden Issues}
+
address@hidden: e:\\cvsroot/ARM/Source/13a.mss,v $}
address@hidden: 1.113 $}
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[clause],Old=[section]} describes features 
for
+querying and controlling @Chg{New=[certain aspects of entities],
+Old=[aspects of representation]} and for interfacing to hardware.]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The @Chg{Version=[3],New=[subclauses],Old=[clauses]} of this
address@hidden,New=[clause],Old=[section]} have been reorganized.
+This was necessary to preserve a logical order,
+given the new Ada 95 semantics given in this section.
address@hidden
+
address@hidden,New=[Operational and Representation Aspects],Old=[Representation 
Items]}
address@hidden@LabeledRevisedClause{Version=[1],New=[Operational and 
Representation Items],Old=[Representation Items]} Don't have a way to include 
the middle title}
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0295-1]}
address@hidden,address@hidden@Chg{Version=[3],address@hidden,
+Old=[Representation and operational items can be used to specify aspects of
+entities. ]}Two kinds of aspects of entities can be specified:
address@hidden,New=[],Old=[aspects of address@hidden,
+New=[ aspects],Old=[]} and operational aspects. Representation
address@hidden,New=[aspects affect],Old=[items specify]}
+how the types and other entities of the language are to be mapped onto
+the underlying machine. Operational @Chg{Version=[3],New=[aspects determine],
+Old=[items specify]} other properties of entities.]]}
+
address@hidden,Kind=[Added],ARef=[AI05-0183-1],ARef=[AI05-0295-1]}
address@hidden,address@hidden kind of aspect of an entity may be
+specified by means of an @nt{aspect_specification} (see @RefSecNum{Aspect 
Specifications}),
+which is an optional element
+of most kinds of declarations and applies to the entity or entities being
+declared. Aspects may also be specified by certain other constructs occurring
+subsequent to the declaration of the affected entity: a representation aspect
+value may be specified by means of a representation item
+and an operational aspect value may be specified by means of an
+operational item.]]}
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden item}
address@hidden pragma}
address@hidden, representation}
+There are @Chg{New=[six],Old=[three]} kinds of @i{representation items}:
address@hidden@address@hidden@!clause}s for representation attributes,
address@hidden@address@hidden,
address@hidden@address@hidden, @nt{at_clause}s, ],
address@hidden@!clause}s, address@hidden<component_clause>s, and
address@hidden pragmas}.
address@hidden@Chg{New=[],Old=[Representation items specify how the types and 
other entities of
+the language are to be mapped onto the underlying machine.]}
+They can be provided to give more efficient representation or to
+interface with features that are outside the domain of the language
+(for example, peripheral hardware).
address@hidden,Old=[Representation items also specify other specifiable
+properties of entities.
+A representation item applies to an entity identified by
+a @nt<local_name>, which denotes an entity declared local to the
+current declarative region, or a library unit declared immediately
+preceding a representation pragma in a @nt<compilation>.]}]
+
address@hidden,Kind=[Added],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Text=[An @Defn{operational address@hidden<operational item> is an
address@hidden<attribute_definition_clause> for an operational attribute.]}
+
address@hidden,Kind=[Added],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,address@hidden operational item or a representation
+item applies to an entity identified by a @nt<local_name>, which denotes an
+entity declared local to the current declarative region, or a library unit
+declared immediately preceding a representation pragma in a
address@hidden<compilation>.]]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0295-1]}
address@hidden,address@hidden,New=[Representation
+aspects],Old=[Aspects of representation]} are intended to refer to
+properties that need to be known before the compiler can generate code to
+create or access an entity. For instance, the size of an object needs to be
+known before the object can be created. Conversely, operational aspects are
+those that only need to be known before they can be used. For instance, how an
+object is read from a stream only needs to be known when a stream read is
+executed. Thus, @Chg{Version=[3],New=[],Old=[aspects of
address@hidden, New=[ aspects],Old=[]} have stricter rules as
+to when they can be specified.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00291-02]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0295-1]}
address@hidden,Text=[Confirming the value of an aspect
address@hidden,New=[],Old=[with an operational or representation item ]}should
+never change the semantics of
+the aspect. Thus Size = 8 (for example) means the same thing whether it
+was specified with a representation item or whether the compiler chose this
+value by default.]}
address@hidden
+
address@hidden,Kind=[Added],Term=<Aspect>,
+Text=<@ChgAdded{Version=[3],Text=[An aspect is
+a specifiable property of an entity. An aspect may be specified by an
address@hidden on the declaration of the entity. Some aspects may be
+queried via attributes.]}>}
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden<@Chg{New=[aspect_clause],Old=[representation_clause]}>,rhs="@Syn2{attribute_definition_clause}
+      | @Syn2{enumeration_representation_clause}
+      | @Syn2{record_representation_clause}
+      | @Syn2{at_clause}"}
+
address@hidden<local_name>,rhs="@Syn2{direct_name}
+      | @address@hidden@Syn2{attribute_designator}
+      | @address@hidden"}
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+A representation pragma is allowed only at places where
address@hidden @nt{aspect_clause}],Old=[a @nt{representation_clause}]}
+or @nt{compilation_unit} is allowed.
address@hidden@IndexSee(Term=(representation_clause),See=(aspect_clause))],Old=[]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+In @Chg{New=[an operational item or],Old=[a]} representation item,
+if the @nt<local_name> is a @nt<direct_name>, then it shall
+resolve to denote a declaration
+(or, in the case of a @nt{pragma}, one or more declarations)
+that occurs immediately within the same
+declarative region as the @Chg{New=[],Old=[representation ]}item.
+If the @nt<local_name> has an @nt<attribute_designator>, then it shall
+resolve to denote an implementation-defined
+component (see @RefSecNum{Record Representation Clauses})
+or a class-wide
+type implicitly declared immediately within the same
+declarative region as the @Chg{New=[],Old=[representation ]}item.
+A @nt<local_name> that is a @address@hidden<name> (only
+permitted in a representation pragma) shall resolve
+to denote the @nt<library_item> that immediately precedes
+(except for other pragmas) the representation pragma.
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+This is a @ResolutionName,
+because we don't want @Chg{New=[an operational or],Old=[a]} representation
+item for X to be ambiguous just because there's another X declared in an outer
+declarative region.
+It doesn't make much difference, since most
address@hidden or ],Old=[]}representation items are for types or
+subtypes, and type and subtype names can't be overloaded.
address@hidden
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+The visibility rules imply that the declaration has to occur
+before the @Chg{New=[operational or ],Old=[]}representation item.
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+For objects, this implies that @Chg{New=[operational or 
],Old=[]}representation items can be
+applied only to stand-alone objects.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+The @nt{local_name} of @Chg{New=[an @nt<aspect_clause>],
+Old=[a @nt<representation_clause>]} or representation pragma shall
+statically denote an entity (or, in the case of a @nt{pragma},
+one or more entities) declared immediately preceding it in a @nt<compilation>,
+or within the same @address@hidden, @address@hidden,
address@hidden@!definition}, @address@hidden, or
address@hidden@!definition} as the representation @Chg{New=[or operational 
],Old=[]}item.
+If a @nt<local_name> denotes a @Redundant[local] callable entity,
+it may do so through a @Redundant[local]
address@hidden<address@hidden@!declaration>
address@hidden(as a way to resolve ambiguity in the presence of overloading)];
+otherwise, the @nt<local_name> shall not denote a @nt<address@hidden>.
address@hidden
+The @lquotes@;statically address@hidden@; part
+implies that it is impossible to specify the representation of
+an object that is not a stand-alone object,
+except in the case of a representation
+item like pragma Atomic
+that is allowed inside a @nt{component_list}
+(in which case the representation item specifies
+the representation of components of all objects of the type).
+It also prevents the problem of
+renamings of things like @lquotes@;address@hidden@rquotes@;
+(where P is an access-to-subprogram value)
+or @lquotes@;E(I)@rquotes@; (where E is an entry family).
+
+The part about where the denoted entity has to have been
+declared appears twice @em once as a @ResolutionName,
+and once as a @LegalityName.
+Suppose P renames Q,
+and we have a representation item in a @nt{declarative_part}
+whose @nt<local_name> is P.
+The fact that the representation item has to appear in the same
address@hidden as P is a @ResolutionName,
+whereas the fact that the representation item has to appear in the
+same @nt{declarative_part} as Q is a @LegalityName.
+This is subtle, but it seems like the least confusing set of rules.
address@hidden
address@hidden
+  A separate @LegalityName applies for @nt<component_clause>s.
+  See @RefSec{Record Representation Clauses}.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00291-02]}
address@hidden of an object}
address@hidden, Sec=(of an object)}The @i{representation} of an
+object consists of a certain
+number of bits (the @i(size) of
+the object).
address@hidden,New=[For an object of an elementary type, these],Old=[These]}
+are the bits that are normally read
+or updated by the machine code
+when loading, storing, or operating-on the value of the object.
address@hidden,New=[For an object of a composite type, these
+are the bits reserved for this object, and include bits occupied by
+subcomponents of the object. If],Old=[This includes some padding bits, when]}
+the size of @Chg{Version=[2],New=[an],Old=[the]} object
+is greater than @Chg{Version=[2],New=[that],Old=[the size]} of its 
address@hidden,
+New=[, the additional bits are padding bits.],Old=[.
address@hidden
address@hidden bits}
address@hidden,New=[For an elementary object, these],Old=[Such]} padding bits
address@hidden,New=[],Old=[are considered to be part of the representation of 
the
+object, rather than being gaps between objects,
+if these bits ]}are normally read and address@hidden,New=[ along
+with the others. For a
+composite object, padding bits might not be read or updated in any given
+composite operation, depending on the implementation],Old=[]}.
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00291-02]}
address@hidden representation}
address@hidden representation}
+Discontiguous representations are allowed,
+but the ones we're interested in here are generally contiguous
+sequences of address@hidden,New=[ For a discontiguous representation,
+the size doesn't necessarily describe the @lquotes@;address@hidden of
+the object in memory (that is, the amount of space taken in the address space
+for the object).],Old=[]}
address@hidden
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00291-02]}
address@hidden,Text=[In the case of composite objects, we want the
+implementation to have the flexibility to either do operations
+component-by-component, or with a block operation covering all of the bits. We
+carefully avoid giving a preference in the wording. There is no requirement
+for the choice to be documented, either, as the implementation can make that
+choice based on many factors, and could make a different choice for different
+operations on the same object.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00291-02]}
address@hidden,Text=[In the case of a properly aligned, contiguous
+object whose size is a multiple of the storage unit size, no other bits should
+be read or updated as part of operating on the object. We don't say this
+normatively because it would be difficult to normatively define
address@hidden@;properly address@hidden or @lquotes@;address@hidden
address@hidden
address@hidden
address@hidden@;Two objects with the same value do not necessarily have the same
+representation.
+For example, an implementation might represent False as zero and True
+as any odd value.
+Similarly, two objects (of the same type)
+with the same sequence of bits do not necessarily have the
+same value.
+For example, an implementation might use a biased representation in
+some cases but not others:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden S @key[is] Integer @key[range] 1..256;
address@hidden A @key[is] @key[array](Natural @key[range] 1..4) @key[of] 
address@hidden,New=[
+   @key[with] Pack],Old=[;
address@hidden Pack(A)]};
+X : S := 3;
+Y : A := (1, 2, 3, 4);
address@hidden
+
+The implementation might use a biased-by-1 representation for the
+array elements, but not for X.
+X and Y(3) have the same value, but different representation:
+the representation of X is a sequence of (say) 32 bits: 0...011,
+whereas the representation of Y(3) is a sequence of 8 bits:
+00000010 (assuming a two's complement representation).
+
+Such tricks are not required, but are allowed.
address@hidden
address@hidden
+  The value of any padding bits is not specified by the language,
+  though for a numeric type, it will be much harder to properly implement
+  the predefined operations if the padding bits are not either all zero,
+  or a sign extension.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+For example, suppose S'Size = 2, and an object X is of subtype S.
+If the machine code typically uses a 32-bit load instruction to load the
+value of X, then X'Size should be 32, even though 30 bits of the value
+are just zeros or sign-extension bits.
+On the other hand, if the machine code typically masks out those 30
+bits, then X'Size should be 2.
+Usually, such masking only happens for components of a composite type
+for which @Chg{Version=[3],New=[Pack],Old=[packing]}, Component_Size, or
+record layout is specified.
+
+Note, however, that the formal parameter of an instance of
+Unchecked_Conversion is a special case.
+Its Size is required to be the same as that of its subtype.
+
+Note that we don't generally talk about the representation of a
+value.
+A value is considered to be an amorphous blob
+without any particular representation.
+An object is considered to be more concrete.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0112-1],ARef=[AI05-0295-1]}
address@hidden of representation}
address@hidden aspect}
address@hidden,address@hidden specified],
+  Sec=(of a representation aspect of an entity)}],
address@hidden specified],
+  Sec=(of an aspect of representation of an entity)}]}
+A representation item @i{directly specifies}
address@hidden,New=[a @i{representation aspect}],
+Old=[an @i{aspect of representation}]} of the entity denoted
+by the @nt{local_name},
+except in the case of a type-related representation item,
+whose @nt{local_name} shall denote a first subtype,
+and which directly specifies an aspect
+of the subtype's type.
address@hidden, Sec=(representation item)}
address@hidden, Sec=(of a representation item)}
address@hidden, Sec=(aspect)}
address@hidden, Sec=(of an aspect)}
+A representation item that names a subtype is either
address@hidden(subtype-specific) (Size and Alignment clauses)
+or @i{type-related} (all others).
address@hidden aspects may differ for
+different subtypes of the same type.]
+
address@hidden
address@hidden and @i{subtype-specific} are defined likewise for
+the corresponding aspects of representation.
address@hidden
address@hidden
+Some representation items directly specify more than one aspect.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+For example, a @nt{pragma} Export
address@hidden,New=[(see @RefSecNum{Interfacing Pragmas}) ],Old=[]}specifies 
the convention
+of an entity,
+and also specifies that it is address@hidden,New=[ Such items are
+obsolescent; directly specifying
+the associated aspects is preferred.],Old=[]}
address@hidden
address@hidden
+Each specifiable attribute constitutes a separate aspect.
+An @nt{enumeration_representation_clause} specifies the coding aspect.
+A @nt{record_representation_clause} (without the @nt{mod_clause})
+specifies the record layout aspect.
+Each representation pragma specifies a separate aspect.
address@hidden
address@hidden
+We don't need to say that an @nt{at_clause} or a
address@hidden specify separate aspects,
+because these are equivalent to @nt{attribute_definition_clause}s.
+See @RefSec{At Clauses}, and @RefSec{Mod Clauses}.
+
address@hidden,Kind=[Added],ARef=[AI05-0112-1]}
address@hidden,Text=[We give a default naming for representation
+aspects of representation pragmas so we don't have to do that for every
+pragma. Operational and representation attributes are given a default naming
+in @RefSecNum{Operational and Representation Attributes}.
+We don't want any anonymous aspects; that would make other rules
+more difficult to write and understand.]}
address@hidden
address@hidden
address@hidden@;The following representation items are type-related:
address@hidden
address@hidden
+
address@hidden
+
+Component_Size clause
+
address@hidden,Kind=[Deleted],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Text=[External_Tag clause]}
+
+Small clause
+
+Bit_Order clause
+
+Storage_Pool clause
+
+Storage_Size clause
+
address@hidden,Kind=[Added],ARef=[AI95-00270-01]}
address@hidden,Text=[Stream_Size clause]}
+
address@hidden,Kind=[Deleted],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Text=[Read clause]}
+
address@hidden,Kind=[Deleted],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Text=[Write clause]}
+
address@hidden,Kind=[Deleted],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Text=[Input clause]}
+
address@hidden,Kind=[Deleted],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Text=[Output clause]}
+
+Machine_Radix clause
+
+pragma Pack
+
+pragmas Import, Export, and Convention (when applied to a type)
+
address@hidden,Kind=[Revised],ARef=[AI05-0009-1]}
+pragmas address@hidden,New=[, Independent,],Old=[]} and Volatile
+(when applied to a type)
+
address@hidden,Kind=[Revised],ARef=[AI05-0009-1]}
+pragmas address@hidden,New=[, Independent_Components,],Old=[]}
+and Volatile_Components (when applied to @Chg{Version=[3],New=[a],Old=[an
+array]} type)
+
+pragma Discard_Names (when applied to an enumeration or tagged type)
address@hidden
+
address@hidden@;The following representation items are subtype-specific:
address@hidden
+Alignment clause (when applied to a first subtype)
+
+Size clause (when applied to a first subtype)
address@hidden
+
address@hidden@;The following representation items do not apply to subtypes,
+so they are neither type-related nor subtype-specific:
address@hidden
+Address clause (applies to objects and program units)
+
+Alignment clause (when applied to an object)
+
+Size clause (when applied to an object)
+
+pragmas Import, Export, and Convention (when applied to anything other
+than a type)
+
+pragmas Atomic and Volatile (when applied to an object or a component)
+
address@hidden,Kind=[Revised],ARef=[AI05-0009-1]}
+pragmas address@hidden,New=[, Independent_Components,],Old=[]}
+and Volatile_Components (when applied to an array object)
+
+pragma Discard_Names (when applied to an exception)
+
+pragma Asynchronous (applies to procedures)
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00414-01]}
address@hidden,Text=[pragma No_Return (applies to subprograms)]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[While an @nt{aspect_specification} is not
+a representation item, a similar categorization applies to the aspect
+that corresponds to each of these representation items (along with
+aspects that do not have associated representation items).]}
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0183-1]}
address@hidden,Text=[An operational item @i<directly specifies> an 
@i<operational aspect>
+of the @Chg{Version=[3],New=[entity],Old=[type of the subtype]} denoted by
+the @address@hidden,New=[, except in
+the case of a type-related operational item, whose @nt{local_name} shall
+denote a first subtype, and which directly specifies an aspect of the
+type of the subtype],Old=[. The @nt{local_name}
+of an operational item shall denote a first subtype. An operational item that
+names a subtype is type-related]}.
address@hidden aspect}
address@hidden specified],
+  Sec=(of an operational aspect of an entity)}
address@hidden, Sec=(operational item)}
address@hidden, Sec=(aspect)}]}
+
address@hidden
address@hidden,Kind=[AddedNormal],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Type=[Leading],Text=[The following operational items are
+type-related:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[External_Tag clause]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Read clause]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Write clause]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Input clause]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Output clause]}
+
address@hidden
address@hidden
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0116-1]}
+A representation item that directly specifies an aspect of a subtype or
+type shall appear after the type is completely defined
+(see @RefSecNum{Completions of Declarations}),
+and before the subtype or type is frozen (see
address@hidden Rules})address@hidden,New=[],Old=[ If a
+representation item @Chg{Version=[3],New=[or @nt{aspect_specification} 
],Old=[]}is
+given that directly specifies an aspect of an
+entity, then it is illegal to give another representation item
address@hidden,New=[or @nt{aspect_specification} ],Old=[]}that
+directly specifies the same aspect of the entity.]}
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+The fact that a representation item @Chg{New=[(or operational item,
+see next paragraph) ],Old=[]}that directly specifies
+an aspect of an entity is required to appear before the entity is frozen
+prevents changing the representation of an entity
+after using the entity in ways that require the representation to be known.
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgRef{Version=[4],Kind=[Deleted],ARef=[AI12-0116-1]}
+  @ChgAdded{Version=[3],address@hidden,New=[],Old=[The rule preventing
+  multiple specification
+  is also intended to cover other ways to specify representation aspects,
+  such as obsolescent @nt{pragma} Priority. Priority is not a representation
+  pragma, and as such is neither a representation item nor an
+  @nt{aspect_specification}. Regardless, giving both a @nt{pragma} Priority
+  and an @nt{aspect_specification} for Priority is illegal. We didn't want
+  to complicate the wording solely to support obsolescent features.]}]}
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0183-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0116-1]}
address@hidden,Text=[An operational item that directly specifies an
+aspect of @Chg{Version=[3],New=[an entity],Old=[a type]} shall appear before 
the
address@hidden,New=[entity],Old=[type]} is frozen (see
address@hidden Rules})address@hidden,New=[],Old=[ If an operational
+item @Chg{Version=[3],New=[or
address@hidden ],Old=[]}is given that directly specifies an aspect of
address@hidden,New=[an entity],Old=[a type]}, then it is illegal to give
+another operational item @Chg{Version=[3],New=[or @nt{aspect_specification}
+],Old=[]}that directly specifies the same aspect of the
address@hidden,New=[entity],Old=[type]}.]}]}
address@hidden
+  @ChgRef{Version=[1],Kind=[AddedNormal]}
+  @ChgAdded{Version=[1],Text=[Unlike representation items, operational
+  items can be specified on
+  partial views. Since they don't affect the representation, the full
+  declaration need not be known to determine their legality.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0116-1]}
address@hidden,Text=[If a representation item, operational item, or
address@hidden is given that directly specifies an aspect of an
+entity, then it is illegal to give another representation item, operational
+item, or @nt{aspect_specification} that directly specifies the same aspect of
+the entity.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0116-1]}
+  @ChgAdded{Version=[4],Text=[This rule applies to all aspects, not just
+  those that are operational aspects or representation aspects. For instance,
+  it applies to subtype predicates and type invariants.]}
address@hidden
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0116-1]}
+  @ChgAdded{Version=[4],Text=[This rule is also intended to cover other ways
+  to specify representation aspects,
+  such as obsolescent @nt{pragma} Priority. Priority is not a representation
+  pragma, and as such is neither a representation item nor an
+  @nt{aspect_specification}. Regardless, giving both a @nt{pragma} Priority
+  and an @nt{aspect_specification} for Priority is illegal. We didn't want
+  to complicate the wording solely to support obsolescent features.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0106-1],ARef=[AI05-0295-1]}
address@hidden,Kind=[RevisedAdded],address@hidden a paragraph number change}
address@hidden,Text=[Unless otherwise specified, it is illegal to
+specify an operational or representation aspect of a generic formal
+parameter.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Specifying an aspect on a generic formal
+  parameter implies an added contract for a generic unit. That contract
+  needs to be defined via generic parameter matching rules, and, as
+  aspects vary widely, that has to be done for each such aspect. Since
+  most aspects do not need this complexity (including all language-defined
+  aspects as of this writing), we avoid the complexity by saying that
+  such contract-forming aspect specifications are banned unless the
+  rules defining them explicitly exist. Note that the method of specification
+  does not matter: @nt{aspect_specification}s, representation items,
+  and operational items are all covered by this (and similar) rules.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0295-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0109-1]}
+For an untagged derived type, @Chg{Version=[3],New=[it is illegal to
+specify a],Old=[no]} type-related representation
address@hidden,New=[aspect],Old=[items are allowed]} if the parent type is a
+by-reference type, or has any user-defined primitive
address@hidden,New=[ Similarly, it is illegal to specify a
+nonconfirming type-related representation aspect for
+an untagged by-reference type
+after one or more types have been derived from it.],Old=[]}
address@hidden
+  @ChgRef{Version=[1],Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0295-1]}
+  On the other hand, subtype-specific representation
+  @Chg{Version=[3],New=[aspects],Old=[items]} may
+  be @Chg{Version=[3],New=[specified],Old=[given]}
+  for the first subtype of such a address@hidden, as can operational
+  @Chg{Version=[3],New=[aspects],Old=[items]}],Old=[]}.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1],ARef=[AI05-0295-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0109-1]}
+  The reason for forbidding
+  @Chg{Version=[3],New=[specification of ],Old=[]}type-related
+  representation @Chg{Version=[3],New=[aspects],Old=[items]} on
+  untagged by-reference types is because a change of representation
+  is impossible when passing by reference (to an inherited
+  subprogram)address@hidden,New=[ (A by-reference object cannot be copied
+  to change its representation.)],Old=[]}
+  The reason for forbidding
+  @Chg{Version=[3],New=[specification of ],Old=[]}type-related
+  representation @Chg{Version=[3],New=[aspects],Old=[items]} on
+  untagged types with user-defined primitive subprograms
+  was to prevent implicit change of representation for type-related
+  aspects of representation upon calling inherited subprograms,
+  because such changes of representation are likely to be
+  expensive at run time.
+  Changes of subtype-specific representation attributes, however, are
+  likely to be cheap.
+  This rule is not needed for tagged types,
+  because other rules prevent a type-related representation
+  @Chg{Version=[3],New=[aspect],Old=[item]}
+  from changing the representation of the parent part;
+  we want to allow
+  @Chg{Version=[3],New=[specifying ],Old=[]}a type-related
+  representation @Chg{Version=[3],New=[aspect],Old=[item]}
+  on a type extension to specify aspects of the extension part.
+  For example, @Chg{Version=[3],New=[specifying aspect],Old=[a @nt{pragma}]}
+  Pack will cause packing of the extension part, but not of the parent part.
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI12-0109-1]}
+   @ChgAdded{Version=[4],address@hidden@;By-reference address@hidden usually
+   cannot be used in @LegalityTitle, as it is privacy breaking. Our use here
+   is privacy breaking, but we're stuck with it for compatibility reasons.
+   Since representation aspects cannot be specified on partial views, privacy
+   violations only can happen when a type includes a component of a private 
type.
+   In that case, whether these rules are triggered depends on the full type of
+   the private type @em which is clearly privacy breaking.]}
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01],Ref=[8652/0011],ARef=[AI95-00117-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00326-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0295-1]}
address@hidden and representation],Old=[Representation]} aspects of
+a generic formal parameter are the same as those of the actual.
address@hidden and representation aspects
address@hidden,New=[],Old=[of a partial view ]}are the
+same @Chg{Version=[2],New=[for all views of a type],Old=[as those of the full 
view]}.],Old=[]}
address@hidden,New=[Specification of a],Old=[A]}
+type-related representation @Chg{Version=[3],New=[aspect],Old=[item]}
+is not allowed for a descendant of a generic formal untagged type.
address@hidden
+  @ChgRef{Version=[1],Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0295-1]}
+  @Chg{Version=[3],New=[Specifying representation aspects 
is],Old=[Representation
+  items are]} allowed for
+  types whose subcomponent types
+  or index subtypes are generic formal types.
+  @address@hidden,New=[Specifying operational
+  aspects],Old=[Operational items]} and subtype-related representation
+  @Chg{Version=[3],New=[aspects is],Old=[items are]}
+  allowed on descendants of generic formal types.],Old=[]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0295-1]}
+  Since it is not known whether a formal type has
+  user-defined primitive subprograms, specifying
+  type-related representation @Chg{Version=[3],New=[aspects],Old=[items]}
+  for them is not allowed, unless they are tagged (in which case only
+  the extension part is affected in any case).
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00326-01]}
+  @ChgAdded{Version=[2],Text=[All views of a type, including the incomplete
+  and partial views, have the same operational and representation aspects.
+  That's important so that the properties don't change when changing views.
+  While most aspects are not available for an incomplete view, we don't want
+  to leave any holes by not saying that they are the same.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0083-1]}
+  @ChgAdded{Version=[3],Text=[However, this does not apply to objects.
+  Different views of an object can have
+  different representation aspects. For instance, an actual object passed
+  by reference and the associated formal parameter may have different values 
for
+  Alignment even though the formal parameter is merely a view of the
+  actual object. This is necessary to maintain the language design principle
+  that Alignments are always known at compile time.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0295-1]}
address@hidden,New=[The specification of],Old=[A
+representation item that specifies]} the address@hidden,New=[ aspect],Old=[]}
+for a given subtype, or the size or storage place for an object (including a 
component)
+of a given subtype, shall allow for enough storage space to
+accommodate any value of the subtype.
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0295-1]}
address@hidden,New=[If a specification of a],Old=[A]}
+representation @Chg{New=[or operational ],address@hidden,New=[aspect],
+Old=[item that]} is
+not supported by the address@hidden,New=[, it ],Old=[]}is
address@hidden,New=[],Old=[,]} or raises an exception at run time.
+
address@hidden,Kind=[Added],ARef=[AI95-00251-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0295-1]}
address@hidden,Text=[A @nt{type_declaration} is illegal if it has one or
+more progenitors, and a
address@hidden,New=[nonconfirming value was specified
+for a ],Old=[]}representation
address@hidden,New=[aspect of],Old=[item applies to]}
+an ancestor, and address@hidden,New=[],Old=[ representation item]}
+conflicts with the representation of
+some other ancestor. The cases that cause conflicts are
+implementation defined.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The cases that cause conflicts between the representation of
+the ancestors of a @nt{type_declaration}.]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0295-1]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[This rule is needed because it 
may be the case
+  that only the combination of types in a type declaration causes a conflict.
+  Thus it is not possible, in general, to reject the original representation
+  address@hidden,New=[ or @nt{aspect_specification}],Old=[]}.
+  For instance:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Pkg1 @key{is}
+   @key{type} Ifc @key{is interface};
+   @key{type} T @key{is tagged record}
+      Fld : Integer;
+   @key{end record};
+   @key{for} T @key{use record}
+      Fld @key{at} 0 @key{range} 0 .. Integer'Size - 1;
+   @key{end record};
address@hidden Pkg1;]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[Assume the implementation uses a
+  single tag with a default offset of zero, and that it allows the use of
+  nondefault locations for the tag (and thus accepts representation items
+  like the one above). The representation item will force a nondefault
+  location for the tag (by putting a component other than the tag into the
+  default location). Clearly, this package will be accepted by the
+  implementation. However, other declarations could cause trouble. For
+  instance, the implementation could reject:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Pkg1;
address@hidden Pkg2 @key{is}
+   @key{type} NewT @key{is new} Pkg1.T @key{and} Pkg1.Ifc @key{with null 
record};
address@hidden Pkg2;]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0295-1]}
+  @ChgAdded{Version=[2],Text=[because the declarations of T and Ifc have a
+  conflict in their representation items. This is clearly necessary (it's hard
+  to imagine how Ifc'Class could work with the tag at a location other than the
+  one it is address@hidden,New=[ without introducing distributed
+  overhead],Old=[]})address@hidden Steve happy.}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0295-1]}
+  @ChgAdded{Version=[2],Text=[Conflicts will usually involve
+  implementation-defined attributes (for specifying the location of the tag,
+  for instance), although the example above shows that doesn't have to be the
+  case. For this reason, we didn't try to specify exactly what causes a
+  conflict; it will depend on the implementation's implementation model and
+  what representation @Chg{Version=[3],New=[aspects],Old=[items]} it
+  address@hidden,New=[ to be changed],Old=[]}.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0295-1]}
+  @ChgAdded{Version=[2],Text=[An implementation can only use this rule to
+  reject @nt{type_declaration}s where one of its ancestors
+  @Chg{Version=[3],New=[had a nonconfirming],Old=[has a]} representation
+  @Chg{Version=[3],New=[value specified],Old=[item]}.
+  An implementation must ensure that
+  the default representations of ancestors cannot conflict.]}
address@hidden
address@hidden
+
address@hidden
+If two subtypes statically match,
+then their subtype-specific aspects (Size and Alignment)
+are the same.
address@hidden matching],Sec=(effect on subtype-specific aspects)}
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0295-1]}
+  This is necessary because we allow (for example)
+  conversion between access types whose designated subtypes
+  statically match.
+  Note that @Chg{Version=[3],New=[most aspects (including the subtype-specific 
aspects
+  Size and Alignment) may not be specified for a nonfirst subtype. The only
+  language-defined exceptions to this rule are the Static_Predicate and
+  Dynamic_Predicate aspects.],Old=[it is illegal to specify an aspect
+  (including a subtype-specific one) for a nonfirst subtype.]}
+
address@hidden@Keepnext@;Consider, for example:
address@hidden
address@hidden,address@hidden AI-00114}
address@hidden P1 @key[is]
+   @key[subtype] S1 @key[is] Integer @key[range] 0..2**16-1;
+   @key[for] S1'Size @key[use] 16; address@hidden Illegal!}
+      address@hidden S1'Size would be 16 by default.}
+   @key[type] A1 @key[is] @key[access] @address@hidden ],Old=[]}S1;
+   X1: A1;
address@hidden P1;
+
address@hidden,address@hidden AI-00114}
address@hidden P2 @key[is]
+   @key[subtype] S2 @key[is] Integer @key[range] 0..2**16-1;
+   @key[for] S2'Size @key[use] 32; address@hidden Illegal!}
+   @key[type] A2 @key[is] @key[access] @address@hidden ],Old=[]}S2;
+   X2: A2;
address@hidden P2;
+
address@hidden,address@hidden AI-00114}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden Q @key[is]
+   @key[use] P1, P2;
+   @key[type] Array1 @key[is] @key[array](Integer @key[range] <>) @key[of] 
@key[aliased] address@hidden,New=[
+      @key[with] Pack],Old=[;
+   @key[pragma] Pack(Array1)]};
+   Obj1: Array1(1..100);
+   @key[type] Array2 @key[is] @key[array](Integer @key[range] <>) @key[of] 
@key[aliased] address@hidden,New=[
+      @key[with] Pack],Old=[;
+   @key[pragma] Pack(Array2)]};
+   Obj2: Array2(1..100);
address@hidden
+   X1 := Obj2(17)'@Chg{New=[Unchecked_],Old=[]}Access;
+   X2 := Obj1(17)'@Chg{New=[Unchecked_],Old=[]}Access;
address@hidden Q;
address@hidden
+
+Loads and stores through X1 would read and write 16 bits,
+but X1 points to a 32-bit location.
+Depending on the endianness of the machine,
+loads might load the wrong 16 bits.
+Stores would fail to zero the other half in any case.
+
+Loads and stores through X2 would read and write 32 bits,
+but X2 points to a 16-bit location.
+Thus, adjacent memory locations would be trashed.
+
+Hence, the above is illegal.
+Furthermore, the compiler is forbidden from choosing different
+Sizes by default, for the same reason.
+
+The same issues apply to Alignment.
+
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0040],ARef=[AI95-00108-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0009-1],ARef=[AI05-0295-1]}
+A derived type inherits each type-related
address@hidden,New=[representation ],Old=[]}aspect
address@hidden,New=[],address@hidden representation ],Old=[]}]}of
+its parent type that
+was directly specified before the declaration of the derived type,
+or (in the case where the parent is derived)
+that was inherited by the parent type from the grandparent type.
+A derived subtype inherits each subtype-specific
address@hidden,New=[representation ],Old=[]}aspect
address@hidden,New=[],address@hidden representation ],Old=[]}]}of
+its parent subtype that
+was directly specified before the declaration of the derived type,
+or (in the case where the parent is derived)
+that was inherited by the parent subtype from the grandparent subtype,
+but only if the parent subtype statically matches the first subtype of
+the parent type.
+An inherited @Chg{Version=[3],New=[representation ],Old=[]}aspect
address@hidden,New=[],Old=[of representation ]}is
+overridden by a subsequent
address@hidden,address@hidden or ],Old=[]}representation
+item that specifies @Chg{Version=[3],New=[a different value for ],Old=[]}the
+same aspect of the type or subtype.
address@hidden
+A @nt{record_representation_clause} for a record extension
+does not override the layout of the parent part;
+if the layout was specified for the parent type,
+it is inherited by the record extension.
address@hidden
address@hidden
+  If a representation item for the parent appears after the
+  @address@hidden@!definition},
+  then inheritance does not happen for that representation item.
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0009-1],ARef=[AI05-0295-1]}
+  @ChgAdded{Version=[3],Text=[If an inherited aspect is confirmed by
+  an @nt{aspect_specification} or a later representation item for a derived 
type,
+  the confirming specification does
+  not override the inherited one. Thus the derived type has both a specified
+  confirming value and an inherited nonconfirming representation value @em this
+  means that rules that apply only to nonconfirming representation values still
+  apply to this type.]}
+
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0109-1]}
+  @ChgAdded{Version=[4],Text=[If an aspect was specified by an
+  @nt{aspect_specification} and the parent type has not yet been frozen, then
+  the inherited aspect might not yet have been resolved and evaluated. The
+  implementation will need to have a mechanism to handle such an aspect.]}
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0040],ARef=[AI95-00108-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00444-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0183-1],ARef=[AI05-0295-1]}
address@hidden,Text=[In contrast, whether operational aspects are
+inherited by @Chg{Version=[3],New=[a],address@hidden,New=[an 
untagged],Old=[a]}]}
+derived type depends on each specific address@hidden,New=[; unless specified,
+an operational aspect is not inherited],Old=[]}. @Chg{Version=[3],New=[],
address@hidden,address@hidden aspects are never inherited
+for a tagged type.] ],Old=[]}]}When operational aspects are
+inherited by @Chg{Version=[3],New=[a],address@hidden,New=[an 
untagged],Old=[a]}]} derived type,
+aspects that were directly specified @Chg{Version=[2],New=[by
address@hidden,address@hidden or ],Old=[]}operational
+items that are visible at the point],Old=[before the declaration]} of
+the derived address@hidden,New=[ declaration],Old=[]}, or
+(in the case where the parent is derived)
+that were inherited by the parent type from the grandparent type are inherited.
+An inherited operational aspect is overridden by a subsequent
address@hidden,address@hidden or ],Old=[]}operational
+item that specifies the same aspect of the type.]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[As with representation items, if an operational
+item for the parent appears after the @address@hidden@!definition}, then
+inheritance does not happen for that operational item.]}
address@hidden
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00444-01]}
address@hidden,Kind=[DeletedAddedNoDelMsg],ARef=[AI05-0183-1]}
address@hidden,address@hidden,address@hidden,New=[Only],Old=[Currently, only]}
+untagged types inherit operational aspects.
address@hidden,New=[Inheritance from tagged types causes problems, as the
+different views can have different visibility on operational items @em
+potentially leading to operational items that depend on the view. We want
+aspects to be the same for all views. Untagged types don't have this problem
+as plain private types don't have ancestors, and thus can't inherit anything.
+In addition, it seems unlikely that we'll need inheritance for tagged types,
+as usually we'll want to incorporate the parent's operation into a new one that
+also handles any extension components.],Old=[We considered writing this rule
+that way, but rejected it as that could be too
+specific for future operational aspects. (After all, that is precisely the
+problem that caused us to introduce @lquotes@;operational address@hidden in
+the first place.)]}],Old=[]}]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00444-01]}
address@hidden,Text=[When an aspect that is a subprogram is inherited,
+the derived type inherits the aspect in the same way that a derived type
+inherits a user-defined primitive subprogram from its parent (see
address@hidden Types and Classes}).]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This defines the parameter names and types,
+and the needed implicit conversions.]}
address@hidden
+
address@hidden@;Each aspect of representation of an entity is as follows:
address@hidden
address@hidden,
+  Sec=(of an aspect of representation of an entity)}
+If the aspect is @i{specified} for the entity,
+meaning that it is
+either directly specified or inherited,
+then that aspect of the entity is as specified,
+except in the case of Storage_Size,
+which specifies a minimum.
address@hidden
+This rule implies that queries of the aspect return the
+specified value. For example, if the user writes @lquotes@;@key{for}
+X'Size @key{use} 32;@rquotes@;,
+then a query of X'Size will return 32.
address@hidden
+
address@hidden
+If an aspect of representation of an entity is not specified,
+it is chosen by default in an unspecified manner.
address@hidden
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0295-1]}
+Note that @address@hidden,New=[specifying a ],Old=[]}representation
address@hidden,New=[aspect],Old=[items]}],address@hidden
+can affect the semantics of the entity.
+
+The rules forbid things like
address@hidden@;@key[for] S'Base'Alignment @key[use] address@hidden@;
+and
address@hidden@;@key[for] S'Base @key[use] record address@hidden@;.
address@hidden
address@hidden
+The intent is that implementations will represent the
+components of a composite value in the same way for all subtypes of a
+given composite type.
+Hence, Component_Size and record layout are type-related aspects.
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0083-1]}
address@hidden,Text=[As noted previously, in the case of an
+object, the entity mentioned in this text is a specific view of an object. That
+means that only references to the same view of an object that has a specified
+value for a representation aspect @i<R> necessarily have that value for the
+aspect @i<R>. The value of the aspect @i<R> for a different view of that object
+is unspecified. In particular, this means that the representation values for
+by-reference parameters is unspecified; they do not have to be the same as 
those
+of the underlying object.]}
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0040],ARef=[AI95-00108-01]}
address@hidden,address@hidden, Sec=(of an operational aspect of an entity)}
+If an operational aspect is @i<specified> for an entity (meaning
+that it is either directly specified or inherited), then that aspect of the
+entity is as specified. Otherwise, the aspect of the entity has the default
+value for that aspect.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00291-02]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0295-1]}
address@hidden,address@hidden,New=[An @nt{aspect_specification}
+or ],Old=[A]}representation
+item that specifies @Chg{Version=[3],New=[a],Old=[an aspect of]}
address@hidden,New=[ aspect],Old=[]}
+that would have been chosen in the absence of the
address@hidden,address@hidden or ],Old=[]}
+representation item is said to be
address@hidden@Defn2{Term=[confirming], Sec=(representation 
item)address@hidden,New=[
+The aspect value specified in this case is said to be a
address@hidden<confirming> representation aspect value. Other values of the 
aspect
+are said to be @i<nonconfirming>, as are the
address@hidden and representation items that specified
address@hidden, Sec=(representation value)}
address@hidden, Sec=(aspect specification)}
address@hidden, Sec=(representation value)}
address@hidden, Sec=(representation item)}
address@hidden, Sec=(aspect specification)}],Old=[]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden@PDefn2{Term=[elaboration], Sec=(aspect_clause)}],
address@hidden, Sec=(representation_clause)}]}
+For the elaboration of @Chg{New=[an @nt{aspect_clause}],
+Old=[a @nt{representation_clause}]},
+any evaluable constructs within it are evaluated.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Elaboration of representation pragmas is covered by the
+general rules for pragmas in @Chg{Version=[3],address@hidden,Old=[Section 2]}.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0295-1]}
+An implementation may interpret
address@hidden,New=[],Old=[aspects of
address@hidden,New=[ aspects],Old=[]}
+in an implementation-defined manner.
+An implementation may place implementation-defined restrictions on
address@hidden,New=[the specification of ],Old=[]}representation
address@hidden,New=[aspects],Old=[items]}.
address@hidden level of support}
+A @i{recommended level of support} is
address@hidden,New=[defined],Old=[specified]} for
address@hidden,New=[the specification of ],Old=[]}representation
address@hidden,New=[aspects],Old=[items]}
+and related features in each subclause.
+These recommendations are changed to requirements
+for implementations that support the Systems Programming Annex
+(see @RefSec{Required Representation Support}).
+
address@hidden,Kind=[Revised],InitialVersion=[0],Text=[The
+interpretation of each @Chg{Version=[3],New=[],Old=[aspect of
address@hidden,New=[ aspect],Old=[]}.]}
+
address@hidden,Kind=[Revised],InitialVersion=[0],Text=[Any restrictions
+placed upon @Chg{Version=[3],New=[the specification of ],Old=[]}representation
address@hidden,New=[aspects],Old=[items]}.]}
+
address@hidden
+Implementation-defined restrictions may be enforced either at compile
+time or at run time.
+There is no requirement that an implementation justify any such
+restrictions.
+They can be based on avoiding implementation complexity,
+or on avoiding excessive inefficiency, for example.
+
address@hidden,Kind=[Added],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Text=[There is no such permission for operational aspects.]}
address@hidden
address@hidden
+
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0295-1]}
address@hidden level of support], Sec=(with respect to
+nonstatic expressions)}
+The recommended level of support for
address@hidden,New=[the specification of ],Old=[]}all representation
address@hidden,New=[aspects],Old=[items]}
+is qualified as follows:
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00291-02]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0295-1]}
address@hidden,Text=[A confirming
address@hidden,New=[specification for a ],Old=[]}representation
address@hidden,New=[aspect],Old=[item]}
+should be supported.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0295-1]}
+  @ChgAdded{Version=[2],Text=[A confirming representation
+  @Chg{Version=[3],New=[aspect value],Old=[item]} might not be possible for 
some
+  entities. For instance, consider an unconstrained array. The size of such a
+  type is implementation-defined, and might not actually be a representable
+  value, or might not be static.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0295-1]}
+An implementation need not support @Chg{Version=[3],New=[the specification for
+a ],Old=[]}representation
address@hidden,New=[aspect that contains],Old=[items containing]}
+nonstatic expressions,
address@hidden,New=[unless],Old=[except that an implementation should
+support a representation item for a given entity if]} each nonstatic
address@hidden,New=[],Old=[ in the representation item]}
+is a @Chg{Version=[3],address@hidden,Old=[name]} that statically denotes
+a constant declared before the entity.
address@hidden
address@hidden@;This is to avoid the following sort of thing:
address@hidden
+X : Integer := F(...);
+Y : Address := G(...);
address@hidden X'Address @key[use] Y;
address@hidden
+
+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.
+
address@hidden@;The above code should instead be written like this:
address@hidden
+Y : @key[constant] Address := G(...);
+X : Integer := F(...);
address@hidden X'Address @key[use] Y;
address@hidden
+
+This allows the expression @lquotes@;address@hidden@; to be safely evaluated 
before X is
+created.
+
+The constant could be a formal parameter of mode @key[in].
+
+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.
address@hidden
+
+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.
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00291-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0295-1]}
address@hidden,New=[An implementation need not support
address@hidden,New=[specifying ],Old=[]}a nonconfirming
+representation @Chg{Version=[3],New=[aspect value],Old=[item]}
+if it could cause an aliased object or an object of a
+by-reference type to be allocated at a nonaddressable location or, when the
+alignment attribute of the subtype of such an object is nonzero, at an address
+that is not an integral multiple of that alignment.],Old=[An aliased component,
+or a component whose type is by-reference, should always be allocated at an
+addressable location.]}
address@hidden
address@hidden,address@hidden AI-0079}
+The intent is that access types, type System.Address,
+and the pointer used for a by-reference parameter should
+be implementable as a single machine address @em bit-field pointers
+should not be required.
+(There is no requirement that this implementation be used @em we just
+want to make sure @Chg{New=[it's],Old=[its]} feasible.)
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00291-02]}
address@hidden,New=[We want subprograms to be able to assume the properties
+of the types of their parameters inside of subprograms. While many objects
+can be copied to allow this
+(and thus do not need limitations), aliased or by-reference objects cannot
+be copied (their memory location is part of their identity). Thus,],
+Old=[Note that]}
+the above rule does not apply to types that merely allow
+by-reference parameter passing;
+for such types, a copy typically needs to be made at the call site
+when a bit-aligned component is passed as a parameter.
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00291-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0295-1]}
address@hidden,Text=[An implementation need not support
address@hidden,New=[specifying ],Old=[]}a nonconfirming
+representation @Chg{Version=[3],New=[aspect value],Old=[item]}
+if it could cause an aliased object of an elementary type
+to have a size other than that which would have been chosen by default.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Since all bits of elementary objects participate
+  in operations, aliased objects must not have a different size than that
+  assumed by users of the access type.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00291-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0295-1]}
address@hidden,Text=[An implementation need not support
address@hidden,New=[specifying ],Old=[]}a nonconfirming
+representation @Chg{Version=[3],New=[aspect value],Old=[item]}
+if it could cause an aliased object of a composite type, or
+an object whose type is by-reference, to have a size smaller than that which
+would have been chosen by default.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Unlike elementary objects, there is no
+  requirement that all bits of a composite object participate in operations.
+  Thus, as long as the object is the same or larger in size than that expected
+  by the access type, all is well.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This rule presumes that the implementation
+  allocates an object of a size specified to be larger than the default size in
+  such a way that access of the default size suffices to correctly read and
+  write the value of the object.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00291-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0295-1]}
address@hidden,Text=[An implementation need not support
address@hidden,New=[specifying ],Old=[]}a nonconfirming
+subtype-specific representation @Chg{Version=[3],New=[aspect value
+for],Old=[item specifying an aspect of representation of]}
+an indefinite or abstract subtype.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0295-1]}
+  @ChgAdded{Version=[2],address@hidden,New=[Representation aspects],
+  Old=[Aspects of representations]} are often not
+  well-defined for such types.]}
address@hidden
+
address@hidden
address@hidden,address@hidden AI-00075}
address@hidden,Kind=[Revised],ARef=[AI95-00291-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[A type with the Pack aspect specified],Old=[A pragma Pack]}
+will typically not @Chg{Version=[3],New=[be packed],Old=[pack]} so tightly as 
to
+disobey the above
address@hidden,New=[rules],Old=[rule]}. A Component_Size clause or
address@hidden will typically @Chg{New=[be],Old=[by]}
+illegal if it disobeys the above @Chg{Version=[2],New=[rules],Old=[rule]}.
+Atomic components have similar restrictions
+(see @RefSec{Shared Variable Control}).
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00291-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0295-1]}
address@hidden,Text=[For purposes of these rules, the determination of
+whether @Chg{Version=[3],New=[specifying ],Old=[]}a
+representation @Chg{Version=[3],New=[aspect value for],Old=[item applied to]}
+a type @i{could cause} an object to have
+some property is based solely on the properties of the type itself, not on any
+available information about how the type is used. In particular, it presumes
+that minimally aligned objects of this type might be declared at some point.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The recommended level of support for all representation items should be
+followed.]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[Aspects that can be specified are defined
+    throughout this International Standard, and are summarized in
+    @RefSecNum{Language-Defined Aspects}.]}
address@hidden
+
+
address@hidden
address@hidden with Ada 83}
+It is now illegal for a representation item to cause a derived
+by-reference type to have a different record layout from its
+parent.
+This is necessary for by-reference parameter passing to be feasible.
+This only affects programs that specify the representation of types
+derived from types containing tasks;
+most by-reference types are new to Ada 95.
+For example, if A1 is an array of tasks, and A2 is derived from A1,
+it is illegal to apply a @nt{pragma} Pack to A2.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden to Ada 83}
+Ada 95 allows additional @address@hidden,
address@hidden for objects.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+The syntax rule for @ntf{type_representation_clause} is removed;
+the right-hand side of that rule is moved up to where it was used,
+in @address@hidden,address@hidden
+There are two references to @lquotes@;type representation address@hidden@; in 
RM83,
+both in Section 13; these have been reworded.
address@hidden, the @ntf{representation_clause} has been renamed the
address@hidden to reflect that it can be used to control more than just
+representation aspects.],Old=[]}
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+We have defined a new term @lquotes@;representation item,@rquotes@;
+which includes @Chg{New=[all representation clauses],
address@hidden and representation pragmas, as well as
address@hidden<component_clause>s.
+This is convenient because the rules are almost identical for all @Chg{New=[of 
them],
+Old=[three]}. @Chg{New=[We have also defined the new terms
address@hidden@;operational address@hidden@; and @lquotes@;operational 
address@hidden@;
+in order to conveniently handle new types of 
@Chg{Version=[2],New=[specifiable],Old=[specifable]} entities.],Old=[]}
+
+All of the forcing occurrence stuff has been moved into its own
+subclause (see @RefSecNum{Freezing Rules}),
+and rewritten to use the term @lquotes@;address@hidden@;.
+
+RM83-13.1(10) requires implementation-defined restrictions on
+representation items to be enforced at compile time.
+However, that is impossible in some cases.
+If the user specifies a junk (nonstatic) address in an address
+clause, and the implementation chooses to detect the error (for example,
+using hardware memory management with protected pages), then it's
+clearly going to be a run-time error.
+It seems silly to call that @lquotes@;address@hidden@; rather than
address@hidden@;a address@hidden@;
+
+RM83-13.1(10) tries to pretend that @ntf{representation_clause}s don't affect
+the semantics of the program.
+One counter-example is the Small clause.
+Ada 95 has more counter-examples.
+We have noted the opposite above.
+
+Some of the more stringent requirements are moved to
address@hidden Representation Support}.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00291-02]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b[Amendment Correction:] Confirming representation items are
+  defined, and the recommended level of support is now that they always
+  be supported.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0009],ARef=[AI95-00137-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added operational items
+  in order to eliminate unnecessary restrictions and permissions on
+  stream attributes. As part of this, @ntf{representation_clause} was
+  renamed to @nt{aspect_clause}.]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0009],ARef=[AI95-00137-01],ARef=[AI95-00326-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added wording to say that 
the
+  partial and full views have the same operational and representation aspects.
+  Ada 2005 extends this to cover all views, including the incomplete view.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0040],ARef=[AI95-00108-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Changed operational items
+  to have inheritance specified for each such aspect.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Text=[Added wording to allow the rejection of
+  types with progenitors that have conflicting representation items.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00291-02]}
+  @ChgAdded{Version=[2],Text=[The description of the representation of an
+  object was clarified (with great difficulty reaching agreement). Added
+  wording to say that representation items on aliased and by-reference objects
+  never need be supported if they would not be implementable without
+  distributed overhead even if other recommended level of support says
+  otherwise. This wording matches the rules with reality.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00444-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[Added wording so that inheritance depends on
+  whether operational items are visible rather than whether they occur before
+  the declaration (we don't want to look into private parts).
+  @Chg{Version=[3],New=[Also limited],Old=[Limited]}
+  operational inheritance to untagged types to avoid
+  @Chg{Version=[3],New=[anomalies],Old=[anomolies]} with private extensions
+  (this is not incompatible, no existing operational attribute used this
+  capability). Also added wording to clearly define that subprogram inheritance
+  works like derivation of subprograms.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0106-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Specifying a language-defined aspect for a generic formal parameter is no
+  longer allowed. Most aspects could not be specified on these anyway; 
moreover,
+  this was not allowed in Ada 83, so it is unlikely that compilers are
+  supporting this as a capability (and it is not likely that they have a
+  consistent definition of what it means if it is allowed). Thus, we expect
+  this to occur rarely in existing programs.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0009-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Defined that overriding of
+  an representation aspect only happens for a nonconfirming representation
+  item. This prevents a derived type from being considered to have
+  only a confirming representation item when the value would be nonconfirming
+  if given on a type that does not inherit any aspects of representation.
+  This change just eliminates a wording confusion and ought not change any
+  behavior.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0112-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Defined a default naming 
for
+  representation aspects that are representation pragmas.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],Text=[Added text ensuring that the rules for
+  representational and operational items also apply appropriately to
+  @nt{aspect_specification}s; generalized operational aspects so that they
+  can be defined for entities other than types. Any extensions are documented
+  elsewhere.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0295-1]}
+  @ChgAdded{Version=[3],Text=[Rewrote many rules to be in terms of
+  "specifying a representation aspect" rather than use of
+  a "representation item". This better separates @i<how> an aspect is
+  specified from @i<what> rules apply to the value of the aspect.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0109-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Added a rule that makes it illegal to specify a representation value after
+  a type is derived from an untagged by-reference type. This restriction is
+  incompatible, but since the implementation would have had to copy an object
+  that does not allow copying in order to change the representation for any
+  implicit or explicit conversion between the original and the derived type,
+  it is unlikely that any program could exist without running into internal
+  compiler errors or bogus results.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0116-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that an aspect
+  (any aspect) can be specified only once for an entity, no matter what
+  means of specifying it are used. We did not document this as an
+  incompatibility as only aspects that are neither operational nor
+  representation could change behavior and there is no known implementation
+  of these new aspects that allows multiple definitions.]}
address@hidden
+
+
address@hidden,Name=[Aspect Specifications]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,address@hidden representation or operational
+aspects of an entity may be specified as part of its declaration using an
address@hidden, rather than using a separate representation or
+operational item.] The declaration with the @nt{aspect_specification} is termed
+the @i{associated address@hidden declaration],Sec=[of an
+aspect specification]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<aspect_specification>,Old=<>}>,
address@hidden,New="
+   @key[with] @Syn2{aspect_mark} [=> @Syn2{aspect_definition}] {,
+           @Syn2{aspect_mark} [=> @Syn2{aspect_definition}] }",Old=<>}'}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<aspect_mark>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<@SynI<aspect_>@Syn2<identifier>['Class]>,Old=<>}"}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<aspect_definition>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<@Syn2<name> | @Syn2<expression> | 
@Syn2<identifier>>,Old=<>}"}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1],ARef=[AI05-0267-1]}
+  @ChgAdded{Version=[3],Text=[The @nt{aspect_specification} is an
+   optional element in most kinds of declarations. Here is a list
+   of all kinds of declarations and an indication
+   of whether or not they allow aspect clauses, and in some cases
+   a short discussion of why (* = allowed, NO = not allowed). Kinds
+   of declarations with no indication are followed by their subdivisions
+   (which have indications).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0005-1]}
address@hidden,address@hidden
+  @nt{type_declaration}
+    @nt{full_type_declaration}
+      @i<type declaration syntax>*
+      @nt{task_type_declaration}*
+      @nt{protected_type_declaration}*
+    @nt{incomplete_type_declaration}  --  NO
+      -- @Examcom{Incomplete type aspects cannot be read by an attribute or 
specified by @nt{attribute_definition_clause}s }
+      -- @Examcom{(the attribute name is illegal), so it would not make sense 
to allow this in another way.}
+    @nt{private_type_declaration}*
+    @nt{private_extension_declaration}*
+  @nt{subtype_declaration}*
+  @nt{object_declaration}
+    @i<object declaration syntax>*
+    @nt{single_task_declaration}*
+    @nt{single_protected_declaration}*
+  @nt{number_declaration}  --  NO
+  @nt{subprogram_declaration}*
+  @nt{abstract_subprogram_declaration}*
+  @address@hidden,New=[
+  @nt{expression_function_declaration}*],Old=[]}
+  @nt{package_declaration}*  -- @Examcom{via} @nt{package_specification}
+  @nt{renaming_declaration}*
+    -- @Examcom{There are no language-defined aspects that may be specified}
+    -- @Examcom{on renames, but implementations might support some.}
+  @nt{exception_declaration}*
+  @nt{generic_declaration}
+    @nt{generic_subprogram_declaration}*
+    @nt{generic_package_declaration}* -- @Examcom{via} 
@nt{package_specification}
+  @nt{generic_instantiation}*
address@hidden  --  NO
address@hidden  --  NO
address@hidden
address@hidden  --  NO
address@hidden  --  NO
address@hidden  --  NO
address@hidden  --  @Examcom{ - but language-defined aspects only if there is 
no explicit specification}
address@hidden
address@hidden  --  NO
address@hidden  --  @Examcom{ - but language-defined aspects only if there is 
no explicit specification}
address@hidden  --  NO
address@hidden
+    -- @Examcom{There are no language-defined aspects that may be specified}
+    -- @Examcom{on generic formals, but implementations might support some.}
+  @nt{formal_object_declaration}*
+  @nt{formal_type_declaration}*
+  @nt{formal_subprogram_declaration}
+    @nt{formal_concrete_subprogram_declaration}*
+    @nt{formal_abstract_subprogram_declaration}*
+  @nt{formal_package_declaration}*
address@hidden  --  NO]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[-- @Examcom{We also allow @nt{aspect_specification}s on 
all kinds of bodies, but are no language-defined aspects}
+-- @Examcom{that may be specified on a body. These are allowed for 
implementation-defined aspects.}
+-- @Examcom{See above for subprogram bodies and stubs (as these can be 
declarations).}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0267-1]}
+  @ChgAdded{Version=[3],Text=[Syntactically, @nt{aspect_specification}s
+  generally are located at the end of declarations. When a declaration is all 
in
+  one piece such as a @nt{null_procedure_declaration}, @nt{object_declaration},
+  or @nt{generic_instantiation} the @nt{aspect_specification} goes at the end 
of
+  the declaration; it is then more visible and less likely to interfere with 
the
+  layout of the rest of the structure. However, we make an exception for 
program
+  units (other than subprogram specifications) and bodies, in which the
+  @nt{aspect_specification} goes before the @key[is]. In these cases, the 
entity
+  could be large and could contain other declarations that also have
+  @nt{aspect_specification}s, so it is better to put the
+  @nt{aspect_specification} toward the top of the declaration. (Some aspects 
@en
+  such as Pure @en also affect the legality of the contents of a unit, so it
+  would be annoying to only see those after reading the entire unit.)]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Type=[Leading],Text=[An @nt{aspect_mark} identifies an
+aspect of the entity defined by the associated declaration (the @i<associated
+entity>@Defn2{Term=[associated entity],Sec=[of an aspect specification]}); the
+aspect denotes an object, a value, an expression, a subprogram, or some other
+kind of entity. If the @nt{aspect_mark} identifies:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[an aspect that denotes an
+object, the @nt{aspect_definition} shall be a @nt{name}. The expected type for
+the @nt{name} is the type of the identified aspect of the associated
+entity;@PDefn2{Term=[expected type], Sec=[object in an 
@nt{aspect_specification}]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[an aspect that is
+a value or an expression, the @nt{aspect_definition} shall be an 
@nt{expression}.
+The expected type for the @nt{expression} is the type of the identified aspect
+of the associated
+entity;@PDefn2{Term=[expected type],
address@hidden in an @address@hidden type],
address@hidden in an @nt{aspect_specification}]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[an aspect that denotes a subprogram, the
address@hidden shall be a @nt{name}; the expected profile for the @nt{name}
+is the profile required for the aspect of the associated
+entity;@PDefn2{Term=[expected profile], address@hidden in an 
@nt{aspect_specification}]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[an aspect that
+denotes some other kind of entity, the @nt{aspect_definition} shall be a
address@hidden, and the name shall resolve to denote an entity of the 
appropriate
+kind;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[an aspect that is given by an identifier specific to
+the aspect, the @nt{aspect_definition} shall be an @nt{identifier}, and the
address@hidden shall be one of the identifiers specific to the identified
+aspect.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Text=[The usage names in an @nt{aspect_definition}
address@hidden are not resolved at the point of the associated declaration, but
+rather] are resolved at the end of the immediately enclosing declaration 
list.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Text=[If the associated declaration is for a subprogram or
+entry, the names of the formal parameters are directly visible within the
address@hidden, as are certain attributes, as specified elsewhere in
+this International Standard for the identified aspect. If the associated
+declaration is a @nt{type_declaration}, within the @nt{aspect_definition} the
+names of any components are directly visible, and the name of the first subtype
+denotes the current instance of the type (see
address@hidden Context of Overload Resolution}). If the associated declaration
+is a @nt{subtype_declaration}, within the @nt{aspect_definition} the name of
+the new subtype denotes the current instance of the subtype.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Text=[If the first freezing point of the associated entity
+comes before the end of the immediately enclosing declaration list, then each
+usage name in the @nt{aspect_definition} shall resolve to the same entity at 
the
+first freezing point as it does at the end of the immediately enclosing
+declaration list.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Text=[At most one occurrence of each @nt{aspect_mark} is
+allowed within a single @nt{aspect_specification}. The aspect identified by the
address@hidden shall be an aspect that can be specified for the associated
+entity (or view of the entity defined by the associated declaration).]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI12-0116-1]}
address@hidden,Text=[This rule prevents multiple specifications in the same
+  @nt{aspect_specification}. Rules in @RefSecNum{Operational and 
Representation Aspects} prevent multiple specifications in
+  different @nt{aspect_specification}s (on different views of the same type,
+  for instance) or between operational or representation items and
+  an @nt{aspect_specification}, even for aspects that are neither operational
+  nor representation aspects.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Text=[The @nt{aspect_definition} associated with a given
address@hidden may be omitted only when the @nt{aspect_mark} identifies an
+aspect of a boolean type, in which case it is equivalent to the
address@hidden being specified as True.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Text=[If the @nt{aspect_mark} includes
+'Class, then the associated entity shall be a tagged type or a primitive
+subprogram of a tagged type.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1],ARef=[AI05-0267-1]}
address@hidden,Text=[There are no language-defined aspects that
+may be specified on a @nt{renaming_declaration},
+a @nt{generic_formal_parameter_declaration}, a @nt{subunit}, a 
@nt{package_body},
+a @nt{task_body}, a @nt{protected_body}, or a @nt{body_stub} other than a
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Implementation-defined aspects can be allowed on
+  these, of course; the implementation will need to define the semantics. In
+  particular, the implementation will need to define actual type matching
+  rules for any aspects allowed on formal types; there are no default matching
+  rules defined by the language.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1],ARef=[AI05-0267-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0105-1]}
address@hidden,Text=[A language-defined aspect shall not be specified in
+an @nt{aspect_specification} given on a
address@hidden,New=[],address@hidden or
address@hidden that is a ]}completion of @Chg{Version=[4],New=[a
+subprogram or generic subprogram],Old=[another declaration]}.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Most language-defined aspects (for example,
+    preconditions) are intended to be available to callers, and specifying them
+    on a body that has a separate declaration hides them from callers. Specific
+    language-defined aspects may allow this, but they have to do so explicitly
+    (by defining an alternative @LegalityName), and provide any needed rules
+    about visibility. Note that this rule does not apply to
+    implementation-defined aspects, so implementers need to carefully define
+    whether such aspects can be applied to bodies and stubs, and what happens
+    if they are specified on both the declaration and body of a unit.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0183-1],ARef=[AI12-0138-1]}
address@hidden,Text=[If an aspect of a derived type is inherited from an
+ancestor type and has the boolean value True, the inherited value shall not be
+overridden to have the value False for the derived type, unless otherwise
+specified in this International Standard.]}
+
address@hidden,Kind=[Added],ARef=[AI12-0138-1]}
address@hidden,Text=[Certain type-related aspects are defined to be
address@hidden<nonoverridable>; all such aspects are specified using
+an @nt{aspect_definition} that is a @address@hidden,Sec=[aspect]}]}
+
address@hidden,Kind=[Added],ARef=[AI12-0138-1]}
address@hidden,Text=[If a nonoverridable aspect is directly specified
+for a type @i<T>, then any explicit specification of that aspect for any
+other descendant of @i<T> shall be 
@i<confirming>;@PDefn2{Term=[confirming],Sec=[nonoverridable aspect]}
+that is, the specified @nt{name} shall @i<match>@Defn2{Term=[match],Sec=[value 
of nonoverridable aspect]}
+the inherited aspect, meaning that the specified @nt{name} shall denote the
+same declarations as would the inherited @nt{name}.]}
+
address@hidden,Kind=[Added],ARef=[AI12-0138-1]}
address@hidden,Text=[If a full type has a partial view, and a given
+nonoverridable aspect is allowed for both the full view and the partial view,
+then the given aspect for the partial view and the full view shall be the same:
+the aspect shall be directly specified only on the partial view; if the full
+type inherits the aspect, then a matching definition shall be specified
+(directly or by inheritance) for the partial view.]}
+
address@hidden
+  @ChgAdded{Version=[4],Text=[In order to enforce these rules without breaking
+  privacy, we cannot allow a private type that could have a particular
+  overridable aspect to have a hidden definition of that aspect. There is no
+  problem if the private type does not allow the aspect (as the
+  aspect could not be specified on descendants in that case).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0138-1]}
address@hidden,address@hidden contract issue}
+In addition to the places where
address@hidden normally apply (see @RefSecNum{Generic Instantiation}),
+these rules about nonoverridable aspects also apply in the private part
+of an instance of a generic unit.]}
+
address@hidden,Kind=[Added],ARef=[AI12-0138-1]}
address@hidden,address@hidden Default_Iterator, Iterator_Element,
+Implicit_Dereference, Constant_Indexing, and Variable_Indexing aspects
+are nonoverridable.]]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[We don't need an assume-the-worst rule for most
+  nonoverridable aspects as they only work on tagged types and deriving from
+  formal tagged types is not allowed in generic bodies. In the case of
+  Implicit_Dereference, a derivation in a generic body does not cause problems
+  (the ancestor necessarily cannot have the aspect, else specifying the aspect
+  would be illegal), as there could be no place with visibility on both 
aspects.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Type=[Leading],Text=[Depending on which aspect is
+identified by the @nt{aspect_mark}, an @nt{aspect_definition} specifies:]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[a @nt{name} that denotes a subprogram, object, or
+  other kind of entity;]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[an @nt{expression}, which is either evaluated to
+  produce a single value, or which (as in a precondition) is to be evaluated at
+  particular points during later execution; or]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[an @nt{identifier} specific to the aspect.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Type=[Leading],Text=[The identified aspect of the
+associated entity, or in some cases, the view of the entity defined by the
+declaration, is as specified by the @nt{aspect_definition} (or by the default 
of
+True when boolean). Whether an @nt{aspect_specification} @i<applies> to an 
entity or
+only to the particular view of the entity defined by the declaration is
+determined by the @nt{aspect_mark} and the kind of entity. The following 
aspects
+are view specific:@PDefn2{Term=[applies],Sec=[aspect]}]}
+
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[An aspect specified on an 
@nt{object_declaration};]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[An aspect specified on a 
@nt{subprogram_declaration};]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[An aspect specified on a 
@nt{renaming_declaration}.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Text=[All other @nt{aspect_specification}s are associated
+with the entity, and @i<apply> to all views of the entity, unless otherwise
+specified in this International address@hidden,Sec=[aspect]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0106-1]}
address@hidden,Type=[Leading],Text=[If the @nt{aspect_mark} includes
+'address@hidden,New=[ (a @i<class-wide
+aspect>)@Defn{class-wide address@hidden,Sec=[class-wide]}],Old=[]},
address@hidden,New=[, unless specified otherwise for a particular
+class-wide aspect],Old=[]}:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[if the associated entity is a tagged type, the
+  specification @i<applies> to all descendants of the 
type;@PDefn2{Term=[applies],Sec=[aspect]}]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[if the associated entity is a primitive 
subprogram
+  of a tagged type @i<T>, the specification @i<applies> to the corresponding 
primitive
+  subprogram of all descendants of @i<T>address@hidden,Sec=[aspect]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1],ARef=[AI05-0229-1]}
address@hidden,Text=[All specifiable operational and representation
+attributes may be specified with an @nt{aspect_specification} instead of an
address@hidden (see
address@hidden and Representation Attributes}).]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The name of the aspect is the same as that of 
the attribute
+  (see @RefSecNum{Operational and Representation Attributes}), so the 
@nt{aspect_mark}
+  is the @nt{attribute_designator} of the attribute.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0154-1]}
address@hidden,Text=[Any aspect specified by a representation pragma
+or library unit pragma that has a @nt{local_name} as its single argument
+may be specified by an @nt{aspect_specification}, with the entity being the
address@hidden The @nt{aspect_definition} is expected to be of type Boolean.
+The expression shall be address@hidden,New=[ Notwithstanding what
+this International Standard says elsewhere, the expression of an aspect that
+can be specified by a library unit pragma is resolved and evaluated at the
+point where it occurs in the @address@hidden, rather
+than the first freezing point of the associated
address@hidden,Old=[]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The name of the aspect is the same as that of the
+  pragma (see @RefSecNum{Operational and Representation Aspects}), so the
+  @nt{aspect_mark} is the name of the pragma.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[In addition,
+other operational and representation aspects not associated with specifiable
+attributes or representation pragmas may be specified, as specified elsewhere
+in this International Standard.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Kind=[Deleted],ARef=[AI12-0138-1]}
address@hidden,address@hidden,New=[],Old=[If an aspect of a
+derived type is inherited from an ancestor type and has the boolean value True,
+the inherited value shall not be overridden to have the value False for the
+derived type, unless otherwise specified in this International Standard.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Text=[If a @LegalityName or @StaticSemTitle rule only
+applies when a particular aspect has been specified, the aspect is considered 
to
+have been specified only when the @nt{aspect_specification} or
address@hidden is visible (see @RefSecNum{Visibility}) at the point
+of the application of the rule.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Some rules only apply when an aspect has been
+  specified (for instance, an indexable type is one that has aspect
+  Variable_Indexing specified). In order to prevent privacy breaking, this can
+  only be true when the specification of the aspect is visible. In particular,
+  if the Variable_Indexing aspect is specified on the full view of a private
+  type, the private type is not considered an indexable type.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Text=[Alternative legality and semantics rules may apply
+for particular aspects, as specified elsewhere in this International 
Standard.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Text=[At the freezing point of the associated entity, the
address@hidden is elaborated. The elaboration of the
address@hidden includes the evaluation of the @nt{name} or
address@hidden, if any, unless the aspect itself is an expression. If the
+corresponding aspect represents an expression (as in a precondition), the
+elaboration has no effect; the expression is evaluated later at points
+within the execution as specified elsewhere in this International Standard for
+the particular aspect.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0183-1]}
address@hidden,Text=[Implementations may support implementation-defined
+aspects. The @nt{aspect_specification} for an implementation-defined aspect may
+use an implementation-defined syntax for the @nt{aspect_definition}, and may
+follow implementation-defined legality and semantics rules.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The intent is to allow implementations to support
+  aspects that are defined, for example, by a @nt{subtype_indication} rather
+  than an @nt{expression} or a @nt{name}. We chose not to try to enumerate all
+  possible @nt{aspect_definition} syntaxes, but to give implementations maximum
+  freedom. Unrecognized aspects are illegal whether or not they use custom
+  syntax, so this freedom does not reduce portability.]}
address@hidden
address@hidden,Kind=[Added],address@hidden,
+Text=[Implementation-defined aspects, inluding the syntax for specifying
+such aspects and the legality rules for such aspects.]}]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1],ARef=[AI05-0229-1],ARef=[AI05-0267-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Aspect specifications are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0154-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Added a clarification that aspects that correspond to library unit pragmas
+  are resolved and evaluated immediately. This is incompatible, as a
+  reference to an entity defined after the aspect will now be illegal.
+  However, this would have
+  require retroactive enforcement of such aspects, which is a new
+  capability not available from the associated pragma, and moreover
+  no known Ada 2012 implementation has ever allowed late evaluation of
+  such aspects. As such, there should be no practical incompatibility.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI125-0105-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified the wording so 
that the restriction
+  against language-defined aspects on subprogram completions includes
+  completions that are expressions functions and null procedures.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI125-0106-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Defined class-wide aspect
+  for use in rules in @RefSecNum{Stream-oriented attributes}.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI125-0138-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Added a definition of
+  nonoverridable aspects. This is necessary to prevent generic contract
+  problems with formal derived types.]}
address@hidden
+
+
address@hidden,New=[Packed Types],Old=[Pragma Pack]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden@Chg{Version=[3],New=[The Pack aspect having the value 
True],Old=[A
address@hidden Pack]} specifies that storage minimization should be the main
+criterion when selecting the representation of a composite type.]
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 2
+through 4 were moved to @RefSec{Obsolescent Features}.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0001-1]}
+  @ChgAdded{Version=[4],Text=[If the default representation already uses
+  minimal storage for a particular type, aspect Pack might not cause any
+  representation change. It follows that aspect Pack should always be allowed,
+  even when it has no effect on representation.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[As a consequence, the chosen representation for a
+  packed type may change during program maintenance even if the type is
+  unchanged (in particular, if other representation aspects change on a part of
+  the type). This is different than the behavior of most other representation
+  aspects, whose properties remain guaranteed no matter what changes are made 
to
+  other aspects.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[Therefore, aspect Pack should not be used to
+  achieve a representation required by external criteria. For instance, setting
+  Component_Size to 1 should be preferred over using aspect Pack to ensure an
+  array of bits. If future maintenance would make the array components aliased,
+  independent, or atomic, the program would become illegal if Component_Size is
+  used (immediately identifying a problem) while the aspect Pack version would
+  simply change representations (probably causing a hard-to-find bug).]}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],KeepNext=[T],Text=[The form of a
address@hidden Pack is as follows:]}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden<Version=[3],InitialVersion=[0],@ChgDeleted{Version=[3],
address@hidden @prag(Pack)(@address@hidden);]}>
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Text=[The @address@hidden of a
address@hidden Pack shall denote a composite subtype.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],address@hidden fake to get a conditional Leading}
address@hidden,New=[For a full type declaration of a composite type, the
+following language-defined representation aspect may be specified:],
address@hidden pragma], Sec=(Pack)}
address@hidden, representation], Sec=(Pack)}
address@hidden,address@hidden aspect], Sec=(packing)}],
address@hidden of representation], Sec=(packing)}
address@hidden, Sec=(aspect of representation)}]}
address@hidden
+A @nt{pragma} Pack specifies the @i{packing} aspect of representation;
+the type (or the extension part) is said to be @i{packed}.
+For a type extension, the parent part is packed as for the parent
+type, and a @nt{pragma} Pack causes packing only of the extension part.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden type of aspect Pack is Boolean. When
+  aspect Pack is True for a type, the type (or the extension part) is said to 
be
+  @i{packed}. For a type extension, the parent part is packed as for the parent
+  type, and specifying Pack causes packing only of the extension part.
address@hidden@AspectDefn{Pack}]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Pack],
+    address@hidden,Text=[Minimize storage when laying out records
+      and arrays.]}]}
+
address@hidden,Kind=[Added]}
+  @ChgAdded{Version=[3],NoPrefix=[T],Text=[If directly specified, the
+  @nt{aspect_definition} shall be a static expression. If not specified
+  (including by inheritance), the aspect is False.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The only high level semantic effect of @Chg{Version=[3],New=[specifying 
the],Old=[a @nt{pragma}]
address@hidden,New=[ aspect],Old=[]}
+is @Chg{Version=[3],New=[potential loss of ],Old=[]}independent
+addressability (see @RefSec{Shared Variables}).]}
address@hidden
address@hidden
+
address@hidden
+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.
address@hidden,Kind=[Added],address@hidden,
+Text=[Storage allocated to objects of a packed type should be minimized.]}]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[Specifying the],Old=[A @nt{pragma}]}
address@hidden,New=[ aspect],Old=[]} is for gaining space efficiency,
+possibly at the expense of time.
+If more explicit control over representation is desired,
+then a @nt{record_representation_clause},
+a Component_Size clause,
+or a Size clause should be used instead of,
+or in addition to,
address@hidden,New=[the],Old=[a @nt{pragma}]}
address@hidden,New=[ aspect],Old=[]}.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00291-02]}
address@hidden,Kind=[DeletedAdded],ARef=[AI12-0001-1]}
address@hidden,address@hidden,New=[If a packed type has a
+component that is not of a by-reference type and has no aliased part, then such
+a component need not be aligned according to the Alignment of its subtype; in
+particular it need not be allocated on a storage element
address@hidden "should" here; thus no ImplAdvice entry. This really
+qualifies the item above}],Old=[]}]}
+
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,address@hidden level of support], Sec=(aspect Pack)}],
address@hidden level of support], Sec=(pragma Pack)}]}
+The recommended level of support for
address@hidden,New=[the],address@hidden
address@hidden,New=[ aspect],Old=[]} is:
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0001-1]}
+  @ChgAdded{Version=[4],Text=[Any component of a packed type that is of a
+  by-reference type, that is specified as independently addressable, or that
+  contains an aliased part, shall be aligned according to the alignment of its
+  subtype.]}
+
+  @begin{Ramification}
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This also applies to atomic components. "Atomic"
+  implies "specified as independently addressable", so we don't need to mention
+  atomic here.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[Other components do not have to respect the
+  alignment of the subtype when packed; in many cases, the Recommended Level of
+  Support will require the alignment to be ignored.]}
+  @end{Ramification}
+
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0001-1]}
+  For a packed record type, the components should be packed as tightly as
+  possible subject to @Chg{Version=[4],New=[the above alignment
+  requirements, ],Old=[]}the Sizes of the component subtypes, and
+  @Chg{Version=[4],New=[],Old=[subject to ]}any
+  @nt{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.
+
+  @begin{Ramification}
+    The implementation can always allocate an integral number of words for a
+    component that will not fit in a word. The rule also allows small component
+    sizes to be rounded up if such rounding does not waste space. For example,
+    if Storage_Unit = 8, then a component of size 8 is probably more efficient
+    than a component of size 7 plus a 1-bit gap (assuming the gap is needed
+    anyway).
+  @end{Ramification}
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0009-1]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0001-1]}
+  For a packed array type, if the @Chg{Version=[3],New=[], Old=[component
+  subtype's address@hidden,New=[ of the component subtype],Old=[]} is
+  less than or equal to the word address@hidden,New=[],Old=[, and
+  Component_Size is not specified for the type]}, Component_Size should be less
+  than or equal to the Size of the component subtype, rounded up to the nearest
+  factor of the word address@hidden,New=[, unless this would violate
+  the above alignment requirements],Old=[]}.
+
+  @begin{Ramification}
+    @ChgRef{Version=[4],Kind=[Deleted],ARef=[AI12-0001-1]}
+    @ChgDeleted{Version=[4],Text=[If a component subtype is aliased,
+    its Size will generally be a multiple of Storage_Unit,
+    so it probably won't get packed very tightly.]}
+  @end{Ramification}
address@hidden
address@hidden,Kind=[Revised],InitialVersion=[2],
address@hidden,
+Text=[The recommended level of support for 
@Chg{Version=[3],New=[the],Old=[pragma]}
address@hidden,New=[ aspect],Old=[]} should be
+followed.]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00291-02]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[2],Text=[Added clarification that
+  @Chg{Version=[3],New=[the],Old=[pragma]} address@hidden,New=[ 
aspect],Old=[]} can
+  ignore alignment requirements on types that don't have by-reference or
+  aliased parts. This was always intended, but there was no wording to that
+  effect.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Aspect Pack is new; @nt{pragma} Pack is now obsolescent.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0009-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Fixed so that the
+  presence or absence of a confirming Component_Size representation
+  clause does not change the meaning of the Pack aspect.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0001-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Fixed so that the
+  Recommended Level of Support does not require packing of
+  components for which such packing would violate other representation
+  items or aspects. This is not incompatible, as either such Pack
+  aspects were treated as illegal or the Recommended Level of Support
+  was ignored as impractical, neither of which would change the
+  behavior of any working programs. (Other behavior cannot be justifed
+  from the Standard.)]}
address@hidden
+
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,New=[Operational and Representation Attributes], 
Old=[Representation Attributes]}
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden@Defn{representation attribute}
address@hidden, Sec=(representation)}
+The values of certain implementation-dependent characteristics can be
+obtained by interrogating appropriate
address@hidden or ],Old=[]}representation attributes.
address@hidden, Sec=(specifying)}
+Some of these attributes are specifiable via an
address@hidden
address@hidden
+
address@hidden
+In general, the meaning of a given attribute should not depend on
+whether the attribute was specified via an
address@hidden,
+or chosen by default by the implementation.
address@hidden
+
address@hidden
address@hidden<attribute_definition_clause>,rhs="
+      @key{for} @address@hidden@Syn2{attribute_designator} @key{use} 
@Syn2{expression};
+    | @key{for} @address@hidden@Syn2{attribute_designator} @key{use} 
@Syn2{name};"}
address@hidden
+
address@hidden
+For an @nt{attribute_definition_clause} that specifies
+an attribute that denotes a value,
+the form with an @nt{expression} shall be used.
+Otherwise, the form with a @nt{name} shall be used.
+
address@hidden type],
+  Sec=(attribute_definition_clause expression or name)}
+For an @nt{attribute_definition_clause} that specifies
+an attribute that denotes a value or an object,
+the expected type for the expression or @nt{name}
+is that of the attribute.
address@hidden profile],
+  Sec=(attribute_definition_clause name)}
+For an @nt{attribute_definition_clause} that specifies
+an attribute that denotes a subprogram,
+the expected profile for the @nt{name}
+is the profile required for the attribute.
+For an @nt{attribute_definition_clause} that specifies
+an attribute that denotes some other kind of entity,
+the @nt{name} shall resolve to denote an entity of the appropriate
+kind.
address@hidden
+For example, the Size attribute is of type @i{universal_integer}.
+Therefore, the expected type for Y in @lquotes@;@key[for] X'Size @key[use] 
Y;@rquotes@; is
address@hidden,
+which means that Y can be of any integer type.
address@hidden
address@hidden
+For attributes that denote subprograms, the required profile is indicated
+separately for the individual attributes.
address@hidden
address@hidden
address@hidden@;For an @nt{attribute_definition_clause} with a @nt{name},
+the @nt{name} need not statically denote the entity it denotes.
+For example, the following kinds of things are allowed:
address@hidden
address@hidden Some_Access_Type'Storage_Pool @key[use] Storage_Pool_Array(I);
address@hidden Some_Type'Read @key[use] address@hidden;
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
address@hidden (of an attribute and for an entity)}
address@hidden, Sec=(specifiable)}
+An @nt{attribute_designator} is allowed in an
address@hidden only if this International Standard
+explicitly allows it,
+or for an implementation-defined attribute
+if the implementation allows it.
address@hidden,address@hidden aspect], Sec=(specifiable attributes)}],
address@hidden of representation], Sec=(specifiable attributes)}]}
+Each specifiable attribute constitutes an
address@hidden@PDefn2{Term=[operational aspect], Sec=(specifiable attributes)}
+operational aspect or ],Old=[]}aspect of address@hidden,New=[;
+the name of the aspect is that of the attribute],Old=[]}.
address@hidden
+For each specifiable attribute,
+we generally say something like,
address@hidden@;The ... attribute may be specified for ... via
+an @address@hidden@;
+
+The above wording allows for
+T'Class'Alignment, T'Class'Size, T'Class'Input, and T'Class'Output
+to be specifiable.
+
+A specifiable attribute is not necessarily
+specifiable for all entities for which it is defined.
+For example, one is allowed to ask T'Component_Size for an array
+subtype T, but @lquotes@;@key[for] T'Component_Size @key[use] address@hidden@;
+is only allowed if T is a first subtype,
+because Component_Size is a type-related aspect.
address@hidden
+
+For an @nt{attribute_definition_clause} that specifies
+an attribute that denotes a subprogram,
+the profile shall be mode conformant with the one
+required for the attribute,
+and the convention shall be Ada.
+Additional requirements are defined for particular attributes.
address@hidden conformance],Sec=(required)}
address@hidden
address@hidden@;This implies, for example, that if one writes:
address@hidden
address@hidden T'Read @key[use] R;
address@hidden
+
+R has to be a procedure with two parameters with the appropriate
+subtypes and modes as shown in
address@hidden Attributes}.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00270-01]}
address@hidden clause}
address@hidden clause}
address@hidden clause}
address@hidden clause}
address@hidden clause}
address@hidden clause}
address@hidden clause}
address@hidden clause}
address@hidden address@hidden,New=[
address@hidden clause}],Old=[]}
address@hidden clause}
address@hidden clause}
address@hidden clause}
address@hidden clause}
address@hidden clause}
+A @i{Size clause} is an @nt{attribute_definition_clause} whose
address@hidden is Size.
+Similar definitions apply to the other specifiable attributes.
address@hidden
address@hidden, Sec=(attribute_definition_clause)}
address@hidden, Sec=(attribute_definition_clause)}
+An @nt{attribute_definition_clause}
+is type-related or subtype-specific if the @nt{attribute_designator}
+denotes a type-related or subtype-specific attribute, respectively.
address@hidden
+
address@hidden element}
address@hidden,See=(storage element)}
+A @i{storage element} is
+an addressable element of storage in the machine.
address@hidden
+A @i{word} is the largest amount of storage that can be conveniently and
+efficiently manipulated by the hardware,
+given the implementation's run-time model.
+A word consists of an integral number of storage elements.
address@hidden
+A storage element is not intended to be a single bit,
+unless the machine can efficiently address individual bits.
address@hidden
address@hidden
+For example, on a machine with 8-bit storage elements,
+if there exist 32-bit integer registers,
+with a full set of arithmetic and logical instructions to manipulate those
+registers, a word ought to be 4 storage elements @em that is, 32 bits.
address@hidden
address@hidden
+The @lquotes@;given the implementation's run-time address@hidden@; part is
+intended to imply that, for example, on an 80386 running MS-DOS,
+the word might be 16 bits, even though the hardware can support 32
+bits.
+
+A word is what ACID refers to as a @lquotes@;natural hardware
address@hidden@;.
+
+Storage elements may, but need not be, independently addressable
+(see @RefSec{Shared Variables}).
+Words are expected to be independently addressable.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00133-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0092-1]}
address@hidden,address@hidden scalar}
+A @i{machine scalar} is an amount of storage that can be conveniently and
+efficiently loaded, stored, or operated upon by the hardware. Machine scalars
+consist of an integral number of storage elements. The set of machine scalars
+is implementation defined, but @Chg{Version=[3],New=[includes],Old=[must 
include]}
+at least the storage element and
+the word. Machine scalars are used to interpret @nt{component_clause}s when the
+nondefault bit ordering applies.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The set of machine scalars.]}]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0092-1]}
+  @ChgAdded{Version=[3],Text=[A single storage element is a machine scalar
+  in all Ada implementations. Similarly, a word is a machine scalar in
+  all implementations (although it might be the same as a storage element).
+  An implementation may define other machine scalars that make sense on the
+  target (a half-word, for instance).]}
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0191-1]}
address@hidden following representation attributes are defined: Address,
+Alignment, Size, Storage_Size,
address@hidden,New=[],Old=[and address@hidden,New=[,
+Has_Same_Storage, and Overlaps_Storage],Old=[]}.],
address@hidden@;The following attributes are defined:]}
+
address@hidden,address@hidden be consistent with 8652/0006}
address@hidden@;For @ChgPrefixType{Version=[1],Kind=[Revised],Text=[a
address@hidden@nt{prefix}],Old=[prefix]} X that
+denotes an object, program unit, or label]}:
address@hidden
address@hidden<X>, AttrName=<Address>,
+  Text=<Denotes the address of the first of the storage elements
+allocated to X. For a program unit or
+label, this value refers to the machine code associated with
+the corresponding body or @nt{statement}.
+The value of this attribute is of type System.Address.>}
+
address@hidden
+  Here, the @lquotes@;first of the storage address@hidden@; is intended
+  to mean the one with the lowest address;
+  the endianness of the machine doesn't matter.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0095-1]}
address@hidden,NoPrefix=[T],Text=[The prefix of X'Address shall not statically 
denote
+a subprogram that has convention Intrinsic. X'Address raises Program_Error if X
+denotes a subprogram that has convention Intrinsic.]}
+
address@hidden@PDefn2{Term=[specifiable], Sec=(of Address for stand-alone
+objects and for program units)}
address@hidden clause}
address@hidden Redundant here, as per AI-00114. Did not mark change, as it is
+AARM-only, not to the text of the item.}Address may be specified for
+stand-alone objects and for program units via an
address@hidden@Chg{Version=[3],address@hidden,Old=[]}
+  @begin{Ramification}
+  Address is not allowed for enumeration literals,
+  predefined operators, derived task types,
+  or derived protected types, since they are not program units.
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Address is not allowed for intrinsic subprograms,
+  either. That can be checked statically unless the prefix is a generic formal
+  subprogram and the attribute reference is in the body of a generic unit.
+  We define that case to raise Program_Error, in order that the compiler
+  does not have to build a wrapper for intrinsic subprograms.]}
+
+  The validity of a given address depends on the run-time model;
+  thus, in order to use Address clauses correctly,
+  one needs intimate knowledge of the run-time model.
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  If the Address of an object is specified,
+  any explicit or implicit initialization takes place as usual,
+  unless @Chg{Version=[3],New=[the],Old=[a @nt{pragma}]} Import
+  @Chg{Version=[3],New=[aspect ],Old=[]}is also specified for the object
+  (in which case any necessary initialization is presumably
+  done in the foreign language).
+
+  Any compilation unit containing an @nt<attribute_reference> of
+  a given type depends semantically on the declaration of the package
+  in which the type is declared, even if not mentioned
+  in an applicable @nt<with_clause>
+  @em see @RefSecNum{Compilation Units - Library Units}.
+  In this case, it means that if a compilation unit contains
+  X'Address, then it depends on the declaration of System.
+  Otherwise, the fact that the value of Address is of
+  a type in System wouldn't make sense;
+  it would violate the @lquotes@;legality determinable via semantic
+  address@hidden@; @MetaRulesName.
+
+  AI83-00305 @em If X is a task type,
+  then within the body of X,
+  X denotes the current task object;
+  thus, X'Address denotes the object's address.
+
+  Interrupt entries and their addresses are
+  described in @RefSec{Interrupt Entries}.
+
+  If X is not allocated on a storage element boundary,
+  X'Address points at the first of the storage elements
+  that contains any part of X.
+  This is important for the definition of the Position
+  attribute to be sensible.
+  @end{Ramification}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Address],
+    address@hidden,Text=[Machine address of an entity.]}]}
+
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0009-1]}
address@hidden(erroneous execution),Sec=(cause)}If an Address is specified,
+it is the programmer's responsibility to ensure that
+the address is address@hidden,New=[ and appropriate for the entity and
+its use],Old=[]}; otherwise, program execution is erroneous.
+
address@hidden
address@hidden,address@hidden@;Appropriate for the entity and its
address@hidden covers cases such as
+misaligned addresses, read-only code addresses for variable data objects (and
+nonexecutable data addresses for code units), and addresses which would
+force objects that are supposed to be independently addressable to not be.
+Such addresses may be @ldquote@;address@hidden as they designate locations that
+are accessible to the program, but the program execution is still erroneous
+(meaning that implementations do not have to worry about these cases).]}
address@hidden
address@hidden
+
address@hidden
+For an array X, X'Address should point at the first component of the
+array, and not at the array bounds.
address@hidden,Kind=[Added],address@hidden,
+Text=[For an array X, X'Address should point at the first component of the
+array rather than the array bounds.]}]}
address@hidden
+On the other hand, we have no advice to offer about
+discriminants and tag fields;
+whether or not the address points at them is
+not specified by the language.
+If discriminants are stored separately,
+then the Position of a discriminant might be negative,
+or might raise an exception.
address@hidden
+
address@hidden level of support], Sec=(Address attribute)}
address@hidden@;The recommended level of support for the Address attribute is:
address@hidden
+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.
address@hidden
+  Aliased objects are the ones for which the
+  Unchecked_Access attribute is allowed;
+  hence, these have to be allocated on an addressable
+  boundary anyway. Similar considerations apply to objects
+  of a by-reference type.
+
+  An implementation need not go to any trouble
+  to make Address work in other cases.
+  For example, if an object X is not aliased and not of a by-reference type,
+  and the implementation chooses to store it in a register,
+  X'Address might return System.Null_Address
+  (assuming registers are not addressable).
+  For a subprogram whose calling convention is Intrinsic,
+  or for a package,
+  the implementation need not generate an out-of-line
+  piece of code for it.
address@hidden
+
+An implementation should support Address clauses for
+imported subprograms.
+
address@hidden,Kind=[Deleted],ARef=[AI95-00291-02]}
address@hidden,Text=[Objects (including subcomponents) that are
+aliased or of a by-reference type
+should be allocated on storage element boundaries.]}
address@hidden is a now a blanket permission to this effect}
address@hidden
address@hidden,Kind=[Deleted]}
address@hidden,Text=[This is necessary for the Address attribute to be
+useful (since First_Bit and Last_Bit apply only to components). Implementations
+generally need to do this anyway, for tasking to work properly.]}
address@hidden
+
+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.
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The recommended level of support for the Address attribute should be
+followed.]}]}
address@hidden
+
address@hidden
+The specification of a link name @Chg{Version=[3],New=[with the Link_Name
+aspect],Old=[in a @nt{pragma} Export]}
+(see @RefSecNum{Interfacing Aspects})
+for a subprogram or object is an alternative to explicit
+specification of its link-time address, allowing a link-time directive
+to place the subprogram or object within memory.
+
+The rules for the Size attribute imply,
+for an aliased object X, that if X'Size = Storage_Unit,
+then X'Address points at a storage element containing all
+of the bits of X, and only the bits of X.
address@hidden
+
address@hidden
+The intended meaning of the various attributes,
+and their @nt{attribute_definition_clause}s,
+is more explicit.
+
+The @ntf{address_clause} has been renamed to @nt{at_clause} and moved
+to @RefSec{Obsolescent Features}.
+One can use an Address clause
+(@lquotes@;for T'Address @key[use] ...;@rquotes@;)
+instead.
+
+The attributes defined in RM83-13.7.3 are moved to
address@hidden,
address@hidden of Floating Point Types}, and
address@hidden of Fixed Point Types}.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],Text=[Defined that the names of aspects are the same as
+  the name of the attribute; that gives a name to use in 
@nt{aspect_specification}s
+  (see @RefSecNum{Aspect Specifications}).]}
address@hidden
+
address@hidden
+By default, the Alignment of a subtype should
+reflect the @lquotes@;address@hidden@; alignment for objects of the
+subtype on the machine.
+The Alignment, whether specified or default,
+should be known at compile time, even though
+Addresses are generally not known at compile
+time.
+(The generated code should never need to check
+at run time the number of zero bits at the end
+of an address to determine an alignment).
+
+There are two symmetric purposes of Alignment clauses, depending on
+whether or not the implementation has control over object
+allocation.
+If the implementation allocates an object,
+the implementation should ensure that
+the Address and Alignment are consistent with
+each other.
+If something outside the implementation allocates an
+object, the implementation should be allowed to
+assume that the Address and Alignment are
+consistent, but should not assume stricter alignments
+than that.
address@hidden
+
address@hidden
address@hidden,address@hidden be consistent with 8652/0006}
address@hidden,Kind=[Revised],ARef=[AI95-00291-02]}
address@hidden@;For @ChgPrefixType{Version=[1],Kind=[Revised],Text=[a
address@hidden@nt{prefix}],Old=[prefix]} X that denotes 
@Chg{Version=[2],New=[an],
+Old=[a subtype or]} object]}:
address@hidden
address@hidden, Kind=[Revised], ChginAnnex=[T], Leading=[F],
+  Prefix=<X>, AttrName=<Alignment>, ARef=[AI95-00291-02], InitialVersion=[0],
+  address@hidden,New=[The value of this attribute is of type
+    @i{universal_integer}, and nonnegative; zero means that the object is not
+    necessarily aligned on a storage element boundary. If X'Alignment is not
+    zero, then X is aligned on a storage unit boundary and X'Address],
+    Old=[The Address of an object that is allocated under
+    control of the implementation]} is an integral multiple of
+    @Chg{Version=[2],New=[X'Alignment],Old=[the Alignment of the object]}
+    (that is, the Address modulo the Alignment is zero)address@hidden,
+    New=[],Old=[The offset of a record component is a multiple of the
+    Alignment of the component.
+    For an object that is not allocated under control of
+    the implementation
+    (that is, one that is imported,
+    that is allocated by a user-defined allocator,
+    whose Address has been specified,
+    or is designated by an access value returned by an
+    instance of Unchecked_Conversion),
+    the implementation may assume that the Address is
+    an integral multiple of its Alignment.
+    The implementation shall not assume a stricter alignment.]}
+
address@hidden below causes trouble in the generated text for attributes,
+but no fix appears to be possible. And the trouble is much worse in the
+RTF version than the HTML version, so for now we're making a hand fix.}
address@hidden,Kind=[Deleted],ARef=[AI95-00291-02]}
address@hidden,NoPrefix=[T],Text=[The value of this attribute
+    is of type @i{universal_integer}, and nonnegative;
+    zero means that the object is not necessarily
+    aligned on a storage element address@hidden X'Alignment}
address@hidden
address@hidden
+The Alignment is passed by an @nt{allocator} to the Allocate operation;
+the implementation has to choose a value such that if the address
+returned by Allocate is aligned as requested,
+the generated code can correctly access the object.
+
+The above mention of @lquotes@;address@hidden@; is referring to the "@key[mod]"
+operator declared in System.Storage_Elements;
+if X @key[mod] N = 0, then X is by definition aligned on an
+N-storage-element boundary.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00291-02]}
address@hidden@Chg{Version=[2],address@hidden, Sec=(of Alignment for objects)}],
address@hidden, Sec=(of Alignment for first subtypes and objects)}]}
address@hidden clause}
+Alignment may be specified address@hidden,New=[],Old=[ first subtypes and]}
address@hidden objects via an @address@hidden@!clause};
+the expression of such a clause shall be static, and its value
address@hidden,New=[],Old=[If the Alignment of a subtype is
+specified, then the Alignment of an object of the subtype is at least as
+strict, unless the object's Alignment is also specified.
+The Alignment of an object created by an allocator is that of the
+designated address@hidden,address@hidden (object)}],Old=[]}]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Alignment (object)],
+    address@hidden,Text=[Alignment of an object.]}]}
+
address@hidden,Kind=[Deleted],ARef=[AI95-00247-01]}
address@hidden,NoPrefix=[T],Text=[If an Alignment is specified
+for a composite subtype or object, this
+Alignment shall be equal to the least common multiple of any
+specified Alignments of the subcomponent subtypes, or an integer
+multiple thereof.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00291-02]}
address@hidden,Type=[Leading],KeepNext=[T],
+Text=[For @PrefixType{every subtype S}:]}
address@hidden
address@hidden, Kind=[Added], ChginAnnex=[T], Leading=[F],
+  Prefix=<S>, AttrName=<Alignment>, ARef=[AI95-00291-02], InitialVersion=[2],
+  address@hidden,New=[The value of this attribute is of type
+  @i{universal_integer}, and nonnegative.],Old=[]}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00051-02],ARef=[AI95-00291-02]}
+  @ChgAdded{Version=[2],NoPrefix=[T], Text=[For an object X of subtype S,
+  if S'Alignment is not zero, then X'Alignment is a nonzero integral multiple
+  of S'Alignment unless specified otherwise by a representation
+  address@hidden S'Alignment}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00291-02]}
+  @ChgAdded{Version=[2],NoPrefix=[T], address@hidden, Sec=(of Alignment for 
first subtypes)}
+  @Defn{Alignment clause}
+  Alignment may be specified for first subtypes via an
+  @address@hidden@!clause};
+  the expression of such a clause shall be static, and its value
+  address@hidden,address@hidden (subtype)}],Old=[]}]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Alignment (subtype)],
+    address@hidden,Text=[Alignment of a subtype.]}]}
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)}
+Program execution is erroneous if an Address clause is given that
+conflicts with the Alignment.
address@hidden
+The user has to either give an Alignment clause also,
+or else know what Alignment the implementation will choose by default.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00051-02],ARef=[AI95-00291-02]}
address@hidden(erroneous execution),Sec=(cause)}
address@hidden,New=[For],Old=[If the Alignment is specified for]} an
+object that is not allocated under control of the implementation,
+execution is erroneous if the object is not aligned according to
address@hidden,New=[its],Old=[the]} Alignment.
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0116-1]}
address@hidden,Text=[For any tagged specific subtype @i<S>,
address@hidden<S>'Class'Alignment should equal @i<S>'Alignment.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[A tagged object should never be less aligned than
+the alignment of the type of its view, so for a class-wide type T'Class, the
+alignment should be no greater than that of any type covered by T'Class. If the
+implementation only supports alignments that are required by the recommended
+level of support (and this is most likely), then the alignment of any covered
+type has to be the same or greater than that of T @em which leaves the only
+reasonable value of T'Class'Alignment being T'Alignment. Thus we recommend 
this,
+but don't require it so that in the unlikely case that the implementation does
+support smaller alignments for covered types, it can select a smaller value
+for T'Class'Alignment.]}
address@hidden
address@hidden,Kind=[Added],address@hidden,
+Text=[For any tagged specific subtype @i<S>,
address@hidden<S>'Class'Alignment should equal @i<S>'Alignment.]}]}
+
address@hidden level of support], Sec=(Alignment attribute
+for subtypes)}
address@hidden@;The recommended level of support for the Alignment attribute for
+subtypes is:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00051-02]}
+An implementation should support @Chg{Version=[2],New=[an Alignment clause
+for a discrete type, fixed point type, record type, or
+array type, specifying an Alignment value that is zero or
+a power of two],Old=[specified Alignments that are factors and multiples of
+the number of storage elements per word]}, subject to the following:
+
address@hidden,Kind=[Revised],ARef=[AI95-00051-02]}
+An implementation need not support
address@hidden, New=[an Alignment clause for a signed
+integer type specifying an Alignment greater than the largest
+Alignment value that is ever chosen by default by the implementation
+for any signed integer type. A corresponding limitation may be
+imposed for modular integer types, fixed point types, enumeration types,
+record types, and array types],Old=[specified Alignments for combinations
+of Sizes and Alignments that cannot be easily loaded and
+stored by available machine instructions]}.
+
address@hidden,Kind=[Revised],ARef=[AI95-00051-02]}
+An implementation need not support
address@hidden,New=[a nonconfirming Alignment clause which could enable the
+creation of an object of an elementary type which cannot be easily loaded and
+stored by available machine instructions.],
+Old=[specified Alignments that are greater than the maximum
+Alignment the implementation ever returns
+by default.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00291-02]}
address@hidden,Text=[An implementation need not support an
+Alignment specified for a derived tagged type which is not a multiple of the
+Alignment of the parent type. An implementation need not support a
+nonconfirming Alignment specified for a derived untagged by-reference type.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00291-02]}
+  @ChgAdded{Version=[2],Text=[There is no recommendation to support any
+  nonconfirming Alignment clauses for types not mentioned above.
+  Remember that
+  @RefSecNum{Operational and Representation Aspects} requires support for
+  confirming Alignment clauses for all types.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0116-1]}
+  @ChgAdded{Version=[3],Text=[An implementation that tries to support other
+  alignments for derived tagged types will need to allow inherited subprograms
+  to be passed objects that are less aligned than expected by the parent
+  subprogram and type. This is unlikely to work if alignment has any effect on
+  code selection. Similar issues arise for untagged derived types whose
+  parameters are passed by reference.]}
address@hidden
address@hidden
+
address@hidden@PDefn2{Term=[recommended level of support], Sec=(Alignment 
attribute
+for objects)}
+The recommended level of support for the Alignment attribute for
+objects is:
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00291-02]}
address@hidden,Text=[Same as above, for subtypes, but in addition:]}
+
+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.
+
address@hidden,Kind=[Added],ARef=[AI95-00291-02]}
address@hidden,Text=[For other objects, an implementation should at
+least support the alignments supported for their
+subtype, subject to the following:]}
+
address@hidden,Kind=[Added],ARef=[AI95-00291-02]}
address@hidden,Text=[An implementation need not support Alignments
+specified for objects of a by-reference type or for objects of types containing
+aliased subcomponents if the specified Alignment is not a multiple of the
+Alignment of the subtype of the object.]}
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The recommended level of support for the Alignment attribute should be
+followed.]}]}
address@hidden
+
address@hidden
+Alignment is a subtype-specific attribute.
+
address@hidden,Kind=[Deleted],ARef=[AI95-00247-01]}
address@hidden,Text=[The Alignment of a composite object is always
+equal to the least common multiple of the Alignments of its components, or a
+multiple thereof.]}
address@hidden
address@hidden,Kind=[Deleted]}
address@hidden,Text=[For default Alignments, this follows from the
+semantics of Alignment. For specified Alignments, it follows from a
address@hidden stated above.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1],ARef=[AI05-0269-1]}
+A @nt{component_clause}, Component_Size clause, or
address@hidden,New=[specifying the],Old=[a @nt{pragma}]} Pack
address@hidden,New=[aspect as True ],Old=[]}can override a specified
+Alignment.
address@hidden
+Most objects are allocated by the implementation; for these, the
+implementation obeys the Alignment. The implementation is of course
+allowed to make an object @i{more} aligned than its Alignment requires
address@hidden an object whose Alignment is 4 might just happen to land at an
+address that's a multiple of 4096.
+For formal parameters, the implementation might
+want to force an Alignment stricter than the parameter's subtype.
+For example, on some systems, it is customary to always align
+parameters to 4 storage elements.
+
+Hence, one might initially assume that the implementation could
+evilly make all Alignments 1 by default, even though integers, say,
+are normally aligned on a 4-storage-element boundary. However, the
+implementation cannot get away with that @em if the Alignment is 1,
+the generated code cannot assume an Alignment of 4, at least not for
+objects allocated outside the control of the implementation.
+
+Of course implementations can assume anything they can prove, but
+typically an implementation will be unable to prove much about the
+alignment of, say, an imported object. Furthermore, the information
+about where an address @lquotes@;came address@hidden@; can be lost to the 
compiler due to
+separate compilation.
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The Alignment of an object that is a component of a packed
+composite object will usually be 0, to indicate that the component is
+not necessarily aligned on a storage element boundary.
+For a subtype, an Alignment of 0 means that objects of the subtype are
+not normally aligned on a storage element boundary at all.
+For example, an implementation might choose to make Component_Size be
address@hidden,New=[1],Old=[0]}
+for an array of Booleans, even
+when @Chg{Version=[3],New=[the],address@hidden Pack
address@hidden,New=[aspect ],Old=[]}has not been
+specified for the array.
+In this case, Boolean'Alignment would be 0.
+(In the presence of tasking, this would in general be feasible only on a
+machine that had atomic test-bit and set-bit instructions.)
+
+If the machine has no particular natural alignments, then all subtype
+Alignments will probably be 1 by default.
+
+Specifying an Alignment of 0 in an @nt{attribute_definition_clause} does
+not require the implementation to do anything (except return 0 when the
+Alignment is queried).
+However, it might be taken as advice on some implementations.
+
+It is an error for an Address clause to disobey the object's Alignment.
+The error cannot be detected at compile time, in general, because the
+Address is not necessarily known at compile time (and is almost
+certainly not static). We do not require a run-time check, since
+efficiency seems paramount here, and Address clauses are treading on
+thin ice anyway. Hence, this misuse of Address clauses is just like any
+other misuse of Address clauses @em it's erroneous.
+
+A type extension can have a stricter Alignment than its parent.
+This can happen, for example, if the Alignment of the parent is 4,
+but the extension contains a component with Alignment 8.
+The Alignment of a class-wide type or object will have to be the
+maximum possible Alignment of any extension.
+
+The recommended level of support for the Alignment attribute is
+intended to reflect a minimum useful set of capabilities. An
+implementation can assume that all Alignments are multiples of each
+other @em 1, 2, 4, and 8 might be the only supported Alignments for
+subtypes. An Alignment of 3 or 6 is unlikely to be useful.
+For objects that can be allocated statically, we recommend that
+the implementation support larger alignments, such as 4096. We do
+not recommend such large alignments for subtypes, because the maximum
+subtype alignment will also have to be used as the alignment of stack
+frames, heap objects, and class-wide objects. Similarly, we do not
+recommend such large alignments for stack-allocated objects.
+
+If the maximum default Alignment is 8
+(say, Long_Float'Alignment = 8),
+then the implementation can refuse to accept stricter alignments
+for subtypes. This simplifies the generated code, since the compiler
+can align the stack and class-wide types to this maximum without a
+substantial waste of space (or time).
+
+Note that the recommended level of support takes into account
+interactions between Size and Alignment. For example, on a 32-bit
+machine with 8-bit storage elements, where load and store
+instructions have to be aligned according to the size of the thing
+being loaded or stored, the implementation might accept an Alignment
+of 1 if the Size is 8, but might reject an Alignment of 1 if the Size
+is 32. On a machine where unaligned loads and stores are merely
+inefficient (as opposed to causing hardware traps),
+we would expect an Alignment of 1 to be supported for any Size.
address@hidden
address@hidden
+
address@hidden
+The nonnegative part is missing from RM83
+(for @nt{mod_clause}s, nee @ntf{alignment_clause}s,
+which are an obsolete version of Alignment clauses).
address@hidden
+
address@hidden
address@hidden,address@hidden be consistent with 8652/0006}
address@hidden@;For @ChgPrefixType{Version=[1],Kind=[Revised],Text=[a
address@hidden@nt{prefix}],Old=[prefix]} X that denotes an object]}:
address@hidden
address@hidden<X>, AttrName=<Size>,
+  Text=<Denotes the size in bits of
+the representation of the object.
+The value of this attribute is of the type
address@hidden>}
address@hidden
address@hidden
+Note that Size is in bits even if Machine_Radix is 10.
+Each decimal digit (and the sign) is presumably represented
+as some number of bits.
address@hidden
+
address@hidden@PDefn2{Term=[specifiable], Sec=(of Size for stand-alone objects)}
address@hidden clause}
+Size may be specified for @Redundant[stand-alone] objects
+via an @nt{attribute_definition_clause};
+the expression of such a clause shall be static and its
+value address@hidden,address@hidden (object)}],Old=[]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Size (object)],
+    address@hidden,Text=[Size in bits of an object.]}]}
+
address@hidden
address@hidden
+
address@hidden
address@hidden from 13.9}
address@hidden,Kind=[Added],ARef=[AI95-00051-02]}
address@hidden,Text=[The size of an array object should not include
+its bounds.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The Size of an array object should not include its bounds.]}]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00051-02],ARef=[AI95-00291-02]}
address@hidden,Type=[Leading],address@hidden fake to get a conditional Leading}
address@hidden level of support], Sec=(Size attribute)}
+The recommended level of support for the Size attribute
+of objects address@hidden,New=[ the same as for subtypes (see below),
+except that only a confirming Size clause need be supported for an aliased
+elementary object.],Old=[:]}
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00051-02]}
address@hidden,Text=[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).]}
address@hidden ImplDef summary here; there is no reason to separately mention 
it}
address@hidden
address@hidden
+
address@hidden
address@hidden@Keepnext@;For @PrefixType{every subtype S}:
address@hidden
address@hidden<S>, AttrName=<Size>,
+  Text=<If S is definite,
+denotes the size @Redundant{(in bits)}
+that the implementation would choose for
+the following objects of subtype S:
address@hidden
+A record component of subtype S
+when the record type is packed.
+
+The formal parameter of an instance of Unchecked_Conversion
+that converts from subtype S to some other subtype.
address@hidden
+
address@hidden@;If S is indefinite,
+the meaning is implementation defined.
+The value of this attribute is of the type
address@hidden>}
address@hidden, Sec=(of Size for first subtypes)}
address@hidden clause}
+The Size of an object is at least as large as that of its subtype,
+unless the object's Size is determined by a Size clause,
+a component_clause, or a Component_Size clause.
+Size may be specified for first subtypes
+via an @address@hidden@!clause};
+the expression of such a clause shall be static
+and its value address@hidden,address@hidden (subtype)}],Old=[]}
address@hidden meaning of Size for indefinite subtypes.}
+  @begin{Reason}
+  @Leading@;The effects of specifying the Size of a subtype are:
+  @begin{Itemize}
+    Unchecked_Conversion works in a predictable manner.
+
+    A composite type cannot be packed so tightly as to override
+    the specified Size of a component's subtype.
+
+    Assuming the @ImplAdviceName is obeyed,
+    if the specified Size allows independent addressability,
+    then the Size of certain objects of the subtype
+    should be equal to the subtype's Size.
+    This applies to stand-alone objects and to components
+    (unless a @nt{component_clause} or a Component_Size clause applies).
+  @end{Itemize}
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  A @nt{component_clause} or a Component_Size clause can cause an object
+  to be smaller than its subtype's specified size.
+  @Chg{Version=[3],New=[The aspect],Old=[A @nt{pragma}]}
+  Pack cannot; if a component subtype's size is specified,
+  this limits how tightly the composite object can be packed.
+
+  The Size of a class-wide (tagged) subtype is unspecified,
+  because it's not clear what it should mean;
+  it should certainly not depend on all of the descendants that happen
+  to exist in a given program.
+  Note that this cannot be detected at compile time,
+  because in a generic unit, it is not necessarily known
+  whether a given subtype is class-wide.
+  It might raise an exception on some implementations.
+  @end{Reason}
+  @begin{Ramification}
+  @Leading@;A Size clause for a numeric subtype need not
+  affect the underlying numeric type.
+  For example, if I say:
+  @begin{Example}
address@hidden S @key[is] @key[range] 1..2;
address@hidden S'Size @key[use] 64;
+  @end{Example}
+
+  I am not guaranteed that S'Base'Last >= address@hidden@;1,
+  nor that intermediate results will be represented in 64 bits.
+  @end{Ramification}
+  @begin{Reason}
+  There is no need to complicate implementations for this sort of
+  thing, because the right way to affect the base range of a type
+  is to use the normal way of declaring the base range:
+  @begin{Example}
address@hidden Big @key[is] @key[range] -2**63 .. 2**63 - 1;
address@hidden Small @key[is] Big @key[range] 1..1000;
+  @end{Example}
+  @end{Reason}
+  @begin{Ramification}
+  The Size of a large unconstrained subtype (e.g. String'Size)
+  is likely to raise Constraint_Error,
+  since it is a nonstatic expression of type @i{universal_integer}
+  that might overflow the largest signed integer type.
+  There is no requirement that the largest integer type be able to
+  represent the size in bits of the largest possible object.
+  @end{Ramification}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Size (subtype)],
+    address@hidden,Text=[Size in bits of a subtype.]}]}
+
address@hidden
address@hidden
address@hidden
+
address@hidden
+In an implementation, Boolean'Size shall be 1.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00051-02]}
address@hidden@;If the Size of a subtype @Chg{Version=[2],New=[],Old=[is 
specified,
+and ]}allows for efficient independent addressability
+(see @RefSecNum{Shared Variables}) on the target architecture,
+then the Size of the following objects of the subtype should equal the
+Size of the subtype:
address@hidden
+Aliased objects (including components).
+
+Unaliased components, unless the Size of the
+component is determined by a @nt{component_clause} or Component_Size
+clause.
address@hidden
address@hidden,Kind=[Added],address@hidden,
+Text=[If the Size of a subtype allows for efficient independent
+addressability, then the Size of most objects of the subtype should
+equal the Size of the subtype.]}]}
address@hidden
+Thus, on a typical 32-bit machine,
address@hidden@;@key[for] S'Size @key[use] 32;@rquotes@;
+will guarantee that aliased objects of subtype S,
+and components whose subtype is S, will have Size
+= 32 (assuming the implementation chooses to obey this @ImplAdviceTitle).
+On the other hand, if one writes,
address@hidden@;@key[for] S2'Size @key[use] 5;@rquotes@;
+then stand-alone objects of subtype S2 will typically have their Size
+rounded up to ensure independent addressability.
+
+Note that @lquotes@;@key[for] S'Size @key[use] 32;@rquotes@;
+does not cause things like formal parameters to have Size = 32 @em
+the implementation is allowed to make all parameters be at least 64
+bits, for example.
+
+Note that
address@hidden@;@key[for] S2'Size @key[use] 5;@rquotes@;
+requires record components whose subtype is S2 to be exactly 5 bits
+if the record type is packed.
+The same is not true of array components;
+their Size may be rounded up to the nearest factor of the word size.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00291-02]}
address@hidden
+On most machines, arrays don't contain gaps between @Chg{Version=[2],
+New=[elementary ],Old=[]}components;
+if the Component_Size is greater than the Size of the component subtype,
+the extra bits are generally considered part of each component,
+rather than gaps between components.
+On the other hand,
+a record might contain gaps between @Chg{Version=[2],
+New=[elementary ],Old=[]}components,
+depending on what sorts of loads, stores, and masking operations
+are generally done by the generated code.
+
address@hidden,Kind=[Revised],ARef=[AI95-00291-02]}
+For an array,
+any extra bits stored for each @Chg{Version=[2],
+New=[elementary ],Old=[]}component will generally be part
+of the component @em the whole point of storing extra bits is to
+make loads and stores more efficient by avoiding the need to mask out
+extra bits.
+The PDP-10 is one counter-example;
+since the hardware supports byte strings with a gap at the end of
+each word,
+one would want to pack in that manner.
address@hidden
+
+A Size clause on a composite subtype should not affect
+the internal layout of components.
address@hidden,Kind=[Added],address@hidden,
+Text=[A Size clause on a composite subtype should not affect
+the internal layout of components.]}]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+That's what Pack @Chg{Version=[3],New=[aspects],address@hidden,
address@hidden,
+and Component_Size clauses are for.
address@hidden
+
address@hidden@PDefn2{Term=[recommended level of support], Sec=(Size attribute)}
+The recommended level of support for the Size attribute
+of subtypes is:
address@hidden
+
+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.
+
address@hidden
+  This applies to static enumeration subtypes,
+  using the internal codes used to represent the values.
+
+  For a two's-complement machine, this implies that
+  for a static signed integer subtype S,
+  if all values of S are in the range 0 .. address@hidden@address@hidden@;1,
+  or all values of S are in the range @en@;address@hidden@address@hidden@;1}} 
.. address@hidden@address@hidden@;address@hidden@;1,
+  for some @i{n} less than or equal to the word size,
+  then S'Size should be <= the smallest such @i{n}.
+  For a one's-complement machine,
+  it is the same except that in the second range,
+  the lower bound 
@lquotes@;@en@;address@hidden@address@hidden@;address@hidden@; is replaced by 
@lquotes@;@en@;address@hidden@address@hidden@;address@hidden@;.
+
+
+  If an integer subtype (whether signed or unsigned)
+  contains no negative values, the Size should not include space
+  for a sign bit.
+
+
+  Typically, the implementation will choose to make the Size of a
+  subtype be exactly the smallest such @i{n}.
+  However, it might, for example, choose a biased representation,
+  in which case it could choose a smaller value.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+  On most machines, it is in general not a good idea to pack (parts of)
+  multiple stand-alone objects into the same storage element,
+  because (1) it usually doesn't save much space,
+  and (2) it requires locking to prevent tasks from interfering with each
+  other, since separate stand-alone objects are independently
+  addressable.
+  Therefore, if S'Size = 2
+  on a machine with 8-bit storage elements,
+  the size of a stand-alone object of subtype S will probably not be 2.
+  It might, for example, be 8, 16 or 32, depending on the availability
+  and efficiency of various machine instructions.
+  The same applies to components of composite types,
+  unless @Chg{Version=[3],New=[Pack],Old=[packing]},
+  Component_Size, or record layout is specified.
+
+  For an unconstrained discriminated object,
+  if the implementation allocates the maximum
+  possible size,
+  then the Size attribute should return that maximum
+  possible size.
address@hidden
+  @begin{Ramification}
+  The Size of an object X is not usually the same as that of
+  its subtype S.
+  If X is a stand-alone object or a parameter, for example,
+  most implementations will round X'Size up to a storage
+  element boundary, or more, so X'Size might be greater than S'Size.
+  On the other hand,
+  X'Size cannot be less than S'Size, even
+  if the implementation can prove, for example,
+  that the range of values actually taken on by X during execution
+  is smaller than the range of S.
+
+  For example, if S is a first integer subtype whose range
+  is 0..3, S'Size will be probably be 2 bits, and components of
+  packed composite types of this subtype will be 2 bits
+  (assuming Storage_Unit is a multiple of 2),
+  but stand-alone objects and parameters will probably
+  not have a size of 2 bits; they might be rounded up to
+  32 bits, for example.
+  On the other hand, Unchecked_Conversion will use the 2-bit size,
+  even when converting a stand-alone object,
+  as one would expect.
+
+  Another reason for making the Size of an object bigger than
+  its subtype's Size is to support the run-time detection of
+  uninitialized variables.
address@hidden variables}
+  The implementation might add an extra value to a discrete subtype
+  that represents the uninitialized state,
+  and check for this value on use.
+  In some cases, the extra value will require an extra bit in the
+  representation of the object.
+  Such detection is not required by the language.
+  If it is provided, the implementation has to be able to turn it off.
+  For example, if the programmer gives a
+  @nt{record_representation_clause} or Component_Size clause that makes
+  a component too small to allow the extra bit,
+  then the implementation will not be able to perform the checking
+  (not using this method, anyway).
+
+  @Leading@;The fact that the size of an object is not necessarily the same
+  as its subtype can be confusing:
+  @begin{Example}
address@hidden Device_Register @key[is] @key[range] 0..2**8 - 1;
address@hidden Device_Register'Size @key[use] 8; address@hidden Confusing!}
+My_Device : Device_Register;
address@hidden My_Device'Address @key[use] To_Address(16#FF00#);
+  @end{Example}
+
+  The programmer might think that My_Device'Size is 8,
+  and that My_Device'Address points at an 8-bit location.
+  However, this is not true.
+  In Ada 83 (and in Ada 95), My_Device'Size might well be 32,
+  and My_Device'Address might well point at the high-order 8 bits of
+  the 32-bit object, which are always all zero bits.
+  If My_Device'Address is passed to an assembly language subprogram,
+  based on the programmer's assumption,
+  the program will not work properly.
+  @end{Ramification}
+  @begin{Reason}
+  It is not reasonable to require that an implementation allocate
+  exactly 8 bits to all objects of subtype Device_Register.
+  For example, in many run-time models, stand-alone objects
+  and parameters are always aligned to a word boundary.
+  Such run-time models are generally based on hardware considerations
+  that are beyond the control of the implementer.
+  (It is reasonable to require that an implementation allocate exactly
+  8 bits to all components of subtype Device_Register, if packed.)
+  @end{Reason}
+  @begin{Ramification}
+  @Leading@;The correct way to write the above code is like this:
+  @begin{Example}
address@hidden Device_Register @key[is] @key[range] 0..2**8 - 1;
+My_Device : Device_Register;
address@hidden My_Device'Size @key[use] 8;
address@hidden My_Device'Address @key[use] To_Address(16#FF00#);
+  @end{Example}
+
+  If the implementation cannot accept 8-bit stand-alone objects,
+  then this will be illegal.
+  However, on a machine where an 8-bit device register exists,
+  the implementation will probably be able to accept 8-bit stand-alone
+  objects. Therefore, My_Device'Size will be 8,
+  and My_Device'Address will point at those 8 bits,
+  as desired.
+
+  If an object of subtype Device_Register is passed to a foreign
+  language subprogram, it will be passed according to that subprogram's
+  conventions. Most foreign language implementations have similar
+  run-time model restrictions.
+  For example, when passing to a C function,
+  where the argument is of
+  the C type char* (that is, pointer to char),
+  the C compiler will generally expect a full word value,
+  either on the stack, or in a register.
+  It will @i{not} expect a single byte.
+  Thus, Size clauses for subtypes really have nothing to do with
+  passing parameters to foreign language subprograms.
+  @end{Ramification}
+
+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.
address@hidden
+For example, if a task object is represented as a pointer to some
+information (including a task stack), then the size of the object
+should be the size of the pointer.
+The Storage_Size, on the other hand,
+should include the size of the stack.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00051-02]}
address@hidden,Type=[Leading],Text=[An implementation should support a
+Size clause for a discrete type, fixed point type, record type, or array type,
+subject to the following:]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00051-02]}
address@hidden,Text=[An implementation need not support a Size clause
+for a signed integer type specifying a Size greater than that of the largest
+signed integer type supported by the implementation in the absence of a size
+clause (that is, when the size is chosen by default). A corresponding
+limitation may be imposed for modular integer types, fixed point types,
+enumeration types, record types, and array types.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00051-02]}
+  @ChgAdded{Version=[2],Text=[Note that the @lquotes@;corresponding
+  address@hidden for a record or array type implies that an implementation
+  may impose some reasonable maximum size for records and arrays (e.g. 2**32
+  bits), which is an upper bound (@lquotes@;address@hidden limit) on the
+  size, whether chosen by default or by being specified by the user. The
+  largest size supported for records need not be the same as the largest
+  size supported for arrays.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0155-1]}
+  @ChgAdded{Version=[3],Text=[Only Size clauses with a size greater than or
+  equal to the Size that would be chosen by default may be safely presumed to 
be
+  supported on nonstatic elementary subtypes. Implementations may choose to
+  support smaller sizes, but only if the Size allows any value of the subtype 
to
+  be represented, for any possible value of the bounds.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00291-02]}
address@hidden,Text=[A nonconfirming size clause for the first subtype
+of a derived untagged by-reference type need not be supported.]}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The recommended level of support for the Size attribute should be
+followed.]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00291-02]}
+  @ChgAdded{Version=[2],Text=[There is no recommendation to support any
+  nonconfirming Size clauses for types not mentioned above.
+  Remember that
+  @RefSecNum{Operational and Representation Aspects} requires support for
+  confirming Size clauses for all types.]}
address@hidden
address@hidden
+
address@hidden
+Size is a subtype-specific attribute.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+A @nt{component_clause} or Component_Size clause
+can override a specified Size.
address@hidden,New=[Aspect],Old=[A @nt{pragma}]} Pack cannot.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00114-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 83}We specify
+  the meaning of Size in much more
+  detail than Ada 83. This is not technically an inconsistency, but it is in
+  practice, as most Ada 83 compilers use a different definition for Size than
+  is required here. This should have been documented more explicitly during
+  the Ada 9X process.]}
address@hidden
+
address@hidden
+The requirement for a nonnegative value in a Size clause
+was not in RM83, but it's hard to see how it would make sense.
+For uniformity, we forbid negative sizes,
+rather than letting implementations define their meaning.
address@hidden
+
address@hidden
address@hidden,address@hidden be consistent with 8652/0006}
address@hidden@;For @ChgPrefixType{Version=[1],Kind=[Revised],Text=[a
address@hidden@nt{prefix}],Old=[prefix]} T that denotes a task
+object @Redundant[(after any implicit dereference)]]}:
address@hidden
address@hidden, Kind=[Revised], ChginAnnex=[F], Leading=[F],
+  Prefix=<T>, AttrName=<Storage_Size>, ARef=[AI05-0229-1],
+  Text=<Denotes the number of storage elements reserved for
+  the task.
+The value of this attribute is of the type
address@hidden
+The Storage_Size includes the size of the task's stack,
+if any. The language does not specify whether or
+not it includes other storage associated with the task
+(such as the @lquotes@;task control address@hidden@; used by some
+implementations.)>}
+If @Chg{Version=[3],New=[the aspect],Old=[a @nt{pragma}]} Storage_Size is
address@hidden,New=[specified for the type of the object],Old=[given]},
+the value of the Storage_Size attribute is at least
+the value @Chg{Version=[3],New=[determined by the aspect],Old=[specified
+in the @nt{pragma}]}.
address@hidden
+  @begin{Ramification}
+  The value of this attribute is never negative,
+  since it is impossible to @lquotes@;address@hidden@; a negative number
+  of storage elements.
+
+  If the implementation chooses to allocate an initial amount of
+  storage, and then increase this as needed,
+  the Storage_Size cannot include the additional amounts
+  (assuming the allocation of the additional amounts can raise
+  Storage_Error); this is inherent in the meaning of @lquotes@;address@hidden@;
+
+  The implementation is allowed to allocate different amounts of
+  storage for different tasks of the same subtype.
+
+  Storage_Size is also defined for access subtypes
+  @em see @RefSecNum{Storage Management}.
+  @end{Ramification}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-0229-1]}
address@hidden@Chg{Version=[3],New=[Aspect],address@hidden clause],See=[pragma 
Storage_Size]}
+A @nt{pragma}]} Storage_Size specifies the amount of storage to be
+reserved for the execution of a task.]
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 62
+through 65 were moved to @RefSec{Obsolescent Features}.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],KeepNext=[T],Text=[The form of a
address@hidden Storage_Size is as follows:]}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden<Version=[3],InitialVersion=[0],@ChgDeleted{Version=[3],
address@hidden @prag(Storage_Size)(@Syn2{expression});]}>
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Text=[A @nt{pragma} Storage_Size is allowed only
+immediately within a @nt{task_definition}.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,address@hidden type],
+  Sec=(Storage_Size pragma argument)}
+The @nt{expression} of a @nt<pragma> Storage_Size
+is expected to be of any integer type.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0229-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Leading],Text=[For a task type (including the
+anonymous type of a @nt{single_task_declaration}),
+the following language-defined representation aspect may be specified:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden Storage_Size aspect is
+an @nt{expression}, which shall be of any integer
address@hidden (task)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This definition somewhat conflicts with the
+  "automatic" one for the obsolescent attribute Storage_Size (which can be
+  specified). The only difference is where the given expression is evaluated.
+  We intend for the above definition to supersede that "automatic"
+  definition for this attribute.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Note that the value of the Storage_Size aspect
+  @i<is> an @nt{expression}; it is not the @i<value> of an @nt{expression}.
+  The @nt{expression} is evaluated for each object of the type (see below).]}
address@hidden
+
address@hidden,Kind=[AddedNormal],Aspect=[Storage_Size (task)],
+  address@hidden,Text=[Size in storage elements reserved for a task
+    type or single task object.]}]}
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Text=[The Storage_Size aspect shall not be specified for a
+task interface type.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[When a task object is created, the @nt{expression}
+(if any) associated with the Storage_Size aspect of its
+type],Old=[A @nt<pragma> Storage_Size is elaborated when an object
+of the type defined by the immediately enclosing @nt<task_definition>
+is created.
address@hidden,Sec=(Storage_Size pragma)}
+For the elaboration of a @nt<pragma> Storage_Size, the @nt<expression>]}
+is evaluated; the Storage_Size attribute of the newly created task object
+is at least the value of the @nt<expression>.
+
address@hidden
+  The implementation is allowed to round up a specified Storage_Size
+  amount.
+  For example, if the implementation always allocates in
+  chunks of 4096 bytes, the number 200 might be rounded
+  up to 4096. Also, if the user specifies a negative
+  number, the implementation has to normalize this to 0,
+  or perhaps to a positive number.
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[If the Storage_Size aspect is not specified for
+  the type of the task object, the value of the Storage_Size attribute is
+  unspecified.]}
address@hidden
+
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+At the point of task object creation, or upon task activation,
+Storage_Error is raised if there is insufficient free storage to
+accommodate the requested Storage_Size.
address@hidden
+
address@hidden
address@hidden,address@hidden be consistent with 8652/0006}
address@hidden@;For @ChgPrefixType{Version=[1],Kind=[Revised],Text=[a
address@hidden@nt{prefix}],Old=[prefix]} X that denotes an array subtype or
+array object @Redundant[(after any implicit dereference)]]}:
address@hidden
address@hidden<X>, AttrName=<Component_Size>,
+  Text=<Denotes the size in bits of
+components of the type of X.
+The value of this attribute is of type @i{universal_integer}.>}
address@hidden
+
address@hidden@PDefn2{Term=[specifiable], Sec=(of Component_Size for
+array types)address@hidden clause}
+Component_Size may be specified for array types
+via an @address@hidden@!clause};
+the expression of such a clause shall be static,
+and its value address@hidden,address@hidden,Old=[]}
+
address@hidden
+The intent is that the value of X'Component_Size is always nonnegative.
+If the array is stored @lquotes@;address@hidden@; in memory
+(which might be caused by an implementation-defined pragma),
+X'Component_Size is still positive.
address@hidden
address@hidden
+For an array object A, A'Component_Size = A(I)'Size for any index I.
address@hidden
+
address@hidden,Kind=[AddedNormal],Aspect=[Component_Size],
+  address@hidden,Text=[Size in bits of a component of an array type.]}]}
+
address@hidden
address@hidden
+
address@hidden
address@hidden@PDefn2{Term=[recommended level of support], Sec=(Component_Size 
attribute)}
+The recommended level of support for the Component_Size attribute is:
address@hidden
+An implementation need not support specified Component_Sizes that
+are less than the Size of the component subtype.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+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
address@hidden,New=[Pack],Old=[packing]} is also specified;
+the implementation should forbid this combination in cases where it
+cannot support a no-gaps representation.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+For example, if Storage_Unit = 8, and Word_Size = 32,
+then the user is allowed to specify a Component_Size of
+1, 2, 4, 8, 16, and 32, with no gaps.
+In addition, @i{n}*32 is allowed for positive integers @i{n},
+again with no gaps.
+If the implementation accepts Component_Size = 3,
+then it might allocate 10 components per word,
+with a 2-bit gap at the end of each word
+(unless @Chg{Version=[3],New=[Pack],Old=[packing]} is also specified),
+or it might not have any internal gaps at all.
+(There can be gaps at either end of the array.)
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The recommended level of support for the Component_Size attribute should
+be followed.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0191-1]}
address@hidden,Type=[Leading],Text=[For
address@hidden,Kind=[Added],Text=[a @nt{prefix} X that denotes
+an object]}:]}
address@hidden(description)
address@hidden Original Version=[3],Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ChginAnnex=[T],
+  Leading=<F>, Prefix=<X>, AttrName=<Has_Same_Storage>, ARef=[AI05-0191-1],
+  InitialVersion=[3], address@hidden,New=[X'Has_Same_Storage denotes
+  a function with the following specification:],Old=[]}
+
address@hidden(Descexample)
address@hidden,Kind=[Added]}
address@hidden,address@hidden(function) X'Has_Same_Storage (@RI{Arg} : 
@RI{any_type})
+  @key(return) Boolean]}
address@hidden(Descexample)
+
+   @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0191-1],ARef=[AI05-0264-1]}
+   @ChgRef{Version=[4],Kind=[RevisedAdded],ARef=[AI12-0077-1]}
+   @ChgAdded{Version=[3],NoPrefix=[T],Text=[The actual parameter shall be a 
name
+   that denotes an object. The object denoted by the actual parameter can be of
+   any type. This function evaluates the names of the objects
+   address@hidden,New=[. It],Old=[ and]}
+   returns True if the representation of the object denoted by the actual
+   parameter occupies exactly the same bits as the representation of the object
+   denoted by address@hidden,New=[ and the objects occupy at least
+   one bit],Old=[]}; otherwise, it returns address@hidden of Annex text here.}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Has_Same_Storage means that, if the 
representation
+  is contiguous, the objects sit at the same address and occupy the same length
+  of memory.]}
address@hidden
address@hidden(description)
+
address@hidden,Kind=[Added],ARef=[AI05-0191-1]}
address@hidden,Type=[Leading],Text=[For @PrefixType{a @nt{prefix} X that
+denotes an object}:]}
address@hidden(description)
address@hidden,Kind=[Added],ChginAnnex=[T],
+  Leading=<F>, Prefix=<X>, AttrName=<Overlaps_Storage>, ARef=[AI05-0191-1],
+  InitialVersion=[3], address@hidden,New=[X'Overlaps_Storage denotes
+  a function with the following specification:],Old=[]}
+
address@hidden(Descexample)
address@hidden,Kind=[Added]}
address@hidden,address@hidden(function) X'Overlaps_Storage (@RI{Arg} : 
@RI{any_type})
+  @key(return) Boolean]}
address@hidden(Descexample)
+
+   @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0191-1],ARef=[AI05-0264-1]}
+   @ChgAdded{Version=[3],NoPrefix=[T],Text=[The actual parameter shall be a 
name
+   that denotes an object. The object denoted by the actual parameter can be of
+   any type. This function evaluates the names of the objects involved and
+   returns True if the representation of the object denoted by the actual
+   parameter shares at least one bit with the representation of the object
+   denoted by X; otherwise, it returns address@hidden of Annex text here.}
address@hidden(description)
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0191-1]}
address@hidden,Text=[X'Has_Same_Storage(Y) implies X'Overlaps_Storage(Y).]}
+
address@hidden,Kind=[Added],ARef=[AI05-0191-1]}
address@hidden,Text=[X'Has_Same_Storage(Y) and X'Overlaps_Storage(Y) are
+not considered to be reads of X and Y.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0183-1]}
address@hidden,Text=[The following
address@hidden,New=[type-related ],Old=[]}operational attribute is
+defined: External_Tag.]}
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden@;For @PrefixType{every subtype S of a tagged type @i(T)
+(specific or class-wide)address@hidden,Old=[, the following
+attribute is defined]}:
+
address@hidden
address@hidden @ChgAttribute{Version=[1], Kind=[Revised], ChginAnnex=[F], 
Leading=[F],
+  Prefix=<S>, AttrName=<External_Tag>, Ref=[8652/0040], ARef=[AI95-00108-01], 
...}
+  We don't have a way to change multiple versions for attributes.}
address@hidden, Kind=[Revised], ChginAnnex=[F], Leading=[F],
+  Prefix=<S>, AttrName=<External_Tag>, Ref=[8652/0040], ARef=[AI95-00108-01], 
ARef=[AI05-0092-1],
+  InitialVersion=[0], address@hidden clause}
+  @PDefn2{Term=(specifiable), Sec=(of External_Tag for a tagged type)}
+  S'External_Tag denotes an external string representation
+  for S'Tag; it is of the predefined type String.
+  External_Tag may be specified for a specific tagged type
+  via an @nt{attribute_definition_clause};
+  the expression of such a clause shall be 
address@hidden,address@hidden,Old=[]}
+  The default external tag representation is implementation defined.
+  See @Chg{Version=[3],New=[],address@hidden Operations of Tagged Types}
+  and address@hidden Attributes}.]}
+  @Chg{New=[The value of External_Tag is never address@hidden; the
+  default value is always used unless a new value is directly specified
+  for a type].],Old=[]}
+  @ImplDef{The default external representation for a type tag.}
+  @end{Description}
address@hidden()
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[External_Tag],
+    address@hidden,Text=[Unique identifier for a tagged type in
+      streams.]}]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0113-1]}
address@hidden,Text=[If a user-specified external tag S'External_Tag is
+the same as T'External_Tag for some other tagged type declared by a different
+declaration in the partition, Program_Error is raised by the elaboration of the
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This rule does not depend on the visibility of 
the
+  other tagged type, but it does depend on the existence of the other tagged
+  type. The other tagged type could have the default external tag or a
+  user-specified external tag.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This rule allows the same declaration to be
+  elaborated multiple times. In that case, different types could have the same
+  external tag. If that happens, Internal_Tag would return some unspecified 
tag,
+  and Descendant_Tag probably would return the intended tag (using the given
+  ancestor to determine which type is intended). However, in some cases (such 
as
+  multiple instantiations of a derived tagged type declared in a generic body),
+  Tag_Error might be raised by Descendant_Tag if multiple types are 
identified.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Note that while there is a race condition 
inherent
+  in this definition (which attribute_definition_clause raises Program_Error
+  depends on the order of elaboration), it doesn't matter as a program with two
+  such clauses is simply wrong. Two types that both come from the same
+  declaration are allowed, as noted previously.]}
address@hidden
address@hidden
+
address@hidden
+In an implementation, the default external tag for each specific tagged type
+declared in a partition
+shall be distinct, so long as the type is declared outside an
+instance of a generic body.
+If the compilation unit in which
+a given tagged type is declared, and all compilation units on which it
+semantically depends, are the same in two different partitions,
+then the external tag for the type shall be the same in the
+two partitions.
+What it means for a compilation unit to be the same in
+two different partitions is implementation defined.
+At a minimum, if the compilation unit is not recompiled
+between building the two different partitions that include it, the compilation
+unit is considered the same in the two partitions.
address@hidden determines whether a compilation unit is the
+same in two different partitions.}
address@hidden
+  These requirements are important because external tags are used
+  for input/output of class-wide types. These requirements ensure
+  that what is written by one program can be read back by some other
+  program so long as they share the same declaration for the
+  type (and everything it depends on).
+
+  The user may specify the external tag if (s)he wishes its value
+  to be stable even across changes to the compilation unit
+  in which the type is declared (or changes in some unit on which it
+  depends).
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00114-01]}
+  We use a String rather than a @Chg{Version=[2],
+  New=[Stream_Element_Array],Old=[Storage_Array]} to represent an
+  external tag for portability.
address@hidden
address@hidden
+  Note that the characters
+  of an external tag need not all be graphic characters.
+  In other words, the external tag can be a sequence of arbitrary
+  8-bit bytes.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0113-1]}
address@hidden,Text=[If a user-specified external tag S'External_Tag is
+the same as T'External_Tag for some other tagged type declared by a different
+declaration in the partition, the partition may be rejected.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is, in general, a post-compilation check.
+  This permission is intended for implementations that do link-time 
construction
+  of the external tag lookup table; implementations that dynamically construct
+  the table will likely prefer to raise Program_Error upon elaboration of the
+  problem construct. We don't want this check to require any implementation
+  complexity, as it will be very rare that there would be a problem.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00270-01]}
+The following language-defined attributes are specifiable,
+at least for some of the kinds of entities to which they apply:
+Address,
address@hidden,New=[],Old=[Size, Component_Size, ]}Alignment,
address@hidden,New=[Bit_Order, Component_Size, ],Old=[]}
+External_Tag,
address@hidden,New=[Input, Machine_Radix, Output, Read, Size, ],Old=[]}
+Small, @Chg{Version=[2],New=[],Old=[Bit_Order, ]}
+Storage_Pool, Storage_Size,
address@hidden,New=[Stream_Size, and ],Old=[]}
address@hidden,New=[],Old=[, Output, Read,
+Input, and Machine_Radix]}.
+
+It follows from the general rules in @RefSecNum{Operational and Representation 
Aspects}
+that if one writes @lquotes@;@key[for] X'Size @key[use] Y;@rquotes@; then
+the X'Size @nt{attribute_reference} will return Y
+(assuming the implementation allows the Size clause).
+The same is true for all of the specifiable attributes except Storage_Size.
address@hidden
+An implementation may specify that an implementation-defined attribute is
+specifiable for certain entities.
+This follows from the fact that the semantics of
+implementation-defined attributes is implementation defined.
+An implementation is not allowed to make a language-defined attribute
+specifiable if it isn't.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of attribute definition clauses:}
address@hidden
+Byte : @key[constant] := 8;
+Page : @key[constant] := 2**12;
+
address@hidden Medium @key[is] @key[range] 0 .. 65_000;
address@hidden Medium'Size @key[use] 2*Byte;
address@hidden Medium'Alignment @key[use] 2;
+Device_Register : Medium;
address@hidden Device_Register'Size @key[use] Medium'Size;
address@hidden Device_Register'Address @key[use] 
System.Storage_Elements.To_Address(16#FFFF_0020#);
+
address@hidden Short @key[is] @key[delta] 0.01 @key[range] -100.0 .. 100.0;
address@hidden Short'Size @key[use] 15;
+
address@hidden Car_Name'Storage_Size @key[use] address@hidden specify access 
type's storage pool size}
+        2000*((Car'Size/System.Storage_Unit) +1); address@hidden approximately 
2000 cars}
+
address@hidden,Kind=[Revised],ARef=[AI95-00441-01]}
address@hidden @Chg{Version=[2],New=[My_Input],Old=[My_Read]}(Stream : 
@address@hidden,New=[not null ],Old=[]}access] 
Ada.Streams.Root_Stream_Type'Class)
+  @key[return] T;
address@hidden(for) T'@Chg{Version=[2],New=[Input],Old=[Read]} @key(use) 
@Chg{Version=[2],New=[My_Input],Old=[My_Read]}; address@hidden see 
@RefSecNum{Stream-Oriented Attributes}}
address@hidden
address@hidden
+
address@hidden
address@hidden on the examples:}
+In the Size clause for Short,
+fifteen bits is the minimum necessary,
+since the type definition requires Short'Small <= 2**(@en@;7).
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The syntax rule for @ntf{length_clause} is replaced with the new syntax rule
+for @nt{attribute_definition_clause}, and it is modified to allow a
address@hidden (as well as an expression).
address@hidden
+
address@hidden
+The syntax rule for @nt{attribute_definition_clause} now requires that the
+prefix of the attribute be a @nt{local_name};
+in Ada 83 this rule was stated in the text.
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+In Ada 83, the relationship between a 
@Chg{Version=[2],address@hidden,address@hidden
+specifying a certain aspect and an attribute that queried that
+aspect was unclear.
+In Ada 95, they are the same,
+except for certain explicit exceptions.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0009],ARef=[AI95-00137-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added wording to specify 
for
+  each attribute whether it is an operational or representation attribute.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0040],ARef=[AI95-00108-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added wording to specify 
that
+  External_Tag is never inherited.]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00051-01],ARef=[AI95-00291-01]}
+  @ChgAdded{Version=[2],Text=[Adjusted the Recommended Level of Support for
+  Alignment to eliminate nonsense requirements and to ensure that useful
+  capabilities are required.]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00051-01],ARef=[AI95-00291-01]}
+  @ChgAdded{Version=[2],Text=[Adjusted the Recommended Level of Support for
+  Size to eliminate nonsense requirements and to ensure that useful
+  capabilities are required. Also eliminated any dependence on whether an
+  aspect was specified (a confirming representation item should not affect the
+  semantics).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00133-01]}
+  @ChgAdded{Version=[2],Text=[Added the definition of machine scalar.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00247-01]}
+  @ChgAdded{Version=[2],Text=[Removed the requirement that specified
+  alignments for a composite type cannot override those for their components,
+  because it was never intended to apply to components whose location was
+  specified with a representation item. Moreover, it causes a difference in
+  legality when a confirming alignment is specified for one of the composite
+  types.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00291-02]}
+  @ChgAdded{Version=[2],Text=[Removed recommended level of support rules about
+  types with by-reference and aliased parts, because there are now blanket
+  rules covering all recommended level of support rules.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00291-02]}
+  @ChgAdded{Version=[2],Text=[Split the definition of Alignment for subtypes
+  and for objects. This simplified the wording and eliminated confusion about
+  which rules applied to objects, which applied to subtypes, and which applied
+  to both.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI95-0095-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  @b<Correction:> An address attribute with a prefix of a generic formal
+  subprogram whose actual parameter has convention Intrinsic now raises
+  Program_Error. Since it is unlikely that such an attribute would have done
+  anything useful (a subprogram with convention Intrinsic is not expected to
+  have a normal subprogram body), it is highly unlikely that any existing
+  programs would notice the difference, and any that do probably are buggy.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI95-0113-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> User-specified
+  external tags that conflict with other external tags raise Program_Error
+  (or are optionally illegal). This was legal and did not raise an exception
+  in the past, although the effects were not defined. So while a program
+  might depend on such behavior, the results were not portable (even to
+  different versions of the same implementation). Such programs should be
+  rare.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0095-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden:]
+  An address attribute with a prefix of a subprogram with convention Intrinsic 
is
+  now illegal. Such attributes are very unlikely to have provided a useful
+  answer (the intended meaning
+  of convention Intrinsic is that there is no actual subprogram body for
+  the operation), so this is highly unlikely to affect any existing programs
+  unless they have a hidden bug.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0191-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Attributes Has_Same_Storage and Overlaps_Storage are new.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[Aspect Storage_Size is new;
+  @nt{pragma} Storage_Size is now obsolescent, joining attribute
+  Storage_Size for task types.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0009-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Improved the description
+  of erroneous execution for address clauses to make it clear that
+  specifying an address inappropriate for the entity will lead to
+  erroneous execution.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0116-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added @ImplAdviceTitle for
+  the alignment of class-wide types.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0070-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified the behavior of
+  Has_Same_Storage when 'Size = 0.]}
address@hidden
+
+
+
address@hidden Representation Clauses}
+
address@hidden
address@hidden @nt{enumeration_representation_clause} specifies the internal
+codes for enumeration literals.]
address@hidden
+
address@hidden
address@hidden<enumeration_representation_clause>,rhs="
+    @key{for} @address@hidden @key{use} @Syn2{enumeration_aggregate};"}
address@hidden<enumeration_aggregate>,rhs="@Syn2{array_aggregate}"}
address@hidden
+
address@hidden
address@hidden type],
+  Sec=(enumeration_representation_clause expressions)}
+The @nt<enumeration_aggregate> shall be written as a one-dimensional
address@hidden<array_aggregate>, for which the index subtype is the 
unconstrained
+subtype of the enumeration type, and each component expression
+is expected to be of any integer type.
address@hidden
+The @lquotes@;full coverage address@hidden@; for @nt<aggregate>s applies.
+An @key{others} is not allowed @em there is no applicable index
+constraint in this context.
address@hidden
address@hidden
+
address@hidden
+The @address@hidden of an
address@hidden shall denote an
+enumeration subtype.
address@hidden
+As for all type-related representation items,
+the @nt{local_name} is required to denote a first subtype.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00287-01]}
address@hidden,New=[Each component of the @nt{array_aggregate} shall be
+given by an @nt{expression} rather than a <>. ],Old=[]}The
address@hidden,address@hidden,Old=[expressions]} given in the
address@hidden shall be static,
+and shall specify distinct integer codes for each value
+of the enumeration type; the associated integer codes shall
+satisfy the predefined ordering relation of the type.
address@hidden
+  Each value of the enumeration type has to be given an internal code,
+  even if the first subtype of the enumeration type is constrained
+  to only a subrange (this is only possible if the enumeration type
+  is a derived type). This @lquotes@;full address@hidden@; requirement
+  is important because one may refer to Enum'Base'First and Enum'Base'Last,
+  which need to have defined representations.
address@hidden
address@hidden
+
address@hidden
address@hidden,address@hidden aspect], Sec=(coding)}],
address@hidden of representation], Sec=(coding)}
address@hidden, Sec=(aspect of representation)}]}
+An @nt{enumeration_representation_clause} specifies the
address@hidden aspect of representation.
address@hidden code}
+The coding consists of the @i{internal code} for each enumeration
+literal, that is, the integral value used internally to
+represent each address@hidden,address@hidden,Old=[]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Coding],
+    address@hidden,Text=[Internal representation of enumeration
+      literals. Specified by an @nt{enumeration_representation_clause}, not
+      by an @nt{aspect_specification}.]}]}
+
address@hidden
+
address@hidden
+For nonboolean enumeration types,
+if the coding is not specified for the type, then
+for each value of the type, the internal code shall be equal to
+its position number.
address@hidden
+  This default representation is already used by all known
+  Ada compilers for nonboolean enumeration types. Therefore,
+  we make it a requirement so users can depend on it, rather
+  than feeling obliged to supply for every enumeration type
+  an enumeration representation clause that is equivalent
+  to this default rule.
address@hidden
address@hidden
+  For boolean types, it is relatively common to use all ones for
+  True, and all zeros for False, since some hardware supports
+  that directly. Of course, for a one-bit Boolean object
+  (like in a packed array), False is presumably zero and True
+  is presumably one (choosing the reverse would be extremely
+  unfriendly!).
address@hidden
address@hidden
+
address@hidden
address@hidden@PDefn2{Term=[recommended level of support], 
Sec=(@nt{enumeration_representation_clause})}
+The recommended level of support for @nt{enumeration_representation_clause}s 
is:
address@hidden
+An implementation should support at least the internal codes in the
+range System.Min_Int..System.Max_Int. An implementation need not support
address@hidden@address@hidden for boolean types.
address@hidden
+The implementation may support numbers outside the above
+range, such as numbers greater than System.Max_Int.
+See AI83-00564.
address@hidden
address@hidden
+The benefits of specifying the internal coding of a boolean type do
+not outweigh the implementation costs.
+Consider, for example, the implementation of the logical operators on
+a packed array of booleans with strange internal codes.
+It's implementable, but not worth it.
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The recommended level of support for
address@hidden should be followed.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Unchecked_Conversion may be used to query the internal codes used
+for an enumeration type.
+The attributes of the type, such as Succ, Pred, and Pos,
+are unaffected by the @address@hidden,address@hidden
+For example, Pos always returns the position number, @i{not} the
+internal integer code that might have been specified in
address@hidden @nt{enumeration_representation_clause}],
+Old=[a @address@hidden<Version=[3],New=[],Old=[}]>.
address@hidden
address@hidden@;Suppose the enumeration type in question is derived:
address@hidden
address@hidden T1 @key[is] (Red, Green, Blue);
address@hidden S1 @key[is] T1 @key[range] Red .. Green;
address@hidden S2 @key[is] @key[new] S1;
address@hidden S2 @key[use] (Red => 10, Green => 20, Blue => 30);
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden@;The @address@hidden,address@hidden
+has to specify values for all enumerals, even ones that are not in S2 (such as
+Blue). The Base attribute can be used to get at these values.
+For example:
address@hidden
address@hidden I @key[in] S2'Base @key[loop]
+    ... address@hidden When I equals Blue, the internal code is 30.}
address@hidden @key[loop];
address@hidden
+
+We considered allowing or requiring
address@hidden@;@key[for] S2'Base @key[use] address@hidden@; in cases like this,
+but it didn't seem worth the trouble.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of an enumeration representation clause:}
address@hidden
address@hidden Mix_Code @key[is] (ADD, SUB, MUL, LDA, STA, STZ);
+
address@hidden Mix_Code @key[use]
+   (ADD => 1, SUB => 2, MUL => 3, LDA => 8, STA => 24, STZ =>33);
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+As in other similar contexts, Ada 95 allows expressions of any integer type,
+not just expressions of type @i{universal_integer}, for the component
+expressions in the @nt<enumeration_aggregate>. The preference rules
+for the predefined operators of @i{root_integer} eliminate
+any ambiguity.
+
+For portability, we now require that the default coding for an enumeration
+type be the @lquotes@;address@hidden@; coding using position numbers.
+This is satisfied by all known implementations.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0009],ARef=[AI95-00137-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Updated to reflect that we
+  no longer have something called @ntf{representation_clause}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00287-01]}
+  @ChgAdded{Version=[2],Text=[Added wording to prevent the use of <> in a
+  @nt{enumeration_representation_clause}. (<> is newly added to
+  @nt{array_aggregate}s.)]}
address@hidden
+
+
+
address@hidden Layout}
+
address@hidden
address@hidden,address@hidden
address@hidden aspect], Sec=(layout)}
address@hidden aspect], Sec=(record layout)}
address@hidden layout}
address@hidden aspect], Sec=(storage place)}
address@hidden place], Sec=(representation aspect)}
address@hidden place], Sec=(of a component)}],
address@hidden of representation], Sec=(layout)}
address@hidden, Sec=(aspect of representation)}
address@hidden of representation], Sec=(record layout)}
address@hidden layout], Sec=(aspect of representation)}
address@hidden of representation], Sec=(storage place)}
address@hidden place], Sec=(of a component)}]}
+The @i{(record) layout} aspect of representation
+consists of the @i{storage places} for some or all components,
+that is, storage place attributes of the components.
+The layout can be specified with a @address@hidden@!clause}.
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Representation Clauses}
+
address@hidden
address@hidden @nt{record_representation_clause} specifies the storage 
representation
+of records and record extensions, that is, the order, position, and size
+of components (including discriminants, if any).
address@hidden field],See=(record_representation_clause)}]
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+It should be feasible for an implementation to use negative offsets
+in the representation of composite types.
+However, no implementation should be forced to support negative
+offsets.
address@hidden,New=[, in the interest of uniformity],Old=[]},
+negative offsets should be disallowed in
address@hidden
address@hidden
+
address@hidden
address@hidden<record_representation_clause>,rhs="
+    @key{for} @address@hidden @key{use}
+      @key{record} address@hidden
+        address@hidden
+      @key{end} @key{record};"}
+
+
address@hidden<component_clause>,rhs="
+    @address@hidden @key{at} @Syn2{position} @key{range} @Syn2{first_bit} .. 
@Syn2{last_bit};"}
+
address@hidden<position>,rhs="@address@hidden"}
address@hidden<first_bit>,rhs="@address@hidden"}
address@hidden<last_bit>,rhs="@address@hidden"}
address@hidden
address@hidden and @nt{last_bit} need to be @nt{simple_expression}
+instead of @nt{expression} for the same reason as in @nt{range}
+(see @RefSec{Scalar Types}).
address@hidden
address@hidden
+
address@hidden
address@hidden type],
+  Sec=(component_clause expressions)}
address@hidden type],
+  Sec=(position)}
address@hidden type],
+  Sec=(first_bit)}
address@hidden type],
+  Sec=(last_bit)}
+Each @nt{position}, @nt{first_bit}, and @nt{last_bit} is expected to
+be of any integer type.
address@hidden
+These need not have the same integer type.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00436-01]}
+The @address@hidden of a
address@hidden shall denote a specific
address@hidden,New=[],Old=[nonlimited ]}record or record extension subtype.
address@hidden
+As for all type-related representation items,
+the @nt{local_name} is required to denote a first subtype.
address@hidden
+
+If the @address@hidden<local_name> is a @nt<direct_name>,
+the @nt{local_name} shall denote a component of the type.
+For a record extension, the component shall not be inherited,
+and shall not be a discriminant that corresponds to a discriminant of
+the parent type.
+If the @address@hidden@nt<address@hidden> has an @address@hidden,
+the @address@hidden of the @nt<address@hidden> shall denote either
+the declaration of the type or a component of the type,
+and the @address@hidden shall denote an
+implementation-defined implicit component of the type.
+
+The @nt{position}, @nt{first_bit}, and @nt{last_bit} shall be
+static expressions.
+The value of @nt{position} and @nt{first_bit} shall be nonnegative.
+The value of @nt{last_bit} shall be no less than
address@hidden @en 1.
address@hidden
+A @nt{component_clause} such as
address@hidden@;X @key{at} 4 @key{range} address@hidden@;1;@rquotes@;
+is allowed if X can fit in zero bits.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00133-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[If the
+nondefault bit ordering applies to the type, then either:]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[the value of @nt{last_bit} shall be
+  less than the size of the largest machine scalar; or]}
+
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[the value of @nt{first_bit} shall be zero and the
+  value of @nt{last_bit} + 1 shall be a multiple of System.Storage_Unit.]}
address@hidden
+
+At most one @nt{component_clause} is allowed for each component of
+the type, including for each discriminant
+(@nt{component_clause}s may be given for some, all, or none of the
+components).
+Storage places within a @nt{component_list} shall not overlap,
+unless they are for components in distinct @nt{variant}s of the same
address@hidden
+
+A name that denotes a component of a type is not allowed within
+a @nt{record_representation_clause} for the type,
+except as the @address@hidden<local_name>
+of a @nt{component_clause}.
address@hidden
+    @Leading@;It might seem strange to make the
+    @nt{record_representation_clause} part of the declarative region,
+    and then disallow mentions of the components within almost all of
+    the @nt{record_representation_clause}.
+    The alternative would be to treat the
+    @address@hidden<local_name> like a formal parameter name in
+    a subprogram call (in terms of visibility).
+    However, this rule would imply slightly different semantics,
+    because (given the actual rule)
+    the components can hide other declarations.
+    This was the rule in Ada 83, and we see no reason to change it.
+    The following, for example, was and is illegal:
+    @begin{Example}
address@hidden T @key[is]
+    @key[record]
+        X : Integer;
+    @key[end] @key[record];
+X : @key[constant] := 31; address@hidden Same defining name as the component.}
address@hidden T @key[use]
+    @key[record]
+        X @key[at] 0 @key[range] 0..X; address@hidden Illegal!}
+    @key[end] @key[record];
+    @end{Example}
+
+    The component X hides the named number X throughout
+    the @nt{record_representation_clause}.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00133-01]}
+A @nt{record_representation_clause}
+(without the @nt{mod_clause})
+specifies the address@hidden,New=[],Old=[
+The storage place
+attributes (see @RefSecNum{Storage Place Attributes})
+are taken from the
+values of the @nt{position}, @nt{first_bit},
+and @nt{last_bit} expressions
+after normalizing those values so that
address@hidden is less than
address@hidden,address@hidden (record)}],Old=[]}]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Layout (record)],
+    address@hidden,Text=[Layout of record components. Specified by
+      a @nt{record_representation_clause}, not by an 
@nt{aspect_specification}.]}]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Record layout],
+    address@hidden,Text=[See Layout.]}]}
+
address@hidden,Kind=[Added],ARef=[AI95-00133-01]}
address@hidden,Text=[If the default bit ordering applies to the type,
+the @nt{position}, @nt{first_bit}, and @nt{last_bit} of each
address@hidden directly specify
+the position and size of the corresponding component.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00133-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0264-1]}
address@hidden,Type=[Leading],Text=[If the nondefault bit ordering
+applies to the address@hidden,New=[,],Old=[]} then
+the layout is determined as follows:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[the @nt{component_clause}s for which the value of
address@hidden is greater than or equal to the size of the largest machine 
scalar
+directly specify the position and size of the corresponding component;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[for other @nt{component_clause}s, all of the
+components having the same value of @nt{position} are considered to be part of
+a single machine scalar, located at that @nt{position}; this machine scalar
+has a size which is the smallest machine scalar size larger than the largest
address@hidden for all @nt{component_clause}s at that @nt{position}; the
address@hidden and @nt{last_bit} of each @nt{component_clause} are then
+interpreted as bit offsets in this machine scalar.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00133-01]}
address@hidden want the header title to remain, so we use @Chg instead if 
@ChgDeleted.}
address@hidden,New=[],Old=[For example,
+if Storage_Unit is 8, then
address@hidden@;C @key[at] 0 @key[range] 24..31;@rquotes@;
+defines C'Position = 3, C'First_Bit = 0, and C'Last_Bit = 7.
+This is true of machines with either bit ordering.]}
+
+A @nt{component_clause} also determines the value of the Size
+attribute of the component,
+since this attribute is related to First_Bit and Last_Bit.
address@hidden
+
address@hidden @nt{record_representation_clause} for a record extension
+does not override the layout of the parent part;]
+if the layout was specified for the parent type,
+it is inherited by the record extension.
address@hidden
+
address@hidden
+An implementation may generate implementation-defined components (for
+example, one containing the offset of another component).
+An implementation may generate names that denote
+such implementation-defined components;
+such names shall be implementation-defined @nt{attribute_reference}s.
+An address@hidden may allow such implementation-defined names to be
+used in @address@hidden@!clause}s.
+An implementation can restrict such @address@hidden in any
+manner it sees fit.
address@hidden components.}
address@hidden
+Of course, since the semantics of implementation-defined
+attributes is implementation defined, the implementation need not
+support these names in all situations.
+They might be purely for the purpose of @nt{component_clause}s,
+for example.
+The visibility rules for such names are up to the implementation.
+
+We do not allow such component names to be normal identifiers
address@hidden that would constitute blanket permission to do all kinds of evil
+things.
address@hidden
address@hidden
address@hidden
+Such implementation-defined components are known in the
+vernacular as @lquotes@;address@hidden@;
+Their main purpose is for storing offsets of components that depend
+on discriminants.
address@hidden
+
+If a @nt<record_representation_clause> is given for an untagged derived type,
+the storage place attributes for all of the components of the derived
+type may differ
+from those of the corresponding components of the parent type,
+even for components whose storage
+place is not specified explicitly in the @nt<address@hidden@!clause>.
address@hidden
+  This is clearly necessary, since the whole record may need to be
+  laid out differently.
address@hidden
address@hidden
+
address@hidden
address@hidden@PDefn2{Term=[recommended level of support], 
Sec=(@nt{record_representation_clause})}
+The recommended level of support for @nt{record_representation_clause}s is:
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00133-01]}
address@hidden,Text=[An implementation should support machine scalars
+that correspond to all of the integer, floating point, and address formats
+supported by the machine.]}
+
+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.
+
+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.
+
address@hidden,Kind=[Revised],ARef=[AI95-00133-01]}
address@hidden,New=[For],Old=[If the default bit ordering applies to
+the declaration of a given type, then for]} a component
address@hidden,New=[with a subtype ],Old=[]}whose
address@hidden,New=[],Old=[subtype's ]}Size is less than the word size, any
+storage place that does not cross an aligned word boundary should be supported.
+
address@hidden
+The above recommendations are sufficient to
+define interfaces to most interesting hardware.
+This causes less implementation burden than the definition in ACID,
+which requires arbitrary bit alignments of arbitrarily large
+components.
+Since the ACID definition is neither enforced by the ACVC,
+nor supported by all implementations,
+it seems OK for us to weaken it.
address@hidden
+
+An implementation may reserve a storage place for the tag
+field of a tagged type, and disallow other components from overlapping
+that place.
address@hidden
+Similar permission for other dope is not granted.
address@hidden
+
+An implementation need not support a
address@hidden 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.
address@hidden
+These restrictions are probably necessary if block equality
+operations are to be feasible for class-wide types.
+For block comparison to work, the implementation typically has to fill
+in any gaps with zero (or one) bits.
+If a @lquotes@;address@hidden@; in the parent type is filled in with a 
component in a
+type extension, then this won't work when a class-wide object is
+passed by reference, as is required.
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The recommended level of support for @nt{record_representation_clause}s
+should be followed.]}]}
address@hidden
+
address@hidden
+If no @nt{component_clause} is given for a component, then the
+choice of the storage place for the component is left to the
+implementation. If @nt{component_clause}s are given for all components,
+the @nt{record_representation_clause} completely specifies the
+representation of the type and will be obeyed exactly by the
+implementation.
address@hidden
+The
+visibility rules prevent the name of a component of the type from
+appearing in a @nt{record_representation_clause} at any place
address@hidden for the @address@hidden<local_name> of a
address@hidden
+However, since the @nt{record_representation_clause} is part of the
+declarative region of the type declaration,
+the component names hide outer homographs throughout.
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+A @nt{record_representation_clause} cannot be given for a protected type,
+even though protected types, like record types, have components.
+The primary reason for this rule is that there is likely to be too
+much dope in a protected type @em entry queues,
+bit maps for barrier values, etc.
+In order to control the representation of the user-defined components, simply
+declare a record type, give it a
address@hidden@address@hidden@!clause}],address@hidden,
+and give the protected type one component whose type is the record type.
+Alternatively, if the protected object is protecting something like a
+device register, it makes more sense to keep the thing being
+protected outside the protected object (possibly with a pointer to it
+in the protected object), in order to keep implementation-defined
+components out of the way.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of specifying the layout of a record type:}
address@hidden
+Word : @key[constant] := 4;  address@hidden  storage element is byte, 4 bytes 
per word}
+
address@hidden State         @key[is] (A,M,W,P);
address@hidden Mode          @key[is] (Fix, Dec, Exp, Signif);
+
address@hidden Byte_Mask     @key[is] @key[array] (0..7)  @key[of] Boolean;
address@hidden State_Mask    @key[is] @key[array] (State) @key[of] Boolean;
address@hidden Mode_Mask     @key[is] @key[array] (Mode)  @key[of] Boolean;
+
address@hidden Program_Status_Word @key[is]
+  @key[record]
+      System_Mask        : Byte_Mask;
+      Protection_Key     : Integer @key[range] 0 .. 3;
+      Machine_State      : State_Mask;
+      Interrupt_Cause    : Interruption_Code;
+      Ilc                : Integer @key[range] 0 .. 3;
+      Cc                 : Integer @key[range] 0 .. 3;
+      Program_Mask       : Mode_Mask;
+      Inst_Address       : Address;
address@hidden @key[record];
+
address@hidden Program_Status_Word @key[use]
+  @key[record]
+      System_Mask      @key[at] 0*Word @key[range] 0  .. 7;
+      Protection_Key   @key[at] 0*Word @key[range] 10 .. 11; address@hidden 
bits 8,9 unused}
+      Machine_State    @key[at] 0*Word @key[range] 12 .. 15;
+      Interrupt_Cause  @key[at] 0*Word @key[range] 16 .. 31;
+      Ilc              @key[at] 1*Word @key[range] 0  .. 1;  address@hidden 
second word}
+      Cc               @key[at] 1*Word @key[range] 2  .. 3;
+      Program_Mask     @key[at] 1*Word @key[range] 4  .. 7;
+      Inst_Address     @key[at] 1*Word @key[range] 8  .. 31;
+  @key[end] @key[record];
+
address@hidden Program_Status_Word'Size @key[use] 8*System.Storage_Unit;
address@hidden Program_Status_Word'Alignment @key[use] 8;
address@hidden
address@hidden
+
address@hidden
address@hidden on the example:}
+The @nt{record_representation_clause} defines the record layout. The
+Size clause guarantees that (at least) eight storage elements are used
+for objects of the type. The Alignment clause guarantees that
+aliased, imported, or exported objects of the type will have
+addresses divisible by eight.
address@hidden
+
+
address@hidden
+The @ntf{alignment_clause} has been renamed to @nt{mod_clause} and moved
+to @RefSec{Obsolescent Features}.
+
+We have clarified that implementation-defined component names have to be
+in the form of an @nt{attribute_reference} of a component or of the
+first subtype itself;
+surely Ada 83 did not intend to allow arbitrary identifiers.
+
+The RM83-13.4(7) wording incorrectly allows components in
+nonvariant records to overlap.
+We have corrected that oversight.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00133-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] The meaning of a @nt{record_representation_clause}
+  for the nondefault
+  bit order is now clearly defined. Thus, such clauses can be portably
+  written. In order to do that though, the equivalence of bit 1 in word 1 to
+  bit 9 in word 0 (for a machine with Storage_Unit = 8) had to be dropped for
+  the nondefault bit order. Any @nt{record_representation_clause}s which
+  depends on that equivalence will break (although such code would imply a
+  noncontiguous representation for a component, and it seems unlikely that
+  compilers were supporting that anyway).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00436-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b[Amendment Correction:] The undocumented (and
+  likely unintentional) incompatibility with Ada 83 caused by not allowing
+  @nt{record_representation_clause}s on limited record types is removed.]}
address@hidden
+
address@hidden Place Attributes}
+
address@hidden
address@hidden@Defn2{Term=[storage place attributes], Sec=(of a component)}
+For @PrefixType{a component C of a composite, non-array
+object R},
+the @i{storage place attributes} are defined:
address@hidden
+The storage place attributes are not (individually) specifiable,
+but the user may control their values by giving a
address@hidden
address@hidden
address@hidden
address@hidden,Kind=[Revised],ChginAnnex=[T],
+  Leading=<F>, Prefix=<R.C>, AttrName=<Position>,
+  ARef=[AI95-00133-01], InitialVersion=[0],
+  Text=<@Chg{Version=[2],New=[If the nondefault bit ordering applies to the
+  composite type, and if a @nt{component_clause} specifies the placement of C,
+  denotes the value given for the @nt{position} of the @nt{component_clause};
+  otherwise, denotes],Old=[Denotes]} the same value as R.C'Address @en@;
+  R'Address. The value of this attribute is of the type
+  @i{universal_integer}.>}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00133-01]}
+Thus, @Chg{Version=[2],New=[for the default bit order, ],Old=[]}R.C'Position
+is the offset of C in storage
+elements from the beginning of the object,
+where the first storage element of an object is numbered zero.
+R'Address + R.C'Position = R.C'Address.
+For record extensions, the offset is not measured from
+the beginning of the extension part, but from the
+beginning of the whole object, as usual.
+
+In @lquotes@;R.C'Address @en@; R'address@hidden@;,
+the "@en@;" operator is the one in System.Storage_Elements
+that takes two Addresses and returns a Storage_Offset.
address@hidden
+
address@hidden,Kind=[Revised],ChginAnnex=[T],
+  Leading=<F>, Prefix=<R.C>, AttrName=<First_Bit>,
+  ARef=[AI95-00133-01], InitialVersion=[0],
+  Text=<@Chg{Version=[2],New=[If the nondefault bit ordering applies to the
+  composite type, and if a @nt{component_clause} specifies the placement of C,
+  denotes the value given for the @nt{first_bit} of the @nt{component_clause};
+  otherwise, denotes],Old=[Denotes]} the offset, from the start of the first
+  of the storage elements occupied by C, of the first bit occupied by C.
+  This offset is measured in bits.
+  The first bit of a storage element is numbered zero.
+  The value of this attribute is of the type
+  @i{universal_integer}.>}
+
address@hidden,Kind=[Revised],ChginAnnex=[T],
+  Leading=<F>, Prefix=<R.C>, AttrName=<Last_Bit>,
+  ARef=[AI95-00133-01], InitialVersion=[0],
+  Text=<@Chg{Version=[2],New=[If the nondefault bit ordering applies to the
+  composite type, and if a @nt{component_clause} specifies the placement of C,
+  denotes the value given for the @nt{last_bit} of the @nt{component_clause};
+  otherwise, denotes],Old=[Denotes]} the offset, from the start of the first
+  of the storage elements occupied by C, of the last bit occupied by C.
+  This offset is measured in bits. The value of this attribute
+  is of the type @i{universal_integer}.>}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+The ordering of bits in a storage element is
address@hidden,New=[],Old=[is ]}defined in @RefSec{Bit Ordering}.
+
+R.C'Size = R.C'Last_Bit @en@; R.C'First_Bit + 1.
+(Unless the implementation chooses an indirection
+representation.)
+
+If a @nt{component_clause} applies to a component,
+then that component will be at the same relative storage place
+in all objects of the type.
+Otherwise, there is no such requirement.
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden representation}
address@hidden representation}
+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 discontiguously from the rest of the object,
+then a warning should be generated upon reference to one
+of its storage place attributes.
address@hidden
+For discontiguous components, these attributes make no sense.
+For example, an implementation might allocate dynamic-sized components
+on the heap.
+For another example, an implementation might allocate the discriminants
+separately from the other components, so that multiple objects of the
+same subtype can share discriminants.
+Such representations cannot happen if there is a @nt{component_clause}
+for that component.
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If a component is represented using a pointer to the actual data of
+the component which is contiguous with
+the rest of the object, then the storage place attributes should reflect
+the place of the actual data.
+If a component is allocated discontiguously from the rest of the object,
+then a warning should be generated upon reference to one
+of its storage place attributes.]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00133-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] The meaning of the storage place attributes for
+  the nondefault
+  bit order is now clearly defined, and can be different than that given by
+  strictly following the Ada 95 wording. Any code which depends on the
+  original Ada 95 values for a type using the nondefault bit order where
+  they are different will break.]}
address@hidden
+
+
+
address@hidden Ordering}
+
address@hidden
address@hidden Bit_Order attribute specifies the interpretation of the storage
+place attributes.]
address@hidden
+The intention is to provide uniformity in the
+interpretation of storage places across implementations on a
+particular machine by allowing the user to specify the Bit_Order.
+It is not intended to fully support data interoperability across
+different machines,
+although it can be used for that purpose in some situations.
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+We can't require all implementations on a given machine to use the same
+bit ordering by default;
+if the user cares, a @Chg{Version=[2],New=[],address@hidden ]}Bit_Order
address@hidden,address@hidden ],Old=[]}can be used
+to force all implementations to use the same bit ordering.
address@hidden
address@hidden
+
address@hidden
address@hidden ordering}
+A bit ordering is a method of interpreting the meaning of the
+storage place attributes.
address@hidden
address@hidden endian}
address@hidden, Sec=(big)}
+High_Order_First @Redundant[(known in the vernacular as @lquotes@;big 
address@hidden@;)]
+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).
address@hidden
address@hidden endian}
address@hidden, Sec=(little)}
+Low_Order_First @Redundant[(known in the vernacular as @lquotes@;little 
address@hidden@;)]
+means the opposite: the first bit is the least significant.
+
address@hidden@;For @PrefixType{every specific record subtype S},
+the following attribute is defined:
address@hidden
address@hidden<S>, AttrName=<Bit_Order>,
+  Text=<Denotes the bit ordering for the type of S.
+The value of this attribute is of type System.Bit_Order.>}
address@hidden
address@hidden, Sec=(of Bit_Order for record types and
+record extensions)}
address@hidden clause}
+Bit_Order may be specified for specific record types
+via an @nt{attribute_definition_clause};
+the expression of such a clause shall be
address@hidden,address@hidden,Old=[]}
+
address@hidden,Kind=[AddedNormal],Aspect=[Bit_Order],
+  address@hidden,Text=[Order of bit numbering in a
+    @nt{record_representation_clause}.]}]}
+
address@hidden
+
+If Word_Size = Storage_Unit,
+the default bit ordering is implementation defined.
+If Word_Size > Storage_Unit,
+the default bit ordering is the same as the ordering of storage
+elements in a word, when interpreted as an
+integer.
address@hidden sex],See=(ordering of storage elements in a word)}
address@hidden Word_Size = Storage_Unit,
+the default bit ordering.}
address@hidden
+Consider machines whose Word_Size = 32,
+and whose Storage_Unit = 8.
+Assume the default bit ordering applies.
+On a machine with big-endian addresses,
+the most significant storage element of an integer is at the address of
+the integer.
+Therefore, bit zero of a storage element is the most significant bit.
+On a machine with little-endian addresses,
+the least significant storage element of an integer is at the address of
+the integer.
+Therefore, bit zero of a storage element is the least significant
+bit.
address@hidden
+
+The storage place attributes of a
+component of a type are
+interpreted according to the bit ordering
+of the type.
address@hidden
+This implies that the interpretation of the @nt{position},
address@hidden, and @nt{last_bit} of a @nt{component_clause} of a
address@hidden obey the bit ordering given in a
+representation item.
address@hidden
address@hidden
+
address@hidden
address@hidden@PDefn2{Term=[recommended level of support], Sec=(bit ordering)}
+The recommended level of support for the nondefault bit ordering is:
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00133-01]}
+  @Chg{Version=[2],New=[The],Old=[If Word_Size = Storage_Unit, then
+  the]} implementation should support the nondefault bit ordering
+  in addition to the default bit ordering.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00133-01]}
address@hidden,New=[The],Old=[If Word_Size = Storage_Unit,
+the]} implementation should support both bit orderings.
address@hidden,New=[Implementations],Old=[We don't push for support of
+the nondefault bit ordering when Word_Size > Storage_Unit (except
+of course for upward compatibility with a preexisting implementation
+whose Ada 83 bit order did not correspond to the required Ada 95
+default bit order), because
+implementations]} are required to support storage positions that cross
+storage element boundaries when Word_Size > address@hidden,
+New=[ but the definition of the storage place attributes for the nondefault
+bit order ensures that such],Old=[. Such]} storage positions will 
@Chg{Version=[2],
+New=[not ],Old=[]}be split into two or three address@hidden,New=[. Thus,
+there is no significant implementation burden to supporting the nondefault
+bit order, given that the set of machine scalars is implementation-defined],
+Old=[ if the nondefault bit ordering is used, which could be onerous to
+support. However, if Word_Size = Storage_Unit,
+there might not be a natural bit ordering,
+but the splitting problem need not occur]}.
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The recommended level of support for the nondefault bit ordering
+should be followed.]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00133-01]}
+  @ChgAdded{Version=[2],Text=[Bit_Order clauses make it possible to write
+  @nt{record_representation_clause}s that can be ported between machines having
+  different bit ordering. They do not guarantee transparent exchange of data
+  between such machines.]}
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The Bit_Order attribute is new to Ada 95.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00133-01]}
+  @ChgAdded{Version=[2],Text=[We now suggest that all implementations
+  support the nondefault bit order.]}
address@hidden
+
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden of Representation}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden@Defn{change of representation}
address@hidden, Sec=(change of)}
+A @nt{type_conversion} (see @RefSecNum{Type Conversions})
+can be used to convert between two different
+representations of the same array or record.
+To convert an array from one representation to another,
+two array types need to be declared with
+matching component subtypes, and convertible index types.
+If one type has @Chg{Version=[3],New=[Pack],Old=[packing]}
+specified and the other does not,
+then explicit conversion can be used to pack or unpack an array.
+
+To convert a record from one representation to another,
+two record types with a common ancestor type need to be declared,
+with no inherited subprograms. Distinct representations can then
+be specified for the record types, and explicit conversion between
+the types can be used to effect a change in representation.]
address@hidden
+This technique does not work if the first type is an
+untagged type with user-defined primitive subprograms.
+It does not work at all for tagged types.
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of change of representation:}
address@hidden
address@hidden Packed_Descriptor and Descriptor are two different types}
address@hidden with identical characteristics, apart from their}
address@hidden representation}
+
address@hidden Descriptor @key[is]
+    @key[record]
+      address@hidden components of a descriptor}
+    @key[end] @key[record];
+
address@hidden Packed_Descriptor @key[is] @key[new] Descriptor;
+
address@hidden Packed_Descriptor @key[use]
+    @key[record]
+      address@hidden component clauses for some or for all components}
+    @key[end] @key[record];
+
address@hidden Change of representation can now be accomplished by explicit 
type conversions:}
+
+D : Descriptor;
+P : Packed_Descriptor;
+
+P := Packed_Descriptor(D);  address@hidden pack D}
+D := Descriptor(P);         address@hidden unpack P}
address@hidden
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/13b.mss 
b/packages/ada-ref-man/source_2012/13b.mss
new file mode 100755
index 0000000..2e52e41
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/13b.mss
@@ -0,0 +1,7071 @@
address@hidden(13, Root="ada.mss")
+
address@hidden: 2015/04/03 04:12:42 $}
+
address@hidden: e:\\cvsroot/ARM/Source/13b.mss,v $}
address@hidden: 1.112 $}
+
address@hidden
address@hidden Package System}
+
address@hidden
address@hidden each implementation there is a library package called System
+which includes the definitions of certain configuration-dependent
+characteristics.]
address@hidden
+
address@hidden
address@hidden@;The following language-defined library package exists:
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[The contents of the visible part
+of package address@hidden,New=[],Old=[and its language-defined children]}.]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00362-01]}
address@hidden@key[package] System @key[is]
+   @key{pragma} @Chg{Version=[2],New=[Pure],Old=[Preelaborate]}(System);
+
+   @key[type] @AdaTypeDefn{Name} @key[is] 
@RI{implementation-defined-enumeration-type};
+   @AdaObjDefn{System_Name} : @key[constant] Name := 
@RI{implementation-defined};
+
+
+   address@hidden System-Dependent Named Numbers:}
+
+   @AdaObjDefn{Min_Int}               : @key[constant] := 
@RI{root_integer}'First;
+   @AdaObjDefn{Max_Int}               : @key[constant] := 
@RI{root_integer}'Last;
+
+   @AdaObjDefn{Max_Binary_Modulus}    : @key[constant] := 
@RI{implementation-defined};
+   @AdaObjDefn{Max_Nonbinary_Modulus} : @key[constant] := 
@RI{implementation-defined};
+
+   @AdaObjDefn{Max_Base_Digits}       : @key[constant] := 
@RI{root_real}'Digits;
+   @AdaObjDefn{Max_Digits}            : @key[constant] := 
@RI{implementation-defined};
+
+   @AdaObjDefn{Max_Mantissa}          : @key[constant] := 
@RI{implementation-defined};
+   @AdaObjDefn{Fine_Delta}            : @key[constant] := 
@RI{implementation-defined};
+
+   @AdaObjDefn{Tick}                  : @key[constant] := 
@RI{implementation-defined};
+
+
+   address@hidden Storage-related Declarations:}
+
+   @key[type] @AdaTypeDefn{Address} @key[is] @RI{implementation-defined};
+   @AdaObjDefn{Null_Address} : @key[constant] Address;
+
+   @AdaObjDefn{Storage_Unit} : @key[constant] := @RI{implementation-defined};
+   @AdaObjDefn{Word_Size}    : @key[constant] := @RI{implementation-defined} * 
Storage_Unit;
+   @AdaObjDefn{Memory_Size}  : @key[constant] := @RI{implementation-defined};
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   address@hidden @Defn2{Term=[address], Sec=(comparison)}Address Comparison:}
+   @key(function) "<" (Left, Right : Address) @key(return) address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+   @key(function) "<="(Left, Right : Address) @key(return) address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+   @key(function) ">" (Left, Right : Address) @key(return) address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+   @key(function) ">="(Left, Right : Address) @key(return) address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+   @key(function) "=" (Left, Right : Address) @key(return) address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+-- @key(function) "/=" (Left, Right : Address) @key(return) Boolean;
+   address@hidden "/=" is implicitly address@hidden,New=[],Old=[
+   @key[pragma] Convention(Intrinsic, "<");
+   ... address@hidden and so on for all language-defined subprograms in this 
package}]}
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00221-01]}
+   address@hidden Other System-Dependent Declarations:}
+   @key[type] @AdaTypeDefn{Bit_Order} @key[is] (@AdaObjDefn{High_Order_First}, 
@AdaObjDefn{Low_Order_First});
+   @AdaObjDefn{Default_Bit_Order} : @key[constant] address@hidden,New=[ := 
@RI{implementation-defined}],Old=[]};
+
+
+   address@hidden Priority-related declarations (see @RefSecNum{Task 
Priorities}):}
+   @key{subtype} @AdaSubtypeDefn{Name=[Any_Priority],Of=[Integer]} @key{is} 
Integer @key{range} @RI{implementation-defined};
+   @key{subtype} @AdaSubtypeDefn{Name=[Priority],Of=[Any_Priority]} @key{is} 
Any_Priority @key{range} Any_Priority'First ..
+             @RI{implementation-defined};
+   @key{subtype} @AdaSubtypeDefn{Name=[Interrupt_Priority],Of=[Any_Priority]} 
@key{is} Any_Priority @key{range} Priority'Last+1 ..
+             Any_Priority'Last;
+
+   @AdaObjDefn{Default_Priority} : @key{constant} Priority :=
+             (Priority'First + Priority'Last)/2;
+
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden System;
address@hidden
+
+
+Name is an enumeration subtype.
+Values of type Name are the names of alternative machine
address@hidden handled by the implementation.
+System_Name represents the current machine configuration.
+
+The named numbers Fine_Delta and Tick are of the type
address@hidden; the others are of the type @i{universal_integer}.
+
address@hidden@;The meanings of the named numbers are:
address@hidden
address@hidden
+Min_Int @\The smallest (most negative) value
+allowed for the expressions of a
address@hidden@address@hidden@!definition}.
+
+Max_Int @\The largest (most positive) value
+allowed for the expressions of a
address@hidden@address@hidden@!definition}.
+
+Max_Binary_Modulus @\A power of two such that it,
+and all lesser positive powers of two, are allowed
+as the modulus of a @nt<modular_type_definition>.
+
+Max_Nonbinary_Modulus @\A value such that it,
+and all lesser positive integers, are allowed
+as the modulus of a @nt<modular_type_definition>.
address@hidden
+There is no requirement that Max_Nonbinary_Modulus
+be less than or equal to Max_Binary_Modulus,
+although that's what makes most sense.
+On a typical 32-bit machine, for example,
+Max_Binary_Modulus will be 2**32
+and Max_Nonbinary_Modulus will be 2**31,
+because supporting nonbinary moduli in above 2**31
+causes implementation difficulties.
address@hidden
+
+Max_Base_Digits @\The largest value allowed for the requested decimal
+precision in a @address@hidden@!definition}.
+
+Max_Digits @\The largest value allowed for the requested decimal
+precision in a @address@hidden@!definition}
+that has no @address@hidden@!specification}.
+Max_Digits is less than or equal to Max_Base_Digits.
+
+Max_Mantissa @\The largest possible number of binary digits in the mantissa
+of machine numbers of a user-defined ordinary fixed point type.
+(The mantissa is defined in @RefSecNum{Numerics}.)
+
+Fine_Delta @\The smallest delta allowed in an 
@nt{ordinary_fixed_point_definition} that
+has the @address@hidden@!specification} @key{range} @en@;1.0 .. 1.0.
+]
+
+Tick @\A period in seconds approximating the real time interval during
+which the value of Calendar.Clock remains constant.
address@hidden
+There is no required relationship between System.Tick and
+Duration'Small,
+other than the one described here.
+
+The inaccuracy of the @nt{delay_statement} has no relation to Tick.
+In particular, it is possible that the clock used for the
address@hidden is less accurate than Calendar.Clock.
+
+We considered making Tick a run-time-determined quantity,
+to allow for easier configurability.
+However, this would not be upward compatible,
+and the desired configurability can be achieved using
+functionality defined in @RefSec{Real-Time Systems}.
address@hidden
+
+Storage_Unit @\The number of bits per storage element.
+
+Word_Size @\The number of bits per word.
+
+Memory_Size @\An implementation-defined value
address@hidden is intended to reflect the memory size of the
+configuration in storage elements.]
address@hidden
+It is unspecified whether this refers to the size of the
+address space, the amount of physical memory on the machine,
+or perhaps some other interpretation of @lquotes@;memory address@hidden@;
+In any case, the value has to be given by a static expression,
+even though the amount of memory on many modern machines is
+a dynamic quantity in several ways.
+Thus, Memory_Size is not very useful.
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00161-01]}
+Address is @Chg{Version=[2],New=[],Old=[of ]}a definite, nonlimited
address@hidden,New=[ with preelaborable initialization (see
address@hidden Control})],Old=[]}.
+Address represents machine addresses capable of addressing individual
+storage elements.
+Null_Address is an address that is distinct from the
+address of any object or program unit.
address@hidden,See=(type System.Address)}
address@hidden
+The implementation has to ensure that there is at least one
+address that nothing will be allocated to;
+Null_Address will be one such address.
address@hidden
address@hidden
+Address is the type of the result of the attribute Address.
address@hidden
address@hidden
+Address is required to be nonlimited and definite because
+it is important to be able to assign addresses,
+and to declare uninitialized address variables.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00161-01]}
+  @ChgAdded{Version=[2],Text=[If System.Address is defined as a private type
+  (as suggested below), it might be necessary to add a pragma
+  Preelaborable_Initialization to the specification of System in order that
+  Address have preelaborable initialization as required.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00221-01]}
address@hidden,New=[ Default_Bit_Order shall
+be a static constant. ],Old=[]}See @RefSecNum{Bit Ordering} for an
+explanation of Bit_Order and Default_Bit_Order.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00362-01]}
+An implementation may add additional implementation-defined
+declarations to package System and its children.
address@hidden, it is usually better
+for the implementation to provide
+additional functionality via implementation-defined
+children of address@hidden,New=[],Old=[
+Package System may be declared pure.]}
address@hidden
+The declarations in package System and its children can be implicit.
+For example, since Address is not limited,
+the predefined "=" and "/=" operations are probably sufficient.
+However, the implementation is not @i{required} to use the predefined
+"=".
address@hidden
address@hidden
+
address@hidden
address@hidden,address@hidden bogus "of"}
+Address should be @Chg{New=[],Old=[of ]}a private type.
address@hidden
+This promotes uniformity by avoiding having
+implementation-defined predefined operations for the type.
+We don't require it, because implementations may want to stick with
+what they have.
address@hidden
address@hidden,Kind=[Added],address@hidden,
+Text=[Type System.Address should be a private type.]}]}
address@hidden
+It is not necessary for Address to be able to point at
+individual bits within a storage element.
+Nor is it necessary for it to be able to point at machine registers.
+It is intended as a memory address that matches the hardware's notion
+of an address.
+
+The representation of the @key{null} value of a general access type should
+be the same as that of Null_Address;
+instantiations of Unchecked_Conversion should work accordingly.
+If the implementation supports interfaces to other languages,
+the representation of the @key{null} value of a general access type
+should be the same as in those other languages, if appropriate.
+
+Note that the children of the Interfaces package will generally provide
+foreign-language-specific null values where appropriate.
+See UI-0065 regarding Null_Address.
address@hidden
address@hidden
+
address@hidden
+There are also some language-defined child packages of System
+defined elsewhere.
address@hidden
+
address@hidden
address@hidden,address@hidden AI-00114}
address@hidden,address@hidden to Ada 83}
+The declarations Max_Binary_Modulus, Max_Nonbinary_Modulus, Max_Base_Digits,
+Null_Address, Word_Size, Bit_Order, Default_Bit_Order, Any_Priority,
+Interrupt_Priority, and Default_Priority are added to System in Ada 95.
+The presence of ordering operators for type Address is also guaranteed (the
+existence of these depends on the definition of Address in an Ada 83
+implementation). We do not list these as incompatibilities, as the contents of
+System can vary between implementations anyway; thus a program that depends on
+the contents of System (by using @address@hidden System;} for example) is
+already at risk of being incompatible when moved between Ada implementations.]}
address@hidden
+
address@hidden
+Much of the content of System is standardized,
+to provide more uniformity across implementations.
+Implementations can still add their own declarations to System,
+but are encouraged to do so via children of System.
+
+Some of the named numbers are defined more explicitly in terms of the
+standard numeric types.
+
+The pragmas System_Name, Storage_Unit, and Memory_Size are no
+longer defined by the language.
+However, the corresponding declarations in package
+System still exist.
+Existing implementations may continue to support the three
+pragmas as implementation-defined pragmas,
+if they so desire.
+
+Priority semantics, including subtype Priority,
+have been moved to the Real Time Annex.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00161-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b[Amendment Correction:] Type Address is defined to have preelaborable
+  initialization, so that it
+  can be used without restriction in preelaborated units. (If Address is
+  defined to be a private type, as suggested by the @ImplAdviceTitle,
+  in Ada 95 it cannot be used in some contexts in a preelaborated units.
+  This is an unnecessary portability issue.)]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00221-01]}
+  @ChgAdded{Version=[2],address@hidden Correction:] Default_Bit_Order
+  is now a static constant.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00362-01]}
+  @ChgAdded{Version=[2],Text=[Package System is now Pure, so it can be
+  portably used in more places. (Ada 95 allowed it to be Pure, but did not
+  require that.)]}
address@hidden
+
+
address@hidden Package System.Storage_Elements}
+
address@hidden
address@hidden@;The following language-defined library package exists:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00362-01]}
address@hidden,address@hidden System.Storage_Elements @key[is]
+   @key{pragma} 
@Chg{Version=[2],New=[Pure(],Old=[Preelaborate(System.]}Storage_Elements);
+
+   @key[type] @AdaTypeDefn{Storage_Offset} @key[is] @key[range] 
@RI(implementation-defined);
+
+   @key[subtype] @AdaSubtypeDefn{Name=[Storage_Count],Of=[Storage_Offset]} 
@key[is] Storage_Offset @key[range] 0..Storage_Offset'Last;
+
+
+   @key[type] @AdaTypeDefn{Storage_Element} @key[is] @key[mod] 
@RI{implementation-defined};
+   @key[for] Storage_Element'Size @key[use] Storage_Unit;
+   @key[type] @AdaTypeDefn{Storage_Array} @key[is] @key[array]
+     (Storage_Offset @key[range] <>) @key[of] @key[aliased] Storage_Element;
+   @key[for] Storage_Array'Component_Size @key[use] Storage_Unit;
+
+
+   address@hidden @Defn2{Term=[address], Sec=(arithmetic)}Address Arithmetic:}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key(function) "+"(Left : Address; Right : 
Storage_Offset)@Chg{Version=[3],New=[],Old=[
+     ]} @key(return) address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+   @key(function) "+"(Left : Storage_Offset; Right : 
Address)@Chg{Version=[3],New=[],Old=[
+     ]} @key(return) address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+   @key(function) "-"(Left : Address; Right : 
Storage_Offset)@Chg{Version=[3],New=[],Old=[
+     ]} @key(return) address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+   @key(function) "-"(Left, Right : Address)@Chg{Version=[3],New=[],Old=[
+     ]} @key(return) address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key(function) "@key(mod)"(Left : Address; Right : Storage_Offset)
+      @key(return) address@hidden,New=[
+         @key(with) Convention => Intrinsic],Old=[]};
+
+
+   address@hidden Conversion to/from integers:}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key[type] @AdaTypeDefn{Integer_Address} @key[is] 
@RI{implementation-defined};
+   @key[function] @AdaSubDefn{To_Address}(Value : Integer_Address) 
@key[return] address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+   @key[function] @AdaSubDefn{To_Integer}(Value : Address) @key[return] 
address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[],Old=[   @key[pragma] Convention(Intrinsic, "+");
+      @RI(-- ...and so on for all language-defined subprograms declared in 
this package.)
address@hidden System.Storage_Elements;
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The Convention @Chg{Version=[3],New=[aspects],address@hidden imply that
+the attribute Access is not allowed for those operations.
+
+The @key(mod) function is needed so that the
+definition of Alignment makes sense.
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The range of Storage_Elements.Storage_Offset, the modulus of
+Storage_Elements.Storage_Element, and the declaration of
+Storage_Elements.Integer_Address.]}.]}
+
+Storage_Element represents a storage element.
+Storage_Offset represents an offset in storage elements.
+Storage_Count represents a number of storage elements.
address@hidden representation}
address@hidden representation}
+Storage_Array represents a contiguous sequence of storage elements.
address@hidden
+The index subtype of Storage_Array is Storage_Offset
+because we wish to allow maximum flexibility.
+Most Storage_Arrays will probably have a lower bound of 0 or 1,
+but other lower bounds, including negative ones,
+make sense in some situations.
+
address@hidden,Kind=[Deleted],ARef=[AI95-00114-01]}
address@hidden,Text=[Note that there are some language-defined
+subprograms that fill part of a Storage_Array, and return the index of the
+last element filled as a Storage_Offset.
+The Read procedures in
+Streams (see @RefSecNum{The Package Streams}),
+Streams.Stream_IO (see @RefSecNum{The Package Streams.Stream_IO}),
+and System.RPC (see @RefSecNum{Partition Communication Subsystem})
+behave in this manner.
+These will raise Constraint_Error if the resulting Last value is not in
+Storage_Offset.
+This implies that the Storage_Array passed to these subprograms should
+not have a lower bound of Storage_Offset'First,
+because then a read of 0 elements would always raise Constraint_Error.
+A better choice of lower bound is 1.]}
address@hidden
+
+Integer_Address is a @Redundant[(signed or modular)] integer subtype.
+To_Address and To_Integer convert back and forth between
+this type and Address.
address@hidden
+
address@hidden
+Storage_Offset'Last shall be greater than or equal to Integer'Last or
+the largest possible storage offset,
+whichever is smaller.
+Storage_Offset'First shall be <= (@en@;Storage_Offset'Last).
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00362-01]}
address@hidden,Text=[Package System.Storage_Elements may be declared
+pure.]}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraph 15 was
+deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered.}
address@hidden
+
address@hidden
+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 @lquotes@;wrap address@hidden@;
address@hidden,Sec=(raised by failure of run-time check)}
+Operations that do not make sense should raise
+Program_Error.
address@hidden,Kind=[Added],address@hidden,
+Text=[Operations in System and its children should reflect the
+target environment; operations that do not make sense should raise 
Program_Error.]}]}
address@hidden
+For example, on a segmented architecture,
+X < Y might raise Program_Error if X and Y do not point at the same
+segment (assuming segments are unordered).
+Similarly, on a segmented architecture,
+the conversions between Integer_Address and Address
+might not make sense for some values,
+and so might raise Program_Error.
address@hidden
address@hidden
+We considered making Storage_Element a private type.
+However, it is better to declare it as a modular type in the visible part,
+since code that uses it is already low level,
+and might as well have access to the underlying representation.
+We also considered allowing Storage_Element to be any
+integer type, signed integer or modular, but it is better to have
+uniformity across implementations in this regard, and viewing storage elements
+as unsigned seemed to make the most sense.
address@hidden
address@hidden
+To_Address is intended for use in Address clauses.
+Implementations should overload To_Address if appropriate.
+For example, on a segmented architecture,
+it might make sense to have a record type representing a
+segment/offset pair, and have a To_Address conversion that
+converts from that record type to type Address.
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00362-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Package System.Storage_Elements is now Pure, so it can be
+  portably used in more places. (Ada 95 allowed it to be Pure, but did not
+  require that.)]}
address@hidden
+
+
+
address@hidden@Comment{For ISO version of Ada 2012 Standard}
address@hidden Package System.Address_To_Access_Conversions}
+
address@hidden
+
address@hidden@;The following language-defined generic library package exists:
address@hidden
address@hidden,address@hidden@address@hidden@key[generic]
+    @key[type] Object(<>) @key[is] @key[limited] @key[private];
address@hidden System.Address_To_Access_Conversions @key[is]
+   @key[pragma] Preelaborate(Address_To_Access_Conversions);
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key[type] Object_Pointer @key[is] @key[access] @key[all] Object;
+   @key[function] @AdaSubDefn{To_Pointer}(Value : Address) @key[return] 
address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+   @key[function] @AdaSubDefn{To_Address}(Value : Object_Pointer) @key[return] 
address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[],Old=[   @key[pragma] Convention(Intrinsic, To_Pointer);
+   @key[pragma] Convention(Intrinsic, To_Address);
address@hidden System.Address_To_Access_Conversions;
address@hidden
+
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01]}
+The To_Pointer and To_Address subprograms
+convert back and forth between
+values of types Object_Pointer and Address.
+To_Pointer(X'Address) is equal to X'Unchecked_Access
+for any X that allows Unchecked_Access.
+To_Pointer(Null_Address) returns @key[null].
address@hidden
+For other addresses,
+the behavior is unspecified.
+To_Address(@key[null]) returns address@hidden,New=[],Old=[ (for
address@hidden of the appropriate type)]}.
+To_Address(Y), where Y /= @key[null], returns address@hidden'Address.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+The programmer should ensure that
+the address passed to To_Pointer is either Null_Address,
+or the address of an object of type Object. @Chg{Version=[2],New=[(If Object is
+not a @Chg{Version=[3],New=[],Old=[not ]}by-reference type, the object ought to
+be aliased; recall that the Address attribute is not required to provide a
+useful result @Chg{Version=[3],New=[for ],Old=[]}other objects.)],Old=[]}
+Otherwise, the behavior of the program is unspecified;
+it might raise an exception or crash, for example.
address@hidden
address@hidden
+Unspecified is almost the same thing as erroneous;
+they both allow arbitrarily bad behavior.
+We don't say erroneous here, because the implementation
+might allow the address passed to To_Pointer to point
+at some memory that just happens to @lquotes@;look address@hidden@; an
+object of type Object.
+That's not necessarily an error; it's just not portable.
+However, if the actual type passed to Object is (for example)
+an array type, the programmer
+would need to be aware of any dope that the implementation expects to
+exist, when passing an address that did not come from the Address
+attribute of an object of type Object.
+
+One might wonder why To_Pointer and To_Address are any better than
+unchecked conversions. The answer is that Address does not necessarily
+have the same representation as an access type. For example, an access
+value might point at the bounds of an array when an address would point
+at the first element. Or an access value might be an offset in words
+from someplace, whereas an address might be an offset in bytes from the
+beginning of memory.
address@hidden
address@hidden
+
address@hidden
+An implementation may place restrictions on instantiations of
+Address_To_Access_Conversions.
address@hidden
+For example, if the hardware requires aligned loads and stores,
+then dereferencing an access value that is not properly aligned might
+raise an exception.
+
+For another example,
+if the implementation has chosen to use negative component offsets
+(from an access value),
+it might not be possible to preserve the semantics,
+since negative offsets from the Address are not allowed.
+(The Address attribute always points at
address@hidden@;the first of the storage address@hidden@;)
+Note that while the implementation knows how to convert an access
+value into an address, it might not be able to do the reverse.
+To avoid generic contract model violations,
+the restriction might have to be detected at run time in some cases.
address@hidden
address@hidden
+
address@hidden Code Insertions}
+
address@hidden
address@hidden@Defn{machine code insertion}
+A machine code insertion can be achieved by a call to a subprogram whose
address@hidden contains @nt{code_statement}s.]
address@hidden
+
address@hidden
address@hidden<code_statement>,rhs="@Syn2{qualified_expression};"}
+
address@hidden
+A @nt{code_statement} is only allowed in the
address@hidden@!statements} of a @address@hidden
+If a @address@hidden contains any @address@hidden, then within
+this @address@hidden the only allowed form of @nt{statement} is a
address@hidden@!statement} (labeled or not),
+the only allowed @address@hidden are @address@hidden,
+and no @address@hidden is allowed (@nt{comment}s and
address@hidden are allowed as usual).
address@hidden
address@hidden
+
address@hidden
address@hidden type],
+  Sec=(code_statement)}
+The @nt{qualified_expression} is expected to be of any type.
address@hidden
+
address@hidden
+The @nt{qualified_expression} shall be of a
+type declared in package System.Machine_Code.
address@hidden
+This includes types declared in children of System.Machine_Code.
address@hidden
+
+A @nt<code_statement> shall appear only within the scope of
+a @nt<with_clause> that mentions package System.Machine_Code.
address@hidden
+Note that this is not a note;
+without this rule, it would be possible to write machine code
+in compilation units which depend on System.Machine_Code only indirectly.
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden,Child=[Machine_Code]}
+The contents of the library package System.Machine_Code
+(if provided) are implementation defined.
+The meaning of @nt{code_statement}s is implementation defined.
address@hidden, each @nt{qualified_expression}
+represents a machine instruction or assembly directive.}
address@hidden
+For example, an instruction might be a record with an Op_Code
+component and other components for the operands.
address@hidden
address@hidden contents of the visible part of package System.Machine_Code,
+and the meaning of @nt{code_statement}s.}
address@hidden
+
address@hidden
+An implementation may place restrictions on @nt{code_statement}s.
+An implementation is not required to provide package System.Machine_Code.
address@hidden
+
address@hidden
+An implementation may provide implementation-defined pragmas
+specifying register conventions and calling conventions.
+
address@hidden,Kind=[Revised],ARef=[AI95-00318-02]}
+Machine code functions are exempt from the rule that a
address@hidden,New=[return statement],address@hidden@!statement}]}
+is required. In fact,
address@hidden,New=[return statements],address@hidden@!statement}s]} are
+forbidden, since only @nt{code_statement}s are allowed.
address@hidden
+The idea is that the author of a machine code subprogram knows
+the calling conventions, and refers to parameters and results
+accordingly.
+The implementation should document where to put the result of a
+machine code function, for example,
address@hidden@;Scalar results are returned in register address@hidden@;
address@hidden
+
+Intrinsic subprograms (see @RefSec{Conformance Rules})
+can also be used to achieve machine code insertions.
+Interface to assembly language can be achieved
+using the features in @RefSec{Interface to Other Languages}.
address@hidden
+
address@hidden
address@hidden@address@hidden of a code statement:}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+M : Mask;
address@hidden address@hidden,New=[
+  @key[with] Inline],Old=[]};@Chg{Version=[3],New=[],Old=[ @key[pragma] 
Inline(Set_Mask);]}
+
address@hidden Set_Mask @key[is]
+  @key[use] System.Machine_Code; address@hidden assume @lquotes@;@key[with] 
System.Machine_Code;@rquotes@; appears somewhere above}
address@hidden
+  SI_Format'(Code => SSM, B => M'Base_Reg, D => M'Disp);
+  address@hidden  Base_Reg and Disp are implementation-defined attributes}
address@hidden Set_Mask;
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Machine code functions are allowed in Ada 95;
+in Ada 83, only procedures were allowed.
address@hidden
+
address@hidden
+The syntax for @nt{code_statement} is changed to say
address@hidden@;@address@hidden@; instead of
address@hidden@;@Syn2{subtype_mark}'@address@hidden@;.
+Requiring the type of each instruction to be a record type is
+overspecification.
address@hidden
+
address@hidden Type Conversions}
+
address@hidden
address@hidden@Defn{unchecked type conversion}
address@hidden conversion], Sec=(unchecked)}
address@hidden, Sec=(unchecked)}
address@hidden,See=(unchecked type conversion)}
address@hidden,See=(unchecked type conversion)}
+An unchecked type conversion can be achieved by a call to an instance
+of the generic function Unchecked_Conversion.]
address@hidden
+
address@hidden
address@hidden@keepnext@;The following language-defined generic library 
function exists:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden
+   @key[type] Source(<>) @key[is] @key[limited] @key[private];
+   @key[type] Target(<>) @key[is] @key[limited] @key[private];
address@hidden,address@hidden Ada.Unchecked_Conversion(S : Source) @key[return] 
address@hidden,New=[
+   @key(with) Convention => Intrinsic],Old=[]};@Chg{Version=[3],New=[],Old=[
address@hidden Convention(Intrinsic, Ada.Unchecked_Conversion);]}
address@hidden Pure(Ada.Unchecked_Conversion);
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The @Chg{Version=[3],New=[aspect],address@hidden Convention implies that
+the attribute Access is not allowed
+for instances of Unchecked_Conversion.
address@hidden
address@hidden
+
address@hidden
+The size of the formal parameter S in an instance of
+Unchecked_Conversion is that of its subtype.
address@hidden is the actual subtype passed to Source,
+except when the actual is an unconstrained composite subtype,
+in which case the subtype is constrained by the bounds or
+discriminants of the value of the actual expression passed to S.]
+
address@hidden@;If all of the following are true,
+the effect of an unchecked conversion is to return the
+value of an object of the target subtype whose representation is the
+same as that of the source object S:
address@hidden
+S'Size = Target'Size.
address@hidden
+Note that there is no requirement that the Sizes be known at compile
+time.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0078-1]}
+S'Alignment @Chg{Version=[3],New=[is a multiple of],Old=[=]}
+Target'address@hidden,New=[ or Target'Alignment is zero],Old=[]}.
+
+The target subtype is not an unconstrained composite subtype.
+
address@hidden representation}
address@hidden representation}
+S and the target subtype both have a contiguous
+representation.
+
+The representation of S is a representation of
+an object of the target subtype.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00426-01]}
+Otherwise, @Chg{Version=[2],New=[if the result type is scalar, the result
+of the function is implementation defined, and can have an invalid
+representation (see @RefSecNum{Data Validity}).
+If the result type is nonscalar, ],Old=[]}the effect is implementation defined;
+in particular, the result can be abnormal
+(see @RefSecNum{Data Validity}).
+
address@hidden,Kind=[Added],address@hidden,New=[The result
+of unchecked conversion for instances with scalar result types whose
+result is not defined by the language.],Old=[]}]}
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[The effect of unchecked
address@hidden,New=[ for instances
+with nonscalar result types whose effect is not defined by
+the language],Old=[]}.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00426-01]}
+  @ChgAdded{Version=[2],Text=[Note the difference between these sentences;
+  the first only says that the bits returned are implementation defined, while
+  the latter allows any effect. The difference is because scalar objects should
+  never be abnormal unless their assignment was disrupted or if they are a
+  subcomponent of an abnormal composite object. Neither exception applies to
+  instances of Unchecked_Conversion.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00426-01]}
+  Whenever unchecked conversions are used, it is the programmer's
+  responsibility to ensure that these conversions maintain the properties
+  that are guaranteed by the language for objects of the target type.
+  @Chg{Version=[2],New=[For nonscalar types, this],Old=[This]} requires the
+  user to understand the underlying run-time model of  the implementation.
+  The execution of a program that violates these properties by means of
+  unchecked conversions @Chg{Version=[2],New=[returning a nonscalar type ],
+  Old=[]}is address@hidden,New=[ Properties of scalar types can
+  be checked by using the Valid attribute (see @RefSecNum{The Valid 
Attribute});
+  programs can avoid violating properties of the type (and erroneous
+  execution) by careful use of this attribute.],Old=[]}
+
+  An instance of Unchecked_Conversion can be applied to an object of a
+  private type, assuming the implementation allows it.
address@hidden
address@hidden
+
address@hidden
+An implementation may return the result of
+an unchecked conversion
+by reference, if the Source type is not a by-copy type.
address@hidden this case, the result of the unchecked conversion represents
+simply a different (read-only) view of the operand of the conversion.]
address@hidden
+  In other words, the result object of a call on an instance
+  of Unchecked_Conversion can occupy the same storage as the
+  formal parameter S.
address@hidden
+
+An implementation may place restrictions on Unchecked_Conversion.
address@hidden
+For example, an instantiation of Unchecked_Conversion for types for
+which unchecked conversion doesn't make sense may be disallowed.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00051-02]}
address@hidden,New=[Since the],Old=[The]} Size of an array object
address@hidden,New=[generally does],Old=[should]} not include its
address@hidden,New=[],Old=[; hence]}, the bounds should not be part
+of the converted data.
address@hidden,Kind=[Added],address@hidden,
+Text=[Since the Size of an array object generally does not include its bounds,
+the bounds should not be part of the converted data in an instance of
+Unchecked_Conversion.]}]}
address@hidden
+On the other hand, we have no advice to offer about
+discriminants and tag fields.
address@hidden
+
+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.
address@hidden,Kind=[Added],address@hidden,
+Text=[There should not be unnecessary run-time checks on the result of
+an Unchecked_Conversion; the result should be returned by reference when
+possible. Restrictions on Unchecked_Conversions should be avoided.]}]}
address@hidden
+  As an example of an unnecessary run-time check,
+  consider a record type with gaps between components.
+  The compiler might assume that such gaps are always zero bits.
+  If a value is produced that does not obey that assumption,
+  then the program might misbehave.
+  The implementation should not generate extra code to check for zero bits
+  (except, perhaps, in a special error-checking mode).
address@hidden
+
address@hidden@PDefn2{Term=[recommended level of support], Sec=(unchecked 
conversion)}
+The recommended level of support for unchecked conversions is:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Unchecked conversions should be supported and should be reversible in
+the cases where this @Chg{Version=[3],New=[subclause],Old=[clause]} defines
+the address@hidden representation}
address@hidden representation}
+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.
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The recommended level of support for Unchecked_Conversion should be
+followed.]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00051-02]}
+  @ChgAdded{Version=[2],Text=[The implementation advice about the size of
+  array objects was moved to 13.3 so that all of the advice about Size is
+  in one place.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00426-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that the result of Unchecked_Conversion
+  for scalar types can be invalid, but not abnormal.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0078-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Relaxed the alignment
+  requirement slightly, giving a defined result in more cases.]}
+  @ChgNote{This is not an extension, as a program taking advantage of this
+  change was (and very well might have worked) legal before the change; it's
+  just guaranteed to be portable now.}
address@hidden
+
+
address@hidden Validity}
+
address@hidden
+Certain actions that can potentially lead to erroneous execution are not
+directly erroneous,
+but instead can cause objects to become @i{abnormal}.
+Subsequent uses of abnormal objects can be erroneous.
+
+A scalar object can have an @i{invalid representation},
+which means that the object's representation does not represent any
+value of the object's subtype.
address@hidden variables}
+The primary cause of invalid representations is uninitialized variables.
+
+Abnormal objects and invalid representations are explained in this
+subclause.
address@hidden
+
address@hidden
address@hidden@RootDefn{normal state of an object}
address@hidden state of an object}
+When an object is first created, and any explicit or default
+initializations have been performed, the object
+and all of its parts are in the @i{normal} state.
+Subsequent operations generally leave them normal.
+However, an object or part of an object can become @i{abnormal}
+in the following ways:
address@hidden
address@hidden of an assignment}
+An assignment to the object is disrupted due to an abort
+(see @RefSecNum{Abort of a Task - Abort of a Sequence of Statements})
+or due to the failure of a language-defined check
+(see @RefSecNum{Exceptions and Optimization}).
+
address@hidden,Kind=[Revised],ARef=[AI95-00426-01]}
+The object is not scalar, and is passed to an @key[in out]
+or @key[out] parameter of an imported address@hidden,New=[,
+the Read procedure of an instance of Sequential_IO,
+Direct_IO, or Storage_IO, or the stream attribute T'Read], Old=[ or
+language-defined input procedure]},
+if after return from the procedure the representation of the parameter
+does not represent a value of the parameter's subtype.
+
address@hidden,Kind=[Added],ARef=[AI95-00426-01]}
address@hidden,Text=[The object is the return object of a function call
+of a nonscalar type, and the function is an imported function, an instance of
+Unchecked_Conversion, or the stream attribute T'Input, if after return from the
+function the representation of the return object does not represent a value of
+the function's subtype.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We explicitly list the routines involved in order
+  to avoid future arguments. All possibilities are listed.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We did not include Stream_IO.Read in the list
+  above. A Stream_Element should include all possible bit patterns, and thus it
+  cannot be invalid. Therefore, the parameter will always represent a value of
+  its subtype. By omitting this routine, we make it possible to write arbitrary
+  I/O operations without any possibility of abnormal objects.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00426-01]}
address@hidden,address@hidden an imported object, it is the
+programmer's responsibility to ensure that the object remains in a normal
+state.]]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This follows (and echos) the standard rule
+  of interfacing; the programmer must ensure that Ada semantics are
+  followed (see @RefSecNum{Interfacing Aspects}).]}
address@hidden
+
address@hidden
+Whether or not an object actually becomes abnormal in these cases is
+not specified.
+An abnormal object becomes normal again upon successful completion of
+an assignment to the object as a whole.
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)}
+It is erroneous to evaluate a @nt<primary> that is a @nt<name>
+denoting an abnormal object,
+or to evaluate a @nt{prefix} that denotes an abnormal object.
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00114-01]}
address@hidden appears to be no justification for this statement; everything
+can become abnormal. We leave the prefix for the next paragraph, so we use
+Chg rather than ChgDeleted.}
address@hidden,New=[],Old=[Although a composite object with no
+subcomponents of an access type, and with static constraints all the way down
+cannot become abnormal, a scalar subcomponent of such an object can become
+abnormal.]}
+
+The @key[in out] or @key[out] parameter case does not apply to scalars;
+bad scalars are merely invalid representations,
+rather than abnormal, in this case.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+The reason we allow access objects, and objects containing subcomponents of an
+access type, to become abnormal is because the correctness of an access
+value cannot necessarily be determined merely by looking at the bits of
+the object.
+The reason we allow scalar objects to become abnormal is that we wish to
+allow the compiler to optimize assuming that the value of a scalar
+object belongs to the object's subtype,
+if the compiler can prove that the object is initialized with a value
+that belongs to the subtype.
+The reason we allow composite objects to become abnormal
address@hidden,New=[],Old=[if some constraints are nonstatic ]}is
+that such object might be represented with implicit levels of indirection;
+if those are corrupted, then even assigning into a component of the
+object, or simply asking for its Address, might have an unpredictable
+effect. The same is true if the discriminants have been destroyed.
address@hidden
address@hidden
+
address@hidden
address@hidden@Defn{invalid address@hidden(bounded error),Sec=(cause)}
+If the representation of a scalar object does not represent a value of
+the object's subtype
+(perhaps because the object was not initialized),
+the object is said to have an @i{invalid representation}.
+It is a bounded error to evaluate the value of such
+an object.
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,Sec=(raised by failure of run-time check)}
+If the error is detected, either Constraint_Error or Program_Error is
+raised.
+Otherwise, execution continues using the invalid representation.
+The rules of the language outside this subclause assume that all objects
+have valid representations.
+The semantics of operations on invalid representations are as follows:
+
address@hidden
+
+The AARM is more explicit about what happens when
+the value of the case expression is an invalid representation.
+
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00426-01]}
+  @ChgAdded{Version=[2],Text=[This includes the result object of functions,
+  including the result of Unchecked_Conversion, T'Input, and imported
+  functions.]}
address@hidden
+
address@hidden
+If the representation of the object represents a value of the object's
+type, the value of the type is used.
+
+If the representation of the object does not represent a value of the
+object's type,
+the semantics of operations on such representations is
+implementation-defined, but does not by itself lead to
+erroneous or unpredictable
+execution, or to other objects becoming abnormal.
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00426-01]}
+  @ChgAdded{Version=[2],Text=[This means that the implementation must take care
+  not to use an invalid representation in a way that might cause erroneous
+  execution. For instance, the exception mandated for @nt{case_statement}s
+  must be raised. Array indexing must not cause memory outside of
+  the array to be written (and usually, not read either). These cases and
+  similar cases may require explicit checks by the implementation.]}
address@hidden
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00167-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0279-1]}
address@hidden(erroneous execution),Sec=(cause)}
+A call to an imported function or an instance of Unchecked_Conversion is
+erroneous if the result is scalar, @Chg{Version=[2],New=[],Old=[and ]}the
+result object has an invalid address@hidden,New=[, and
+the result is used other than as the @nt{expression} of
+an @nt{assignment_statement} or an 
@nt{object_declaration},@Chg{Version=[3],New=[
+as the @address@hidden of an @nt{object_renaming_declaration},],Old=[]} or as 
the
address@hidden of a Valid attribute. If such a result object is used as the 
source
+of an assignment, and the assigned value is an invalid representation for the
+target of the assignment, then any use of the target object prior to a further
+assignment to the target object, other than as the @nt{prefix} of a Valid
+attribute reference, is erroneous],Old=[]}.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00167-01]}
+In a typical implementation, every bit pattern that fits in an object of
address@hidden,New=[a signed],Old=[an]} integer subtype will represent a
+value of the type, if not of the subtype.
+However, for an enumeration or floating point type,@Chg{Version=[2],New=[ as
+well as some modular types,],Old=[]}
+there are typically bit patterns that do not represent any
+value of the type.
+In such cases, the implementation ought to define the semantics of
+operations on the invalid representations in the obvious manner
+(assuming the bounded error is not detected):
+a given representation should be equal to itself,
+a representation that is in between the internal codes of
+two enumeration literals should behave accordingly when passed to
+comparison operators and membership tests, etc.
+We considered @i{requiring} such sensible behavior,
+but it resulted in too much arcane verbiage,
+and since implementations have little incentive to behave
+irrationally, such verbiage is not important to have.
+
address@hidden,Kind=[Revised],ARef=[AI95-00167-01]}
+If a stand-alone scalar object is initialized to a an in-range
+value, then the implementation can take advantage of the fact
+that @Chg{Version=[2],New=[the use of ],Old=[]}any out-of-range value
+has to be @Chg{Version=[2],New=[erroneous],address@hidden you
+see "abnormal" in the rules above? Thought not.}
+Such an out-of-range value can be produced only by things like
+unchecked conversion, @Chg{Version=[2],New=[imported functions],Old=[input]},
+and @Chg{Version=[2],New=[abnormal values caused by ],Old=[]}disruption
+of an assignment due to abort or to failure of a
+language-defined check.
+This depends on out-of-range values being checked before
+assignment (that is, checks are not optimized away unless they
+are proven redundant).
+
address@hidden@;Consider the following example:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00167-01]}
address@hidden My_Int @key[is] @key[range] 0..99;
address@hidden Safe_Convert @key[is] @key[new] Unchecked_Conversion(My_Int, 
Integer);
address@hidden Unsafe_Convert @key[is] @key[new] Unchecked_Conversion(My_Int, 
Positive);
+X : Positive := Safe_Convert(0); address@hidden Raises Constraint_Error.}
+Y : Positive := Unsafe_Convert(0); address@hidden,address@hidden Bounded 
Error, may be invalid.}
+B : Boolean  := Y'Valid; address@hidden OK, B = False.}
+Z : Positive := Y+1; address@hidden Erroneous to use Y.}],address@hidden 
Erroneous.}]}
+
address@hidden
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00167-01],ARef=[AI95-00426-01]}
+  The call to Unsafe_Convert @Chg{Version=[2],New=[ is a bounded error, which
+  might raise Constraint_Error, Program_Error, or return an invalid value.
+  Moreover, if an exception is not raised, most uses of that invalid value
+  (including the use of Y) cause],Old=[causes]} erroneous execution. The call 
to
+  Safe_Convert is not erroneous. The result object is an object of subtype
+  Integer containing the value 0. The assignment to X is required to do a
+  constraint check; the fact that the conversion is unchecked does not obviate
+  the need for subsequent checks required by the language rules.
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00167-01],ARef=[AI95-00426-01]}
+  @ChgAdded{Version=[2],Text=[The reason for delaying erroneous execution until
+  the object is used is so that the invalid representation can be tested for
+  validity using the Valid attribute (see @RefSecNum{The Valid Attribute})
+  without causing execution to become erroneous. Note that this delay does not
+  imply an exception will not be raised; an implementation could treat both
+  conversions in the example in the same way and raise Constraint_Error.]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0279-1]}
+  @ChgAdded{Version=[3],Text=[The rules are defined in terms of the result
+  object, and thus the name used to reference that object is irrelevant.
+  That is why we don't need any special rules to describe what happens
+  when the function result is renamed.]}
+
address@hidden
address@hidden
+  If an implementation wants to have a @lquotes@;address@hidden@; mode, it
+  might always assign an uninitialized scalar a default initial value
+  that is outside the object's subtype (if there is one), and check
+  for this value on some or all reads of the object, so as to help
+  detect references to uninitialized scalars.
+  Alternatively, an implementation might want to provide an
+  @lquotes@;address@hidden@; mode where it presumed even uninitialized scalars
+  were always within their subtype.
address@hidden
address@hidden
+  The above rules imply that it is a bounded error
+  to apply a predefined operator to
+  an object with a scalar subcomponent having an invalid representation,
+  since this implies reading the value of each subcomponent.
+  Either Program_Error or Constraint_Error is raised,
+  or some result is produced, which if composite, might have a corresponding
+  scalar subcomponent still with an invalid representation.
+
+  Note that it is not an error to assign, convert, or pass as a parameter
+  a composite object with an uninitialized scalar subcomponent.
+  In the other hand, it is a (bounded) error to apply
+  a predefined operator such as =, <, and @key(xor)
+  to a composite operand with an invalid scalar subcomponent.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0054-2]}
address@hidden(erroneous execution),Sec=(cause)}
+The dereference of an access value is erroneous if
+it does not designate an object of an appropriate type or a subprogram
+with an appropriate profile,
+if it designates a nonexistent object,
+or if it is an access-to-variable value that designates a
+constant address@hidden,New=[ and it did not originate from an
+attribute_reference applied to an aliased variable view
+of a controlled or immutably limited object],Old=[]}.
address@hidden@Chg{Version=[3],New=[An],Old=[Such an]} access value
address@hidden,New=[whose dereference is erroneous ],Old=[]}can exist,
+for example, because of
+Unchecked_Deallocation, Unchecked_Access, or Unchecked_Conversion.]
+
address@hidden
+The above mentioned Unchecked_... features are not the only causes
+of such access values.
+For example, interfacing to other languages can also cause the problem.
+
address@hidden,Kind=[Revised],ARef=[AI05-0054-2]}
address@hidden,New=[We permit the use of access-to-variable
+values that designate constant objects so long as they originate
+from an aliased variable view of a controlled or immutably limited
+constant, such as during the initialization of a constant (both via
+the @ldquote@;current address@hidden and during a call to Initialize) or
+during an assignment (during a call to Adjust).],Old=[One obscure example is if
+the Adjust subprogram of a controlled type uses Unchecked_Access to create an
+access-to-variable value designating a subcomponent of its controlled 
parameter,
+and saves this access value in a global object. When Adjust is called during 
the
+initialization of a constant object of the type, the end result will be an
+access-to-variable value that designates a constant object.]}
address@hidden
address@hidden
+
address@hidden
+Objects can become abnormal due to other kinds of actions that directly
+update the object's representation;
+such actions are generally considered directly erroneous, however.
address@hidden
+
address@hidden
+In order to reduce the amount of erroneousness,
+we separate the concept of an undefined value into
+objects with invalid representation (scalars only)
+and abnormal objects.
+
+Reading an object with an invalid representation is a bounded error
+rather than erroneous;
+reading an abnormal object is still erroneous.
+In fact, the only safe thing to do to an abnormal object is
+to assign to the object as a whole.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00167-01]}
+  @ChgAdded{Version=[2],Text=[The description of erroneous execution for
+  Unchecked_Conversion and imported objects was tightened up so that
+  using the Valid attribute to test such a value is not erroneous.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00426-01]}
+  @ChgAdded{Version=[2],Text=[Clarified the definition of objects that can
+  become abnormal; made sure that all of the possibilities are included.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0054-2]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Common programming
+  techniques such as squirreling address@hidden away} an access to a
+  controlled object during initialization and using a self-referencing
+  discriminant (the so-called @ldquote@;Rosen address@hidden@Defn{Rosen trick})
+  no longer are immediately erroneous if the object is declared constant,
+  so these techniques can be used portably and safely. Practically,
+  these techniques already worked as compilers did not take much advantage
+  of this rule, so the impact of this change will be slight.]}
+  @ChgNote{This is not an extension, as such a program was already legal
+  (although erroneous).}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0279-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> The description of 
erroneous
+  execution for Unchecked_Conversion and imported objects was adjusted to
+  clarify that renaming such an object is not, by itself, erroneous.]}
address@hidden
+
+
+
address@hidden Valid Attribute}
+
address@hidden
+The Valid attribute can be used to check the validity of data produced
+by unchecked conversion, input, interface to foreign languages,
+and the like.
address@hidden
+
address@hidden
address@hidden@;For @PrefixType{a @nt<prefix> X that
+denotes a scalar object @Redundant[(after any implicit dereference)]},
+the following attribute is defined:
address@hidden(description)
address@hidden ought to have a separate change for version [3] here, but
+we don't have that capability.}
address@hidden,Kind=[Revised],ChginAnnex=[T],
+  Leading=<F>, Prefix=<X>, AttrName=<Valid>,
+  ARef=[AI05-0153-3], ARef=[AI12-0071-1], InitialVersion=[0],
+  Text=<Yields True if and only if
+the object denoted by X is address@hidden,New=[,],Old=[ and]} has a
+valid address@hidden,New=[, and @Chg{Version=[4],New=[then,
+if the preceding conditions hold, the value of X also satisfies the
address@hidden satisfied required],Sec=[Valid attribute]}], Old=[the
address@hidden evaluated],Sec=[Valid attribute]}]}
+of the nominal subtype of address@hidden,New=[],Old=[ evaluates to
+True]}],Old=[]}. The value of this attribute is of the predefined type 
Boolean.>}
address@hidden
+  Having checked that X'Valid is True, it is safe to read the
+  value of X without fear of erroneous execution caused by abnormality,
+  or a bounded error caused by an invalid representation.
+  Such a read will produce a value in the subtype of X.
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden@;Invalid data can be created in the following cases
+(not counting erroneous or unpredictable execution):
address@hidden
+an uninitialized scalar object,
+
+the result of an unchecked conversion,
+
+input,
+
+interface to another language (including machine code),
+
+aborting an assignment,
+
+disrupting an assignment due to the failure
+of a language-defined check
+(see @RefSecNum{Exceptions and Optimization}), and
+
+use of an object whose Address has been specified.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI12-0071-1]}
address@hidden,New=[Determining whether X is normal and has a valid
+representation as part of the evaluation of ],Old=[]}X'Valid is not considered
+to @Chg{Version=[4],New=[include an evaluation],Old=[be a read]} of X;
+hence, it is not an error to check the validity
+of @Chg{Version=[4],New=[an object that is invalid or abnormal.
+Determining whether X satisfies the predicates of its nominal
+subtype may include an evaluation of X, but only after
+it has been determined that X has a valid representation],Old=[invalid data]}.
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0071-1]}
address@hidden,NoPrefix=[T],Text=[If X is volatile, the evaluation of
+X'Valid is considered a read of X.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[Since an implementation is not allowed to add,
+  remove, or reorder accesses to volatile objects, we have to define X'Valid
+  as a read so that it is implementable for most subtypes as the value
+  of the object is required.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00426-01]}
address@hidden,Text=[The Valid attribute may be used to check the
+result of calling an instance of Unchecked_Conversion (or any other
+operation that can return invalid values). However, an exception handler
+should also be provided because implementations are permitted to raise
+Constraint_Error or Program_Error if they detect the use of an invalid
+representation (see @RefSecNum{Data Validity}).]}
+
address@hidden
+If X is of an enumeration type with a representation clause, then
+X'Valid checks that the value of X when viewed as an integer is one of
+the specified internal codes.
address@hidden
address@hidden
+Valid is defined only for scalar objects because the implementation
+and description burden would be too high for other types.
+For example, given a typical run-time model, it is impossible to check
+the validity of an access value.
+The same applies to composite types implemented with internal pointers.
+One can check the validity of a composite object by checking the
+validity of each of its scalar subcomponents.
+The user should ensure that any composite types that need to be checked
+for validity are represented in a way that does not involve
+implementation-defined components, or gaps between components.
+Furthermore, such types should not contain access subcomponents.
+
address@hidden,Kind=[Deleted],ARef=[AI95-00114-01]}
address@hidden was never true, even in Ada 95}
address@hidden,Text=[Note that one can safely check the validity
+of a composite object with
+an abnormal value only if the constraints on
+the object and all of its subcomponents are static.
+Otherwise, evaluation of the @nt{prefix} of the @nt{attribute_reference}
+causes erroneous execution (see @RefSecNum{Names}).]}
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+X'Valid is new in Ada 95.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00426-01]}
+  @ChgAdded{Version=[2],Text=[Added a note explaining that handlers for
+  Constraint_Error and Program_Error are needed in the general case of
+  testing for validity. (An implementation could document cases where these
+  are not necessary, but there is no language requirement.)]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0153-3]}
+  @ChgAdded{Version=[3],Text=[The validity check now also includes a check
+  of the predicate aspects (see @RefSecNum{Subtype Predicates}), if any, of
+  the subtype of the object.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0071-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Updated wording of the
+  attributes X'Valid to use the new term
+  "satisfies the predicates" (see @RefSecNum{Subtype Predicates}).
+  Also updated the notes to make sense when evaluating predicates and
+  testing validity of volatile objects.]}
address@hidden
+
+
address@hidden Access Value Creation}
+
address@hidden
address@hidden attribute Unchecked_Access is used to create access values
+in an unsafe manner @em the programmer is responsible for preventing
address@hidden@;dangling address@hidden@;]
address@hidden
+
address@hidden
address@hidden@;The following attribute is defined for @PrefixType{a 
@nt{prefix} X that
+denotes an aliased view of an object}:
address@hidden
address@hidden<X>, AttrName=<Unchecked_Access>,
+  Text=<All rules and semantics that apply to
+X'Access (see @RefSecNum{Operations of Access Types})
+apply also to X'Unchecked_Access,
+except that,
+for the purposes of accessibility rules and checks,
+it is as if X were declared immediately within a library package.>}
address@hidden attribute],See=(Unchecked_Access attribute)}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,Text=[We say @ldquote@;rules and address@hidden@;
+here so that library-level accessibility applies to the value created by
+X'Unchecked_Access as well as to the checks needed for the attribute itself.
+This means that any anonymous access values that inherit the accessibility of
+this attribute (such as access parameters) also act as if they have
+library-level accessibility. We don't want the "real" accessibility of the
+created value re-emerging at a later point @en that would create
+hard-to-understand bugs.]}
address@hidden
address@hidden
+
address@hidden
+This attribute is provided to support the situation where a local
+object is to be inserted into a global linked data structure, when the
+programmer knows that it will always be removed from the data structure prior
+to exiting the object's scope. The Access attribute would
+be illegal in this case
+(see @RefSec{Operations of Access Types}).
address@hidden
address@hidden type],
+  Sec=(Unchecked_Access attribute)}
+The expected type for X'Unchecked_Access is as for X'Access.
+
+If an @nt<attribute_reference> with Unchecked_Access is used
+as the actual parameter for an access parameter,
+an Accessibility_Check can never fail on that access
+parameter.
address@hidden
+
+There is no Unchecked_Access attribute for subprograms.
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00254-01]}
+  Such an attribute would allow @Chg{Version=[2],New=[unsafe ],
+  address@hidden@;downward address@hidden@;,
+  where an access value designating a more nested subprogram is passed
+  to a less nested address@hidden,New=[ (Anonymous
+  access-to-subprogram parameters provide safe
+  @lquotes@;downward address@hidden@;.)],Old=[]}
+  This requires some means of reconstructing the global environment for
+  the more nested subprogram,
+  so that it can do up-level references to objects.
+  The two methods of implementing up-level references are displays and
+  static links.
+  If @Chg{Version=[2],New=[unsafe ],Old=[]}downward closures were
+  supported,
+  each access-to-subprogram value would have to carry the static link
+  or display with it.
+  @Chg{Version=[2],New=[We don't want to require the space and time
+  overhead of requiring the extra information for all access-to-subprogram
+  types, especially as including it
+  would make interfacing to other languages (like C) harder],Old=[In the case
+  of displays, this was judged to be infeasible,
+  and we don't want to disrupt implementations by forcing them
+  to use static links if they already use displays]}.
+
+  If desired, an instance of Unchecked_Conversion can be used to create
+  an access value of a global access-to-subprogram type that
+  designates a local subprogram. The semantics of using
+  such a value are not specified by the language.
+  In particular, it is not specified what happens if such
+  subprograms make up-level references; even if the frame
+  being referenced still exists, the up-level reference might
+  go awry if the representation of a value of a global access-to-subprogram
+  type doesn't include a static link.
address@hidden
+
address@hidden
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Management}
+
address@hidden
address@hidden
address@hidden storage management}
address@hidden management], Sec=(user-defined)}
address@hidden heap management}
address@hidden management], Sec=(user-defined)}
+Each access-to-object type has an associated storage
+pool.
+The storage allocated by an @nt{allocator} comes from the pool;
+instances of Unchecked_Deallocation return storage to the pool.
+Several access types can share the same pool.]
+
address@hidden,Kind=[Revised],ARef=[AI95-00435-01]}
address@hidden storage pool is a variable of a type in the class rooted
+at Root_Storage_Pool, which is an abstract limited controlled type.
+By default, the implementation chooses a @i{standard storage pool}
+for each address@hidden,New=[-to-object],Old=[]} type.
+The user may define new pool types,
+and may override the choice of pool for an 
address@hidden,New=[-to-object],Old=[]}
+type by specifying Storage_Pool for the type.]
address@hidden
+By default, the implementation might choose to have a single global
+storage pool,
+which is used (by default) by all access types,
+which might mean that storage is reclaimed automatically only
+upon partition completion.
+Alternatively, it might choose to create a new pool
+at each accessibility level,
+which might mean that storage is reclaimed for an access type
+when leaving the appropriate scope.
+Other schemes are possible.
address@hidden
+
address@hidden,Kind=[Added],Term=<Storage pool>,
+Text=<@ChgAdded{Version=[3],Text=[Each access-to-object type has an associated
+storage pool object. The storage for an object created by an @nt{allocator}
+comes from the storage pool of the type of the @nt{allocator}. Some storage
+pools may be partitioned into subpools in order to support finer-grained 
storage
+management.]}>}
+
address@hidden
+
address@hidden
+If Storage_Pool is specified for a given access type,
+Storage_Size shall not be specified for it.
address@hidden
+The Storage_Pool determines the Storage_Size;
+hence it would not make sense to specify both.
+Note that this rule is simplified by the fact that the aspects in
+question cannot be specified for derived types,
+nor for nonfirst subtypes,
+so we don't have to worry about whether, say, Storage_Pool on a
+derived type overrides Storage_Size on the parent type.
+For the same reason, @lquotes@;address@hidden@; means the same thing as
address@hidden@;directly address@hidden@; here.
address@hidden
address@hidden
+
address@hidden
address@hidden@keepnext@;The following language-defined library package exists:
address@hidden
address@hidden Ada.Finalization;
address@hidden System.Storage_Elements;
address@hidden,address@hidden System.Storage_Pools @key[is]
+    @key{pragma} Preelaborate(System.Storage_Pools);
+
address@hidden,Kind=[Revised],ARef=[AI95-00161-01]}
+    @key[type] @AdaTypeDefn{Root_Storage_Pool} @key[is]
+        @key[abstract] @key[new] Ada.Finalization.Limited_Controlled 
@key[with] @key[private];@Chg{Version=[2],New=[
+    @key[pragma] Preelaborable_Initialization(Root_Storage_Pool);],Old=[]}
+
+    @key[procedure] @AdaSubDefn{Allocate}(
+      Pool : @key[in] @key[out] Root_Storage_Pool;
+      Storage_Address : @key[out] Address;
+      Size_In_Storage_Elements : @key[in] Storage_Elements.Storage_Count;
+      Alignment : @key[in] Storage_Elements.Storage_Count) @key[is] 
@key[abstract];
+
+    @key[procedure] @AdaSubDefn{Deallocate}(
+      Pool : @key[in] @key[out] Root_Storage_Pool;
+      Storage_Address : @key[in] Address;
+      Size_In_Storage_Elements : @key[in] Storage_Elements.Storage_Count;
+      Alignment : @key[in] Storage_Elements.Storage_Count) @key[is] 
@key[abstract];
+
+    @key[function] @AdaSubDefn{Storage_Size}(Pool : Root_Storage_Pool)
+        @key[return] Storage_Elements.Storage_Count @key[is] @key[abstract];
+
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden System.Storage_Pools;
address@hidden
address@hidden
+The Alignment parameter is provided to Deallocate because some
+allocation strategies require it.
+If it is not needed, it can be ignored.
address@hidden
+
address@hidden pool type}
address@hidden type}
+A @i{storage pool type} (or @i{pool type}) is a descendant of
+Root_Storage_Pool.
address@hidden pool element}
address@hidden element}
address@hidden, Sec=(of a storage pool)}
+The @i{elements} of a storage pool are the objects allocated in the
+pool by @nt{allocator}s.
address@hidden
+In most cases, an element corresponds to a single memory block
+allocated by Allocate.
+However, in some cases the implementation may choose to associate
+more than one memory block with a given pool element.
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00435-01]}
address@hidden@;For @PrefixType{every address@hidden,New=[-to-object],Old=[]} 
subtype S},
+the following @Chg{New=[representation ],Old=[]}attributes are defined:
address@hidden
address@hidden<S>, AttrName=<Storage_Pool>,
+  Text=<Denotes the storage pool of the type of S.
+The type of this attribute is address@hidden@!Pool'Class.>}
+
address@hidden<S>, AttrName=<Storage_Size>,
+  Text=<Yields the result of calling
+Storage_Size(S'Storage_Pool)@Redundant{,
+which is intended to be a measure of the number of storage elements
+reserved for the pool.}
+The type of this attribute is @i{universal_integer}.>}
address@hidden
address@hidden
+Storage_Size is also defined for task subtypes and objects
address@hidden see @RefSecNum{Operational and Representation Attributes}.
+
+Storage_Size is not a measure of how much un-allocated space is
+left in the pool.
+That is, it includes both allocated and unallocated space.
+Implementations and users may provide a Storage_Available function
+for their pools, if so desired.
address@hidden
address@hidden
+
address@hidden, Sec=(of Storage_Size for
+a nonderived access-to-object type)}
address@hidden, Sec=(of Storage_Pool for
+a nonderived access-to-object type)}
address@hidden clause}
address@hidden clause}
+Storage_Size or Storage_Pool may be specified for
+a nonderived access-to-object type
+via an @address@hidden@!clause};
+the @nt{name} in a Storage_Pool clause shall denote a
address@hidden,address@hidden@AspectDefn{Storage_Size (access)}],Old=[]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Storage_Pool],
+    address@hidden,Text=[Pool of memory from which @key[new] will
+    allocate for a given access type.]}]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Storage_Size (access)],
+    address@hidden,Text=[Sets memory size for allocations for an
+      access type.]}]}
+
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0107-1],ARef=[AI05-0111-3],ARef=[AI05-0116-1]}
+An @nt{allocator} of @Chg{Version=[3],New=[a ],Old=[]}type @i<T>
address@hidden,New=[that does not support subpools ],Old=[]}allocates
+storage from @i<T>'s storage pool.
+If the storage pool is a user-defined object, then
+the storage is allocated by calling address@hidden,New=[ as described
+below. @nt{Allocator}s for types that support subpools are described
+in @RefSecNum{Storage Subpools}.],Old=[,
+passing T'Storage_Pool as the Pool parameter.
+The Size_In_Storage_Elements parameter indicates the number of storage elements
+to be allocated,
+and is no more than D'Max_Size_In_Storage_Elements,
+where D is the designated subtype.
+The Alignment parameter is D'Alignment.
address@hidden representation}
address@hidden representation}
+The result returned in the Storage_Address parameter is used by the
address@hidden as the address of the allocated storage,
+which is a contiguous block of memory of address@hidden@!Elements
+storage elements.
address@hidden exception propagated by Allocate is propagated by the
address@hidden
address@hidden
+If the implementation chooses to represent the designated
+subtype in multiple pieces,
+one @nt{allocator} evaluation might result in more than one call upon
+Allocate.
+In any case, @nt{allocator}s for the access type obtain all the required
+storage for an object of the designated type by calling the
+specified Allocate procedure.
+
address@hidden,Kind=[Deleted],ARef=[AI05-0107-1]}
address@hidden,Text=[Note that the implementation does not turn other
+exceptions into Storage_Error.]}
+
address@hidden,Kind=[Added],Ref=[8652/0111],ARef=[AI95-00103-01]}
address@hidden,Text=[If @i<D> (the designated type of @i<T>) includes
+subcomponents of other access types, they will be allocated from the storage
+pools for those types, even if those @nt{allocator}s are executed as part of
+the @nt{allocator} of @i<T> (as part of the initialization of the object). For
+instance, an access-to-task type @i<TT> may allocate the data structures used 
to
+implement the task value from other storage pools. (In particular, the task
+stack does not necessarily need to be allocated from the storage pool for
address@hidden<TT>.)]}
address@hidden
+
address@hidden storage pool}
+If Storage_Pool is not specified for a type defined by an
address@hidden,
+then the implementation chooses a standard storage pool for it
+in an implementation-defined manner.
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+In this case,
+the exception Storage_Error is raised by an @nt{allocator}
+if there is not enough storage.
+It is implementation defined whether or not the implementation
+provides user-accessible names for the standard pool type(s).
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,Text=[The
+manner of choosing a storage pool for an access type when
+Storage_Pool is not specified for the type.]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[The manner of choosing a storage pool is
+  covered by a @DocReqName below, so it is not summarized here.]}
address@hidden
address@hidden or not the implementation
+provides user-accessible names for the standard pool type(s).}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00230-01]}
address@hidden was never address@hidden,New=[],Old=[An anonymous access
+type has no pool. ]}An access-to-object type defined by a
address@hidden
+inherits its pool from its parent type, so
+all access-to-object types in the same derivation class share the same pool.
+Hence the @lquotes@;defined by an @address@hidden@; wording
+above.
+
address@hidden representation}
address@hidden representation}
+There is no requirement that all storage pools be implemented using a
+contiguous block of memory (although each allocation returns
+a pointer to a contiguous block of memory).
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI12-0043-1]}
+If Storage_Size is specified for an access address@hidden,New=[ @i<T>,
+an implementation-defined pool @i<P> is used for the type. The],Old=[, then 
the]}
+Storage_Size of @Chg{Version=[4],address@hidden<P>],Old=[this pool]} is at 
least
+that requested, and the storage for 
@Chg{Version=[4],address@hidden<P>],Old=[the pool]}
+is reclaimed when the master containing
+the declaration of the access type is left.
address@hidden,Sec=(raised by failure of run-time check)}
+If the implementation cannot satisfy the request, Storage_Error is raised at 
the
address@hidden,New=[freezing ],Old=[]}point of @Chg{Version=[4],New=[type
address@hidden<T>. The storage pool @i<P> is used only for allocators returning 
type @i<T>
+or other access types specified to use @i<T>'Storage_Pool. Storage_Error is
+raised by an @nt{allocator} returning such a type if the storage space of @i<P>
+is exhausted (additional memory is not allocated).],Old=[the
address@hidden@address@hidden If neither Storage_Pool nor Storage_Size
+are specified, then the meaning of Storage_Size is implementation defined.]}
+
address@hidden,Kind=[Added],ARef=[AI12-0043-1]}
address@hidden,Text=[If neither Storage_Pool nor Storage_Size are
+specified, then the meaning of Storage_Size is implementation defined.]}
+
address@hidden,Kind=[Revised],InitialVersion=[0],Text=[The meaning of
address@hidden, New=[ when neither the
+Storage_Size nor the Storage_Pool is specified for an access type],Old=[]}.]}
address@hidden
+The Storage_Size function and attribute will return the actual
+size, rather than the requested size.
+Comments about rounding up, zero, and negative
+on task Storage_Size apply here, as well.
+See also AI83-00557, AI83-00558, and AI83-00608.
+
+The expression in a Storage_Size clause
+need not be static.
+
+The reclamation happens after the master is finalized.
address@hidden
address@hidden
+For a pool allocated on the stack, normal stack cut-back can
+accomplish the reclamation.
+For a library-level pool, normal partition termination actions can
+accomplish the reclamation.
address@hidden
+
+If Storage_Pool is specified for an access type,
+then the specified pool is used.
+
address@hidden
+The effect of calling Allocate and Deallocate for a standard storage
+pool directly
+(rather than implicitly via an @nt{allocator} or an instance
+of Unchecked_Deallocation) is unspecified.
address@hidden
+For example, an @nt{allocator} might put the pool element on a
+finalization list.
+If the user directly Deallocates it, instead of calling an instance
+of Unchecked_Deallocation, then the implementation would probably try
+to finalize the object upon master completion,
+which would be bad news.
+Therefore, the implementation should define such situations as
+erroneous.
address@hidden
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)}
+If Storage_Pool is specified for an access type,
+then if Allocate can satisfy the request,
+it should allocate a contiguous block of memory,
+and return the address of the first storage element in Storage_Address.
+The block should contain Size_In_Storage_Elements storage elements,
+and should be aligned according to Alignment.
+The allocated storage should not be used for any
+other purpose while the pool element remains in existence.
+If the request cannot be satisfied,
+then Allocate should propagate an exception
address@hidden(such as Storage_Error)].
+If Allocate behaves in any other manner,
+then the program execution is erroneous.
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0107-1],ARef=[AI05-0262-1]}
address@hidden,Type=[Leading],Text=[The Allocate procedure of a
+user-defined storage pool object @i<P> may be called by the implementation only
+to allocate storage for a type @i<T> whose pool is @i<P>, only at the
+following points:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[During the execution of an @nt{allocator} of type
address@hidden<T>;]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This includes during the evaluation of the
+  initializing expression such as an @nt{aggregate}; this is important if the
+  initializing expression is built in place. We need to allow allocation to be
+  deferred until the size of the object is known.]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Text=[During the execution of a return statement for a
+function whose result is built-in-place in the result of an @nt{allocator}
+of type @i<T>;]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We need this bullet as well as the preceding one
+  in order that exceptions that propagate from such a call to Allocate can be
+  handled within the return statement. We don't want to require the generation
+  of special handling code in this unusual case, as it would add overhead to
+  most return statements of composite types.]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Text=[During the execution of an assignment operation with
+a target of an allocated object of type @i<T> with a part that has an
+unconstrained discriminated subtype with defaults.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We allow Allocate to be called during assignment
+  of objects with mutable parts so that mutable objects can be implemented with
+  reallocation on assignment. (Unfortunately, the term "mutable" is only 
defined
+  in the AARM, so we have to use the long-winded wording shown here.)]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Of course, explicit calls to Allocate are also
+  allowed and are not bound by any of the rules found here.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0107-1],ARef=[AI05-0116-1],ARef=[AI05-0193-1],ARef=[AI05-0262-1],ARef=[AI05-0269-1]}
address@hidden,Text=[For each of the calls of Allocate described above,
address@hidden (equivalent to @i{T}'Storage_Pool) is passed as the Pool 
parameter. The
+Size_In_Storage_Elements parameter indicates the number of storage elements to
+be allocated, and is no more than @i{D}'Max_Size_In_Storage_Elements, where
address@hidden is the designated subtype of @i{T}. The Alignment parameter is a 
nonzero
+integral multiple of @i{D}'Alignment if @i{D} is a specific type, and otherwise
+is a nonzero integral multiple of the alignment of the specific type identified
+by the tag of the object being created; it is
+unspecified if there is no such value. The Alignment parameter is no more than
address@hidden'Max_Alignment_For_Allocation. The result returned in the 
Storage_Address
+parameter is used as the address of the allocated storage, which is a 
contiguous
+block of memory of Size_In_Storage_Elements storage elements. @Redundant[Any
+exception propagated by Allocate is propagated by the construct that contained
+the call.]]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Note that the implementation does not turn other
+  exceptions into address@hidden from 13.11(16).}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],address@hidden@;Nonzero integral address@hidden
+  of an alignment includes the alignment value itself, of course. The
+  value is unspecified if the alignment of the specific type is zero.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0107-1]}
address@hidden,Text=[The number of calls to Allocate needed to implement
+an @nt{allocator} for any particular type is address@hidden
address@hidden representation}
address@hidden representation}
+The number of calls to Deallocate needed to implement an instance of
+Unchecked_Deallocation (see @RefSecNum{Unchecked Storage Deallocation}) for any
+particular object is the same as the number of Allocate calls for that 
object.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This supports objects that are allocated in one 
or
+  more parts. The second sentence prevents extra or missing calls to 
Deallocate.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[3],Text=[The number of calls to Deallocate from all 
sources
+  for an object always will be the same as the number of calls to Allocate from
+  all sources for that object. However, in unusual cases, not all of those
+  Deallocate calls may be made by an instance of Unchecked_Deallocation.
+  Specifically, in the unusual case of assigning to an object of a mutable
+  variant record type such that the variant changes, some of the Deallocate
+  calls may be made by the assignment (as may some of the Allocate calls).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We do not define the relative order of multiple
+  calls used to deallocate the same object @em that is, if the @nt{allocator}
+  allocated two pieces @i{x} and @i{y}, then an instance of 
Unchecked_Deallocation
+  might deallocate @i{x} and then @i{y}, or it might deallocate @i{y} and then
+  @address@hidden from 13.11.2}
address@hidden
+
+
address@hidden,Kind=[Added],ARef=[AI05-0107-1]}
address@hidden,Text=[The Deallocate procedure of a user-defined storage
+pool object @i{P} may be called by the implementation to deallocate storage 
for a
+type @i{T} whose pool is @i{P} only at the places when an Allocate call is 
allowed for
address@hidden, during the execution of an instance of Unchecked_Deallocation 
for @i{T}, or as
+part of the finalization of the collection of @i{T}. For such a call of 
Deallocate,
address@hidden (equivalent to @i{T}'Storage_Pool) is passed as the Pool 
parameter. The
+value of the Storage_Address parameter for a call to Deallocate is the value
+returned in the Storage_Address parameter of the corresponding successful call
+to Allocate. The values of the Size_In_Storage_Elements and Alignment 
parameters
+are the same values passed to the corresponding Allocate call. Any exception
+propagated by Deallocate is propagated by the construct that contained the
+call.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We allow Deallocate to be called anywhere that
+  Allocate is, in order to allow the recovery of storage from failed 
allocations
+  (that is, those that raise exceptions); from extended return statements that
+  exit via a goto, exit, or locally handled exception; and from objects that
+  are reallocated when they are assigned. In each of these cases, we would have
+  a storage leak if the implementation did not recover the storage (there is no
+  way for the programmer to do it). We do not require such recovery, however, 
as
+  it could be a serious performance drag on these operations.]}
address@hidden
address@hidden
+
address@hidden
+An implementation shall document
+the set of values that a user-defined Allocate procedure needs
+to accept for the Alignment parameter.
+An implementation shall document
+how the standard storage pool is chosen,
+and how storage is allocated by standard storage pools.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Implementation-defined aspects of storage pools.]}]}
address@hidden,Kind=[AddedNormal],address@hidden,Text=[
+The set of values that a user-defined Allocate procedure needs
+to accept for the Alignment parameter.
+How the standard storage pool is chosen, and how storage is allocated
+by standard storage pools.]}]}
address@hidden
+
address@hidden
+An implementation should document any cases in which it dynamically
+allocates heap storage for a purpose other than the evaluation of an
address@hidden
address@hidden,Kind=[Added],address@hidden,
+Text=[Any cases in which heap storage is dynamically allocated other than
+as part of the evaluation of an @nt{allocator} should be documented.]}]}
address@hidden
+This is @lquotes@;@address@hidden@; because the term @lquotes@;heap 
address@hidden@;
+is not formally definable;
+therefore, it is not testable whether the implementation obeys this advice.
address@hidden
+
+A default (implementation-provided) storage pool for an
+access-to-constant type should
+not have overhead to support deallocation of individual objects.
address@hidden,Kind=[Added],address@hidden,
+Text=[A default storage pool for an access-to-constant type should
+not have overhead to support deallocation of individual objects.]}]}
address@hidden
+Unchecked_Deallocation is not defined for
+such types. If the access-to-constant type is library-level,
+then no deallocation (other than at partition completion) will
+ever be necessary, so if the size needed by an @nt{allocator}
+of the type is known at link-time, then the allocation
+should be performed statically.
+If, in addition, the initial value of the designated object is known
+at compile time, the object can be allocated to read-only memory.
address@hidden
address@hidden
+If the Storage_Size for an access type is specified,
+the storage pool should consist of a contiguous block of memory,
+possibly allocated on the stack.
+The pool should contain approximately this number of
+storage elements.
+These storage elements should be reserved at the place of the
+Storage_Size clause,
+so that @nt{allocator}s cannot raise Storage_Error due to running out
+of pool space until the appropriate number of storage elements has
+been used up.
+This approximate (possibly rounded-up) value should be used as a maximum;
+the implementation should not increase the size of the pool on the fly.
+If the Storage_Size for an access type is specified as zero,
+then the pool should not take up any storage space,
+and any @nt{allocator} for the type should raise Storage_Error.
address@hidden
address@hidden
+Note that most of this is approximate,
+and so cannot be (portably) tested.
+That's why we make it an Implementation Note.
+There is no particular number of allocations that is guaranteed to
+succeed, and there is no particular number of allocations that is
+guaranteed to fail.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00230-01]}
address@hidden ChgAdded to get conditional address@hidden,
+Type=[Leading],address@hidden,New=[The],Old=[A]}
+storage pool @Chg{Version=[2],New=[used ],Old=[]}for
address@hidden,New=[an @nt{allocator} of ],Old=[]}an
+anonymous access type should be
address@hidden,New=[determined as follows:],Old=[created
+at the point of an allocator for the type, and be reclaimed when
+the designated object becomes inaccessible;]}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00230-01],ARef=[AI95-00416-01]}
address@hidden,Text=[If the @nt{allocator} is defining a
+coextension (see @RefSecNum{Operations of Access Types}) of an object
+being created by an outer @nt{allocator}, then
+the storage pool used for the outer @nt{allocator} should also be used for
+the coextension;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00230-01]}
address@hidden,Text=[For other access discriminants and access
+parameters, the storage pool should be created at the point of the
address@hidden, and be reclaimed when the allocated object becomes
+inaccessible;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0051-1]}
address@hidden,Text=[If the @nt{allocator} defines the result of a
+function with an access result, the storage pool is determined as though the
address@hidden were in place of the call of the function. If the call is the
+operand of a type conversion, the storage pool is that of the target access 
type
+of the conversion. If the call is itself defining the result of a function with
+an access result, this rule is applied recursively;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00230-01]}
address@hidden,Text=[Otherwise, a default storage pool should be
+created at the point where the anonymous access type is elaborated; such
+a storage pool need not support deallocation of individual objects.]}
address@hidden
+
address@hidden,Kind=[Added],address@hidden,
+Text=[Usually, a storage pool for an access discriminant or access parameter
+should be created at the point of an @nt{allocator}, and be reclaimed when
+the designated object becomes inaccessible. For other anonymous access types,
+the pool should be created at the point where the type is elaborated and need
+not support deallocation of individual objects.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00230-01]}
+  @Chg{Version=[2],New=[For access parameters and access discriminants,],
+  Old=[Normally]} the "storage pool" for an anonymous access type
+  would not @Chg{Version=[2],New=[normally ],Old=[]}exist as a separate
+  entity.
+  Instead, the designated object of the allocator
+  would be allocated, in the case of an access parameter,
+  as a local aliased variable at the call site, and in the
+  case of an access discriminant, contiguous with the object
+  containing the discriminant.
+  This is similar to the way storage for @nt{aggregate}s is typically
+  managed.
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01]}
+  @ChgAdded{Version=[2],Text=[For other sorts of anonymous access types, this
+  implementation is not possible in general, as the accessibility of the
+  anonymous access type is that of its declaration, while the @nt{allocator}
+  could be more nested. In this case, a "real" storage pool is required.
+  Note, however, that this storage pool need not support (separate)
+  deallocation, as it is not possible to instantiate Unchecked_Deallocation
+  with an anonymous access type. (If deallocation is needed, the object should
+  be allocated for a named access type and converted.) Thus, deallocation only
+  need happen when the anonymous access type itself goes out of scope;
+  this is similar to the case of an access-to-constant type.]}
address@hidden
address@hidden
+
address@hidden
+A user-defined storage pool type can be obtained by extending the
+Root_Storage_Pool type,
+and overriding the primitive subprograms Allocate, Deallocate, and
+Storage_Size.
+A user-defined storage pool can then be obtained by declaring
+an object of the type extension.
+The user can override Initialize and Finalize if there is any need
+for nontrivial initialization and finalization for a user-defined
+pool type.
+For example, Finalize might reclaim blocks of storage that are allocated
+separately from the pool object itself.
+
address@hidden@;The writer of the user-defined allocation and deallocation
+procedures, and users of @nt{allocator}s for the associated access
+type, are responsible for dealing with any interactions with
+tasking. In particular:
address@hidden
+  If the @nt{allocator}s are used in different tasks, they require
+mutual exclusion.
+
+ If they are used inside protected objects, they cannot block.
+
+ If they are used by interrupt handlers
+(see @RefSec{Interrupt Support}),
+the mutual exclusion mechanism has to work properly in that context.
+ @end{itemize}
+
+The primitives Allocate, Deallocate, and Storage_Size are declared as
+abstract (see @RefSecNum{Abstract Types and Subprograms}),
+and therefore they have to be overridden when
+a new (nonabstract) storage pool type is declared.
address@hidden
+Note that the Storage_Pool attribute denotes an object,
+rather than a value,
+which is somewhat unusual for attributes.
+
+The calls to Allocate, Deallocate, and Storage_Size are dispatching
+calls @em this follows from the fact that the actual parameter for
+Pool is T'Storage_Pool, which is of type Root_Storage_Pool'Class. In
+many cases (including all cases in which Storage_Pool is not
+specified), the compiler can determine the tag statically.
+However, it is possible to construct cases where it cannot.
+
+All access types in the same derivation class share the same pool,
+whether implementation defined or user defined.
+This is necessary because we allow type conversions among them
+(even if they are pool-specific),
+and we want pool-specific access values to always designate
+an element of the right pool.
address@hidden
address@hidden
+If an access type has a standard storage pool,
+then the implementation doesn't actually have to follow the pool
+interface described here,
+since this would be semantically invisible.
+For example, the allocator could conceivably be implemented with inline
+code.
address@hidden
address@hidden
+
address@hidden
address@hidden@;To associate an access type with a storage pool object, the user
+first declares a pool object of some type derived from
+Root_Storage_Pool. Then, the user defines its Storage_Pool
+attribute, as follows:
+
address@hidden
+Pool_Object : Some_Storage_Pool_Type;
+
address@hidden T @key[is] @key[access] Designated;
address@hidden T'Storage_Pool @key[use] Pool_Object;
address@hidden
+
address@hidden
address@hidden@;Another access type may be added to an existing storage pool, 
via:
address@hidden
address@hidden
address@hidden T2'Storage_Pool @key[use] T'Storage_Pool;
address@hidden
+
+The semantics of this is implementation defined
+for a standard storage pool.
address@hidden
+For example, the implementation is allowed to choose a storage pool
+for T that takes advantage of the fact that T is of a certain size.
+If T2 is not of that size, then the above will probably not work.
address@hidden
+
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0111-3]}
+As usual, a derivative of Root_Storage_Pool may define additional
+operations. For example, @Chg{Version=[3],New=[consider the],Old=[presuming 
that]}
+Mark_Release_Pool_Type @Chg{Version=[3],New=[defined in
address@hidden Subpool Example}, that ],Old=[]}has
+two additional operations, Mark and Release,
+the following is a possible use:
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0041],ARef=[AI95-00066-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0111-3]}
address@hidden Mark_Release_Pool_Type
+   (Pool_Size : address@hidden,New=[],Old=[;
+    Block_Size : Storage_Elements.Storage_Count]})
+        @key[is] @key[new] 
@Chg{Version=[3],New=[Subpools.Root_Storage_Pool_With_Subpools],Old=[Root_Storage_Pool]}
 @key[with @Chg{New=[],Old=[limited ]}private];@Chg{Version=[3],New=[
+           -- @Examcom{As defined in package MR_Pool, see @RefSecNum{Storage 
Subpool Example}}],Old=[]}
+
+...
+
address@hidden,Kind=[Revised],ARef=[AI05-0111-3]}
address@hidden,New=[Our_Pool],Old=[MR_Pool]} : Mark_Release_Pool_Type 
(Pool_Size => address@hidden,New=[],Old=[,
+                                  Block_Size => 100]});
address@hidden,New=[My_Mark : MR_Pool.Subpool_Handle; -- @Examcom{See 
@RefSecNum{Storage Subpool Example}}],Old=[]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0111-3]}
address@hidden Acc @key[is] @key[access] ...;
address@hidden Acc'Storage_Pool @key[use] 
@Chg{Version=[3],New=[Our_Pool],Old=[MR_Pool]};
+...
+
address@hidden,Kind=[Revised],ARef=[AI05-0111-3]}
address@hidden,New=[My_Mark := 
],Old=[]}Mark(@Chg{Version=[3],New=[Our_Pool],Old=[MR_Pool]});
+... address@hidden Allocate objects using @lquotes@;@key[new] 
@Chg{Version=[3],New=[(My_Mark) ],Old=[]}Designated(...)@rquotes@;.}
+Release(@Chg{Version=[3],New=[My_Mark],Old=[MR_Pool]}); address@hidden 
@Chg{Version=[3],New=[Finalize objects and reclaim],Old=[Reclaim the]} storage.}
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+User-defined storage pools are new to Ada 95.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0005-1],ARef=[AI05-0190-1]}
+Ada 83 @Chg{Version=[3],New=[originally introduced the],Old=[had a]}
+concept called a @lquotes@;collection,@rquotes@;
+which is similar to what we call a storage pool.
+All access types in the same derivation class
address@hidden,New=[share],Old=[shared]} the same collection.
address@hidden,New=[],Old=[In ]}Ada address@hidden,New=[ introduces
+the storage pool, which is similar in that],Old=[,]} all access types in the
+same derivation class
+share the same storage pool,
+but other (unrelated) access types can also share the same storage pool,
+either by default, or as specified by the user.
+A collection @Chg{Version=[3],New=[is],Old=[was]} an amorphous
address@hidden,New=[grouping],Old=[collection]}
+of address@hidden,New=[ (mainly used to describe finalization of
+access types)],Old=[]};
+a storage pool is a more concrete concept @em hence
+the different name.
+
+RM83 states the erroneousness of reading or updating deallocated
+objects incorrectly by missing various cases.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00435-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b<Amendment Correction:> Storage pools (and Storage_Size)
+  are not defined for access-to-subprogram types. The original Ada 95 wording
+  defined the attributes, but said nothing about their values.
+  If a program uses attributes Storage_Pool or Storage_Size on an
+  access-to-subprogram type, it will need to be corrected for Ada 2005.
+  That's a good thing, as such a use is a bug @em the concepts
+  never were defined for such types.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00161-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b[Amendment Correction:] Added @nt{pragma} Preelaborable_Initialization to
+  type Root_Storage_Pool, so that extensions of it can be used to declare
+  default-initialized objects in preelaborated units.]}
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0009],ARef=[AI95-00137-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added wording to specify 
that
+  these are representation attributes.]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[Added wording to clarify that an @nt{allocator}
+  for a coextension nested inside an outer @nt{allocator} shares
+  the pool with the outer @nt{allocator}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0051-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added the missing 
definition
+  of the storage pool of an @nt{allocator} for an anonymous access result 
type.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0107-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified when an 
implementation
+  is allowed to call Allocate and Deallocate, and the requirements on such
+  calls.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0111-3]}
+  @ChgAdded{Version=[3],Text=[Added wording to support subpools and refer to
+  the subpool example, see @RefSecNum{Storage Subpools}.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0116-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added wording to specify 
that the
+  alignment for an @nt{allocator} with a class-wide designated type comes from
+  the specific type that is allocated.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0193-1]}
+  @ChgAdded{Version=[3],Text=[Added wording to allow larger
+  alignments for calls to Allocate made by @nt{allocator}s,
+  up to Max_Alignment_For_Allocation. This eases implementation in some 
cases.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0043-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Tightened up the 
description of
+  the implementation-defined pool used when Storage_Size is specified. This
+  is not intended to change any implementation.]}
address@hidden
+
+
address@hidden,New=[Storage Allocation Attributes],
+Old=[The Max_Size_In_Storage_Elements Attribute]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0193-1]}
address@hidden Max_Size_In_Storage_Elements @Chg{Version=[3],New=[and
+Max_Alignment_For_Allocation attributes may be],Old=[attribute is]}
+useful in writing user-defined pool types.]
address@hidden
+
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0193-1]}
+For @PrefixType{every subtype S},
+the following @Chg{Version=[3],New=[attributes are],Old=[attribute is]} 
defined:
address@hidden
address@hidden,Kind=[Revised],ChginAnnex=[T],
+  Leading=<F>, Prefix=<S>, AttrName=<Max_Size_In_Storage_Elements>,
+  ARef=[AI95-00256-01],ARef=[AI95-00416-01],ARef=[AI05-0193-1],
+  InitialVersion=[0], Text=<Denotes the maximum value for
+Size_In_Storage_Elements
+that @Chg{Version=[2],New=[could],Old=[will]} be requested @Chg{Version=[2],
+New=[by the implementation ],Old=[]}via Allocate for an access type whose
+designated subtype is address@hidden,address@hidden,New=[],Old=[ For a type 
with access
+discriminants, if the implementation allocates space for a coextension
+in the same pool as that of the object having the access discriminant,
+then this accounts for any calls on Allocate that could be performed to
+provide space for such coextensions.]}],Old=[]}
+The value of this attribute is of type @i{universal_integer}.>}
address@hidden
+If S is an unconstrained array subtype,
+or an unconstrained subtype with discriminants,
+S'Max_Size_In_Storage_Elements might be very large.
address@hidden
+
address@hidden, Kind=[AddedNormal], ChginAnnex=[T], Leading=[F],
+  Prefix=<S>, AttrName=<Max_Alignment_For_Allocation>, ARef=[AI05-0193-1],
+  InitialVersion=[3], Text=<@Chg{Version=[3],New=[Denotes the maximum value for
+  Alignment that could be requested by the implementation via Allocate for
+  an access type whose designated subtype is S. The value of this attribute
+  is of type @i{universal_integer}.],Old=[]}>}
address@hidden
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0193-1]}
address@hidden,Text=[For a type with access discriminants, if the
+implementation allocates space for a coextension in the same pool as that of 
the
+object having the access discriminant, then these attributes account for any
+calls on Allocate that could be performed to provide space for such
+coextensions.]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0193-1]}
address@hidden,Text=[The values of these attributes should reflect only
+the calls that might be made to the pool specified for an access type with
+designated type S. Thus, if the coextensions would normally be
+allocated from a different pool than the one used for the main object (that is,
+the @ImplAdviceName of @RefSecNum{Storage Management} for determining the pool
+of an anonymous access discriminant is not followed), then these attributes
+should not reflect any calls on Allocate used to allocate the coextensions.]}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0193-1]}
address@hidden,Text=[Coextensions of coextensions of this type (and so on)
+are included in the values of these attributes if they are allocated from the
+same pool.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00256-01]}
+  @ChgAdded{Version=[2],Text=[Corrected the wording so that a
+  fortune-telling compiler that can see the future execution of the
+  program is not required.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0193-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}The
+  Max_Alignment_For_Allocation attribute is new.]}
address@hidden
+
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden Storage Deallocation}
+
address@hidden
address@hidden@Defn{unchecked storage deallocation}
address@hidden deallocation], Sec=(unchecked)}
address@hidden of storage}
address@hidden of storage}
address@hidden storage}
+Unchecked storage deallocation of an object designated by a value of an
+access type is achieved by a call to an instance of
+the generic procedure Unchecked_Deallocation.]
address@hidden
+
address@hidden
address@hidden@keepnext@;The following language-defined generic library 
procedure exists:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden
+   @key[type] Object(<>) @key[is] @key[limited] @key[private];
+   @key[type] Name   @key[is] @key[access]  Object;
address@hidden,address@hidden Ada.Unchecked_Deallocation(X : @key[in] @key[out] 
Name)@Chg{Version=[3],New=[
+   @key(with) Convention => Intrinsic;],Old=[;
address@hidden Convention(Intrinsic, Ada.Unchecked_Deallocation);]}
address@hidden Preelaborate(Ada.Unchecked_Deallocation);
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The @Chg{Version=[3],New=[aspect],address@hidden Convention implies that
+the attribute Access is not allowed
+for instances of Unchecked_Deallocation.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0157-1]}
address@hidden,Text=[A call on an instance of Unchecked_Deallocation is
+illegal if the actual access type of the instance is a type for which the
+Storage_Size has been specified by a static expression with value zero or is
+defined by the language to be zero.
address@hidden contract issue}In addition to the places where
address@hidden normally apply (see @RefSecNum{Generic Instantiation}),
+this rule applies also in the private part of an instance of a generic unit.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This rule is the same as the rule for
address@hidden We could have left the last sentence out, as a call to
+Unchecked_Deallocation cannot occur in a specification as it is a procedure
+call, but we left it for consistency and to avoid future maintenance hazards.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden@;Given an instance of Unchecked_Deallocation
+declared as follows:
address@hidden
address@hidden Free @key[is]
+    @key[new] Ada.Unchecked_Deallocation(
+        @RI[object_subtype_name], @RI[access_to_variable_subtype_name]);
address@hidden
+
address@hidden
address@hidden@Keepnext@;Procedure Free has the following effect:
address@hidden
address@hidden
+After executing Free(X), the value of X is @key{null}.
+
+Free(X), when X is already equal to @key{null}, has no effect.
+
address@hidden,Kind=[Revised],ARef=[AI95-00416-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0107-1]}
+Free(X), when X is not equal to @key{null} first
+performs address@hidden,New=[ of the object designated by X (and
+any coextensions of the object @em see @RefSecNum{Operations of Access 
Types})],
+Old=[]}, as described in
address@hidden,address@hidden and Finalization}],
address@hidden and Finalization}]}.
+It then deallocates the storage occupied by the object designated by
address@hidden,New=[ (and any coextensions)],Old=[]}.
+If the storage pool is a user-defined object, then
+the storage is deallocated by calling address@hidden,New=[ as described
+in @RefSecNum{Storage Management}],Old=[,
+passing @address@hidden@!subtype_name]'Storage_Pool as the Pool parameter.
+Storage_Address is the value returned in the Storage_Address parameter of the
+corresponding Allocate call.
address@hidden@!Elements and Alignment are the same values passed to the
+corresponding Allocate call]}.
+There is one exception: if the object being freed contains tasks,
+the object might not be deallocated.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0107-1]}
+Free calls only the specified Deallocate procedure
+to do address@hidden,New=[],Old=[ For any given
+object deallocation, the number of calls to Free (usually one)
+will be equal to the number of Allocate calls it took
+to allocate the object.
+We do not define the relative order of multiple calls used to deallocate
+the same object @em that is, if the @nt{allocator} allocated two pieces @i{x}
+and @i{y}, then Free might deallocate @i{x} and then @i{y},
+or it might deallocate @i{y} and then @i{x}.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00416-01]}
address@hidden,Kind=[Revised],ARef=[AI12-0148-1]}
address@hidden,See=(nonexistent)}
address@hidden
address@hidden,Sec=[cease to]}
address@hidden to exist],Sec=[object]}
+After @Chg{Version=[4],New=[the finalization step of ],Old=[]}Free(X), the
+object designated by X, and any subcomponents
address@hidden,New=[(and coextensions) ],Old=[]}thereof, no
+longer exist; their storage can be reused for other purposes.
address@hidden
+
address@hidden
address@hidden@PDefn2{Term=(bounded error),Sec=(cause)}
+It is a bounded error to free a discriminated, unterminated
+task object. The possible consequences are:
address@hidden
+  This is an error because the task might refer to its discriminants,
+  and the discriminants might be deallocated by freeing the task object.
address@hidden
address@hidden
+No exception is raised.
+
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,Sec=(raised by failure of run-time check)}
+Program_Error or Tasking_Error is raised at the point of the
+deallocation.
+
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,Sec=(raised by failure of run-time check)}
+Program_Error or Tasking_Error is raised in the task the next time it
+references any of the discriminants.
address@hidden
+  This last case presumes an implementation where the task references
+  its discriminants indirectly,
+  and the pointer is nulled out when the task object is deallocated.
address@hidden
address@hidden
+
+In the first two cases,
+the storage for the discriminants
+(and for any enclosing object if it is designated by an access
+discriminant of the task)
+is not reclaimed prior to task termination.
address@hidden
+  The storage might never be reclaimed.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0148-1]}
address@hidden,Text=[An access value that designates a nonexistent object is 
called a
address@hidden<dangling reference>address@hidden 
address@hidden,Sec=[dangling]}]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[These can result from use of
+    Unchecked_Deallocation, Unchecked_Deallocate_Subpool, and attribute
+    Unchecked_Access. Bad results from Unchecked_Conversion and from
+    stream-oriented attributes are abnormal by @RefSecNum{Data Validity},
+    which is stronger and thus takes precedence.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0148-1]}
address@hidden,address@hidden a dangling reference is dereferenced
+(implicitly or explicitly), execution is erroneous (see below).] If there is
+no explicit or implicit dereference, then it is a bounded error
address@hidden@PDefn2{Term=(bounded error),Sec=(cause)}to evaluate an
+expression whose result is a dangling reference. If the error is detected,
+either Constraint_Error or Program_Error is raised.
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,Sec=(raised by failure of run-time check)}
+Otherwise, execution
+proceeds normally, but with the possibility that the access value designates
+some other existing object.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[If a dangling reference is compared with another
+    access value, a result of either True or False is allowed. We need to allow
+    this so that simple implementations of access values (for instance, as a
+    bare address) can work if the memory in question is reused. (The formal
+    definition of access equality is that it returns True if both access values
+    designate the same object; that can never be True if one of the values is a
+    dangling reference, and the other is not, but both values could refer to 
the
+    same memory.) Membership tests that do not involve an implicit dereference
+    generally do not depend on the access value at all.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[We allow Constraint_Error to be raised here so
+    that dangling reference and null pointer checks can be combined into a
+    single check. If different exceptions are required, then the checks have to
+    be made separately - but there's little semantic difference (neither
+    designate a usable object).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[If a dangling reference is assigned into an
+    object, including being passed to a formal parameter, that object also
+    contains a dangling reference afterwards.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[For equality and membership operations on
+    composite types, this applies to any parts that are access types, as these
+    operations are created based on the operations of the components (which
+    triggers the bounded error). For other operations on composite types, the
+    bounded error is not triggered. For instance, an assignment of a composite
+    object with a subcomponent that is a dangling reference has to work
+    normally; no exception can be raised, but the target object will have a
+    subcomponent that is a dangling references, and a (direct) use of that
+    subcomponent is again a bounded error. This is similar to the way that
+    assignments of invalid subcomponents are handled (see
+    @RefSecNum{Data Validity}).]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0033-1],ARef=[AI05-0262-1]}
address@hidden@PDefn2{Term=(erroneous execution),Sec=(cause)}
+Evaluating a name that denotes a nonexistent address@hidden,
+New=[, or a protected subprogram or subprogram renaming whose
+associated object (if any) is nonexistent, ],Old=[]}is erroneous.
+The execution of a call to an instance of Unchecked_Deallocation is
+erroneous if the object was created other than by an @nt<allocator> for
+an access type whose pool is Name'Storage_Pool.
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0033-1],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Text=[The part about a protected subprogram is intended
+  to cover the case of an access-to-protected-subprogram where the associated
+  object has been deallocated. The part about a subprogram renaming is intended
+  to cover the case of a renaming of a prefixed view where the prefix object 
has
+  been deallocated, or the case of a renaming of an entry or protected
+  subprogram where the associated task or protected object has been
+  deallocated.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0157-1]}
+  @ChgAdded{Version=[3],Text=[This text does not cover the case of
+  a name that contains a null access value, as @key[null] does not
+  denote an object (rather than denoting a nonexistent object).]}
address@hidden
+
address@hidden
+
address@hidden
+For a standard storage pool,
+Free should actually reclaim the storage.
address@hidden,Kind=[Added],address@hidden,
+Text=[For a standard storage pool, an instance of Unchecked_Deallocation
+should actually reclaim the storage.]}]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+  This is not a testable property,
+  since we do not @Chg{Version=[2],New=[know ],Old=[]}how much storage is used
+  by a given pool element, nor whether fragmentation can occur.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0157-1]}
address@hidden,Text=[A call on an instance of Unchecked_Deallocation with
+a nonnull access value should raise Program_Error if the actual access type of
+the instance is a type for which the Storage_Size has been specified to be zero
+or is defined by the language to be zero.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[A call on an instance of Unchecked_Deallocation with
+a nonnull access value should raise Program_Error if the actual access type of
+the instance is a type for which the Storage_Size has been specified to be zero
+or is defined by the language to be zero.]}]}
address@hidden
+  @ChgAdded{Version=[3],Text=[If the call is not illegal (as in a generic 
body), we
+  recommend that it raise Program_Error. Since the execution of this call is
+  erroneous (any allocator from the pool will have raised Storage_Error, so
+  the nonnull access value must have been allocated from a different pool or
+  be a stack-allocated object), we can't require any behavior @em anything at
+  all would be a legitimate implementation.]}
address@hidden
address@hidden
+
address@hidden
+The rules here that refer to Free apply to any instance
+of Unchecked_Deallocation.
+
+Unchecked_Deallocation cannot be instantiated for an
+access-to-constant type.
+This is implied by the rules of @RefSecNum{Formal Access Types}.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00416-01]}
+  @ChgAdded{Version=[2],Text=[The rules for coextensions are clarified
+  (mainly by adding that term). In theory, this reflects no change from
+  Ada 95 (coextensions existed in Ada 95, they just didn't have a name).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0033-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a rule that using
+  an access-to-protected-subprogram is erroneous if the associated
+  object no longer exists. It is hard to imagine an alternative meaning here,
+  and this has no effect on correct programs.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0107-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Moved the requirements
+  on an implementation-generated call to Deallocate to
+  @RefSecNum{Storage Management}, in order to put all of the rules
+  associated with implementation-generated calls to Allocate and Deallocate
+  together.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0157-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added wording so that 
calling
+  an instance of Unchecked_Deallocation is treated similarly to @nt{allocator}s
+  for access types where @nt{allocator}s would be banned.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0148-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada 2012}
+  @b<Corrigendum:> Defined a "dangling reference", and specified that
+  a dangling reference might designate some other existing object.
+  This allows simple implementations of access values and reuse of
+  object memory after deallocation. In prior versions of Ada, "=" between
+  a dangling reference and an access to an existing object has to return
+  False, even if the existing object and the object designated by the
+  dangling reference are
+  allocated in the same memory. A program that depended upon that could break
+  with this revised rule. However, as a practical matter, almost all Ada
+  implementations use simple implementations of access types that do not meet
+  that requirement. So such a program would not work (consistently) on
+  most Ada implementations; thus the change shouldn't break any existing
+  programs - it just aligns the Standard with actual practice.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0148-1]}
+  @ChgAdded{Version=[4],Text=[A side effect of this change is to allow an
+  Ada implementation to detect dangling references in more places. This
+  does not require any Ada implementation to change, and if the implementation
+  does change, it just means that errors will be detected earlier.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0148-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that deallocated
+  objects cease to exist after finalization but before Deallocate is called.
+  This is necessary to prevent erroneous execution from being triggered by
+  the rules in @RefSecNum{Storage Management} in the time between the end
+  of finalization and the end of the call to the instance of
+  Unchecked_Deallocation.]}
address@hidden
+
+
+
+
address@hidden,New=[Default Storage Pools],
+Old=[Pragma Controlled]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0003-1]}
address@hidden,address@hidden,address@hidden and aspect
+Default_Storage_Pool specify the storage pool that
+will be used in the absence of an explicit specification of a storage pool or
+storage size for an access type.]],Old=[]}],address@hidden Controlled
+is used to prevent
+any automatic reclamation of storage (garbage collection) for the objects
+created by @nt<allocator>s of a given access type.]]}
address@hidden
+
address@hidden
address@hidden
address@hidden@address@hidden,Kind=[Revised],ARef=[AI05-0190-1],ARef=[AI05-0229-1]}
+The form of a @nt{pragma} 
@Chg{Version=[3],New=[Default_Storage_Pool],Old=[Controlled]}
+is as follows:
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0190-1],ARef=[AI05-0229-1]}
address@hidden<Version=[3],@Chg{Version=[3],
address@hidden @prag<Default_Storage_Pool> 
(@Syn2{storage_pool_indicator});],Old=[]}>
address@hidden<Version=[3],InitialVersion=[0],@Chg{Version=[3],New=[],
address@hidden @prag(Controlled)(@address@hidden);]}>
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Text=[Not to be confused with type
+Finalization.Controlled.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0190-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0003-1]}
address@hidden,lhs=<@Chg{Version=[3],New=<storage_pool_indicator>,Old=<>}>,
+rhs="@Chg{Version=[3],New=<@address@hidden | @address@hidden,New=< | 
Standard>,Old=<>}>,Old=<>}"}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0190-1]}
address@hidden,Text=[A @nt{pragma} Default_Storage_Pool is allowed
+immediately within the visible part of a @nt{package_specification}, 
immediately
+within a @nt{declarative_part}, or as a configuration pragma.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0190-1]}
address@hidden,Text=[The @address@hidden is expected to be
+of type Root_Storage_Pool'Class.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0190-1],ARef=[AI05-0229-1]}
address@hidden,New=[The @address@hidden shall denote a variable.],
+Old=[The @address@hidden<local_name> of a @nt{pragma} Controlled
+shall denote a nonderived access subtype.]}
+
address@hidden,Kind=[Added],ARef=[AI12-0003-1]}
address@hidden,Text=[The Standard @nt{storage_pool_indicator} is an
+identifier specific to a pragma (see @RefSecNum{Pragmas}) and does not denote
+any declaration. If the @nt{storage_pool_indicator} is Standard, then there
+shall not be a declaration with @nt{defining_identifier} Standard that is
+immediately visible at the point of the pragma, other than package Standard
+itself.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Text=[We considered having the Standard
+  @nt{storage_pool_indicator} resolve to package Standard rather than
+  being an identifier specific to a pragma. That would eliminate the need for a
+  special check. But it would be bizarre to have something that could resolve 
to
+  either an object or a (single) package, and resolving to package Standard
+  would imply that the standard pool is an object declared in that package. A
+  storage pool object must be a variable (see @RefSecNum{Storage Management}),
+  yet preelaborable packages depend on package Standard, which would require
+  implementers to implement the standard storage pool with
+  Preelaborable_Initialization, which is an unnecessary restriction.]}
+
+  @ChgRef{Version=[4],Kind=[Added]}
+  @ChgAdded{Version=[4],Text=[No declaration of Standard can ever be
+    use-visible, as the language-defined nonoverloadable definition of
+    Standard will hide any use-visible declarations. Thus we need only concern
+    ourselves with eliminating any possible confusion with regard to
+    immediately visible declarations with the @nt{defining_identifier} 
Standard.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0190-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0003-1]}
address@hidden,Text=[If the @nt{pragma} is used as a configuration pragma,
+the @nt{storage_pool_indicator} shall address@hidden,New=[ either],Old=[]}
address@hidden@Chg{Version=[4],New=[ or Standard],Old=[]}, and it defines the
address@hidden<default pool>@Defn{default address@hidden 
pool],address@hidden,Sec=[default]} to
+be @Chg{Version=[4],New=[the given 
@nt{storage_pool_indicator}],address@hidden<null>]}
+within all
+applicable compilation units (see @RefSecNum{Pragmas and Program Units}),
+except within the immediate scope of
+another @nt{pragma} Default_Storage_Pool. Otherwise, @Redundant[the pragma
+occurs immediately within a sequence of declarations, and] it defines the
+default pool within the immediate scope of the pragma to be
address@hidden,New=[the given @nt{storage_pool_indicator}],Old=[either
address@hidden or the pool denoted by the @address@hidden, except
+within the immediate scope of a later pragma Default_Storage_Pool.
address@hidden, an inner pragma overrides an outer one.]]}
+
address@hidden,Kind=[Added],ARef=[AI05-0190-1],ARef=[AI05-0262-1]}
address@hidden,address@hidden to mark the fact that the paragraph number 
changed}
address@hidden,Text=[A @nt{pragma} Default_Storage_Pool shall not be used
+as a configuration pragma that applies to a compilation unit that is within the
+immediate scope of another @nt{pragma} Default_Storage_Pool.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[This is to prevent confusion in 
cases like this:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Parent @key[is]
+   pragma Default_Storage_Pool(...);
+   ...
address@hidden Parent;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Default_Storage_Pool(...); address@hidden 
Illegal!}
address@hidden Parent.Child @key[is]
+   ...
address@hidden Parent.Child;]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[where the Default_Storage_Pool
+  on Parent.Child would not (if it were legal) override the one in Parent.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0190-1],ARef=[AI05-0229-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0003-1]}
address@hidden,New=[The language-defined aspect Default_Storage_Pool may be
+specified for a generic instance; it defines the default pool for
+access types within an address@hidden
address@hidden,New=[],Old=[The expected type for the
+Default_Storage_Pool aspect is Root_Storage_Pool'Class. The 
@nt{aspect_definition}
+must be a @nt{name} that denotes a variable. This aspect overrides any
+Default_Storage_Pool pragma that might apply to the generic unit; if the aspect
+is not specified, the default pool of the instance is that defined for the
+generic unit]}],
address@hidden pragma], Sec=(Controlled)}
address@hidden, representation], Sec=(Controlled)}
+A @nt{pragma} Controlled is a representation pragma
address@hidden of representation], Sec=(controlled)}
address@hidden, Sec=(aspect of representation)}
+that specifies the @i{controlled} aspect of representation]}.
+
address@hidden,Kind=[Added],ARef=[AI12-0003-1]}
address@hidden,Text=[The Default_Storage_Pool aspect may be specified as
+Standard, which is an identifier specific to an aspect (see
address@hidden Specifications}) and defines the default pool to be
+Standard. In this case, there shall not be a declaration with
address@hidden Standard that is immediately visible at the point
+of the aspect specification, other than package Standard itself.]}
+
address@hidden,Kind=[Added],ARef=[AI12-0003-1]}
address@hidden,Text=[Otherwise, the expected type for the
+Default_Storage_Pool aspect is Root_Storage_Pool'Class and the 
@nt{aspect_definition}
+shall be a @nt{name} that denotes a variable. This aspect overrides any
+Default_Storage_Pool pragma that might apply to the generic unit; if the aspect
+is not specified, the default pool of the instance is that defined for the
+generic unit.]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Default_Storage_Pool],
+    address@hidden,Text=[Default storage pool for a generic instance.]}]}
+
address@hidden,Kind=[Added],ARef=[AI12-0136-1]}
address@hidden,Text=[The effect of specifying the aspect
+Default_Storage_Pool on an instance of a language-defined generic unit is
+implementation-defined.]}
+
+  @ChgImplDef{Version=[4],Kind=[Added],
+    address@hidden,Text=[The effect of specifying aspect
+    Default_Storage_Pool on an instance of a language-defined generic unit.]}]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0190-1],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],address@hidden leading}
address@hidden,New=[For nonderived access types declared in places where the
+default pool is defined by the pragma or aspect, their Storage_Pool or
+Storage_Size attribute is determined as follows, unless Storage_Pool or
+Storage_Size is specified for the type:],
address@hidden collection}
address@hidden collection} is a process that automatically reclaims storage,
+or moves objects to a different address,
+while the objects still exist.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0190-1]}
+  @ChgAdded{Version=[3],Text=[If the default pool is @key[null], the
+  Storage_Size attribute is defined by the language to be zero.
+  @Redundant[Therefore, an @nt{allocator} for such a type is illegal.]]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0190-1]}
+  @ChgRef{Version=[4],Kind=[RevisedAdded],ARef=[AI12-0003-1]}
+  @ChgAdded{Version=[3],Text=[If the default pool is 
@Chg{Version=[4],New=[neither
+  @key[null] nor Standard],Old=[nonnull]}, the Storage_Pool
+  attribute is that pool.]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0190-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0003-1]}
address@hidden,address@hidden,New=[ (including when
+the default pool is specified as Standard),],Old=[, there is no
+default pool;]} the standard storage
+pool is used for the type as described in @RefSecNum{Storage Management}.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0190-1],ARef=[AI05-0229-1]}
+  @Chg{Version=[3],New=[Default_Storage_Pool is the only way to specify the
+  storage pool for an anonymous access type],
+  Old=[Storage reclamation upon leaving a master is not considered garbage
+  collection]}.
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0190-1],ARef=[AI05-0229-1]}
+  Note that @Chg{Version=[3],New=[coextensions should be allocated in the same
+  pool (or on the stack) as the outer object (see @RefSecNum{Storage 
Management});
+  the Storage_Pool of the access discriminant
+  (and hence the Default_Storage_Pool) is supposed to be ignored for
+  coextensions. This matches the required finalization point for coextensions],
+  Old=[garbage collection includes compaction of a pool (@lquotes@;moved to
+  a different address@hidden@;), even if storage reclamation is not done]}.
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0190-1]}
+  @ChgAdded{Version=[3],Text=[The default storage pool for an allocator that
+  occurs within an instance of a generic is defined by the Default_Storage_Pool
+  aspect of the instantiation (if specified), or by the Default_Storage_Pool
+  pragma that applied to the generic; the Default_Storage_Pool pragma that 
applies
+  to the instantiation is irrelevant.]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0190-1]}
+  @ChgAdded{Version=[3],Text=[It is possible to specify the 
Default_Storage_Pool
+  aspect for an instantiation such that allocations will fail. For example, the
+  generic unit might be expecting a pool that supports certain sizes and
+  alignments, and the one on the instance might be more restrictive. It is the
+  programmer's responsibility to get this right.]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0190-1]}
+  @ChgAdded{Version=[3],Text=[The semantics of the Default_Storage_Pool aspect 
are
+  similar to passing a pool object as a generic formal, and putting pragma
+  Default_Storage_Pool at the top of the generic's visible part, specifying 
that
+  formal.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
+  @ChgDeleted{Version=[3],Text=[Programs that will be damaged by automatic 
storage
+  reclamation are just as likely to be damaged by having objects moved to
+  different locations in memory. A @nt{pragma} Controlled should turn off both
+  flavors of garbage collection.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
+  @ChgDeleted{Version=[3],Text=[If garbage collection reclaims the storage of
+  a controlled object, it should first finalize it.
+  Finalization is not done when moving an object;
+  any self-relative pointers will have to be updated by the garbage
+  collector.
+  If an implementation provides garbage collection
+  for a storage pool containing controlled objects
+  (see @RefSecNum{Assignment and Finalization}),
+  then it should provide a means for deferring garbage collection of
+  those controlled objects.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
+  @ChgDeleted{Version=[3],Type=[Leading],Text=[This allows the manager of a
+  resource released by a Finalize operation to defer garbage collection during
+  its critical regions; it is up to the author of the Finalize operation to do
+  so. Garbage collection, at least in some systems, can happen asynchronously
+  with respect to normal user code. Note that it is not enough to defer garbage
+  collection during Initialize, Adjust, and Finalize, because the resource in
+  question might be used in other situations as well. For example:]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden Ada.Finalization;
address@hidden P @key[is]]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[    @key[type] My_Controlled @key[is]
+        @key[new] Ada.Finalization.Limited_Controlled @key[with] @key[private];
+    @key[procedure] Finalize(Object : @key[in] @key[out] My_Controlled);
+    @key[type] My_Controlled_Access @key[is] @key[access] My_Controlled;]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[    @key[procedure] Non_Reentrant;]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden
+    ...
address@hidden P;]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden @key[body] P @key[is]
+    X : Integer := 0;
+    A : @key[array](Integer @key[range] 1..10) @key[of] Integer;]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[    @key[procedure] Non_Reentrant @key[is]
+    @key[begin]
+        X := X + 1;
+        address@hidden If the system decides to do a garbage collection here,}
+        address@hidden then we're in trouble, because it will call Finalize on}
+        address@hidden the collected objects; we essentially have two threads}
+        address@hidden of control erroneously accessing shared variables.}
+        address@hidden The garbage collector behaves like a separate thread}
+        address@hidden of control, even though the user hasn't declared}
+        address@hidden any tasks.}
+        A(X) := ...;
+    @key[end] Non_Reentrant;]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[    @key[procedure] Finalize(Object : @key[in] @key[out] 
My_Controlled) @key[is]
+    @key[begin]
+        Non_Reentrant;
+    @key[end] Finalize;
address@hidden P;]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden P; @key[use] P;
address@hidden Main @key[is]
address@hidden
+    ... @key[new] My_Controlled ... address@hidden allocate some objects}
+    ... @Examcom{ forget the pointers to some of them, so they become garbage}
+    Non_Reentrant;
address@hidden Main;]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[3],Text=[It is the user's responsibility to protect
+  against this sort of thing, and the implementation's responsibility to 
provide
+  the necessary operations.]}
+
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[3],Text=[We do not give these operations names,
+  nor explain their exact semantics,
+  because different implementations of garbage collection might have
+  different needs, and because garbage collection is not supported by
+  most Ada implementations, so portability is not important here.
+  Another reason not to
+  turn off garbage collection during each entire
+  Finalize operation is that it would create a serial bottleneck;
+  it might be only part of the Finalize operation that conflicts with
+  some other resource.
+  It is the intention that the mechanisms provided be finer-grained
+  than pragma Controlled.]}
address@hidden
+
address@hidden,Kind=[Deleted],ARef=[AI05-0229-1]}
address@hidden,Text=[If a @nt{pragma} Controlled is specified
+for an access type with a standard storage pool,
+then garbage collection is not performed for objects in that pool.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
+  @ChgDeleted{Version=[3],Text=[If Controlled is not specified,
+  the implementation may, but need not, perform garbage
+  collection. If Storage_Pool is specified,
+  then a @nt{pragma} Controlled for that type is ignored.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
+  @ChgDeleted{Version=[3],Text=[Controlled means that implementation-provided
+  garbage collection is turned off;
+  if the Storage_Pool is specified, the pool controls
+  whether garbage collection is done.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0190-1],ARef=[AI05-0229-1]}
address@hidden,New=[An object created by an @nt{allocator} that is passed as
+the actual parameter to an access parameter may be allocated on the stack, and
+automatically reclaimed, regardless of the default pool],
+Old=[An implementation need not support garbage collection, in
+which case, a pragma Controlled has no effect]}.
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0190-1]}
+  @ChgAdded{Version=[3],Text=[This matches the required finalization point for
+  such an allocated object.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0190-1]}
address@hidden,Text=[Default_Storage_Pool may be used with restrictions 
No_Coextensions and
+No_Access_Parameter_Allocators (see @RefSecNum{High Integrity Restrictions})
+to ensure that all @nt{allocator}s use the default pool.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Deleted],ARef=[AI05-0229-1]}
+  @ChgDeleted{Version=[3],Text=[Ada 83 used the term @lquotes@;automatic 
storage
+  address@hidden@; to refer to what is known traditionally as
+  @lquotes@;garbage address@hidden@;. Because of the existence of storage
+  pools (see @RefSecNum{Storage Management}), we need to distinguish this from
+  the storage reclamation that might happen upon leaving a master. Therefore, 
we
+  now use the term @lquotes@;garbage address@hidden@; in its normal
+  computer-science sense. This has the additional advantage of making our
+  terminology more accessible to people outside the Ada world.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 95}Pragma
+  Controlled has been dropped from Ada,
+  as it has no effect in any known Ada implementations and it seems to promise
+  capabilities not expected in Ada implementations. This is usually not an
+  incompatibility, as the pragma merely becomes unrecognized (with a warning)
+  and can be implemented as an implementation-defined pragma if desired. 
However,
+  it is incompatible if it is (now) implemented as an implementation-defined
+  pragma, someone used this pragma in a unit, and they
+  also used restriction No_Implementation_Pragmas on that unit. In that
+  case, the pragma would now violate the restriction; but use of this pragma
+  (which does nothing) should be very rare, so this is not a significant
+  issue.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0190-1]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}The
+  pragma Default_Storage_Pool @Chg{Version=[4],New=[and aspect
+  Default_Storage_Pool are],Old=[is]} new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[The entire discussion of garbage collection
+  (and especially that of controlled objects) is deleted. Ada 2012 provides
+  subpools (see @RefSecNum{Storage Subpools}) for storage management of 
objects,
+  including controlled objects, a mechanism which is much more predictable
+  than garbage collection. Note that no version of Ada allows early
+  finalization of controlled objects (other than via the use of
+  Unchecked_Deallocation or Unchecked_Deallocate_Subpool), so that garbage
+  collection of such objects would be ineffective in the standard mode 
anyway.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0003-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada address@hidden<Corrigendum:>
+  The @nt{storage_pool_indicator} Standard is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0136-1]}
+  @ChgAdded{Version=[4],address@hidden:} We now explicitly say that
+  the behavior of language-defined generic units when given the
+  Default_Storage_Pool aspect is implementation-defined. Portable code
+  cannot rely on such a package using a particular pool implementation.]}
address@hidden
+
+
address@hidden,Name=[Storage Subpools]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Text=[This subclause defines a package to support the
+partitioning of a storage pool into subpools. A subpool may be specified as the
+default to be used for allocation from the associated storage pool, or a
+particular subpool may be specified as part of an @nt{allocator}
+(see @RefSecNum{Allocators}).]}
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Text=[The following language-defined library package
+exists:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden,address@hidden System.Storage_Pools.Subpools 
@key[is]
+   @key[pragma] Preelaborate (Subpools);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] 
@AdaTypeDefn{Root_Storage_Pool_With_Subpools} @key[is]
+      @key[abstract new] Root_Storage_Pool @key[with private];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Root_Subpool} @key[is abstract 
tagged limited private];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Subpool_Handle} @key[is access 
all] Root_Subpool'Class;
+   @key[for] Subpool_Handle'Storage_Size @key[use] 0;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Create_Subpool} (Pool : 
@key[in out] Root_Storage_Pool_With_Subpools)
+      @key[return not null] Subpool_Handle @key[is abstract];]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0252-1]}
address@hidden,Text=[   -- @Examcom{The following operations are intended for 
pool implementers:}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Pool_of_Subpool} (Subpool : 
@key[not null] Subpool_Handle)
+      @key[return access] Root_Storage_Pool_With_Subpools'Class;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Set_Pool_of_Subpool} (
+      Subpool : @key[in not null] Subpool_Handle;
+      To : @key[in out] Root_Storage_Pool_With_Subpools'Class);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Allocate_From_Subpool} (
+      Pool : @key[in out] Root_Storage_Pool_With_Subpools;
+      Storage_Address : @key[out] Address;
+      Size_In_Storage_Elements : @key[in] Storage_Elements.Storage_Count;
+      Alignment : @key[in] Storage_Elements.Storage_Count;
+      Subpool : @key[in not null] Subpool_Handle) @key[is abstract]
+         @key[with] Pre'Class => Pool_of_Subpool(Subpool) = Pool'Access;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Deallocate_Subpool} (
+      Pool : @key[in out] Root_Storage_Pool_With_Subpools;
+      Subpool : @key[in out] Subpool_Handle) @key[is abstract]
+         @key[with] Pre'Class => Pool_of_Subpool(Subpool) = Pool'Access;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0298-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Default_Subpool_for_Pool} (
+      Pool : @key[in out] Root_Storage_Pool_With_Subpools)
+         @key[return not null] Subpool_Handle;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[overriding]
+   @key[procedure] @AdaSubDefn{Allocate} (
+      Pool : @key[in out] Root_Storage_Pool_With_Subpools;
+      Storage_Address : @key[out] Address;
+      Size_In_Storage_Elements : @key[in] Storage_Elements.Storage_Count;
+      Alignment : @key[in] Storage_Elements.Storage_Count);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[overriding]
+   @key[procedure] @AdaSubDefn{Deallocate} (
+      Pool : @key[in out] Root_Storage_Pool_With_Subpools;
+      Storage_Address : @key[in] Address;
+      Size_In_Storage_Elements : @key[in] Storage_Elements.Storage_Count;
+      Alignment : @key[in] Storage_Elements.Storage_Count) @key[is null];]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0298-1]}
address@hidden,Text=[   @key[overriding]
+   @key[function] @AdaSubDefn{Storage_Size} (Pool : 
Root_Storage_Pool_With_Subpools)
+      @key[return] Storage_Elements.Storage_Count
+          @key[is] (Storage_Elements.Storage_Count'Last);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[private
+   ... -- @Examcom{not specified by the language}
+end System.Storage_Pools.Subpools;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,address@hidden@Defn2{Term=[pool],Sec={subpool}}
address@hidden address@hidden,Sec=[subpool]}
address@hidden pool that supports subpools}A @i<subpool> is
+a separately reclaimable portion of a storage pool, identified by
+an object of type Subpool_Handle (a @i<subpool handle>). A subpool handle also
+identifies the enclosing storage pool, a @i<storage pool that supports 
subpools>,
+which is a storage pool whose type is descended from
+Root_Storage_Pool_With_Subpools. A subpool is created by calling Create_Subpool
+or a similar constructor; the constructor returns the subpool handle.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3],ARef=[AI05-0269-1]}
address@hidden,Text=[A @i<subpool object> is an object of a type
+descended from Root_Subpool. @Redundant[Typically, subpool objects are
+managed by the containing storage pool; only the handles need be exposed to
+clients of the storage pool. Subpool objects are designated by subpool handles,
+and are the run-time representation of a subpool.]]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We know that subpool handles designate
+  subpool objects because the declaration of Subpool_Handle says so.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Kind=[Revised],ARef=[AI05-0145-1]}
address@hidden,Text=[Each subpool @i<belongs>@Defn2{Term=[belongs],Sec=[subpool 
to a pool]}
+to a single storage pool @Redundant[(which will always be a pool
+that supports subpools)]. An access to the pool that a subpool belongs to can
+be obtained by calling Pool_of_Subpool with the subpool handle.
+Set_Pool_of_Subpool causes the subpool of the subpool handle to belong to the
+given address@hidden; this is intended to be called from subpool constructors
+like Create_Subpool.] Set_Pool_of_Subpool propagates Program_Error if the
+subpool already belongs to a address@hidden,New=[ If Set_Pool_of_Subpool
+has not yet been called for a subpool, Pool_of_Subpool returns
address@hidden,Old=[]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Pool_of_Subpool and Set_Pool_of_Subpool are
+  provided by the Ada implementation and typically will not be overridden by 
the
+  pool implementer.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Text=[When an @nt{allocator} for a type whose storage pool
+supports subpools is evaluated, a call is made on Allocate_From_Subpool passing
+in a Subpool_Handle, in addition to the parameters as defined for calls on
+Allocate (see @RefSecNum{Storage Management}). The subpool designated by the
address@hidden@nt{name} is used, if specified in an @nt{allocator}.
+Otherwise, Default_Subpool_for_Pool of the Pool is used to provide a subpool
+handle. All requirements on the Allocate procedure also apply to
+Allocate_from_Subpool.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Deallocate_Subpool is expected to do whatever is
+  needed to deallocate all of the objects contained in the subpool; it is 
called
+  from Unchecked_Deallocate_Subpool (see @RefSecNum{Subpool Reclamation}).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Typically, the pool implementer will not override
+  Allocate. In the canonical definition of the language, it will never be 
called
+  for a pool that supports subpools (there is an @ImplPermName below that 
allows
+  it to be called in certain rare cases).]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Text=[If a storage pool that supports subpools is specified as 
the Storage_Pool for
+an access type, the access type is called a
address@hidden<subpool access type>address@hidden access address@hidden 
type],Sec=[subpool]}
+A subpool access type shall be a pool-specific access type.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3],ARef=[AI05-0252-1]}
address@hidden,Text=[The accessibility level of a subpool access type
+shall not be statically deeper than that of the storage pool object.
+If the specified storage pool object is a storage pool that supports subpools,
+then the @nt{name} that denotes the object shall not denote part of a formal
+parameter, nor shall it denote part of a dereference of a value of a
+non-library-level general access type.
address@hidden contract issue}In addition to the places where
address@hidden normally apply (see @RefSecNum{Generic Instantiation}),
+these rules also apply in the private part of an instance of a generic unit.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3],ARef=[AI05-0252-1]}
address@hidden,Type=[Leading],Text=[When an access type with a specified
+storage pool is frozen (see @RefSecNum{Freezing Rules}), if the tag of the
+storage pool object identifies a storage pool that supports subpools, the
+following checks are made:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[the @nt{name} used to specify the storage pool
+  object does not denote part of a formal parameter nor part of a dereference 
of
+  a value of a non-library-level general access type; address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[the accessibility level of the access type is not
+  deeper than that of the storage pool address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0252-1]}
address@hidden,Type=[Trailing],Text=[Program_Error is raised if either
+of these checks
address@hidden,Sec=(raised by failure of run-time check)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This check (and its static counterpart) ensures
+  that the type of the allocated objects exists at least as long as the storage
+  pool object, so that the subpools are finalized (which finalizes any 
remaining
+  allocated objects) before the type of the objects ceases to exist. The access
+  type itself (and the associated collection) will cease to exist before the
+  storage pool ceases to exist.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We also disallow the use of formal parameters and
+  dereferences of non-library-level general access types when specifying a
+  storage pool object if it supports subpools, because the "apparent"
+  accessibility level is potentially deeper than that of the underlying object.
+  Neither of these cases is very likely to occur in practice.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Type=[Leading],Text=[A call to Subpools.Allocate(P, Addr, Size, 
Align) does the following:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Allocate_From_Subpool
+  (Root_Storage_Pool_With_Subpools'Class(P),
+   Addr, Size, Align,
+   Subpool => Default_Subpool_for_Pool
+                (Root_Storage_Pool_With_Subpools'Class(P)));]}
address@hidden
+
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Text=[An @nt{allocator} that allocates in a subpool raises
+Program_Error if the allocated object has task
address@hidden@Defn2{Term=[Program_Error],Sec=(raised by failure of run-time 
check)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is to ease implementation. We envision
+  relaxing this restriction in a future version of Ada, once implementation
+  experience has been gained. At this time, we are unable to come up with a set
+  of rules for task termination that is both useful, and surely feasible to
+  implement.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Text=[Unless overridden, Default_Subpool_for_Pool
+propagates Program_Error.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI12-0142-1]}
address@hidden(erroneous execution),Sec=(cause)}
address@hidden,Text=[If Allocate_From_Subpool does not meet one or more
+of the requirements on the Allocate procedure as given in the Erroneous
+Execution rules of @RefSecNum{Storage Management}, then the program execution
+is erroneous.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Text=[When an allocator for a type whose storage pool is
+of type Root_Storage_Pool'Class is evaluated, but supports subpools, the
+implementation may call Allocate rather than Allocate_From_Subpool.
address@hidden will have the same effect, so long as Allocate has not been
+overridden.]]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[This ensures either of two 
implementation models
+  are possible for an @nt{allocator} with no @nt{subpool_specification}.
+  Note that the "supports subpools" property is not known at compile time for a
+  pool of the class-wide type.]}
+
+  @begin{Itemize}
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The implementation can dispatch to
+      Storage_Pools.Allocate. If the pool supports subpools, this will call
+      Allocate_From_Subpool with the default subpool so long as Allocate has 
not
+      been overridden.]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The implementation can declare
+      Allocate_From_Subpool as a primitive of Root_Storage_Pool in the private
+      part of Storage_Pools. This means that the Allocate_From_Subpool for
+      Root_Storage_Pool_With_Subpools overrides that private one. The
+      implementation can thus call the private one, which will call Allocate 
for
+      non-subpool-supporting pools. The effect of this implementation does not
+      change if Allocate is overridden for a pool that supports subpools.]}
+  @end{Itemize}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Text=[A user-defined storage pool type that supports
+subpools can be implemented by extending the Root_Storage_Pool_With_Subpools
+type, and overriding the primitive subprograms Create_Subpool,
+Allocate_From_Subpool, and Deallocate_Subpool. Create_Subpool should call
+Set_Pool_Of_Subpool before returning the subpool handle. To make use of such a
+pool, a user would declare an object of the type extension, use it to define 
the
+Storage_Pool attribute of one or more access types, and then call 
Create_Subpool
+to obtain subpool handles associated with the pool.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Text=[A user-defined storage pool type that supports
+subpools may define additional subpool constructors similar to Create_Subpool
+(these typically will have additional parameters).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Text=[The pool implementor should override
+Default_Subpool_For_Pool if the pool is to support a default subpool for the
+pool. The implementor can override Deallocate if individual object reclamation
+is to be supported, and can override Storage_Size if there is some limit on the
+total size of the storage pool. The implementor can override Initialize and
+Finalize if there is any need for nontrivial initialization and finalization
+for the pool as a whole. For example, Finalize might reclaim blocks of storage
+that are allocated over and above the space occupied by the pool object itself.
+The pool implementor may extend the Root_Subpool type as necessary to carry
+additional information with each subpool provided by Create_Subpool.]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0111-3],ARef=[AI05-0252-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Subpools and the
+  package System.Storage_Pools.Subpools are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0142-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum>: Clarified that an 
incorrect
+  implementation of Allocate_From_Subpool causes execution to become erroneous.
+  The wording already said that the requirements of Allocate apply to
+  Allocate_From_Subpool, so we're just confirming the consequences of violating
+  those requirements also apply.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0145-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum>: Clarified that 
Pool_of_Subpool
+  returns @key[null] if Set_Pool_of_Subpool has not been called. As that can
+  be inferred from the definition, and all known existing implementations
+  return @key[null] in this case, we document this as a wording change rather
+  than a possible inconsistency.]}
address@hidden
+
+
address@hidden,Name=[Subpool Reclamation]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Text=[A subpool may be explicitly deallocated using
+Unchecked_Deallocate_Subpool.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Type=[Leading],Text=[The following language-defined
+library procedure exists:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden System.Storage_Pools.Subpools;
address@hidden,address@hidden Ada.Unchecked_Deallocate_Subpool
+   (Subpool : @key[in out] System.Storage_Pools.Subpools.Subpool_Handle);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Text=[If Subpool is @key[null], a call on
+Unchecked_Deallocate_Subpool has no effect. Otherwise, the subpool is
+finalized, and Subpool is set to @key[null].]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Type=[Leading],Text=[Finalization of a subpool has the
+following effects:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The subpool no longer belongs to any pool;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Any of the objects allocated from the subpool that
+still exist are finalized in an arbitrary order;@PDefn2{Term=[arbitrary 
order],Sec=[allowed]}]}
+
address@hidden,Kind=[Added],ARef=[AI12-0148-1]}
address@hidden,Text=[All of the objects allocated from the subpool
+cease to exist;@PDefn2{Term=[exist],Sec=[cease to]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[The following @Redundant[dispatching] call 
is then made:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,NoPrefix=[T],Text=[   
Deallocate_Subpool(Pool_of_Subpool(Subpool)address@hidden, Subpool);]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Text=[Finalization of a Root_Storage_Pool_With_Subpools
+object finalizes all subpools that belong to that pool that have not yet been
+finalized.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[There is no need to call Unchecked_Deallocation on
+an object allocated in a subpool. Such objects are deallocated all at once, 
when
+Unchecked_Deallocate_Subpool is called.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If Unchecked_Deallocation is called, the object is
+finalized, and then Deallocate is called on the Pool, which typically will do
+nothing. If it wants to free memory, it will need some way to get from the
+address of the object to the subpool.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[There is no Deallocate_From_Subpool. There is
+no efficient way for the implementation to determine the subpool for
+an arbitrary object, and if the pool implementer can determinate that,
+they can use that as part of the implementation of Deallocate.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If Unchecked_Deallocation is not called (the usual
+case), the object will be finalized when Unchecked_Deallocate_Subpool is
+called.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If that's never called, then the object will be
+finalized when the Pool_With_Subpools is finalized (by permission @em it might
+happen when the collection of the access type is finalized).]}
+
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0111-3]}
+  @ChgAdded{Version=[3],address@hidden to Ada 
2005}Unchecked_Deallocate_Subpool is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0148-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Added missing wording to 
state
+  that the objects cease to exist after the completion of finalization.
+  This is formally an inconsistency (it would be possible to depend on the
+  fact that objects finalized by Unchecked_Deallocate_Subpool still exist),
+  but that violates every sane expectation for a procedure called
+  "Deallocate" something.]}
address@hidden
+
+
address@hidden@Comment{For ISO version of Ada 2012 Standard}
address@hidden,Name=[Storage Subpool Example]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0111-3]}
address@hidden,Type=[Leading],Text=[The following example is a simple but
+complete implementation of the classic Mark/Release pool using subpools:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden System.Storage_Pools.Subpools;
address@hidden System.Storage_Elements;
address@hidden Ada.Unchecked_Deallocate_Subpool;
address@hidden MR_Pool @key[is]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[use] System.Storage_Pools;
+      -- @Examcom{For uses of Subpools.}
+   @key[use] System.Storage_Elements;
+      -- @Examcom{For uses of Storage_Count and Storage_Array.}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @Examcom{Mark and Release work in a stack fashion, 
and allocations are not allowed}
+   -- @Examcom{from a subpool other than the one at the top of the stack. This 
is also}
+   -- @Examcom{the default pool.}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[subtype] Subpool_Handle @key[is] 
Subpools.Subpool_Handle;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] Mark_Release_Pool_Type (Pool_Size : 
Storage_Count) @key[is new]
+      Subpools.Root_Storage_Pool_With_Subpools @key[with private];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] Mark (Pool : @key[in out] 
Mark_Release_Pool_Type)
+      @key[return not null] Subpool_Handle;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] Release (Subpool : @key[in out] 
Subpool_Handle) @key[renames]
+      Ada.Unchecked_Deallocate_Subpool;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] MR_Subpool @key[is new] 
Subpools.Root_Subpool @key[with record]
+      Start : Storage_Count;
+   @key[end record];
+   @key[subtype] Subpool_Indexes @key[is] Positive @key[range] 1 .. 10;
+   @key[type] Subpool_Array @key[is array] (Subpool_Indexes) @key[of aliased] 
MR_Subpool;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0298-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0134-1]}
address@hidden,Text=[   @key[type] Mark_Release_Pool_Type (Pool_Size : 
Storage_Count) @key[is new]
+      Subpools.Root_Storage_Pool_With_Subpools @key[with record]
+      Storage         : Storage_Array (0 .. address@hidden,New=[],Old=[-1]});
+      Next_Allocation : Storage_Count := 0;
+      Markers         : Subpool_Array;
+      Current_Pool    : Subpool_Indexes := 1;
+   @key[end record];]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0298-1]}
address@hidden,Text=[   @key[overriding]
+   @key[function] Create_Subpool (Pool : @key[in out] Mark_Release_Pool_Type)
+      @key[return not null] Subpool_Handle;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] Mark (Pool : @key[in out] 
Mark_Release_Pool_Type)
+      @key[return not null] Subpool_Handle @key[renames] Create_Subpool;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[overriding]
+   @key[procedure] Allocate_From_Subpool (
+      Pool : @key[in out] Mark_Release_Pool_Type;
+      Storage_Address : @key[out] System.Address;
+      Size_In_Storage_Elements : @key[in] Storage_Count;
+      Alignment : @key[in] Storage_Count;
+      Subpool : @key[not null] Subpool_Handle);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[overriding]
+   @key[procedure] Deallocate_Subpool (
+      Pool : @key[in out] Mark_Release_Pool_Type;
+      Subpool : @key[in out] Subpool_Handle);]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0298-1]}
address@hidden,Text=[   @key[overriding]
+   @key[function] Default_Subpool_for_Pool (Pool : @key[in out] 
Mark_Release_Pool_Type)
+      @key[return not null] Subpool_Handle;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[overriding]
+   @key[procedure] Initialize (Pool : @key[in out] Mark_Release_Pool_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @Examcom{We don't need Finalize.}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden MR_Pool;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden body] MR_Pool @key[is]]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0298-1]}
address@hidden,Text=[   @key[use type] Subpool_Handle;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0298-1]}
address@hidden,Text=[   @key[procedure] Initialize (Pool : @key[in out] 
Mark_Release_Pool_Type) @key[is]
+      -- @Examcom{Initialize the first default subpool.}
+   @key[begin]
+      Pool.Markers(1).Start := 1;
+      Subpools.Set_Pool_of_Subpool
+         (Pool.Markers(1)'Unchecked_Access, Pool);
+   @key[end] Initialize;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] Create_Subpool (Pool : @key[in out] 
Mark_Release_Pool_Type)
+      @key[return not null] Subpool_Handle @key[is]
+      -- @Examcom{Mark the current allocation location.}
+   @key[begin]
+      @key[if] Pool.Current_Pool = Subpool_Indexes'Last @key[then]
+         @key[raise] Storage_Error; -- @Examcom{No more subpools.}
+      @key[end if];
+      Pool.Current_Pool := Pool.Current_Pool + 1; -- @Examcom{Move to the next 
subpool}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0298-1]}
address@hidden,Text=[      @key[return] Result : @key[constant not null] 
Subpool_Handle :=
+         Pool.Markers(Pool.Current_Pool)'Unchecked_Access
+      @key[do]
+         Pool.Markers(Pool.Current_Pool).Start := Pool.Next_Allocation;
+         Subpools.Set_Pool_of_Subpool (Result, Pool);
+      @key[end return];
+   @key[end] Create_Subpool;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0298-1]}
address@hidden,Text=[   @key[procedure] Deallocate_Subpool (
+      Pool : @key[in out] Mark_Release_Pool_Type;
+      Subpool : @key[in out] Subpool_Handle) @key[is]
+   @key[begin]
+      @key[if] Subpool /= Pool.Markers(Pool.Current_Pool)'Unchecked_Access 
@key[then]
+         @key[raise] Program_Error; -- @Examcom{Only the last marked subpool 
can be released.}
+      @key[end if];
+      @key[if] Pool.Current_Pool /= 1 @key[then]
+         Pool.Next_Allocation := Pool.Markers(Pool.Current_Pool).Start;
+         Pool.Current_Pool := Pool.Current_Pool - 1; -- @Examcom{Move to the 
previous subpool}
+      @key[else] -- @Examcom{Reinitialize the default subpool:}
+         Pool.Next_Allocation := 1;
+         Subpools.Set_Pool_of_Subpool
+            (Pool.Markers(1)'Unchecked_Access, Pool);
+      @key[end if];
+   @key[end] Deallocate_Subpool;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0298-1]}
address@hidden,Text=[   @key[function] Default_Subpool_for_Pool (Pool : @key[in 
out] Mark_Release_Pool_Type)
+      @key[return not null] Subpool_Handle @key[is]
+   @key[begin]
+      @key[return] Pool.Markers(Pool.Current_Pool)'Unchecked_Access;
+   @key[end] Default_Subpool_for_Pool;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] Allocate_From_Subpool (
+      Pool : @key[in out] Mark_Release_Pool_Type;
+      Storage_Address : @key[out] System.Address;
+      Size_In_Storage_Elements : @key[in] Storage_Count;
+      Alignment : @key[in] Storage_Count;
+      Subpool : @key[not null] Subpool_Handle) @key[is]
+   @key[begin]
+      @key[if] Subpool /= Pool.Markers(Pool.Current_Pool)'Unchecked_Access 
@key[then]
+         @key[raise] Program_Error; -- @Examcom{Only the last marked subpool 
can be used for allocations.}
+      @key[end if];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0080-1]}
address@hidden,address@hidden,New=[      -- @Examcom{Check for the maximum 
supported alignment, which is the alignment of the storage area:}
+      @key[if] Alignment > Pool.Storage'Alignment @key[then]
+         @key[raise] Program_Error;
+      @key[end if];
+],Old=[]}      -- @Examcom{Correct the alignment if necessary:}
+      Pool.Next_Allocation := Pool.Next_Allocation +
+         ((-Pool.Next_Allocation) @key[mod] Alignment);
+      @key[if] Pool.Next_Allocation + Size_In_Storage_Elements >
+         Pool.Pool_Size @key[then]
+         @key[raise] Storage_Error; -- @Examcom{Out of space.}
+      @key[end if];
+      Storage_Address := Pool.Storage (Pool.Next_Allocation)'Address;
+      Pool.Next_Allocation :=
+         Pool.Next_Allocation + Size_In_Storage_Elements;
+   @key[end] Allocate_From_Subpool;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden MR_Pool;]}
address@hidden
+
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0111-3]}
+  @ChgAdded{Version=[3],Text=[This example of subpools is new.]}
address@hidden
+
+
+
address@hidden,New=[Pragma Restrictions and Pragma Profile],Old=[Pragma 
Restrictions]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0246-1]}
address@hidden @nt{pragma} Restrictions expresses the user's intent to abide by
+certain address@hidden,New=[ A @nt{pragma} Profile expresses the
+user's intent to abide by a set of Restrictions or other specified run-time
+policies.],Old=[]}
address@hidden,New=[These],Old=[This]} may facilitate the construction of
+simpler run-time environments.]
address@hidden
+
address@hidden
address@hidden
address@hidden@keepnext@;The form of a @nt{pragma} Restrictions is as follows:
address@hidden
+
address@hidden@key{pragma} @prag(Restrictions)(@Syn2{restriction}{, 
@Syn2{restriction}});'
+
address@hidden,Kind=[Revised],ARef=[AI95-00381-01]}
address@hidden(restriction), rhs="@address@hidden
+    | @address@hidden => @Chg{Version=[2],address@hidden,address@hidden"}
+
address@hidden,Kind=[Added],ARef=[AI95-00381-01]}
address@hidden,lhs=<@Chg{Version=[2],New=<restriction_parameter_argument>,Old=<>}>,
+rhs="@Chg{Version=[2],New=<@Syn2{name} | @Syn2{expression}>,Old=<>}"}
+
address@hidden
+
address@hidden
address@hidden type],
+  Sec=(restriction parameter expression)}
+Unless otherwise specified for a particular restriction,
+the @nt{expression} is expected to be of any integer type.
address@hidden
+
address@hidden
+Unless otherwise specified for a particular restriction,
+the @nt{expression} shall be static,
+and its value shall be nonnegative.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00394-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0269-1]}
address@hidden,Text=[The set of
address@hidden,New=[restrictions],address@hidden is
+implementation defined.]}
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,Text=[The set of
address@hidden,New=[restrictions],address@hidden
+allowed in a @nt{pragma} Restrictions.]}]}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraph 7 was
+deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered.}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0013-1]}
address@hidden ChgAdded to get conditional address@hidden,
+Type=[Leading],address@hidden pragma], Sec=(Restrictions)}
address@hidden, configuration], Sec=(Restrictions)}
+A @nt{pragma} Restrictions is a configuration address@hidden,
+New=[. If a @nt{pragma} Restrictions applies to any compilation unit included 
in
+the partition, this may impose either (or both) of two kinds of
+requirements, as],
+Old=[; unless otherwise]} specified for @Chg{Version=[3],New=[the],Old=[a]}
+particular address@hidden,New=[:],Old=[,
+a partition shall obey the restriction
+if a @nt{pragma} Restrictions applies to any compilation unit
+included in the partition.]}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0013-1]}
address@hidden,Text=[A restriction may impose requirements on some or
+all of the units comprising the partition. Unless otherwise specified for a
+particular restriction, such a requirement applies to all of the units
+comprising the partition and is enforced via a post-compilation check.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0013-1]}
address@hidden,Text=[A restriction may impose requirements on the
+run-time behavior of the program, as indicated by the specification of run-time
+behavior associated with a violation of the requirement.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[In this latter case, there is no post-compilation
+check needed for the requirement.]}
address@hidden
address@hidden
+
+
address@hidden,Kind=[Added],Ref=[8652/0042],ARef=[AI95-00130-01]}
address@hidden,Type=[Leading],Text=[For the purpose of checking whether
+a partition contains constructs that violate any restriction (unless specified
+otherwise for a particular restriction):]}
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0042],ARef=[AI95-00130-01]}
address@hidden,Text=[Generic instances are logically expanded at the
+point of instantiation;]}
+
address@hidden,Kind=[Added],Ref=[8652/0042],ARef=[AI95-00130-01]}
address@hidden,Text=[If an object of a type is declared or allocated and
+not explicitly initialized, then all expressions appearing in the definition
+for the type and any of its ancestors are presumed to be used;]}
+
address@hidden,Kind=[Added],Ref=[8652/0042],ARef=[AI95-00130-01]}
address@hidden,Text=[A @nt{default_expression} for a formal parameter or
+a generic formal object is considered to be used if and only if the
+corresponding actual parameter is not provided in a given call or
+instantiation.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0269-1]}
address@hidden,Text=[An implementation may provide implementation-defined
+restrictions; the identifier for an implementation-defined restriction
+shall differ from those of the language-defined restrictions.]}
address@hidden,Kind=[Added],
address@hidden,Text=[Implementation-defined restrictions
+allowed in a @nt{pragma} Restrictions.]}]}
+
+An implementation may place limitations on the values of the
address@hidden that are supported,
+and limitations on the supported combinations of restrictions.
+The consequences of violating such limitations are
+implementation defined.
address@hidden consequences of violating limitations on
+Restrictions @nt{pragma}s.}
address@hidden
+Such limitations may be enforced at compile time or at run time.
+Alternatively, the implementation is allowed to declare violations of
+the restrictions to be erroneous, and not enforce them at all.
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0042],ARef=[AI95-00130-01]}
address@hidden,Text=[An implementation is permitted to omit restriction
+checks for code that is recognized at compile time to be unreachable and for
+which no code is generated.]}
+
address@hidden,Kind=[Added],Ref=[8652/0043],ARef=[AI95-00190-01]}
address@hidden,Text=[Whenever enforcement of a restriction is not
+required prior to execution, an implementation may nevertheless enforce the
+restriction prior to execution of a partition to which the restriction applies,
+provided that every execution of the partition would violate the restriction.]}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01],ARef=[AI05-0246-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The form of a
address@hidden Profile is as follows:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,@ChgAdded{Version=[3],
address@hidden @prag<Profile> (@address@hidden {, @address@hidden);]}}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01],ARef=[AI05-0246-1]}
address@hidden,Text=[The @address@hidden shall be the name
+of a usage profile. The semantics of any
address@hidden@address@hidden@!association}s are defined by
+the usage profile specified by the @address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01],ARef=[AI05-0246-1]}
address@hidden,Text=[A profile is equivalent to the set of configuration
+pragmas that is defined for each usage profile.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01]}
address@hidden,address@hidden pragma], Sec=(Profile)}
address@hidden, configuration], Sec=(Profile)}
+A @nt{pragma} Profile is a configuration pragma.
+There may be more than one @nt{pragma} Profile for a partition.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0269-1]}
address@hidden,Text=[An implementation may provide implementation-defined
+usage profiles; the identifier for an implementation-defined usage profile
+shall differ from those of the language-defined usage profiles.]}
+
address@hidden,Kind=[Added],
address@hidden,Text=[Implementation-defined usage profiles
+allowed in a @nt{pragma} Profile.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00347-01]}
+Restrictions intended to facilitate the construction of
+efficient tasking run-time systems are defined
+in @RefSecNum{Tasking Restrictions}.
address@hidden,New=[Restrictions intended for use when constructing
+high integrity systems],Old=[Safety- and security-related
+restrictions]} are defined in
address@hidden Integrity Restrictions}.
+
+An implementation has to enforce the restrictions in cases where
+enforcement is required,
+even if it chooses not to take advantage of the restrictions in terms of
+efficiency.
address@hidden
+It is not the intent that an implementation will support a different
+run-time system for every possible combination of restrictions.
+An implementation might support only two run-time systems,
+and document a set of restrictions that is sufficient to allow
+use of the more efficient and safe one.
address@hidden
address@hidden
+
address@hidden
+  @Defn{extensions to Ada 83}
+  Pragma Restrictions is new to Ada 95.
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI95-00249-01],ARef=[AI05-0246-1]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @nt{Pragma} Profile is new; it was moved here by Ada 2012 and renamed to
+  a "usage profile" but was otherwise unchanged.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0042],ARef=[AI95-00130-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the wording so 
that
+  restrictions are checked inside of generic instantiations and in default
+  expressions. Since not making these checks would violate the purpose of
+  restrictions, we are not documenting this as an incompatibility.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0043],ARef=[AI95-00190-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added a permission that
+  restrictions can be enforced at compile-time. While this is technically
+  incompatible, documenting it as such would be unnecessarily alarming -
+  there should not be any programs depending on the runtime failure of
+  restrictions.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00381-01]}
+  @ChgAdded{Version=[2],Text=[The syntax of a 
@nt{restriction_parameter_argument}
+  has been defined to better support restriction No_Dependence (see
+  @RefSecNum{Language-Defined Restrictions and Profiles}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0013-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction>: When restrictions are
+  checked has been clarified.]}
address@hidden
+
+
address@hidden,InitialVersion=[2],New=[Language-Defined Restrictions and 
Profiles],Old=[Language-Defined Restrictions]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00257-01]}
address@hidden,Type=[Leading],Text=[The following
address@hidden@nt{identifier}s are language defined (additional
+restrictions are defined in the Specialized Needs Annexes):]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0241-1]}
address@hidden,address@hidden,
+   Sec=(No_Implementation_Aspect_Specifications)address@hidden,address@hidden 
restriction}],
+   Old=[]}No_Implementation_Aspect_Specifications @\There
+   are no implementation-defined aspects specified by an
+   @nt{aspect_specification}. This restriction applies only to the current
+   compilation or environment, not the entire partition.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0241-1]}
+  @ChgAdded{Version=[3],Text=[This restriction (as well as others below) 
applies
+  only to the current compilation, because it is likely that the runtime (and
+  possibly user-written low-level code) will need to use implementation-defined
+  aspects. But a partition-wide restriction applies everywhere, including the
+  runtime.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00257-01]}
address@hidden,address@hidden,
+   Sec=(No_Implementation_Attributes)address@hidden,address@hidden 
restriction}],
+   Old=[]}No_Implementation_Attributes @\There
+   are no implementation-defined attributes. This restriction applies
+   only to the current compilation or environment, not the entire partition.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg],ARef=[AI05-0241-1]}
+  @ChgDeleted{Version=[3],address@hidden,New=[This restriction (as well as 
No_Implementation_Pragmas)
+  only applies to the current compilation, because it is likely that the
+  runtime (and possibly user-written low-level code) will need to use
+  implementation-defined entities. But a partition-wide restriction applies
+  everywhere, including the runtime.],Old=[]}]}
address@hidden
+
address@hidden end part of this and the bullets are Redundant, but that would
+cause bad nesting, so we don't mark it}
address@hidden,Kind=[Added],ARef=[AI05-0246-1],ARef=[AI05-0269-1]}
address@hidden,address@hidden,
+   Sec=(No_Implementation_Identifiers)address@hidden 
restriction}No_Implementation_Identifiers
+   @\There are no usage names that denote declarations with
+   implementation-defined identifiers that occur within language-defined
+   packages or instances of language-defined generic packages.
+   Such identifiers can arise as follows:]}
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The following language-defined
+  packages and generic packages allow implementation-defined identifiers:]}
+
+  @begin{InnerItemize}
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[package System (see
+      @RefSecNum{The Package System});]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[package Standard (see
+      @RefSecNum{The Package Standard});]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[package Ada.Command_Line (see
+      @RefSecNum{The Package Command_Line});]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[package Interfaces.C (see
+      @RefSecNum{Interfacing with C and C++});]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[package Interfaces.C.Strings (see
+      @RefSecNum{The Package Interfaces.C.Strings});]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[package Interfaces.C.Pointers (see
+      @RefSecNum{The Generic Package Interfaces.C.Pointers});]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[package Interfaces.COBOL (see
+      @RefSecNum{Interfacing with COBOL});]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[package Interfaces.Fortran (see
+      @RefSecNum{Interfacing with Fortran});]}
+  @end{InnerItemize}
+
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The following language-defined
+  packages contain only implementation-defined identifiers:]}
+
+  @begin{InnerItemize}
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[package System.Machine_Code (see
+    @RefSecNum{Machine Code Insertions});]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[package Ada.Directories.Information (see
+    @RefSecNum{The Package Directories});]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[nested Implementation packages of the Queue
+    containers (see @RefSecNum{The Generic Package 
Containers.Unbounded_Synchronized_Queues}-31);]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[package Interfaces (see
+      @RefSecNum{The Package Interfaces});]}
+
+    @ChgRef{Version=[3],Kind=[Added]}
+    @ChgAdded{Version=[3],Text=[package Ada.Interrupts.Names (see
+      @RefSecNum{The Package Interrupts}).]}
+
+  @end{InnerItemize}
+
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,NoPrefix=[T],Text=[For package Standard,
+Standard.Long_Integer and Standard.Long_Float are considered language-defined
+identifiers, but identifiers such as Standard.Short_Short_Integer are 
considered
+implementation-defined.]}
+
address@hidden,Kind=[Added]}
address@hidden,NoPrefix=[T],Text=[This restriction applies only to the
+current compilation or environment, not the entire partition.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00257-01]}
address@hidden,address@hidden,
+Sec=(No_Implementation_Pragmas)address@hidden,
address@hidden restriction}],
+Old=[]}No_Implementation_Pragmas @\There are no
+implementation-defined pragmas or pragma arguments. This restriction applies
+only to the current compilation or environment, not the entire partition.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0242-1]}
address@hidden,address@hidden,
+   Sec=(No_Implementation_Units)address@hidden 
restriction}No_Implementation_Units @\There
+   is no mention in the @nt{context_clause} of any implementation-defined
+   descendants of packages Ada, Interfaces, or System. This restriction applies
+   only to the current compilation or environment, not the entire partition.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00368-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,address@hidden,
+   Sec=(No_Obsolescent_Features)address@hidden,address@hidden restriction}],
+   Old=[]}No_Obsolescent_Features @\There
+   is no use of language features defined in Annex J. It is
+   @Chg{Version=[3],New=[implementation defined whether],
+   Old=[implementation-defined if]} uses of the renamings of
+   @RefSecNum{Renamings of Library Units} @Chg{Version=[3],New=[and of the
+   @nt{pragma}s of @RefSecNum{Aspect-related Pragmas} ],Old=[]}are detected
+   by this restriction. This restriction applies only to the current
+   compilation or environment, not the entire partition.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[A user could compile a rename
+  like]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Text_IO;
address@hidden Text_IO @key{renames} Ada.Text_IO;]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Such a rename must not be disallowed
+  by this restriction, nor should the compilation of such a rename be
+  restricted by an implementation. Many implementations implement the renames
+  of @RefSecNum{Renamings of Library Units}
+  by compiling them normally; we do not want to require implementations to use
+  a special mechanism to implement these renames.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[The pragmas have the same functionality as the
+  corresponding aspect (unlike the typical obsolescent feature), and rejecting
+  them could be a significant portability problem for existing code.]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00381-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0241-1]}
address@hidden,Type=[Leading],Text=[The following
address@hidden@address@hidden,New=[s are],Old=[is]}
+language defined:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00381-01]}
address@hidden,address@hidden,Sec=(No_Dependence)address@hidden 
restriction}No_Dependence @\Specifies
+   a library unit on which there are no semantic dependences.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0241-1]}
address@hidden,address@hidden,
+   Sec=(No_Specification_of_Aspect)address@hidden 
restriction}No_Specification_of_Aspect
+   @\Identifies an aspect for which no
+   @nt{aspect_specification}, @nt{attribute_definition_clause}, or @nt{pragma}
+   is given.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0272-1]}
address@hidden,address@hidden,
+   Sec=(No_Use_Of_Attribute)address@hidden restriction}No_Use_Of_Attribute
+   @\Identifies an attribute for which no @nt{attribute_reference} or
+   @nt{attribute_definition_clause} is given.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0272-1]}
address@hidden,address@hidden,
+   Sec=(No_Use_Of_Pragma)address@hidden restriction}No_Use_Of_Pragma
+   @\Identifies a @nt{pragma} which is not to be used.]}
+
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00381-01]}
address@hidden,Text=[The @nt{restriction_parameter_argument} of a
+No_Dependence restriction shall be a @nt{name}; the @nt{name} shall have
+the form of a full expanded name of a library unit, but need not denote a unit
+present in the environment.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This @nt{name} is not resolved.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0241-1]}
address@hidden,Text=[The @nt{restriction_parameter_argument} of a
+No_Specification_of_Aspect restriction shall be an @nt{identifier}; this
+is an identifier specific to a pragma (see @RefSecNum{Pragmas}) and
+does not denote any declaration.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This @nt{restriction_parameter_argument} is not
+    resolved as it is an identifier specific to a pragma. As
+    for No_Dependence, there is no check that the aspect
+    @nt{identifier} is meaningful; it might refer to an implementation-defined
+    aspect on one implementation, but nothing at all on another 
implementation.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0272-1]}
address@hidden,Text=[The @nt{restriction_parameter_argument} of a
+No_Use_Of_Attribute restriction
+shall be an @nt{identifier} or one of the reserved words Access, Delta, Digits,
+Mod, or Range; this is an identifier specific to a pragma.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This @nt{restriction_parameter_argument} is not
+    resolved as it is an identifier specific to a pragma. There is no check 
that
+    the attribute identifier refers to a known @nt{attribute_designator};
+    it might refer to an implementation-defined
+    attribute on one implementation, but nothing at all on another 
implementation.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0272-1]}
address@hidden,Text=[The @nt{restriction_parameter_argument} of a
+No_Use_Of_Pragma restriction
+shall be an @nt{identifier} or the reserved word Interface;
+this is an identifier specific to a pragma.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This @nt{restriction_parameter_argument} is not
+    resolved as it is an identifier specific to a pragma. There is no check 
that
+    the pragma identifier refers to a known @nt{pragma};
+    it might refer to an implementation-defined pragma on one implementation,
+    but nothing at all on another implementation.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00381-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0241-1]}
address@hidden,Text=[No compilation unit included in the partition shall
+depend semantically on the library unit identified by the
address@hidden@Chg{Version=[3],New=[ of a No_Dependence restriction],Old=[]}.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[There is no requirement that the library unit
+  actually exist. One possible use of the pragma is to prevent the use of
+  implementation-defined units; when the program is ported to a different
+  compiler, it is perfectly reasonable that no unit with the name exist.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0246-1]}
address@hidden,Type=[Leading],Text=[The following
address@hidden@nt{identifier} is language defined:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0246-1]}
address@hidden,address@hidden,Sec=(No_Implementation_Extensions)}No_Implementation_Extensions
 @\]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0246-1]}
address@hidden,Text=[For usage profile No_Implementation_Extensions,
+there shall be no @address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0246-1]}
address@hidden,Type=[Leading],Text=[The No_Implementation_Extensions
+usage profile is equivalent to the following restrictions:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[No_Implementation_Aspect_Specifications,
+No_Implementation_Attributes,
+No_Implementation_Identifiers,
+No_Implementation_Pragmas,
+No_Implementation_Units.]}
address@hidden
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00257-01],ARef=[AI95-00368-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Restrictions No_Implementation_Attributes, No_Implementation_Pragmas, and
+  No_Obsolescent_Features are new.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00381-01]}
+  @ChgAdded{Version=[2],Text=[Restriction No_Dependence is new.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0241-1],ARef=[AI05-0242-1],ARef=[AI05-0246-1],ARef=[AI05-0272-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Restrictions No_Implementation_Aspect_Specifications, 
No_Implementation_Identifiers,
+  No_Implementation_Units, No_Specification_of_Aspect, No_Use_of_Attribute, and
+  No_Use_of_Pragma are new.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0246-1]}
+  @ChgAdded{Version=[3],Text=[Profile No_Implementation_Extensions is new.]}
address@hidden
+
+
address@hidden
+
address@hidden
address@hidden
address@hidden type}
+A @i{stream} is a sequence of elements comprising values from
+possibly different types and allowing sequential access to these values.
+A @i{stream type} is a type in the class whose root type is
+Streams.Root_Stream_Type.
+A stream type may be implemented in various ways,
+such as an external sequential file, an internal buffer,
+or a network channel.
address@hidden
+A stream element will often be the same size as a storage element,
+but that is not required.
address@hidden
+
address@hidden,Kind=[Added],Term=<Stream>,
+Text=<@ChgAdded{Version=[3],Text=[A stream is a sequence of elements that can 
be
+used, along with the stream-oriented attributes, to support marshalling and
+unmarshalling of values of most types.]}>}
+
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Streams are new in Ada 95.
address@hidden
+
address@hidden Package Streams}
+
address@hidden
+The abstract type Root_Stream_Type is the root type of the class of
+stream types. The types in this class represent different kinds of
+streams. A new stream type is defined by extending the root type
+(or some other stream type), overriding the Read and Write
+operations, and optionally defining additional primitive
+subprograms,
+according to the requirements of the particular kind of stream.
+The predefined stream-oriented attributes like T'Read and T'Write
+make dispatching
+calls on the Read and Write procedures of the Root_Stream_Type.
+(User-defined T'Read and T'Write attributes can also make such calls,
+or can call the Read and Write attributes of other types.)
address@hidden
address@hidden,address@hidden Ada.Streams @key[is]
+    @key[pragma] Pure(Streams)@Defn{unpolluted};@Comment{This *must* be a Duff 
joke}
+
address@hidden,Kind=[Revised],ARef=[AI95-00161-01]}
+    @key[type] @AdaTypeDefn{Root_Stream_Type} @key[is] @key[abstract tagged 
limited private];@Chg{Version=[2],New=[
+    @key[pragma] Preelaborable_Initialization(Root_Stream_Type);],Old=[]}
+
address@hidden,Kind=[Revised],Ref=[8652/0044],ARef=[AI95-00181-01]}
+    @key[type] @AdaTypeDefn{Stream_Element} @key[is] @key[mod] 
@RI{implementation-defined};
+    @key[type] @AdaTypeDefn{Stream_Element_Offset} @key[is] @key[range] 
@RI{implementation-defined};
+    @key[subtype] 
@AdaSubtypeDefn{Name=[Stream_Element_Count],Of=[Stream_Element_Offset]} @key[is]
+        Stream_Element_Offset @key[range] 0..Stream_Element_Offset'Last;
+    @key[type] @AdaTypeDefn{Stream_Element_Array} @key[is]
+        @key[array](Stream_Element_Offset @key[range] <>) @address@hidden@key[ 
aliased]],Old=[]} Stream_Element;
+
+    @key[procedure] @AdaSubDefn{Read}(
+      Stream : @key[in] @key[out] Root_Stream_Type;
+      Item   : @key[out] Stream_Element_Array;
+      Last   : @key[out] Stream_Element_Offset) @key[is abstract];
+
+    @key[procedure] @AdaSubDefn{Write}(
+      Stream : @key[in] @key[out] Root_Stream_Type;
+      Item   : @key[in] Stream_Element_Array) @key[is abstract];
+
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden Ada.Streams;
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00227-01]}
+The Read operation transfers @Chg{Version=[2],New=[],Old=[Item'Length ]}stream
+elements from the specified stream to fill the array Item.
address@hidden,New=[Elements are transferred until Item'Length elements have
+been transferred, or until the end of the stream is reached. If any elements
+are transferred, the],Old=[The]} index of the last stream element transferred 
is
+returned in Last. @Chg{Version=[2],New=[Otherwise, Item'First - 1 is returned
+in Last. ],Old=[]}Last is less than Item'Last only if the end of the stream is
address@hidden last sentence should be marked Redundant.}
+
+The Write operation appends Item to the specified stream.
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00114-01]}
address@hidden was moved from 13.7.1.}
address@hidden,Text=[The index subtype of Stream_Element_Array is
+Stream_Element_Offset because we wish to allow maximum flexibility. Most
+Stream_Element_Arrays will probably have a lower bound of 0 or 1, but other
+lower bounds, including negative ones, make sense in some situations.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00114-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
address@hidden was moved from 13.7.1, where it was totally bogus.}
address@hidden,Text=[Note that there are some language-defined
+subprograms that fill part of a Stream_Element_Array, and return the index of 
the
+last element filled as a Stream_Element_Offset. The Read procedures declared
+here, Streams.Stream_IO (see @RefSecNum{The Package Streams.Stream_IO}),
+and System.RPC (see @RefSecNum{Partition Communication Subsystem})
+behave in this manner.
+These will raise Constraint_Error if the resulting Last value is not in
+Stream_Element_Offset.
+This implies that the Stream_Element_Array passed to these subprograms should
+not have a lower bound of Stream_Element_Offset'First,
+because then a read of 0 elements would always raise Constraint_Error.
+A better choice of lower bound is @Chg{Version=[3],New=[0 or ],Old=[]}1.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0044],ARef=[AI95-00181-01]}
address@hidden,Text=[If Stream_Element'Size is not a multiple of
+System.Storage_Unit, then the components of address@hidden@!Array need
+not be aliased.]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00114-01]}
address@hidden,Text=[If the Stream_Element'Size is less than the size of
+System.Storage_Unit, then components of address@hidden@!Array need not be
+aliased. This is necessary as the components of type Stream_Element size might
+not be addressable on the target 
@Chg{Version=[2],New=[architecture],Old=[architechture]}.]}
address@hidden
address@hidden
+
address@hidden
+See @RefSec{The Package Streams.Stream_IO} for an example of extending
+type Root_Stream_Type.
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00227-01]}
address@hidden,Text=[If the end of stream has been reached, and
+Item'First is Stream_Element_Offset'First, Read will raise Constraint_Error.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Thus, Stream_Element_Arrays should start at 0 or
+  1, not Stream_Element_Offset'First.]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00161-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b[Amendment Correction:] Added @nt{pragma} Preelaborable_Initialization
+  to type Root_Stream_Type.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0044],ARef=[AI95-00181-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Stream elements are 
aliased
+  presuming that makes sense.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00227-01]}
+  @ChgAdded{Version=[2],Text=[Fixed the wording for Read to properly define
+  the result in Last when no stream elements are transfered.]}
address@hidden
+
+
address@hidden Attributes}
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0183-1]}
+The @Chg{Version=[3],New=[type-related ],address@hidden
+attributes ],Old=[]}Write, Read, Output, and
+Input @Chg{New=[],Old=[attributes ]}convert values to a
+stream of elements and reconstruct values from a
address@hidden address@hidden,Sec=[stream-oriented]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00270-01]}
address@hidden,Type=[Leading],Text=[For @PrefixType{every subtype S of
+an elementary type @i(T)}, the following representation attribute is defined:]}
address@hidden
+
address@hidden Version=[2],Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ChginAnnex=[T],
+  Leading=<T>, Prefix=<S>, AttrName=<Stream_Size>, ARef=[AI95-00270-01], 
ARef=[AI05-0194-1],
+  InitialVersion=[2], address@hidden,New=[Denotes the number of bits
+  @Chg{Version=[3],New=[read from or written to a stream by the
+  default implementations of S'Read and S'Write],Old=[occupied
+  in a stream by items of subtype S]}. Hence, the number of stream elements
+  required per item of elementary type @i<T> is:],Old=[]}
+
address@hidden(Descexample)
address@hidden,Kind=[Added]}
address@hidden,address@hidden<T>'Stream_Size / Ada.Streams.Stream_Element'Size]}
address@hidden(Descexample)
+
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],NoPrefix=[T],Text=[The value of this attribute is of
+  type @i{universal_integer} and is a multiple of 
Stream_Element'address@hidden attribute Stream_Size}
+
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],NoPrefix=[T],Text=[Stream_Size may be specified for
+  first subtypes via an @nt{attribute_definition_clause}; the @nt{expression}
+  of such a clause shall be static, nonnegative, and a multiple of
+  Stream_Element'address@hidden,address@hidden,Old=[]}]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Stream_Size],
+    address@hidden,Text=[Size in bits used to represent elementary
+      objects in a stream.]}]}
+
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Stream_Size is a type-related attribute (see
+  @RefSecNum{Operational and Representation Aspects}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal], ARef=[AI05-0194-1]}
+  @ChgAdded{Version=[3],Text=[The value of S'Stream_Size is unaffected by the
+    presence or absence of any @nt{attribute_definition_clause}s or
+    @nt{aspect_specification}s specifying the Read or Write attributes of any
+    ancestor of S. S'Stream_Size is defined in terms of the behavior of the
+    default implementations of S'Read and S'Write even if those default
+    implementations are overridden.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00270-01]}
address@hidden,Text=[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.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[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.]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00270-01]}
+  @ChgAdded{Version=[2],Text=[This is @ImplAdviceTitle because we want to
+  allow implementations to remain compatible with their Ada 95 implementations,
+  which may have a different handling of the number of stream elements. Users
+  can always specify Stream_Size if they need a specific number of stream
+  elements.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00270-01]}
address@hidden,Type=[Leading],Keepnext=[T],address@hidden level of support],
+Sec=(Stream_Size attribute)}
+The recommended level of support for the Stream_Size attribute is:]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00270-01]}
address@hidden,Text=[A Stream_Size clause should be supported for a
+discrete or fixed point type @i<T> if the specified Stream_Size is a multiple
+of Stream_Element'Size and is no less than the size of the first subtype
+of @i<T>, and no greater than the size of the largest type of the same
+elementary class (signed integer, modular integer, enumeration,
+ordinary fixed point, or decimal fixed point).]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The recommended level of support for the Stream_Size attribute should be
+followed.]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[There are no requirements beyond supporting
+  confirming Stream_Size clauses for floating point and access types.
+  Floating point and access types usually only have a handful of defined
+  formats, streaming anything else makes no sense for them.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[For discrete and fixed point types, this
+  may require support for sizes other than the @lquotes@;address@hidden
+  ones. For instance, on a typical machine with 32-bit integers and a
+  Stream_Element'Size of 8, setting Stream_Size to 24 must be supported.
+  This is required as such formats can be useful for interoperability with
+  unusual machines, and there is no difficulty with the implementation
+  (drop extra bits on output, sign extend on input).]}
address@hidden
+
address@hidden
address@hidden
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden
+
+For @PrefixType{every subtype S of a specific type @i(T)},
+the following attributes are defined.
address@hidden
address@hidden<S>, AttrName=<Write>,
+  Text=<S'Write denotes a procedure with the following specification:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00441-01]}
address@hidden(procedure) S'Write(
+   @RI{Stream} : @address@hidden,New=[not null ],Old=[]}access} 
Ada.Streams.Root_Stream_Type'Class;
+   @RI{Item} : @key{in} @RI(T))
address@hidden
+
address@hidden@;S'Write writes the value of @i{Item} to @i{Stream}.>}
+
address@hidden<S>, AttrName=<Read>,
+  Text=<S'Read denotes a procedure with the following specification:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00441-01]}
address@hidden(procedure) S'Read(
+   @RI{Stream} : @address@hidden,New=[not null ],Old=[]}access} 
Ada.Streams.Root_Stream_Type'Class;
+   @RI{Item} : @key{out} @RI(T))
address@hidden
+
address@hidden@;S'Read reads the value of @i{Item} from @i{Stream}.>}
address@hidden
address@hidden
+
+
address@hidden,Kind=[Added],Ref=[8652/0040],ARef=[AI95-00108-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00444-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0192-1]}
address@hidden,Text=[For @Chg{Version=[2],New=[an ],Old=[]}untagged
+derived @Chg{Version=[2],New=[type],Old=[types]}, the Write
address@hidden,New=[(resp.],Old=[and]}
address@hidden,New=[) attribute is],Old=[ attributes are]}
+inherited @Chg{Version=[2],New=[according to the rules given],Old=[as 
specified]}
+in @RefSecNum{Operational and Representation address@hidden,
+New=[ if the attribute is @Chg{Version=[3],address@hidden and] ],
+Old=[]}available for the parent type at the point
+where @i{T} is declared. For a tagged derived type, these attributes are
+not inherited, but rather],Old=[; otherwise,]} the default
+implementations @Chg{Version=[2],New=[],Old=[of these attributes ]}are
address@hidden,New=[],Old=[The default implementations of Write and
+Read attributes execute as follows:]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[RevisedAdded],ARef=[AI05-0192-1]}
+  @ChgAdded{Version=[3],Text=[The inheritance rules of
+  @RefSecNum{Operational and Representation Aspects} say that only specified or
+  inherited aspects are inherited; we mention it again here as a 
clarification.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00444-01]}
address@hidden,Type=[Leading],Text=[The default implementations of
+the Write and Read attributes, where available, execute as follows:]}
+
address@hidden,Kind=[Revised],Ref=[8652/0040],ARef=[AI95-00108-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00195-01],ARef=[AI95-00251-01],ARef=[AI95-00270-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0139-2]}
+For elementary types, @Chg{Version=[2],New=[Read reads (and Write writes) the
+number of stream elements implied by the Stream_Size for the type @i<T>;],
+Old=[]} the representation @Chg{Version=[2],New=[],Old=[in terms 
address@hidden,
+New=[ those],Old=[]} stream elements is implementation defined.
+For composite types, the Write or Read attribute for each component is
+called in @Chg{New=[],Old=[a ]}canonical address@hidden, which],
+Old=[. The canonical order of components]} is last dimension varying
+fastest for an address@hidden,New=[ (unless the convention of the array is
+Fortran, in which case it is first dimension varying fastest)],Old=[]},
+and positional aggregate order for a record.
+Bounds are not included in the stream if @i(T) is an array type.
+If @i(T) is a discriminated type, discriminants are included only if they have
+defaults. If @i(T) is a tagged type, the tag is not included.
address@hidden type extensions, the Write or Read attribute for the parent type
+is called, followed by the Write or Read attribute of each component of the
+extension part, in canonical order. For a limited type extension, if the
+attribute of @Chg{Version=[2],New=[the parent],Old=[any ancestor]} type
address@hidden,New=[or any progenitor type ],Old=[]}of
address@hidden(T) @Chg{Version=[2],New=[is available anywhere within the 
immediate scope
+of @i<T>,],Old=[has been directly specified]} and the attribute
+of @Chg{Version=[2],New=[the parent type or],Old=[any ancestor type of]} the
+type of any of the extension components
address@hidden,New=[is not available at the freezing point of @i<T>, then],
+Old=[which are of a limited type has not been specified,]}
+the attribute of @i(T) shall be directly specified.],Old=[]}
+
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[The @Chg{Version=[2],New=[contents
+of the stream elements read and written],Old=[representation used]} by the
+Read and Write attributes of elementary address@hidden,New=[],Old=[ in
+terms of stream elements]}.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0023-1],ARef=[AI05-0264-1]}
address@hidden,Text=[If @i<T> is a discriminated type and its
+discriminants have defaults, then
+S'Read first reads the discriminants from the stream without modifying
address@hidden<Item>. S'Read then creates an object of type @i<T> constrained 
by these
+discriminants. The value of this object is then converted to the subtype
+of @i<Item> and is assigned to @i<Item>. Finally, the Read attribute for each
+nondiscriminant component of @i<Item> is called in canonical
+order as described above. Normal default initialization and finalization
+take place for the created object.]}
+
address@hidden
+  A discriminant with a default value is treated simply as
+  a component of the object. On the other hand,
+  an array bound or a discriminant without a default value,
+  is treated as @lquotes@;address@hidden@; or @lquotes@;address@hidden@;
+  that must be provided in order to create the object and thus is logically
+  separate from the regular components. Such @lquotes@;address@hidden@;
+  data are written by 'Output and produced as part of the delivered result by
+  the 'Input function, but they are not written by 'Write nor read by 'Read.
+  A tag is like a discriminant without a default.
+
+  @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0040],ARef=[AI95-00108-01]}
+  @ChgAdded{Version=[1],Text=[For limited type extensions, we must have a
+  definition of 'Read and 'Write if the parent type has one, as it is possible
+  to make a dispatching call through the attributes. The rule is designed to
+  automatically do the right thing in as many cases as possible.]}
+
+  @ChgRef{Version=[1],Kind=[Added],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[1],Text=[Similarly, a type that has a progenitor
+  with an available attribute must also have that attribute, for the
+  same reason.]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0023-1]}
+  @ChgAdded{Version=[3],Text=[The semantics of S'Read for a discriminated
+  type with defaults involves an anonymous object so that the
+  point of required initialization and finalization is well-defined,
+  especially for objects that change shape and have controlled components.
+  The creation of this anonymous object often can be omitted (see the
+  @ImplPermTitle below).]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00195-01]}
+  For a composite object, the subprogram denoted by the
+  Write or Read attribute of each component is called, whether it is the
+  default or is address@hidden,New=[ Implementations are
+  allowed to optimize these calls (see below), presuming the properties
+  of the attributes are preserved.],Old=[]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00270-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0264-1]}
address@hidden,Text=[Constraint_Error is raised by the predefined Write
+attribute if the value of the elementary item is outside the range of values
+representable using Stream_Size bits. For a signed integer type, an enumeration
+type, or a fixed point type, the range is unsigned only if the integer code for
+the lower bound of the first subtype is nonnegative, and a (symmetric) signed
+range that covers all values of the first subtype would require more than
+Stream_Size bits; address@hidden,New=[,],Old=[]} the range is signed.]}
+
+
address@hidden@;For @PrefixType{every subtype S'Class of a class-wide type
address@hidden(T)'Class}:
address@hidden
address@hidden<S'Class>, AttrName=<Write>,
+  Text=<S'Class'Write denotes a procedure with the following
+specification:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00441-01]}
address@hidden(procedure) S'Class'Write(
+   @RI{Stream} : @address@hidden,New=[not null ],Old=[]}access} 
Ada.Streams.Root_Stream_Type'Class;
+   @RI{Item}   : @key{in} @RI(T)'Class)
address@hidden
+
address@hidden@;Dispatches to the subprogram denoted by the Write attribute of
+the specific type identified by the tag of Item.>}
+
address@hidden<S'Class>, AttrName=<Read>,
+  Text=<S'Class'Read denotes a procedure with the following specification:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00441-01]}
address@hidden(procedure) S'Class'Read(
+   @RI{Stream} : @address@hidden,New=[not null ],Old=[]}access} 
Ada.Streams.Root_Stream_Type'Class;
+   @RI{Item} : @key{out} @RI(T)'Class)
address@hidden
+
address@hidden@;Dispatches to the subprogram denoted by the Read attribute of
+the specific type identified by the tag of Item.>}
address@hidden
+It is necessary to have class-wide versions of Read and Write
+in order to avoid generic contract model violations;
+in a generic, we don't necessarily know at compile time whether a given
+type is specific or class-wide.
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00270-01]}
address@hidden,Text=[If a
+stream element is the same size as a storage element,
+then the normal in-memory representation should be used by Read and
+Write for scalar objects.
+Otherwise, Read and Write should use the smallest
+number of stream elements needed
+to represent all values in the base range of the scalar type.]}
address@hidden don't add an Implementation Advice tag here, as we're deleting 
this.}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraph 17 was
+deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered.}
address@hidden
+
address@hidden
+For @PrefixType{every subtype S of a specific type @i(T)},
+the following attributes are defined.
address@hidden
address@hidden<S>, AttrName=<Output>,
+  Text=<S'Output denotes a procedure with the following specification:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00441-01]}
address@hidden(procedure) S'Output(
+   @RI{Stream} : @address@hidden,New=[not null ],Old=[]}access} 
Ada.Streams.Root_Stream_Type'Class;
+   @RI{Item} : @key{in} @RI(T))
address@hidden
+
address@hidden@;S'Output writes the value of @i{Item} to @i{Stream}, including
+any bounds or discriminants.>}
address@hidden
+Note that the bounds are included even for an array type whose
+first subtype is constrained.
address@hidden
+
address@hidden<S>, AttrName=<Input>,
+  Text=<S'Input denotes a function with the following specification:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00441-01]}
address@hidden(function) S'Input(
+   @RI{Stream} : @address@hidden,New=[not null ],Old=[]}access} 
Ada.Streams.Root_Stream_Type'Class)
+   @key(return) @RI(T)
address@hidden
+
address@hidden@;S'Input reads and returns one value from
address@hidden, using any bounds or discriminants written by a corresponding
+S'Output to determine how much to read.>}
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0040],ARef=[AI95-00108-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00444-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0192-1]}
address@hidden @Chg{Version=[2],New=[an ],Old=[]}untagged derived
address@hidden,New=[type],Old=[types]}, the Output
address@hidden,New=[(resp.],Old=[and]} address@hidden,New=[) attribute
+is],Old=[attributes of the parent type are]}
+inherited @Chg{Version=[2],New=[according to the rules given],
+Old=[as specified]} in
address@hidden and Representation address@hidden,
+New=[ if the attribute is @Chg{Version=[3],address@hidden and] ],
+Old=[]}available for the parent type at the point where @i{T}
+is declared. For a tagged derived type, these attributes are not
+inherited, but rather],Old=[; otherwise,]} the default
address@hidden,New=[],Old=[ of these
+attributes]} are address@hidden,New=[],Old=[ The default implementations of
+Output and Input attributes execute as follows:]}],
+Old=[Unless overridden by an @nt<attribute_definition_clause>, these
+subprograms execute as follows:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0192-1]}
+  @ChgAdded{Version=[3],Text=[See the note following the inheritance rules for
+  the Write attribute, above.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00444-01]}
address@hidden,Type=[Leading],Text=[The default implementations of the
+Output and Input attributes, where available, execute as follows:]}
address@hidden(Itemize)
address@hidden,Kind=[Revised],ARef=[AI05-0269-1]}
+If @i(T) is an array type, S'Output first writes the bounds,
+and S'Input first reads the bounds.
+If @i(T) has discriminants without defaults, S'Output first writes
+the discriminants (using @Chg{Version=[3],New=[the Write attribute of the
+discriminant type],Old=[S'Write]} for each), and S'Input first
+reads the discriminants (using @Chg{Version=[3],New=[the Read attribute of the
+discriminant type],Old=[S'Read]} for each).
+
address@hidden,Kind=[Revised],ARef=[AI95-00195-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0023-1]}
+S'Output then calls S'Write to write the value of @i{Item} to the stream.
+S'Input then creates an object @Chg{Version=[3],New=[of type
address@hidden<T>, ],Old=[(]}with the bounds or @Chg{Version=[3],New=[(when 
without
+defaults) the ],Old=[]}discriminants, if any,
+taken from the address@hidden,New=[],Old=[)]},
address@hidden,New=[passes],Old=[initializes]} it
address@hidden,New=[to],Old=[with]} S'Read, and returns
+the value of the address@hidden,New=[ If @i<T> has discriminants, then this
+object is unconstrained if and only the discriminants have
+defaults.],address@hidden,New=[ Normal default initialization
+and finalization take place for this object (see @RefSecNum{Object 
Declarations},
address@hidden and Finalization}, and
address@hidden and Finalization}).],Old=[]}
address@hidden(Itemize)
+
address@hidden,Kind=[Added],ARef=[AI95-00251-01]}
address@hidden,Text=[If @i<T> is an abstract type, then S'Input is
+an abstract function.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[For an abstract type @i<T>, S'Input can be
+  called in a dispatching call, or passed to an abstract formal
+  subprogram. But it cannot be used in nondispatching
+  contexts, because we don't allow objects of abstract types to exist.
+  The designation of this function as abstract has no
+  impact on descendants of @i<T>, as @i<T>'Input is not inherited for
+  tagged types, but rather recreated (and the default
+  implementation of @i<T>'Input calls @i<T>'Read, not the parent type's
+  @i<T>'Input). Note that @i<T>'Input cannot be specified in this case, as any
+  function with the proper profile is necessarily abstract, and specifying
+  abstract subprograms in an @nt{attribute_definition_clause} is illegal.]}
address@hidden
+
address@hidden@;For @PrefixType{every subtype S'Class of a class-wide type
address@hidden(T)'Class}:
address@hidden
address@hidden<S'Class>, AttrName=<Output>,
+  Text=<S'Class'Output denotes a procedure with the following
+specification:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00441-01]}
address@hidden(procedure) S'Class'Output(
+   @RI{Stream} : @address@hidden,New=[not null ],Old=[]}access} 
Ada.Streams.Root_Stream_Type'Class;
+   @RI{Item}   : @key{in} @RI(T)'Class)
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00344-01]}
address@hidden@;First writes the external tag of @i{Item} to @i{Stream}
+(by calling String'Output(@Chg{Version=[2],address@hidden, 
],address@hidden(@i{Item}'Tag)@Chg{Version=[2],New=[)],Old=[]}
address@hidden see @RefSecNum{Tagged Types and Type Extensions})
+and then dispatches to the subprogram denoted by the Output attribute of
+the specific type identified by the address@hidden,New=[ Tag_Error is
+raised if the tag of Item identifies a type declared at an accessibility
+level deeper than that of S.],Old=[]}>address@hidden of S'Class'Output 
attribute}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00344-01]}
+  @ChgAdded{Version=[2],Text=[We raise Tag_Error here for nested types as
+  such a type cannot be successfully read with S'Class'Input, and it doesn't
+  make sense to allow writing a value that cannot be read.]}
address@hidden
+
address@hidden<S'Class>, AttrName=<Input>,
+  Text=<S'Class'Input denotes a function with the following specification:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00441-01]}
address@hidden(function) S'Class'Input(
+   @RI{Stream} : @address@hidden,New=[not null ],Old=[]}access} 
Ada.Streams.Root_Stream_Type'Class)
+   @key{return} @RI(T)'Class
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00279-01],ARef=[AI95-00344-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0109-1]}
address@hidden@;First reads the external tag from @i{Stream} and determines
+the corresponding internal tag
+(by calling address@hidden,New=[Descendant_Tag],
+Old=[Internal_Tag]}(String'Input(@i{Stream})@Chg{Version=[2],New=[, 
S'Tag],Old=[]})
address@hidden,New=[which might raise Tag_Error ],address@hidden
+see @RefSecNum{Tagged Types and Type Extensions})
+and then dispatches to the subprogram denoted by the Input attribute of
+the specific type identified by the internal tag;
+returns that address@hidden,New=[ If the specific type identified
+by the internal tag @Chg{Version=[3],New=[],Old=[is not covered by
address@hidden<T>'Class or ]}is abstract, Constraint_Error
+is raised.],Old=[]}>address@hidden S'Class'Input attribute}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0109-1]}
+  @ChgAdded{Version=[3],Text=[Descendant_Tag will ensure that the tag it
+  returns is covered by T'Class; Tag_Error will be raised if it would not
+  cover T'Class.]}
address@hidden
+
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00195-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0228-1]}
address@hidden
+In the default implementation of Read and Input for a composite type,
+for each scalar component that is a discriminant or @Chg{Version=[3],New=[that
+has an implicit initial value],Old=[whose
address@hidden includes a @nt{default_expression}]},
+a check is made that the value returned by Read for the component
+belongs to its subtype.
address@hidden,Sec=(raised by failure of run-time check)}
+Constraint_Error is raised if this check fails.
+For other scalar components, no check is made.
+For each component that is of an access type, if the implementation can
+detect that the value returned by Read for the component is not
+a value of its subtype, Constraint_Error is raised. If the value
+is not a value of its subtype and this error is not detected,
+the component has an abnormal value, and erroneous execution
+can result (see @RefSecNum{Data Validity})address@hidden,New=[ In the
+default implementation of Read for a composite type with defaulted
+discriminants, if the actual parameter of Read is constrained, a check is made
+that the discriminants read from the stream are equal to those of the actual
+parameter. Constraint_Error is raised if this check fails.],Old=[]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0228-1]}
+  @ChgAdded{Version=[3],Text=[The check for scalar components that have an
+  implicit initial value is to preserve our @MetaRulesName that all objects
+  that have an implicit initial value do not become "deinitialized".]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0228-1]}
+  @ChgAdded{Version=[3],Text=[A scalar component can have an implicit initial
+  value if it has a default_expression, if the component's type has the
+  Default_Value aspect specified, or if the component is that of an array type
+  that has the Default_Component_Value aspect specified.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0228-1]}
+  @ChgAdded{Version=[3],Text=[An implementation should always be able to detect
+  the error for a null value read into a component of an access subtype with
+  a null exclusion; the "if the implementation can detect" is intended to cover
+  nonnull access values.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00195-01]}
address@hidden,address@hidden is unspecified at which point
+and in which order these checks are performed. In particular, if
+Constraint_Error is raised due to the failure of one of these checks, it is
+unspecified how many stream elements have been read from the stream.]}
+
address@hidden,Kind=[AddedNormal],Ref=[8652/0045],ARef=[AI95-00132-01]}
address@hidden,address@hidden,Sec=(raised by failure of run-time check)}
+In the default implementation of Read and Input for a type, End_Error
+is raised if the end of the stream is reached before the reading of a value of
+the type is completed.]}
+
address@hidden,Kind=[Revised],Ref=[8652/0040],ARef=[AI95-00108-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00195-01],ARef=[AI95-00251-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0039-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0106-1],ARef=[AI12-0121-1]}
address@hidden, Sec=(of Read for a type)}
address@hidden, Sec=(of Write for a type)}
address@hidden, Sec=(of Input for a type)}
address@hidden, Sec=(of Output for a type)}
address@hidden clause}
address@hidden clause}
address@hidden clause}
address@hidden clause}
+The stream-oriented attributes may be specified
+for any type via an @nt{attribute_definition_clause}.
address@hidden,address@hidden, each of the
+specific stream-oriented attributes may be specified using an
address@hidden on any @nt{type_declaration}, with the aspect name
+being the corresponding attribute name.] Each of the class-wide stream-oriented
+attributes may be specified using an @nt{aspect_specification} for a
+tagged type @i<T> using the name of the stream-oriented attribute followed
+by 'Class; such class-wide aspects do not
+apply to other descendants of @i<T>.],address@hidden,New=[The
+subprogram name given in such a
+clause shall @Chg{Version=[3],New=[statically denote a subprogram that
+is not],Old=[not denote]} an abstract subprogram. Furthermore, if a
+stream-oriented attribute is specified for an interface type by an
address@hidden, the subprogram name given in the clause shall
+statically denote a null procedure.],
+Old=[All nonlimited types have default implementations
+for these operations. An @nt{attribute_reference} for one of
+these attributes is illegal if the type is limited,
+unless the attribute has been specified by an
address@hidden@address@hidden@Chg{New=[ or @Redundant[(for a type extension)]
+the attribute has been specified for an ancestor type],Old=[]}.
+For an @address@hidden@!clause} specifying one of these
+attributes, the subtype of the Item parameter shall be the base subtype
+if scalar, and the first subtype otherwise.
+The same rule applies to the result of the Input function.]}]}
address@hidden of the old text is moved down}
address@hidden,address@hidden@address@hidden@AspectDefn{Output}],Old=[]}
address@hidden,address@hidden'address@hidden'address@hidden'address@hidden'Class}],Old=[]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00195-01]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0106-1]}
+  @Chg{Version=[4],New=[We need the last sentence to override the blanket rule
+    given in @RefSecNum{Aspect Specifications} that aspect'Class applies to the
+    type and all descendants.],address@hidden,New=[],Old=[This is to simplify
+    implementation.]}]}
address@hidden
+
address@hidden@ChgNote{This is junk}
+  @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0040],ARef=[AI95-00108-01]}
+  @ChgRef{Version=[2],Kind=[DeletedAdded],ARef=[AI95-00195-01]}
+  @ChgDeleted{Version=[2],address@hidden,address@hidden@;address@hidden
+  includes inherited attributes, and default implementations are never 
inherited.
+  So, for untagged limited types, the second part of the 
@nt{attribute_reference}
+  rule has the same meaning as the first part. However, tagged types never 
inherit
+  attributes, so the second rule is needed so that the default implementations
+  for the attributes can be called when those are constructed from a directly
+  specified ancestor.],Old=[]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0121-1]}
+  @ChgAdded{Version=[4],address@hidden Specifications} says that all
+  operational attributes can be specified with an aspect_specification.]}
address@hidden
+
address@hidden,Kind=[Added],Aspect=[Read'Class],
+  address@hidden,Text=[Procedure to read a value from a stream for
+    the class-wide type associated with a given type.]}]}
+
address@hidden,Kind=[Added],Aspect=[Write'Class],
+  address@hidden,Text=[Procedure to write a value to a stream for a
+    the class-wide type associated with a given type.]}]}
+
address@hidden,Kind=[Added],Aspect=[Input'Class],
+  address@hidden,Text=[Function to read a value from a stream for a
+    the class-wide type associated with a given type, including
+    any bounds and discriminants.]}]}
+
address@hidden,Kind=[Added],Aspect=[Output'Class],
+  address@hidden,Text=[Procedure to write a value to a stream for a
+    the class-wide type associated with a given type, including
+    any bounds and discriminants.]}]}
+
address@hidden,Kind=[Added],ARef=[AI12-0121-1]}
address@hidden,Text=[The subprogram name given in such an
address@hidden@address@hidden or @address@hidden shall
+statically denote a subprogram that is not an abstract subprogram. Furthermore,
+if a specific stream-oriented attribute is specified for an interface type, the
+subprogram name given in the @nt{attribute_definition_clause} or
address@hidden shall statically denote a null procedure.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[Stream attributes (other than
+  Input) are always null procedures for interface types (they have no
+  components). We need to allow explicit setting of the Read and Write
+  attributes in order that the class-wide attributes like LI'Class'Input
+  can be made available. (In that case, any descendant of the interface type
+  would require available attributes.) But we don't allow any concrete
+  implementation because these don't participate in extensions (unless the
+  interface is the parent type). If we didn't ban concrete implementations,
+  the order of declaration of a pair of interfaces would become significant.
+  For example, if Int1 and Int2 are interfaces with concrete implementations
+  of 'Read, then the following declarations would have different
+  implementations for 'Read:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Con1 @key{is new} Int1 @key{and} Int2 @key{with 
null record};
address@hidden Con2 @key{is new} Int2 @key{and} Int1 @key{with null record};]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Trailing],Text=[This would violate our design
+  principle that the order of the specification
+  of the interfaces in a @nt{derived_type_definition} doesn't matter.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[The Input attribute cannot be
+  specified for an interface. As it is a function, a null procedure is
+  impossible; a concrete function is not possible anyway as any function
+  returning an abstract type must be abstract. And we don't allow specifying
+  stream attributes to be abstract subprograms. This has no impact, as the
+  availability of Int'Class'Input (where Int is a limited interface) depends
+  on whether Int'Read (not Int'Input) is specified. There is no reason to
+  allow Int'Output to be specified, either, but there is equally no reason to
+  disallow it, so we don't have a special rule for that.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00195-01]}
+  @ChgAdded{Version=[2],Text=[Limited types generally do not have default
+  implementations of the stream-oriented attributes. The rules defining when
+  a stream-oriented attribute is available (see below) determine when an
+  attribute of a limited type is in fact well defined and usable. The rules are
+  designed to maximize the number of cases in which the attributes are usable.
+  For instance, when the language provides a default implementation of
+  an attribute for a limited type based on a specified attribute for the parent
+  type, we want to be able to call that attribute.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],Aspect=[Read],
+  address@hidden,Text=[Procedure to read a value from a stream for
+    a given type.]}]}
+
address@hidden,Kind=[AddedNormal],Aspect=[Write],
+  address@hidden,Text=[Procedure to write a value to a stream for a
+    given type.]}]}
+
address@hidden,Kind=[AddedNormal],Aspect=[Input],
+  address@hidden,Text=[Function to read a value from a stream for a
+    given type, including any bounds and discriminants.]}]}
+
address@hidden,Kind=[AddedNormal],Aspect=[Output],
+  address@hidden,Text=[Procedure to write a value to a stream for a
+    given type, including any bounds and discriminants.]}]}
+
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00195-01]}
address@hidden,Type=[Leading],Text=[A stream-oriented attribute for a
+subtype of a specific type @i<T> is @i<available> at places where one of the
+following conditions is true: @Defn2{Term=[available],Sec=[stream attribute]}]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<T> is nonlimited.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The @nt{attribute_designator} is Read (resp. Write)
+and @i<T> is a limited record extension, and the attribute Read (resp. Write)
+is available for the parent type of @i<T> and for the types of all of the
+extension components.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[In this case, the language provides a
+  well-defined default implementation, which we want to be able to call.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden is a limited untagged derived type, and the
+attribute was inherited for the type.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Attributes are only inherited for
+  untagged derived types, and surely we want to be able to call
+  inherited attributes.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The @nt{attribute_designator} is Input (resp.
+Output), and @i<T> is a limited type, and the attribute Read (resp. Write) is
+available for @i<T>.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The default implementation of Input and Output
+  are based on Read and Write; so if the implementation of Read or Write is
+  good, so is the matching implementation of Input or Output.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The attribute has been specified via an
address@hidden, and the @nt{attribute_definition_clause}
+is visible.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We always want to allow calling a specified
+  attribute. But we don't want availability to break privacy.
+  Therefore, only attributes whose specification can be seen count. Yes, we
+  defined the visibility of an @nt{attribute_definition_clause}
+  (see @RefSecNum{Visibility}).]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00195-01]}
address@hidden,Type=[Leading],Text=[A stream-oriented attribute for a subtype 
of a class-wide type
address@hidden<T>'Class is available at places where one of the following 
conditions is true:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<T> is nonlimited;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[the attribute has been specified via an
address@hidden, and the @nt{attribute_definition_clause}
+is visible; or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[the corresponding attribute of @i<T> is
+available, provided that if @i<T> has a partial view, the corresponding
+attribute is available at the end of the visible part where @i<T> is
+declared.]}
+
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The rules are stricter for class-wide attributes
+  because (for the default implementation) we must ensure that any specific
+  attribute that might ever be dispatched to is available. Because we require
+  specification of attributes for extensions of limited parent types with
+  available attributes, we can in fact know this. Otherwise, we would not be
+  able to use default class-wide attributes with limited types, a significant
+  limitation.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00195-01]}
address@hidden,Kind=[Revised],ARef=[AI12-0030-1]}
address@hidden,Text=[An @nt{attribute_reference} for one of the
+stream-oriented attributes is illegal unless the attribute is available at
+the place of the @nt{attribute_reference}. Furthermore, an
address@hidden for @i<T>'Input is illegal if @i<T> is an abstract
address@hidden,address@hidden contract issue} In addition to the
+places where @LegalityTitle normally apply (see
address@hidden Instantiation}), these rules also apply in the private
+part of an instance of a generic unit.],Old=[]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Stream attributes always exist. It is illegal
+  to call them in some cases. Having the attributes not be defined for
+  some limited types would seem to be a cleaner solution, but it would lead
+  to contract model problems for limited private types.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],address@hidden<T>'Input is available for abstract types
+  so that @i<T>'Class'Input is available. But we certainly don't want to allow
+  calls that could create an object of an abstract type. Remember that
+  @i<T>'Class is never abstract, so the above legality rule doesn't apply to
+  it. We don't have to discuss whether the attribute is specified, as it cannot
+  be: any function returning the type would have to be abstract, and we do not
+  allow specifying an attribute with an abstract subprogram.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],Aref=[AI12-0030-1]}
+  @ChgAdded{Version=[4],address@hidden@;These rules address@hidden refers to
+  just this paragraph and not to the rest of the rules in this section.
+  This rule probably should have been a @LegalityName, but the word
+  @ldquote@;address@hidden should key the reader that this is a @LegalityName,
+  no matter under what text heading it occurs.]}
address@hidden
+
address@hidden,Kind=[Added],Aref=[AI12-0030-1]}
address@hidden,Text=[Unless inherited from a parent type, if any, for an
+untagged type having a task, protected, or explicitly limited record part, the
+default implementation of each of the Read, Write, Input, and Output attributes
+raises Program_Error and performs no other action.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],Aref=[AI12-0030-1]}
+  @ChgAdded{Version=[4],Text=[It might seem that there is no need to specify 
the
+  behavior of the default implementation of a streaming attribute of, for
+  example, a task type because there is no way that it can be invoked. It is
+  possible, however, to construct an example where such a stream attribute can
+  be invoked. This involves using a formal untagged limited derived type for
+  which some streaming attribute is available (because it was explicitly
+  specified for the ancestor type) and a corresponding actual type for which 
the
+  attribute is unspecified (because the derivation occurred before the aspect
+  was specified for the ancestor type and the specification was therefore not
+  inherited).]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00195-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0192-1]}
address@hidden,Text=[In the @nt{parameter_and_result_profile}s for
address@hidden,New=[the default implementations of ],Old=[]}the
+stream-oriented attributes, the subtype of the Item parameter is the base
+subtype of @i<T> if @i<T> is a scalar type, and the first subtype otherwise.
+The same rule applies to the result of the Input attribute.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0192-1]}
address@hidden,Text=[An inherited stream attribute has a profile as
+determined by the rules for inheriting primitive subprograms (see
address@hidden and Representation Aspects} and
address@hidden Types and Classes}).]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00195-01]}
address@hidden,Kind=[AddedNormal],ARef=[AI05-0007-1]}
address@hidden,Text=[For an @nt{attribute_definition_clause} specifying
+one of these attributes, the subtype of the
address@hidden,address@hidden<Item>],Old=[Item]} parameter shall be the
address@hidden,New=[first subtype or the ],Old=[]}base
+subtype if scalar, and the first subtype
address@hidden,New=[if not scalar],Old=[otherwise]}. The same rule
+applies to the result of the Input function.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is to simplify implementation.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The view of the type at the point of the
+  @nt{attribute_definition_clause} determines whether the @Chg{Version=[3],
+  New=[],Old=[first subtype or ]}base subtype is
+  @Chg{Version=[3],New=[allowed],Old=[required]}. Thus, for a scalar
+  type with a partial view (which is never scalar), whether the
+  @Chg{Version=[3], New=[],Old=[first subtype or the ]} base subtype is
+  @Chg{Version=[3], New=[allowed],Old=[required]} is
+  determined by whether the @nt{attribute_definition_clause} occurs before or
+  after the full definition of the scalar type.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00366-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0065-1]}
address@hidden,address@hidden external streaming}
address@hidden streaming],Sec={type supports}}
address@hidden type is said to @i{support external streaming} if Read and Write 
attributes
+are provided for sending values of such a type between active
+partitions, with Write marshalling the representation, and Read unmarshalling
+the representation.] A limited type supports external streaming only if
+it has available Read and Write attributes. A type with a part that is of
address@hidden,New=[a nonremote],Old=[an]}
+access type supports external streaming only if that access type or the type of
+some part that includes the access type component, has Read and Write
+attributes that have been specified via an @nt{attribute_definition_clause},
+and that @nt{attribute_definition_clause} is visible. @Redundant[An anonymous
+access type does not support external streaming. ]All other types
address@hidden,New=[(including remote access types,
+see @RefSecNum{Remote Types Library Units}) ],Old=[]}support
+external streaming.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised]}
+  @ChgAdded{Version=[2],Text=[A limited type with a part that is of
+  @Chg{Version=[3],New=[a nonremote],Old=[an]} access
+  type needs to satisfy both rules.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00279-01],ARef=[AI95-00344-01]}
address@hidden,address@hidden(erroneous execution),Sec=(cause)}
+If the internal tag returned by Descendant_Tag to T'Class'Input identifies a
+type that is not library-level and whose tag has not been created, or does not
+exist in the partition at the time of the call, execution is erroneous.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The definition of Descendant_Tag prevents such
+  a tag from being provided to T'Class'Input if T is a library-level type.
+  However, this rule is needed for nested tagged types.]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[1],Kind=[AddedNormal],Ref=[8652/0040],ARef=[AI95-00108-01]}
+  @ChgAdded{Version=[1],Text=[For every subtype @i<S> of a language-defined
+  nonlimited specific type @i<T>, the output generated by S'Output or S'Write
+  shall be readable by S'Input or S'Read, respectively. This rule applies
+  across partitions if the implementation conforms to the Distributed Systems
+  Annex.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00195-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0092-1]}
+  @ChgAdded{Version=[2],Text=[If Constraint_Error is raised during a call to
+  Read because of failure of one the above checks, the implementation
+  @Chg{Version=[3],New=[shall],Old=[must]} ensure that the discriminants
+  of the actual parameter of Read are not modified.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00195-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0092-1]}
+  @ChgAdded{Version=[2],Text=[The number of calls performed by the predefined
+  implementation of the stream-oriented attributes on the Read and Write
+  operations of the stream type is unspecified. An implementation may take
+  advantage of this permission to perform internal buffering. However, all the
+  calls on the Read and Write operations of the stream type needed to implement
+  an explicit invocation of a stream-oriented attribute
+  @Chg{Version=[3],New=[shall],Old=[must]} take place before
+  this invocation returns. An explicit invocation is one appearing explicitly
+  in the program text, possibly through a generic instantiation (see
+  @RefSecNum{Generic Instantiation}).]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0023-1],ARef=[AI05-0264-1]}
+  @ChgAdded{Version=[3],Text=[If @i<T> is a discriminated type and its
+  discriminants have defaults, then in two cases an execution of the default
+  implementation of S'Read is not required to create an anonymous object of
+  type @i<T>: If the discriminant values that are read in are equal to the
+  corresponding discriminant values of @i<Item>, then no object of type @i<T>
+  need be created and @i<Item> may be used instead. If they are not equal and
+  @i<Item> is a constrained variable, then Constraint_Error may be raised at
+  that point, before any further values are read from the stream and before
+  the object of type @i<T> is created.]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0023-1]}
+  @ChgAdded{Version=[3],Text=[A default implementation of S'Input that calls 
the default implementation
+  of S'Read may create a constrained anonymous object with discriminants
+  that match those in the stream.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Keepnext=[T],Text=[This allows
+    the combined executions of S'Input and S'Read to create one
+    object of type @i<T> instead of two. If this option is exercised, then:]}
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The discriminants are read from the stream by
+    S'Input, not S'Read.]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[S'Input declares an object of type @i<T>
+    constrained by the discriminants read from the stream, not an
+    unconstrained object.]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The discriminant values that S'Read would
+    normally have read from the stream are read from Item instead.]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The permissions of the preceding paragraph
+    then apply and no object of type @i<T> need be created by the execution
+    of S'Read.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden
+For a definite subtype S of a type @i(T), only @i(T)'Write and @i(T)'Read
+are needed to pass
+an arbitrary value of the subtype through a stream.
+For an indefinite subtype S of a type @i(T), @i(T)'Output and @i(T)'Input
+will normally be needed, since @i(T)'Write and @i(T)'Read do not
+pass bounds, discriminants, or tags.
+
+User-specified attributes of S'Class are not inherited by other
+class-wide types descended from S.
address@hidden
+
address@hidden
address@hidden@address@hidden of user-defined Write attribute:}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00441-01]}
address@hidden My_Write(
+  Stream : @address@hidden,New=[not null ],Old=[]}access] 
Ada.Streams.Root_Stream_Type'Class;@Chg{Version=[2],New=[
+  ],address@hidden,New=[  ],Old=[]} : My_Integer'Base);
address@hidden(for) My_Integer'Write @key(use) My_Write;
address@hidden
address@hidden
address@hidden@address@hidden of network input/output using input output 
attributes:}
address@hidden
address@hidden(with) Ada.Streams; @key(use) Ada.Streams;
address@hidden(generic)
+    @key(type) Msg_Type(<>) @key(is private);
address@hidden(package) Network_IO @key(is)
+    address@hidden Connect/Disconnect are used to establish the stream]
+    @key(procedure) Connect(...);
+    @key(procedure) Disconnect(...);
+
+    address@hidden Send/Receive transfer messages across the network]
+    @key(procedure) Send(X : @key[in] Msg_Type);
+    @key(function) Receive @key(return) Msg_Type;
address@hidden(private)
+    @key(type) Network_Stream @key(is new) Root_Stream_Type @key(with) ...
+    @key(procedure) Read(...);  address@hidden define Read/Write for 
Network_Stream]
+    @key(procedure) Write(...);
address@hidden(end) Network_IO;
+
address@hidden(with) Ada.Streams; @key(use) Ada.Streams;
address@hidden(package body) Network_IO @key(is)
+    Current_Stream : @key(aliased) Network_Stream;
+    . . .
+    @key(procedure) Connect(...) @key(is) ...;
+    @key(procedure) Disconnect(...) @key(is) ...;
+
+    @key(procedure) Send(X : @key[in] Msg_Type) @key(is)
+    @key(begin)
+        Msg_Type'Output(Current_Stream'Access, X);
+    @key(end) Send;
+
+    @key(function) Receive @key(return) Msg_Type @key(is)
+    @key(begin)
+        @key(return) Msg_Type'Input(Current_Stream'Access);
+    @key(end) Receive;
address@hidden(end) Network_IO;
address@hidden
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0040],ARef=[AI95-00108-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b<Corrigendum:> Clarified how the default
+  implementation for stream attributes is determined (eliminating conflicting
+  language). The new wording provides that attributes for type extensions are
+  created by composing the parent's attribute with those for the extension
+  components if any. If a program was written assuming that the extension
+  components were not included in the stream (as in original Ada 95), it
+  would fail to work in the language as corrected by the Corrigendum.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00195-01]}
+  @ChgAdded{Version=[2],address@hidden Correction:] Explicitly provided a
+  permission that the number of calls to the underlying stream Read and Write
+  operations may differ from the number determined by the canonical operations.
+  If Ada 95 code somehow depended on the number of calls to Read or Write, it
+  could fail with an Ada 2005 implementation. Such code is likely to be very
+  rare; moreover, such code is really wrong, as the permission applies to Ada
+  95 as well.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00270-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The Stream_Size attribute is new. It allows specifying the number of bits
+  that will be streamed for a type. The @ImplAdviceTitle involving this
+  also was changed; this is not incompatible because @ImplAdviceTitle does
+  not have to be followed.]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0040],ARef=[AI95-00108-01],ARef=[AI95-00195-01],ARef=[AI95-00444-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Limited types may have 
default
+  constructed attributes if all of the parent and (for extensions) extension
+  components have available attributes. Ada 2005 adds the notion of
+  availability to patch up some holes in the Corrigendum model.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0009],ARef=[AI95-00137-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added wording to specify 
that
+  these are operational attributes.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0045],ARef=[AI95-00132-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that End_Error
+  is raised by the default implementation of Read and Input if the end of
+  the stream is reached. (The result could have been abnormal without this
+  clarification, thus this is not an inconsistency, as the programmer could
+  not have depended on the previous behavior.)]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00195-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that the default implementation of
+  S'Input does normal initialization on the object that it passes to S'Read.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00195-01]}
+  @ChgAdded{Version=[2],Text=[Explicitly stated that what is read from a
+  stream when a required check fails is unspecified.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Text=[Defined availability and default implementations
+  for types with progenitors.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00279-01]}
+  @ChgAdded{Version=[2],Text=[Specified that Constraint_Error is raised if
+  the internal tag retrieved for S'Class'Input is for some type not covered
+  by S'Class or is abstract. We also explicitly state that the program is
+  erroneous if the tag has not been created or does not currently exist in
+  the partition. (Ada 95 did not specify what happened in these
+  cases; it's very unlikely to have provided some useful result, so this is
+  not considered an inconsistency.)]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00344-01]}
+  @ChgAdded{Version=[2],Text=[Added wording to support nested type extensions.
+  S'Input and S'Output always raise Tag_Error for such extensions, and such
+  extensions were not permitted in Ada 95, so this is neither an extension
+  nor an incompatibility.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00366-01]}
+  @ChgAdded{Version=[2],Text=[Defined @i<supports external streaming> to
+  put all of the rules about @lquotes@;address@hidden stream attributes in one
+  place. This is used for distribution and for defining pragma Pure.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00441-01]}
+  @ChgAdded{Version=[2],Text=[Added the @key[not null] qualifier to the
+  first parameter of all of the stream attributes, so that the semantics
+  doesn't change between Ada 95 and Ada 2005. This change is compatible,
+  because mode conformance is required for subprograms specified as
+  stream attributes, and @nt{null_exclusion}s are not considered for
+  mode conformance.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00444-01]}
+  @ChgAdded{Version=[2],Text=[Improved the wording to make it clear that
+  we don't define the default implementations of attributes that cannot be
+  called (that is, aren't @lquotes@;address@hidden@;). Also clarified when
+  inheritance takes place.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0039-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Added a requirement that stream
+  attributes be specified by a static subprogram name rather than a
+  dynamic expression. Expressions cannot provide any useful functionality
+  because of the freezing rules, and the possibility of them complicates
+  implementations. Only pathological programs should be affected.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0007-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada address@hidden<Correction:>
+  Stream attributes
+  for scalar types can be specified with subprograms that take the first
+  subtype as well as the base type. This eliminates confusion about which
+  subtype is appropriate for attributes specified for partial views whose
+  full type is a scalar type. It also eliminates a common user error
+  (forgetting 'Base).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0023-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the definition
+  of the default version S'Read and S'Input to be well-defined if
+  S is a discriminated type with defaulted discriminants and
+  some components require initialization and/or finalizations.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0065-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Defined remote access
+  types to support external streaming, since that is their purpose.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0109-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Removed a misleading phrase
+  which implies that Constraint_Error is raised for internal tags of the
+  wrong type, when Tag_Error should be raised for such tags.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0139-2]}
+  @ChgAdded{Version=[3],Text=[Clarified that arrays with convention Fortran
+  are written in column-major order, rather then row-major order. This
+  is necessary in order that streaming of Fortran arrays is efficient.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0192-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified that the profile
+  of an inherited stream attribute is as defined for an inherited primitive
+  subprogram, while the default implementation of the same attribute might
+  have a different profile.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0194-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified that Stream_Size
+  has no effect on and is not effected by user-defined stream attributes.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0106-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada address@hidden<Corrigendum:>
+  Defined how to specify a class-wide stream-oriented attribute using an
+  @nt{aspect_specification}. It was always intended that this was possible,
+  but the method was not clear, as a class-wide type never has an explicit
+  declaration.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0030-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Defined the runtime
+  effect of stream attributes for untagged limited types, as there
+  is a weird corner case where they can be called. We don't specify this
+  as an inconsistency, as it doesn't make semantic sense to stream a task,
+  and nothing useful could have been done with that, so it should not
+  exist in any programs.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0106-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that the same
+  @LegalityTitle apply when a stream-oriented attribute is specified
+  via an @nt{aspect_specification} as applied when it is specified via
+  an @nt{attribute_definition_clause}.]}
address@hidden
+
+
address@hidden@Comment{For ISO version of Ada 2012 Standard}
address@hidden Rules}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} defines
+a place in the program text where each declared entity becomes
address@hidden@;address@hidden@;
+A use of an entity, such as a reference to it by name,
+or (for a type) an expression of the type,
+causes freezing of the entity in some contexts,
+as described below.
+The @LegalityTitle forbid certain kinds of uses of an entity
+in the region of text where it is frozen.]
address@hidden
+This concept has two purposes: a compile-time one and a run-time one.
+
+The compile-time purpose of the freezing rules comes from the fact that
+the evaluation of static expressions depends on overload resolution,
+and overload resolution sometimes depends on the value of a
+static expression.
+(The dependence of static evaluation upon overload resolution is
+obvious. The dependence in the other direction is more subtle.
+There are three rules that require static expressions in contexts that
+can appear in declarative places: The expression in an
address@hidden shall be static.
+In a record aggregate, variant-controlling discriminants shall be static.
+In an array aggregate with more than one named association,
+the choices shall be static.
+The compiler needs to know the value of these expressions in order to
+perform overload resolution and legality checking.)
+We wish to allow a compiler to evaluate static expressions when it sees
+them in a single pass over the @nt{compilation_unit}.
+The freezing rules ensure that.
+
+The run-time purpose of the freezing rules is called the @lquotes@;linear
+elaboration address@hidden@;
+This means that declarations are elaborated in the order in which they
+appear in the program text,
+and later elaborations can depend on the results of earlier ones.
+The elaboration of the declarations of certain entities requires run-time
+information about the implementation details of other entities.
+The freezing rules ensure that this information has been calculated by
+the time it is used.
+For example, suppose the initial value of a constant is the result of
+a function call that takes a parameter of type @i(T).
+In order to pass that parameter, the size of type @i(T) has to be known.
+If @i(T) is composite, that size might be known only at run time.
+
+(Note that in these discussions, words like @lquotes@;address@hidden@; and 
@lquotes@;address@hidden@;
+generally refer to places in the program text,
+as opposed to times at run time.)
address@hidden
address@hidden
address@hidden@;The @lquotes@;implementation address@hidden@; we're talking
+about above are:
address@hidden
+For a tagged type,
+the implementations of all the primitive subprograms of the type
address@hidden that is (in the canonical implementation model),
+the contents of the type descriptor, which contains pointers to the code for
+each primitive subprogram.
+
+For a type, the full type declaration of any parts (including the type itself)
+that are private.
+
+For a deferred constant,
+the full constant declaration, which gives the constant's value.
+(Since this information necessarily comes after the constant's type
+and subtype are fully
+known, there's no need to worry about its type or subtype.)
+
+For any entity,
+representation information specified by the user
+via representation items.
+Most representation items are for types
+or subtypes; however, various other kinds of entities,
+such as objects and subprograms, are possible.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+Similar issues arise for incomplete types.
+However, we do not use freezing @Chg{Version=[3],
+New=[to prevent premature access],Old=[there]};
+incomplete types have different, more severe, restrictions.
+Similar issues also arise for subprograms, protected operations,
+tasks and generic units.
+However, we do not use freezing @Chg{Version=[3],
+New=[to prevent premature access for those,],Old=[there]} either;
address@hidden Parts} prevents problems with run-time
address@hidden,New=[ Even so, freezing is used for these
+entities to prevent giving representation items too late (that is, after uses
+that require representation information, such as calls).],Old=[]}
address@hidden
address@hidden
+
address@hidden
+An evaluable construct should freeze anything that's needed to evaluate
+it.
+
+However, if the construct is not evaluated where it appears,
+let it cause freezing later, when it is evaluated.
+This is the case for @nt{default_expression}s and @nt{default_name}s.
+(Formal parameters, generic formal parameters, and components can have
address@hidden or @nt{default_name}s.)
+
+The compiler should be allowed to evaluate static expressions without
+knowledge of their context. (I.e. there should not be any special
+rules for static expressions that happen to occur in a context that
+requires a static expression.)
+
+Compilers should be allowed to evaluate static expressions (and record
+the results) using the run-time representation of the type.
+For example, suppose Color'Pos(Red) = 1, but the internal code for Red
+is 37.
+If the value of a static expression is Red,
+some compilers might store 1 in their symbol table,
+and other compilers might store 37.
+Either compiler design should be feasible.
+
+Compilers should never be required to detect erroneousness or exceptions at
+compile time (although it's very nice if they do).
+This implies that we should not require
+code-generation for a nonstatic expression of type @i(T) too early,
+even if we can prove that that expression will be erroneous,
+or will raise an exception.
+
address@hidden@;Here's an example (modified from AI83-00039, Example 3):
address@hidden
address@hidden T @key[is]
+    @key[record]
+        ...
+    @key[end] @key[record];
address@hidden F @key[return] T;
address@hidden G(X : T) @key[return] Boolean;
+Y : Boolean := G(F); address@hidden doesn't force T in Ada 83}
address@hidden T @key[use]
+    @key[record]
+        ...
+    @key[end] @key[record];
address@hidden
+
address@hidden@;AI83-00039 says this is legal.
+Of course, it raises Program_Error because the function bodies aren't
+elaborated yet. A one-pass compiler has to generate code for an expression of
+type T before it knows the representation of T.
+Here's a similar example, which AI83-00039 also says is legal:
address@hidden
address@hidden P @key[is]
+    @key[type] T @key[is] @key[private];
+    @key[function] F @key[return] T;
+    @key[function] G(X : T) @key[return] Boolean;
+    Y : Boolean := G(F); address@hidden doesn't force T in Ada 83}
address@hidden
+    @key[type] T @key[is]
+        @key[record]
+            ...
+        @key[end] @key[record];
address@hidden P;
address@hidden
+
+If T's size were dynamic, that size would be stored in some
+compiler-generated dope; this dope would be initialized at the place
+of the full type declaration.
+However, the generated code for the function calls
+would most likely allocate a temp of the size specified by the dope
address@hidden checking for Program_Error.
+That dope would contain uninitialized junk,
+resulting in disaster.
+To avoid doing that,
+the compiler would have to determine,
+at compile time, that the expression will raise Program_Error.
+
+This is silly. If we're going to require compilers to detect the exception at
+compile time, we might as well formulate the rule as a legality rule.
+
+Compilers should not be required to generate code to load the value
+of a variable before the address of the variable has been determined.
+
+After an entity has been frozen, no further requirements may be
+placed on its representation (such as by a representation item
+or a @nt{full_type_declaration}).
address@hidden
+
address@hidden
address@hidden, Sec=(entity)}
address@hidden points], Sec=(entity)}
+The @i(freezing) of an entity occurs at one or more places
+(@i{freezing points}) in the program
+text where the representation for the entity has to be
+fully determined. Each entity is frozen from its first
+freezing point to the end of the program text
+(given the ordering of compilation units defined in
address@hidden Compilation Process}).
address@hidden
+  The @lquotes@;address@hidden@; for a subprogram includes its calling 
convention
+  and means for referencing the subprogram body, either a 
@lquotes@;address@hidden@; or
+  specified address. It does
+  not include the code for the subprogram body itself, nor its
+  address if a link-name is used to reference the body.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0019-1],ARef=[AI05-0299-1]}
address@hidden,address@hidden, Sec=(profile)}This subclause
+also defines a place in the program text where the profile of each declared
+callable entity becomes @i{frozen}. A use of a callable entity causes freezing
+of its profile in some contexts, as described below. At the place where the
+profile of a callable entity becomes frozen, the entity itself becomes
+frozen.]}
+
address@hidden,Kind=[Revised],Ref=[8652/0014]}
address@hidden,Kind=[Revised],ARef=[AI05-0017-1],ARef=[AI05-0019-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0103-1]}
address@hidden,
+  Sec=(entity caused by the end of an enclosing construct)}
+The end of a @nt{declarative_part}, @nt{protected_body},
+or a declaration of a library package or generic library package,
+causes @i(freezing) of each
+entity @Chg{Version=[3],New=[and profile ],Old=[]}declared within it,
+except for incomplete types.
address@hidden, Sec=(entity caused by a body)}
+A @Chg{Version=[4],address@hidden, @nt{body_stub}, or
address@hidden,Old=[noninstance address@hidden other than a 
renames-as-body],Old=[]}]}
+causes freezing of each entity @Chg{Version=[3],New=[and profile 
],Old=[]}declared
+before it within the same @address@hidden,
+New=[ that is not an incomplete type; it only causes
+freezing of an incomplete type if the body is within the immediate scope of the
+incomplete type],Old=[]}.
address@hidden
+  This is worded carefully to handle nested packages and private types.
+  Entities declared in a nested @nt{package_specification}
+  will be frozen by some containing construct.
+
address@hidden,Kind=[Revised],ARef=[AI05-0017-1]}
+  An incomplete type declared in the private part of
+  a library @nt{package_specification}
+  can be completed in the address@hidden,New=[ For other
+  incomplete types (and in the bodies of library packages),
+  the completion of the type will be frozen at the end of
+  the package or @nt{declarative_part}, and that will freeze the
+  incomplete view as well.],Old=[]}
+
address@hidden,Kind=[Added],ARef=[AI05-0017-1]}
address@hidden,Text=[The reason we have to worry about
+  freezing of incomplete types is to prevent premature uses of
+  the types in dispatching calls. Such uses may need access to
+  the tag of the type, and the type has to be frozen to know
+  where the tag is stored.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  The part about bodies does not say @i{immediately} within.
+  A renaming-as-body does not have this property.
+  Nor does @Chg{Version=[3],New=[an imported body],Old=[a @nt{pragma} Import.]}
address@hidden
address@hidden
+  The reason bodies cause freezing is because we want
+  @ntf{proper_bodies} and @nt{body_stub}s to be interchangeable @em one
+  should be able to move a @nt{proper_body} to a @nt{subunit}, and
+  vice-versa, without changing the semantics.
+  Clearly, anything that should cause freezing should do so even if
+  it's inside a @nt{proper_body}.
+  However, if we make it a @nt{body_stub}, then the compiler can't
+  see that thing that should cause freezing.
+  So we make @nt{body_stub}s cause freezing, just in case they
+  contain something that should cause freezing.
+  But that means we need to do the same for @ntf{proper_bodies}.
+
+  Another reason for bodies to cause freezing,
+  there could be an added implementation burden if an entity
+  declared in an enclosing @nt<declarative_part> is frozen
+  within a nested body,
+  since some compilers look at bodies after looking
+  at the containing @nt{declarative_part}.
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0177-1]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0103-1]}
+  @ChgAdded{Version=[3],Text=[Note that
+  @Chg{Version=[4],New=[],address@hidden@;address@hidden
+  includes address@hidden and
+  @address@hidden,New=[ (even],Old=[]}
+  when those are used as address@hidden,New=[)],Old=[]},
+  as well as @Chg{Version=[4],address@hidden and
+  renames-as-bodies do not necessarily cause freezing; each have their
+  own specific rules],address@hidden (see
+  @RefSecNum{Completions of Declarations}). These all cause freezing,
+  along with @nt{proper_body}s and @nt{body_stub}s]}.]}
address@hidden
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0103-1]}
+  @ChgAdded{Version=[4],Text=[Note that the rule about proper bodies being
+  freezing only applies in @nt{declarative_part}s. All of the kinds of bodies
+  (see @RefSecNum{Completions of Declarations} @en keep in mind the
+  difference from @nt{body}s) that are allowed in a package specification have
+  their own freezing rules, so they don't need to be covered by the above 
rule.]}
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0046],ARef=[AI95-00106-01]}
address@hidden@RootDefn2{Term=[freezing], Sec=(entity caused by a construct)}
+A construct that (explicitly or implicitly) references an
+entity can cause the @i(freezing) of the entity, as defined by
+subsequent paragraphs.
address@hidden, Sec=(by a constituent of a construct)}
+At the place where a construct causes freezing,
+each @nt<name>, @address@hidden<expression>, @nt<implicit_dereference>],
address@hidden, or @nt{range}] within the construct causes
+freezing:
address@hidden
+Note that in the sense of this paragraph,
+a @nt{subtype_mark} @lquotes@;address@hidden@; the denoted subtype,
+but not the type.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0213-1]}
address@hidden, Sec=(generic_instantiation)}
+The occurrence of a @nt{generic_instantiation} causes
address@hidden,New=[, except that
+a @nt{name} which is a generic actual parameter whose corresponding
+generic formal parameter is a formal incomplete type
+(see @RefSecNum{Formal Private and Derived Types})
+does not cause freezing. In addition, if],Old=[;
+also, if]} a parameter of the instantiation is defaulted,
+the @nt{default_expression} or @nt{default_name} for that parameter
+causes freezing.
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0213-1]}
+  @ChgAdded{Version=[3],Text=[Thus, an actual parameter corresponding to a
+  formal incomplete type parameter may denote an incomplete or private type
+  which is not completely defined at the point of the 
@nt{generic_instantiation}.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0103-1],ARef=[AI12-0157-1]}
address@hidden,Text=[At the occurrence of an
address@hidden that is a
+completion, the return expression of the expression function causes freezing.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0103-1]}
+  @ChgAdded{Version=[4],Text=[This rule prevents calls through access values 
to an expression
+that might have unfrozen parts. Typically, elaboration checks and other
+freezing rules prevent this, but in this case the completion is elaborated
+and since this is not a @nt{body} it does not by itself freeze
+anything that precedes it.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0132-1],ARef=[AI12-0157-1]}
address@hidden,Text=[At the occurrence of a renames-as-body whose
address@hidden<callable_entity_>@nt{name} denotes an expression function, the
+return expression of the expression function causes freezing.]}
+
address@hidden, Sec=(object_declaration)}
+The occurrence of an @nt<object_declaration> that has no corresponding
+completion causes freezing.
address@hidden
+  Note that this does not include a @nt{formal_object_declaration}.
address@hidden
+
address@hidden, Sec=(subtype caused by a record extension)}
+The declaration of a record extension causes freezing of the parent
+subtype.
address@hidden
+This combined with another rule specifying
+that primitive subprogram declarations shall precede freezing
+ensures that all descendants of a tagged type implement all of
+its dispatching operations.
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00251-01]}
+  The declaration of a private
+  extension does not cause freezing. The freezing is deferred
+  until the full type declaration, which will necessarily be
+  for a record address@hidden,New=[, task, or protected type (the
+  latter only for a limited private extension derived from an interface)],
+  Old=[]}.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00251-01]}
address@hidden,Text=[The declaration of a record extension,
+interface type, task unit, or protected unit causes freezing of any
+progenitor types specified in the declaration.]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[This rule has the same purpose as the one
+above: ensuring that all descendants of an interface tagged type implement all
+of its dispatching operations. As with the previous rule, a private extension
+does not freeze its progenitors; the full type declaration (which must have the
+same progenitors) will do that.]}
address@hidden
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[An interface type can be a parent as well as a
+progenitor; these rules are similar so that the location of an interface
+in a record extension does not have an effect on the freezing of the interface
+type.]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0183-1]}
address@hidden,Text=[At the freezing point of the entity associated with
+an @nt{aspect_specification}, any @nt{expression}s or @nt{name}s within the
address@hidden cause freezing. Any static expressions within an
address@hidden also cause freezing
+at the end of the immediately enclosing declaration list.]}
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0046],ARef=[AI95-00106-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0177-1],ARef=[AI05-0183-1]}
address@hidden,Kind=[Revised],ARef=[AI05-0157-1]}
address@hidden, Sec=(by an expression)}
+A static expression @Chg{Version=[3],New=[(other than within an
address@hidden) ],Old=[]}causes freezing where it occurs.
address@hidden@PDefn2{Term=[freezing], Sec=(by an object name)}
+An object name or],Old=[A]} nonstatic expression causes freezing where it
+occurs, unless the @Chg{New=[name or ],Old=[]}expression is part of a
address@hidden<default_expression>, a @nt<default_name>, 
@Chg{Version=[3],New=[the
address@hidden,New=[return expression],address@hidden
+of an expression function, an @nt{aspect_specification},
+],Old=[]}or a per-object expression of a component's @nt{constraint}, in which
+case, the freezing occurs later as part of another address@hidden,New=[
+or at the freezing point of an associated entity],Old=[]}.
+
address@hidden,Kind=[Added],Ref=[8652/0046],ARef=[AI95-00106-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0019-1]}
address@hidden,address@hidden, Sec=(by an implicit call)}
+An implicit call freezes the same
+entities @Chg{Version=[3],New=[and profiles ],Old=[]}that would be frozen by an
+explicit call. This is true even if the implicit call is removed via
+implementation permissions.]}
+
address@hidden,Kind=[Added],Ref=[8652/0046],ARef=[AI95-00106-01]}
address@hidden,address@hidden, Sec=(subtype caused by an implicit conversion)}
+If an expression is implicitly converted to a type or subtype @i(T),
+then at the place where the expression causes freezing, @i(T) is frozen.]}
+
address@hidden@;The following rules define which entities are frozen at the 
place where
+a construct causes freezing:
address@hidden
address@hidden@PDefn2{Term=[freezing], Sec=(type caused by an expression)}
+At the place where an expression causes freezing,
+the type of the expression is frozen,
+unless the expression is an enumeration literal used as a
address@hidden of the @address@hidden of an
address@hidden@address@hidden
address@hidden
+We considered making enumeration literals never cause freezing,
+which would be more upward compatible,
+but examples like the variant record aggregate (Discrim => Red, ...)
+caused us to change our mind.
+Furthermore, an enumeration literal is a static expression,
+so the implementation should be allowed to represent it using its
+representation.
address@hidden
address@hidden
address@hidden@;The following pathological example was legal in Ada 83,
+but is illegal in Ada 95:
address@hidden
address@hidden P1 @key[is]
+    @key[type] T @key[is] @key[private];
+    @key[package] P2 @key[is]
+        @key[type] Composite(D : Boolean) @key[is]
+            @key[record]
+                @key[case] D @key[is]
+                    @key[when] False => Cf : Integer;
+                    @key[when] True  => Ct : T;
+                @key[end] @key[case];
+            @key[end] @key[record];
+    @key[end] P2;
+    X : Boolean := P2."="( (False,1), (False,1) );
address@hidden
+    @key[type] T @key[is] @key[array](1..Func_Call) @key[of] Integer;
address@hidden;
address@hidden
+
+In Ada 95, the declaration of X freezes Composite
+(because it contains an expression of that type),
+which in turn freezes T (even though Ct does not exist in this
+particular case).
+But type T is not completely defined at that point,
+violating the rule that a type shall be completely defined before it
+is frozen.
+In Ada 83, on the other hand, there is no occurrence of the name T,
+hence no forcing occurrence of T.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0019-1],ARef=[AI05-0177-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0157-1]}
address@hidden,address@hidden, Sec=(profile of a function call)}
address@hidden, Sec=(expression of an expression function by a call)}
+At the place where a function call causes freezing, the profile of the 
function is
+frozen. Furthermore, if a parameter of the call is defaulted, the
address@hidden for that parameter causes freezing. If the function call
+is to an expression function, the
address@hidden,New=[return expression],address@hidden
+of the expression function
+causes freezing.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0019-1]}
+  @ChgAdded{Version=[3],Text=[This is the important rule for profile freezing: 
a
+  call freezes the profile. That's because generating the call will need to 
know
+  how the parameters are passed, and that will require knowing details of the
+  types. Other uses of subprograms do not need to know about the parameters, 
and
+  thus only freeze the subprogram, and not the profile.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Note that we don't
+  need to consider procedure or entry calls, since a body freezes
+  everything that precedes it, and the end of a declarative part freezes
+  everything in the declarative part.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0177-1]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0103-1],ARef=[AI12-0157-1]}
+  @ChgAdded{Version=[3],Text=[Freezing of the
+  @Chg{Version=[4],New=[return expression],address@hidden
+  of an expression
+  function only needs to be considered when the expression function is in the
+  same compilation unit and there are no intervening
+  @Chg{Version=[4],address@hidden,Old=[bodies]}; the end of a
+  @nt{declarative_part} or library package freezes everything in it, and
+  a @Chg{Version=[4],address@hidden,Old=[body]} freezes everything
+  declared before it.]}
address@hidden
+
+
address@hidden,Kind=[Added],ARef=[AI05-0019-1],ARef=[AI05-0177-1],ARef=[AI05-0296-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0157-1]}
address@hidden,address@hidden, Sec=(profile of a callable entity by an 
instantiation)}
address@hidden, Sec=(expression of an expression function by an instantiation)}
+At the place where a @nt{generic_instantiation} causes freezing of a callable
+entity, the profile of that entity is frozen
+unless the formal subprogram corresponding to the callable entity has a
+parameter or result of a formal untagged incomplete type;
+if the callable entity is
+an expression function, the
address@hidden,New=[return expression],address@hidden
+of the expression function causes freezing.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Elaboration of the generic might call the actual
+  for one of its formal subprograms, so we need to know the profile and
+  (for an expression function) @nt{expression}.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0177-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0157-1]}
address@hidden,address@hidden, Sec=(expression of an expression function by 
Access attribute)}
+At the place where a use of the Access or Unchecked_Access attribute whose
address@hidden denotes an expression function causes freezing, the
address@hidden,New=[return expression],address@hidden
+of the expression function causes freezing.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[This is needed to avoid calls to
+unfrozen expressions. Consider:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Pack @key[is]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] Flub @key[is range] 0 .. 100;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] Foo (A : @key[in] Natural) @key[return] 
Natural @key[is]
+      (A + Flub'Size); -- @Examcom[The expression is not frozen here.]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0005-1]}
address@hidden,Text=[   @key[type] Bar @key[is access function] 
@Chg{Version=[4],New=[],Old=[Foo ]}(A : @key[in] Natural) @key[return] 
Natural;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   P : Bar := Foo'Access; -- @Examcom[(A)]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   Val : Natural := address@hidden(5); -- @Examcom[(B)]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Pack;]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If point (A) did not freeze the expression of Foo
+  (which freezes Flub), then the call at point (B) would be depending on the
+  aspects of the unfrozen type Flub. That would be bad.]}
address@hidden
+
address@hidden@PDefn2{Term=[freezing], Sec=(entity caused by a name)}
+At the place where a @nt<name> causes freezing,
+the entity denoted by the @nt<name> is frozen, unless
+the @nt<name> is a @nt<prefix> of an expanded name;
address@hidden, Sec=(nominal subtype caused by a name)}
+at the place where an object @nt{name} causes freezing, the
+nominal subtype associated with the @nt<name> is frozen.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+This only matters in the presence of deferred constants or
+access types; an @nt{object_declaration} other than a
address@hidden,New=[deferred constant declaration],address@hidden
+causes freezing of the nominal subtype, plus all component junk.
+
address@hidden,Kind=[Deleted],Ref=[8652/0046],ARef=[AI95-00106-01]}
address@hidden,address@hidden are covered by
address@hidden
address@hidden statement is just plain wrong.}
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0046],ARef=[AI95-00106-01]}
address@hidden,Type=[Leading],address@hidden, Sec=(subtype caused by an 
implicit dereference)}
+At the place where an @nt{implicit_dereference} causes freezing,
+the nominal subtype associated with the @nt{implicit_dereference} is frozen.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This rule ensures that X.D freezes the same
+  entities that address@hidden does. Note that an @nt{implicit_dereference} is
+  neither a @nt{name} nor @nt{expression} by itself, so it isn't covered by
+  other rules.]}
address@hidden
+
address@hidden@address@hidden, Sec=(type caused by a range)}
+At the place where a @nt{range} causes freezing, the type of the
address@hidden<range> is frozen.]
address@hidden
+This is consequence of the facts that expressions freeze their type,
+and the Range attribute is defined to be equivalent
+to a pair of expressions separated by @lquotes@;address@hidden@;.}
address@hidden
+
address@hidden@PDefn2{Term=[freezing],
+  Sec=(designated subtype caused by an allocator)}
+At the place where an @nt<allocator> causes freezing,
+the designated subtype of its type is frozen.
+If the type of the @nt<allocator> is a derived type,
+then all ancestor types are also frozen.
address@hidden
+  @nt{Allocator}s also freeze the named subtype,
+  as a consequence of other rules.
+
+  @Leading@;The ancestor types are frozen to prevent things like this:
address@hidden
address@hidden Pool_Ptr @key[is] @key[access] 
System.Storage_Pools.Root_Storage_Pool'Class;
address@hidden F @key[return] Pool_Ptr;
+
address@hidden P @key[is]
+    @key[type] A1 @key[is] @key[access] Boolean;
+    @key[type] A2 @key[is] @key[new] A1;
+    @key[type] A3 @key[is] @key[new] A2;
+    X : A3 := @key[new] Boolean; address@hidden Don't know what pool yet!}
+    @key[for] A1'Storage_Pool @key[use] F.all;
address@hidden P;
address@hidden
+
+  This is necessary because derived access types share their parent's pool.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0019-1]}
address@hidden@PDefn2{Term=[freezing], Sec=(subtypes of the profile of a 
callable entity)}
+At the place where a @Chg{Version=[3],New=[profile],Old=[callable entity]}
+is frozen, each subtype of @Chg{Version=[3],New=[the],Old=[its]} profile is 
frozen.
+If the @Chg{Version=[3],New=[corresponding ],Old=[]}callable entity is
+a member of an entry family, the index subtype of the family is
address@hidden,New=[],Old=[
address@hidden, Sec=(function call)}
+At the place where a function call
+causes freezing, if a parameter of the call is defaulted,
+the @address@hidden for that parameter causes freezing.]}
address@hidden
address@hidden,address@hidden above with rule}
address@hidden,Text=[We don't worry about freezing for procedure calls
+  or entry calls, since a body freezes everything that precedes it, and the end
+  of a declarative part freezes everything in the declarative part.]}
address@hidden
+
address@hidden@PDefn2{Term=[freezing],
+  Sec=[type caused by the freezing of a subtype]}
+At the place where a subtype is frozen,
+its type is frozen.
address@hidden, Sec=(constituents of a full type definition)}
address@hidden,
+  Sec=(first subtype caused by the freezing of the type)}
+At the place where a type is frozen, any expressions or @nt<name>s within
+the full type definition cause freezing;
+the first subtype, and
+any component subtypes,
+index subtypes, and parent subtype
+of the type are frozen as well.
address@hidden,
+  Sec=(class-wide type caused by the freezing of the specific type)}
address@hidden,
+  Sec=(specific type caused by the freezing of the class-wide type)}
+For a specific tagged type,
+the corresponding class-wide type is frozen as well.
+For a class-wide type,
+the corresponding specific type is frozen as well.
address@hidden
+  Freezing a type needs to freeze its first subtype in order to
+  preserve the property that the subtype-specific aspects of statically
+  matching subtypes are the same.
+
+  Freezing an access type does not freeze its designated subtype.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00341-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0019-1]}
address@hidden,Type=[Leading],Text=[At the place where a specific
+tagged type is frozen, the primitive subprograms of the type are
address@hidden,New=[ At the place where a type is frozen,
+any subprogram named in an @nt{attribute_definition_clause} for the type
+is frozen.],Old=[]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We have a language design principle that all of
+  the details of a specific tagged type are known at its freezing point.
+  But that is only true if the primitive subprograms are frozen at this
+  point as well. Late changes of Import and address clauses violate the
+  principle.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This rule means that no implicit call to
+  Initialize or Adjust can freeze a subprogram (the type and thus subprograms
+  would have been frozen at worst at the same point).]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0019-1]}
+  @ChgAdded{Version=[3],Text=[The second sentence is the rule that makes
+  it possible to check that only subprograms with convention Ada are
+  specified in @nt{attribute_definition_clause}s without jumping through 
hoops.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden"Leading" below is to get the last paragraph onto the page with 
everything else.}
address@hidden@Redundant[The explicit declaration of a primitive subprogram of a
+tagged type shall occur before the type is frozen
+(see @RefSecNum{Dispatching Operations of Tagged Types}).]
address@hidden
+This rule is needed
+because (1) we don't want people dispatching to things that haven't
+been declared yet, and (2) we want to allow tagged type descriptors
+to be static (allocated statically, and initialized to link-time-known
+symbols). Suppose T2 inherits primitive P from T1, and then
+overrides P. Suppose P is called @i{before} the declaration of the
+overriding P. What should it dispatch to? If the answer is the new
+P, we've violated the first principle above. If the answer is the
+old P, we've violated the second principle. (A call
+to the new one necessarily raises Program_Error, but that's
+beside the point.)
+
+Note that a call upon a dispatching operation of type @i(T) will freeze @i(T).
+
+We considered applying this rule to all derived types, for uniformity.
+However, that would be upward incompatible, so we rejected the idea.
+As in Ada 83, for an untagged type, the above call upon P will call the
+old P (which is arguably confusing).
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0222-1]}
+  @ChgAdded{Version=[3],Text=[This rule only applies to "original" declarations
+  and not to the completion of a primitive subprogram, even though a completion
+  is technically an explicit declaration, and it may declare a primitive
+  subprogram.]}
address@hidden
+
address@hidden@Redundant[A type shall be completely defined before it is frozen
+(see @RefSecNum{Completions of Declarations} and
address@hidden Types and Private Extensions}).]
+
address@hidden@Redundant[The completion of a deferred constant declaration 
shall occur
+before the constant is frozen
+(see @RefSecNum{Deferred Constants}).]
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00114-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[The above @LegalityTitle are stated
address@hidden@;address@hidden@; in the referenced
address@hidden,New=[subclauses],Old=[clauses]}.]}
address@hidden
+
address@hidden@ChgRef{Version=[1],Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden operational or],Old=[A]} representation item that
+directly specifies an aspect of an entity shall appear before the entity is
+frozen (see @RefSecNum{Operational and Representation Aspects}).
address@hidden last minute change (requested by WG9) moved this rule to 13.1(9).
+However, the rule there only covers types and subtypes. So this rule is not
+redundant, and I removed the @Redundant for it. I don't have a way to mark
+that as a change, so it is just gone. RLB-29-08-00}
+
address@hidden
+
address@hidden following is a "fix" to keep consistent with v. 5.95;
+appearently 6.0 is different.
address@hidden,Kind=[Deleted]}
address@hidden,Text=[Old @b{Change}.]}}
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
+From RM83-13.1(7). The wording here forbids freezing
+within the @address@hidden,address@hidden
+itself, which was not true of the Ada 83 wording.
+The wording of this rule is carefully written to
+work properly for type-related representation items.
+For example, an @address@hidden@!clause} is illegal after the
+type is frozen, even though the @ntf{_clause} refers to the first subtype.
+
address@hidden,Kind=[Added],ARef=[AI95-00114-01]}
address@hidden,Text=[The above @LegalityName is stated
+for types and subtypes in @RefSecNum{Operational and Representation Aspects},
+but the rule here covers all other entities as well.]}
address@hidden
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00114-01]}
address@hidden,Text=[The above @LegalityTitle
+are stated @lquotes@;address@hidden@;
+in the referenced clauses.]}
address@hidden
address@hidden
address@hidden@;Here's an example that illustrates when freezing occurs in the
+presence of defaults:
address@hidden
address@hidden T @key[is] ...;
address@hidden F @key[return] T;
address@hidden R @key[is]
+    @key[record]
+        C : T := F;
+        D : Boolean := F = F;
+    @key[end] @key[record];
+X : R;
address@hidden
+
+Since the elaboration of R's declaration does not allocate component C,
+there is no need to freeze C's subtype at that place.
+Similarly, since the elaboration of R does not evaluate the
address@hidden @lquotes@;F = address@hidden@;, there is no need to freeze the 
types
+involved at that point.
+However, the declaration of X @i{does} need to freeze these things.
+Note that even if component C did not exist, the elaboration of the
+declaration of X would still need information about T @em even though
+D is not of type T,
+its @nt{default_expression} requires that information.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Although we define freezing in terms of the program text as a whole
+(i.e. after applying the rules of @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden Structure and Compilation Issues}),
+the freezing rules actually have no effect beyond compilation unit boundaries.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+That is important, because @Chg{Version=[3],New=[Clause],Old=[Section]}
address@hidden Structure and Compilation Issues} allows some
+implementation definedness in the order of things,
+and we don't want the freezing rules to be implementation defined.
address@hidden
address@hidden
+These rules also have no effect in @nt{statement}s @em they only apply within
+a single @nt{declarative_part}, @nt{package_specification},
address@hidden,
address@hidden,
+or @nt{protected_body}.
address@hidden
address@hidden
+An implementation may choose to generate code for
address@hidden and @nt{default_name}s in
+line at the place of use.
address@hidden
+Alternatively, an implementation may choose to generate thunks
+(subprograms implicitly generated by the compiler)
+for evaluation of defaults.
+Thunk generation cannot, in general, be done at the place of the
+declaration that includes the default.
+Instead, they can be generated at the first freezing point of the
+type(s) involved.
+(It is impossible to write a purely one-pass Ada compiler,
+for various reasons.
+This is one of them @em the compiler needs to store a representation of
+defaults in its symbol table, and then walk that representation later,
+no earlier than the first freezing point.)
+
+In implementation terms, the linear elaboration model can be thought of
+as preventing uninitialized dope.
+For example, the implementation might generate dope to contain the size
+of a private type.
+This dope is initialized at the place where the type becomes
+completely defined.
+It cannot be initialized earlier,
+because of the order-of-elaboration rules.
+The freezing rules prevent elaboration of earlier declarations from
+accessing the size dope for a private type before it is initialized.
+
address@hidden overrides the freezing rules in the case of
+unrecognized @nt{pragma}s.
+
address@hidden,Kind=[Revised],Ref=[8652/0009],ARef=[AI95-00137-01]}
address@hidden @nt{aspect_clause}],Old=[A @nt{representation_clause}]} for
+an entity should most certainly @i{not} be a freezing point for the entity.
address@hidden
address@hidden
+
address@hidden
address@hidden is the last normative paragraph in the subclause}
address@hidden,Kind=[AddedNormal],ARef=[AI95-00279-01]}
address@hidden,Text=[The tag (see
address@hidden Types and Type Extensions}) of a tagged type T
+is created at the point where T is address@hidden,Sec=[of a tag]}]}
address@hidden
+
address@hidden
address@hidden with Ada 83}
+RM83 defines a forcing occurrence of a type as follows:
address@hidden@;A forcing occurrence is any occurrence [of the name of the type,
+subtypes of the type, or types or subtypes with subcomponents of the type]
+other than in a type or subtype
+declaration, a subprogram specification, an entry declaration, a deferred
+constant declaration, a @nt{pragma}, or a @ntf{representation_clause} for the 
type
+itself. In any case, an occurrence within an expression is always 
address@hidden@;
+
address@hidden@;It seems like the wording allows things like this:
address@hidden
address@hidden A @key[is] @key[array](Integer @key[range] 1..10) @key[of] 
Boolean;
address@hidden S @key[is] Integer @key[range] A'Range;
+    address@hidden not forcing for A}
address@hidden
+
+Occurrences within @nt{pragma}s can cause freezing in Ada 95.
+(Since such @nt{pragma}s are ignored in Ada 83,
+this will probably fix more bugs than it causes.)
address@hidden
+
address@hidden
address@hidden@;@Defn{extensions to Ada 83}
+In Ada 95, @nt{generic_formal_parameter_declaration}s
+do not normally freeze the entities from which they are defined.
+For example:
address@hidden
address@hidden Outer @key[is]
+    @key[type] T @key[is] @key[tagged] @key[limited] @key[private];
+    @key[generic]
+        @key[type] T2 @key[is]
+            @key[new] T @key[with] @key[private]; address@hidden Does not 
freeze T}
+                                address@hidden in Ada 95.}
+    @key[package] Inner @key[is]
+        ...
+    @key[end] Inner;
address@hidden
+    @key[type] T @key[is] ...;
address@hidden Outer;
address@hidden
+
+This is important for the usability of generics.
+The above example uses the Ada 95 feature of formal derived types.
+Examples using the kinds of formal parameters already allowed in
+Ada 83 are well known.
+See, for example, comments 83-00627 and 83-00688.
+The extensive use expected for formal derived types
+makes this issue even more compelling
+than described by those comments.
+Unfortunately, we are unable to solve the problem that
address@hidden cause freezing, even though a package
+equivalent to the instance would not cause freezing.
+This is primarily because such an equivalent package would have its
+body in the body of the containing program unit, whereas an instance
+has its body right there.
address@hidden
+
address@hidden
+The concept of freezing is based on Ada 83's concept of @lquotes@;forcing
address@hidden@;
+The first freezing point of an entity
+corresponds roughly to the place of the first forcing occurrence, in Ada
+83 terms.
+The reason for changing the terminology is that the new rules do not
+refer to any particular @lquotes@;address@hidden@; of a name of an entity.
+Instead, we refer to @lquotes@;address@hidden@; of an entity,
+which are sometimes implicit.
+
+In Ada 83, forcing occurrences were used only in rules about
address@hidden
+We have expanded the concept to cover private types,
+because the rules stated in RM83-7.4.1(4) are almost identical to the
+forcing occurrence rules.
+
address@hidden@;The Ada 83 rules are changed in Ada 95 for the following 
reasons:
address@hidden
+The Ada 83 rules do not work right for subtype-specific aspects.
+In an earlier version of Ada 9X, we considered allowing representation
+items to apply to subtypes other than the first subtype.
+This was part of the reason for changing the Ada 83 rules.
+However, now that we have dropped that functionality,
+we still need the rules to be different from the Ada 83 rules.
+
+The Ada 83 rules do not achieve the intended effect.
+In Ada 83, either with or without the AIs,
+it is possible to force the compiler to generate code that references
+uninitialized dope, or force it to detect erroneousness and exception
+raising at compile time.
+
+It was a goal of Ada 83 to avoid uninitialized access values.
+However, in the case of deferred constants, this goal was not achieved.
+
+The Ada 83 rules are not only too weak @em they are also too strong.
+They allow loopholes (as described above),
+but they also prevent certain kinds of @nt{default_expression}s that are
+harmless,
+and certain kinds of @nt{generic_declaration}s that are both harmless
+and very useful.
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+Ada 83 had a case where @Chg{Version=[2],New=[an @nt{aspect_clause}],
+Old=[a @nt{representation_clause}]} had a strong
+effect on the semantics of the program @em 'Small.
+This caused certain semantic anomalies.
+There are more cases in Ada 95,
+because the @Chg{Version=[2],address@hidden,
address@hidden has been generalized.
address@hidden
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0046],ARef=[AI95-00106-01],ARef=[AI95-00341-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b<Corrigendum:> Various freezing rules were added to fix holes in the rules.
+  Most importantly, implicit calls are now freezing, which make some
+  representation clauses illegal in Ada 2005 that were legal (but dubious) in
+  Ada 95. @b[Amendment Correction:] Similarly, the primitive subprograms of a
+  specific tagged type are frozen when the type is frozen, preventing dubious
+  convention changes (and address clauses) after the freezing point. In both
+  cases, the code is dubious and the workaround is easy.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0009],ARef=[AI95-00137-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added wording to specify 
that
+  both operational and representation attributes must be specified before
+  the type is frozen.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00251-01]}
+  @ChgAdded{Version=[2],Text=[Added wording that declaring a specific
+  descendant of an interface type freezes the interface type.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00279-01]}
+  @ChgAdded{Version=[2],Text=[Added wording that defines when a tag is created
+  for a type (at the freezing point of the type). This is used to specify
+  checking for uncreated tags (see @RefSecNum{Tagged Types and Type 
Extensions}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0019-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Separated the freezing of the profile from the rest of a subprogram, in order
+  to reduce the impact of the Ada 95 incompatibility noted above. (The effects
+  were much more limiting than expected.)]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0017-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Reworded so that
+  incomplete types with a deferred completion aren't prematurely
+  frozen.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0177-1]}
+  @ChgAdded{Version=[3],Text=[Added freezing rules for expression functions;
+  these are frozen at the point of call, not the point of declaration, like
+  default expressions.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0183-1]}
+  @ChgAdded{Version=[3],Text=[Added freezing rules for 
@nt{aspect_specification}s;
+  these are frozen at the freezing point of the associated entity, not the
+  point of declaration.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0213-1]}
+  @ChgAdded{Version=[3],Text=[Added freezing rules for formal incomplete types;
+  the corresponding actual is not frozen.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0103-1],ARef=[AI12-0132-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified when and what an
+  @nt{expression_function_declaration} that is a completion or that is the
+  target of a renames-as-body freezes. This is formally an incompatibility,
+  but as all known implementations freeze expression functions more
+  aggressively than allowed by either the old or new wording, practically this
+  will be an extension.]}
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/aa-aarm.msm 
b/packages/ada-ref-man/source_2012/aa-aarm.msm
new file mode 100755
index 0000000..2accc0e
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/aa-aarm.msm
@@ -0,0 +1,110 @@
address@hidden file for the AARM (Ada-Auth.Org on-line version}
+
address@hidden properties}
address@hidden@ShowIndexEntries @Comment{To match the Ada 95 AARM}}
address@hidden @Comment{As recommended by the ARG (Feb. 2011)}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden,Text=[Annotated Ada Reference address@hidden title for all 
versions}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden@Comment{For Ada 95 and 2005, use "section" instead}
+
address@hidden properties}
address@hidden @Comment{One large file allows Word to make a TOC}
address@hidden,Text=[ISO/IEC 8652:1995(E)]}
address@hidden,Text=[ISO/IEC 8652:1995(E) with COR.1:2001]}
address@hidden,Text=[ISO/IEC 8652:2007(E) Ed. 3]}
address@hidden,Text=[ISO/IEC 8652:2012(E)]}
address@hidden,Text=[ISO/IEC 8652:2012(E) with COR.1:2016]}
address@hidden,Text=[ISO/IEC 8652:202x(E)]}
address@hidden,UseClauseName=[T],address@hidden style footers}
address@hidden
address@hidden,SansSerif=[Arial]}
address@hidden,Text=[Original Text]}
address@hidden,Text=[Technical Corrigendum 1]}
address@hidden,Text=[Amendment 1]}
address@hidden,Text=[Ada 2012]}
address@hidden,Text=[Ada 2012 Corrigendum 1]}
address@hidden,Text=[Ada 202x]}
+
address@hidden properties}
address@hidden small files are used, thus no @SingleHTMLOutputFile command}
address@hidden,Unicode=[T]}
address@hidden,SrchName=[AA-SRCH.html],IndexName=[],
+   UseButtons=[T],OnTop=[T],OnBottom=[T]}
address@hidden let the program link to the index}
address@hidden
address@hidden<table border="0" cellspacing="0" cellpadding="6"><tr><td 
height="36" width="510" bgcolor="#339933"><b>&nbsp;&nbsp;<a class="Bar" 
style="font-size:160%" href="http://www.ada-auth.org/index.html";>Ada Conformity 
Assessment Authority</a>&nbsp;&nbsp;</b></td>
+<td height="35" width="120" bgcolor="#003399"><b>&nbsp;&nbsp;&nbsp;<a 
class="Bar" href="http://www.ada-auth.org/index.html";>Home</a></b></td>
+<td height="35" width="240" bgcolor="#003399"><b><a class="Bar" 
href="http://www.ada-auth.org/acaa.html";>Conformity Assessment</a></b></td><td 
height="35" width="160" bgcolor="#003399"><b>&nbsp;&nbsp;&nbsp;<a class="Bar" 
href="http://www.ada-auth.org/acats.html";>Test Suite</a></b></td>
+<td height="35" width="100" bgcolor="#003399"><b><a class="Bar" 
href="http://www.ada-auth.org/arg.html";>ARG</a></b></td><td height="35" 
width="140" bgcolor="#003399"><b><a class="Bar" 
href="http://www.ada-auth.org/arm.html";>Ada Standard</a></b></td></tr>
+</table><div><span style="font-size:60%">&nbsp;</span><br><b><span 
style="font-size:200%; color: rgb(0,51,153)">Annotated</span><span 
style="font-size:200%; color: rgb(0,0,102)"> Ada Reference Manual</span></b> 
&mdash; <a href="AA-TTL.html"><b>Legal Information</b></a></div>}
address@hidden<DIV Style="margin-top:0.0em"><IMG SRC="AE_logo.gif" height=100 
width=113 align=right ALT="Ada-Europe">
+<SPAN Style="vertical-align: middle; font-size:120%">Ada 2005 and 2012 
Editions sponsored in part by <SPAN Style="font-size: 125%"><A 
HREF="http://www.ada-europe.org/";><B>Ada-Europe</B></A></SPAN></SPAN></DIV>}
address@hidden,Background=[#FFFFF0],Link=[#000080],VLink=[#330033],ALink=[#0000FF]}
+
address@hidden files and related items, in collating order}
address@hidden<Title.MSS>,SectionName=<Ttl>,SectionNumber=[0],NewSection=[T]}
address@hidden @Comment{The table of contents goes here in the collating order}
address@hidden<Front_Matter.MSS>,SectionName=<00>,SectionNumber=[0],NewSection=[T]}
address@hidden<01.MSS>,SectionName=<01>,SectionNumber=[1],NewSection=[T]}
address@hidden<02.MSS>,SectionName=<02>,SectionNumber=[2],NewSection=[T]}
address@hidden<03A.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[T]}
address@hidden<03B.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[F]}
address@hidden<03C.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[F]}
address@hidden<04A.MSS>,SectionName=<04>,SectionNumber=[4],NewSection=[T]}
address@hidden<04B.MSS>,SectionName=<04>,SectionNumber=[4],NewSection=[F]}
address@hidden<05.MSS>,SectionName=<05>,SectionNumber=[5],NewSection=[T]}
address@hidden<06.MSS>,SectionName=<06>,SectionNumber=[6],NewSection=[T]}
address@hidden<07.MSS>,SectionName=<07>,SectionNumber=[7],NewSection=[T]}
address@hidden<08.MSS>,SectionName=<08>,SectionNumber=[8],NewSection=[T]}
address@hidden<09.MSS>,SectionName=<09>,SectionNumber=[9],NewSection=[T]}
address@hidden<10.MSS>,SectionName=<10>,SectionNumber=[10],NewSection=[T]}
address@hidden<11.MSS>,SectionName=<11>,SectionNumber=[11],NewSection=[T]}
address@hidden<12.MSS>,SectionName=<12>,SectionNumber=[12],NewSection=[T]}
address@hidden<13A.MSS>,SectionName=<13>,SectionNumber=[13],NewSection=[T]}
address@hidden<13B.MSS>,SectionName=<13>,SectionNumber=[13],NewSection=[F]}
address@hidden, the "Standard Libraries" separator page}
address@hidden<LIBRARY.MSS>,SectionName=<Lib>,SectionNumber=[0],NewSection=[T]}
address@hidden A; all of the files starting with "Pre_" are part of Annex A.}
address@hidden<PRE.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[T]}
address@hidden<PRE_Standard.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Ada.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Chars.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Strings.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Math.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<Real_Attribs.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_IO.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Cmdln.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Dirs.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Environ.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Containers.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Con2.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Locales.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden normative annexes:}
address@hidden<Interface.MSS>,SectionName=<B>,SectionNumber=[B],NewSection=[T]}
address@hidden<SP.MSS>,SectionName=<C>,SectionNumber=[C],NewSection=[T]}
address@hidden<RT.MSS>,SectionName=<D>,SectionNumber=[D],NewSection=[T]}
address@hidden<DS.MSS>,SectionName=<E>,SectionNumber=[E],NewSection=[T]}
address@hidden<InfoSys.MSS>,SectionName=<F>,SectionNumber=[F],NewSection=[T]}
address@hidden<Numerics.MSS>,SectionName=<G>,SectionNumber=[G],NewSection=[T]}
address@hidden<Safety.MSS>,SectionName=<H>,SectionNumber=[H],NewSection=[T]}
address@hidden don't use Annex I, as ISO used to require skipping I and O}
address@hidden<Obsolescent.MSS>,SectionName=<J>,SectionNumber=[J],NewSection=[T]}
address@hidden annexes:}
address@hidden<Attribs.MSS>,SectionName=<K>,SectionNumber=[K],NewSection=[T]}
address@hidden<Pragmas.MSS>,SectionName=<L>,SectionNumber=[L],NewSection=[T]}
address@hidden<Impldef.MSS>,SectionName=<M>,SectionNumber=[M],NewSection=[T]}
address@hidden<Glossary.MSS>,SectionName=<N>,SectionNumber=[N],NewSection=[T]}
address@hidden don't use Annex O, as ISO used to require skipping I and O}
address@hidden<Syntax.MSS>,SectionName=<P>,SectionNumber=[P],NewSection=[T]}
address@hidden<Langdef.MSS>,SectionName=<Q>,SectionNumber=[Q],NewSection=[T]}
address@hidden<Index.MSS>,SectionName=<IDX>,SectionNumber=[0],NewSection=[T]}
+
diff --git a/packages/ada-ref-man/source_2012/aa-rm.msm 
b/packages/ada-ref-man/source_2012/aa-rm.msm
new file mode 100755
index 0000000..e69c2f0
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/aa-rm.msm
@@ -0,0 +1,111 @@
address@hidden file for the RM (Ada-Auth.org on-line version)}
+
address@hidden properties}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden,Text=[Ada Reference address@hidden title for all versions}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden@Comment{For Ada 95 and 2005, use "section" instead}
+
address@hidden properties}
address@hidden @Comment{One large file allows Word to make a TOC}
address@hidden,Text=[ISO/IEC 8652:1995(E)]}
address@hidden,Text=[ISO/IEC 8652:1995(E) with COR.1:2001]}
address@hidden: address@hidden,Text=[ISO/IEC 8652:2007(E) Ed. 3]}
address@hidden: @RTFHeaderPrefix{Version=[2],Text=[Consolidated Ada Reference 
Manual - 2005 Edition]}}
address@hidden: address@hidden,Text=[ISO/IEC 8652:2012(E)]}
address@hidden: @RTFHeaderPrefix{Version=[3],Text=[Ada Reference Manual - 2012 
Edition]}}
address@hidden: address@hidden,Text=[ISO/IEC 8652:2012(E) with COR.1:2016]}
address@hidden,Text=[ISO/IEC 8652:202x(E)]}
address@hidden,UseClauseName=[T],address@hidden style footers}
address@hidden
address@hidden,SansSerif=[Arial]}
address@hidden,Text=[Original Text]}
address@hidden,Text=[Technical Corrigendum 1]}
address@hidden,Text=[Amendment 1]}
address@hidden,Text=[Ada 2012]}
address@hidden,Text=[Ada 2012 Corrigendum 1]}
address@hidden,Text=[Ada 202x]}
+
address@hidden properties}
address@hidden small files are used, thus no @SingleHTMLOutputFile command}
address@hidden,Unicode=[T]}
address@hidden,SrchName=[RM-SRCH.html],IndexName=[],
+   UseButtons=[T],OnTop=[T],OnBottom=[T]}
address@hidden let the program link to the index}
address@hidden
address@hidden<table border="0" cellspacing="0" cellpadding="6"><tr><td 
height="36" width="510" bgcolor="#339933"><b>&nbsp;&nbsp;<a class="Bar" 
style="font-size:160%" href="http://www.ada-auth.org/index.html";>Ada Conformity 
Assessment Authority</a>&nbsp;&nbsp;</b></td>
+<td height="35" width="120" bgcolor="#003399"><b>&nbsp;&nbsp;&nbsp;<a 
class="Bar" href="http://www.ada-auth.org/index.html";>Home</a></b></td>
+<td height="35" width="240" bgcolor="#003399"><b><a class="Bar" 
href="http://www.ada-auth.org/acaa.html";>Conformity Assessment</a></b></td><td 
height="35" width="160" bgcolor="#003399"><b>&nbsp;&nbsp;&nbsp;<a class="Bar" 
href="http://www.ada-auth.org/acats.html";>Test Suite</a></b></td>
+<td height="35" width="100" bgcolor="#003399"><b><a class="Bar" 
href="http://www.ada-auth.org/arg.html";>ARG</a></b></td><td height="35" 
width="140" bgcolor="#003399"><b><a class="Bar" 
href="http://www.ada-auth.org/arm.html";>Ada Standard</a></b></td></tr>
+</table><div><span style="font-size:60%">&nbsp;</span><br><span 
style="font-size:200%; color: rgb(0,0,153)"><b>Ada Reference Manual</b></span> 
&mdash; <a href="RM-TTL.html"><b>Legal Information</b></a></div>}
address@hidden<DIV Style="margin-top:0.0em"><IMG SRC="AE_logo.gif" height=100 
width=113 align=right ALT="Ada-Europe">
+<SPAN Style="vertical-align: middle; font-size:120%">Ada 2005 and 2012 
Editions sponsored in part by <SPAN Style="font-size: 125%"><A 
HREF="http://www.ada-europe.org/";><B>Ada-Europe</B></A></SPAN></SPAN></DIV>}
address@hidden,Background=[#FFFFF0],Link=[#000080],VLink=[#330033],ALink=[#0000FF]}
+
address@hidden files and related items, in collating order}
address@hidden<Title.MSS>,SectionName=<Ttl>,SectionNumber=[0],NewSection=[T]}
address@hidden @Comment{The table of contents goes here in the collating order}
address@hidden<Front_Matter.MSS>,SectionName=<00>,SectionNumber=[0],NewSection=[T]}
address@hidden<01.MSS>,SectionName=<01>,SectionNumber=[1],NewSection=[T]}
address@hidden<02.MSS>,SectionName=<02>,SectionNumber=[2],NewSection=[T]}
address@hidden<03A.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[T]}
address@hidden<03B.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[F]}
address@hidden<03C.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[F]}
address@hidden<04A.MSS>,SectionName=<04>,SectionNumber=[4],NewSection=[T]}
address@hidden<04B.MSS>,SectionName=<04>,SectionNumber=[4],NewSection=[F]}
address@hidden<05.MSS>,SectionName=<05>,SectionNumber=[5],NewSection=[T]}
address@hidden<06.MSS>,SectionName=<06>,SectionNumber=[6],NewSection=[T]}
address@hidden<07.MSS>,SectionName=<07>,SectionNumber=[7],NewSection=[T]}
address@hidden<08.MSS>,SectionName=<08>,SectionNumber=[8],NewSection=[T]}
address@hidden<09.MSS>,SectionName=<09>,SectionNumber=[9],NewSection=[T]}
address@hidden<10.MSS>,SectionName=<10>,SectionNumber=[10],NewSection=[T]}
address@hidden<11.MSS>,SectionName=<11>,SectionNumber=[11],NewSection=[T]}
address@hidden<12.MSS>,SectionName=<12>,SectionNumber=[12],NewSection=[T]}
address@hidden<13A.MSS>,SectionName=<13>,SectionNumber=[13],NewSection=[T]}
address@hidden<13B.MSS>,SectionName=<13>,SectionNumber=[13],NewSection=[F]}
address@hidden, the "Standard Libraries" separator page}
address@hidden<LIBRARY.MSS>,SectionName=<Lib>,SectionNumber=[0],NewSection=[T]}
address@hidden A; all of the files starting with "Pre_" are part of Annex A.}
address@hidden<PRE.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[T]}
address@hidden<PRE_Standard.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Ada.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Chars.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Strings.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Math.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<Real_Attribs.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_IO.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Cmdln.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Dirs.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Environ.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Containers.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Con2.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Locales.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden normative annexes:}
address@hidden<Interface.MSS>,SectionName=<B>,SectionNumber=[B],NewSection=[T]}
address@hidden<SP.MSS>,SectionName=<C>,SectionNumber=[C],NewSection=[T]}
address@hidden<RT.MSS>,SectionName=<D>,SectionNumber=[D],NewSection=[T]}
address@hidden<DS.MSS>,SectionName=<E>,SectionNumber=[E],NewSection=[T]}
address@hidden<InfoSys.MSS>,SectionName=<F>,SectionNumber=[F],NewSection=[T]}
address@hidden<Numerics.MSS>,SectionName=<G>,SectionNumber=[G],NewSection=[T]}
address@hidden<Safety.MSS>,SectionName=<H>,SectionNumber=[H],NewSection=[T]}
address@hidden don't use Annex I, as ISO used to require skipping I and O}
address@hidden<Obsolescent.MSS>,SectionName=<J>,SectionNumber=[J],NewSection=[T]}
address@hidden annexes:}
address@hidden<Attribs.MSS>,SectionName=<K>,SectionNumber=[K],NewSection=[T]}
address@hidden<Pragmas.MSS>,SectionName=<L>,SectionNumber=[L],NewSection=[T]}
address@hidden<Impldef.MSS>,SectionName=<M>,SectionNumber=[M],NewSection=[T]}
address@hidden<Glossary.MSS>,SectionName=<N>,SectionNumber=[N],NewSection=[T]}
address@hidden don't use Annex O, as ISO used to require skipping I and O}
address@hidden<Syntax.MSS>,SectionName=<P>,SectionNumber=[P],NewSection=[T]}
address@hidden<Langdef.MSS>,SectionName=<Q>,SectionNumber=[Q],NewSection=[T]}
address@hidden<Index.MSS>,SectionName=<IDX>,SectionNumber=[0],NewSection=[T]}
+
diff --git a/packages/ada-ref-man/source_2012/aarm.msm 
b/packages/ada-ref-man/source_2012/aarm.msm
new file mode 100755
index 0000000..2cbfe5a
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/aarm.msm
@@ -0,0 +1,106 @@
address@hidden file for the AARM}
+
address@hidden properties}
address@hidden@ShowIndexEntries @Comment{To match the Ada 95 AARM}}
address@hidden @Comment{As recommended by the ARG (Feb. 2011)}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden,Text=[Annotated Ada Reference address@hidden title for all 
versions}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden@Comment{For Ada 95 and 2005, use "section" instead}
+
address@hidden properties}
address@hidden @Comment{One large file allows Word to make a TOC}
address@hidden,Text=[ISO/IEC 8652:1995(E)]}
address@hidden,Text=[ISO/IEC 8652:1995(E) with COR.1:2001]}
address@hidden,Text=[ISO/IEC 8652:2007(E) Ed. 3]}
address@hidden,Text=[ISO/IEC 8652:2012(E)]}
address@hidden,Text=[ISO/IEC 8652:2012(E) with COR.1:2016]}
address@hidden,Text=[ISO/IEC 8652:202x(E)]}
address@hidden,UseClauseName=[T],address@hidden style footers}
address@hidden
address@hidden,SansSerif=[Arial]}
address@hidden,Text=[Original Text]}
address@hidden,Text=[Technical Corrigendum 1]}
address@hidden,Text=[Amendment 1]}
address@hidden,Text=[Ada 2012]}
address@hidden,Text=[Ada 2012 Corrigendum 1]}
address@hidden,Text=[Ada 202x]}
+
address@hidden properties}
address@hidden small files are used, thus no @SingleHTMLOutputFile command}
address@hidden,address@hidden "4Comp" for the Consolidated AARM}
address@hidden,SrchName=[AA-SRCH.html],IndexName=[],
+   UseButtons=[T],OnTop=[T],OnBottom=[T]}
address@hidden let the program link to the index}
address@hidden
address@hidden<DIV><B><SPAN Style="font-size:200%; color: 
rgb(0,51,153)">Annotated</SPAN><SPAN Style="font-size:200%; color: 
rgb(0,0,102)"> Ada Reference Manual</SPAN></B> &mdash; <A 
HREF="AA-TTL.html"><B>Legal Information</B></A></DIV>}
address@hidden<DIV Style="margin-top:0.0em"><IMG SRC="AE_logo.gif" height=100 
width=113 align=right ALT="Ada-Europe">
+<SPAN Style="vertical-align: middle; font-size:120%">Ada 2005 and 2012 
Editions sponsored in part by <SPAN Style="font-size: 125%"><A 
HREF="http://www.ada-europe.org/";><B>Ada-Europe</B></A></SPAN></SPAN></DIV>}
address@hidden,Background=[#FFFFF0],Link=[#000080],VLink=[#330033],ALink=[#0000FF]}
+
address@hidden files and related items, in collating order}
address@hidden<Title.MSS>,SectionName=<Ttl>,SectionNumber=[0],NewSection=[T]}
address@hidden @Comment{The table of contents goes here in the collating order}
address@hidden<Front_Matter.MSS>,SectionName=<00>,SectionNumber=[0],NewSection=[T]}
address@hidden<01.MSS>,SectionName=<01>,SectionNumber=[1],NewSection=[T]}
address@hidden<02.MSS>,SectionName=<02>,SectionNumber=[2],NewSection=[T]}
address@hidden<03A.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[T]}
address@hidden<03B.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[F]}
address@hidden<03C.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[F]}
address@hidden<04A.MSS>,SectionName=<04>,SectionNumber=[4],NewSection=[T]}
address@hidden<04B.MSS>,SectionName=<04>,SectionNumber=[4],NewSection=[F]}
address@hidden<05.MSS>,SectionName=<05>,SectionNumber=[5],NewSection=[T]}
address@hidden<06.MSS>,SectionName=<06>,SectionNumber=[6],NewSection=[T]}
address@hidden<07.MSS>,SectionName=<07>,SectionNumber=[7],NewSection=[T]}
address@hidden<08.MSS>,SectionName=<08>,SectionNumber=[8],NewSection=[T]}
address@hidden<09.MSS>,SectionName=<09>,SectionNumber=[9],NewSection=[T]}
address@hidden<10.MSS>,SectionName=<10>,SectionNumber=[10],NewSection=[T]}
address@hidden<11.MSS>,SectionName=<11>,SectionNumber=[11],NewSection=[T]}
address@hidden<12.MSS>,SectionName=<12>,SectionNumber=[12],NewSection=[T]}
address@hidden<13A.MSS>,SectionName=<13>,SectionNumber=[13],NewSection=[T]}
address@hidden<13B.MSS>,SectionName=<13>,SectionNumber=[13],NewSection=[F]}
address@hidden, the "Standard Libraries" separator page}
address@hidden<LIBRARY.MSS>,SectionName=<Lib>,SectionNumber=[0],NewSection=[T]}
address@hidden A; all of the files starting with "Pre_" are part of Annex A.}
address@hidden<PRE.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[T]}
address@hidden<PRE_Standard.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Ada.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Chars.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Strings.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Math.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<Real_Attribs.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_IO.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Cmdln.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Dirs.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Environ.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Containers.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Con2.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Locales.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden normative annexes:}
address@hidden<Interface.MSS>,SectionName=<B>,SectionNumber=[B],NewSection=[T]}
address@hidden<SP.MSS>,SectionName=<C>,SectionNumber=[C],NewSection=[T]}
address@hidden<RT.MSS>,SectionName=<D>,SectionNumber=[D],NewSection=[T]}
address@hidden<DS.MSS>,SectionName=<E>,SectionNumber=[E],NewSection=[T]}
address@hidden<InfoSys.MSS>,SectionName=<F>,SectionNumber=[F],NewSection=[T]}
address@hidden<Numerics.MSS>,SectionName=<G>,SectionNumber=[G],NewSection=[T]}
address@hidden<Safety.MSS>,SectionName=<H>,SectionNumber=[H],NewSection=[T]}
address@hidden don't use Annex I, as ISO used to require skipping I and O}
address@hidden<Obsolescent.MSS>,SectionName=<J>,SectionNumber=[J],NewSection=[T]}
address@hidden annexes:}
address@hidden<Attribs.MSS>,SectionName=<K>,SectionNumber=[K],NewSection=[T]}
address@hidden<Pragmas.MSS>,SectionName=<L>,SectionNumber=[L],NewSection=[T]}
address@hidden<Impldef.MSS>,SectionName=<M>,SectionNumber=[M],NewSection=[T]}
address@hidden<Glossary.MSS>,SectionName=<N>,SectionNumber=[N],NewSection=[T]}
address@hidden don't use Annex O, as ISO used to require skipping I and O}
address@hidden<Syntax.MSS>,SectionName=<P>,SectionNumber=[P],NewSection=[T]}
address@hidden<Langdef.MSS>,SectionName=<Q>,SectionNumber=[Q],NewSection=[T]}
address@hidden<Index.MSS>,SectionName=<IDX>,SectionNumber=[0],NewSection=[T]}
+
diff --git a/packages/ada-ref-man/source_2012/attribs.mss 
b/packages/ada-ref-man/source_2012/attribs.mss
new file mode 100755
index 0000000..11d72ce
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/attribs.mss
@@ -0,0 +1,41 @@
address@hidden(attribs, Root="ada.mss")
+
address@hidden: 2012/11/28 23:53:05 $}
address@hidden,New=[Language-Defined Aspects and 
Attributes],Old=[Language-Defined Attributes]}
+
address@hidden: e:\\cvsroot/ARM/Source/attribs.mss,v $}
address@hidden: 1.16 $}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[This annex summarizes the definitions given
+elsewhere of the language-defined aspects and attributes. Some aspects have
+corresponding attributes, as noted.]}
address@hidden
+
+
address@hidden,Name=[Language-Defined Aspects]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
address@hidden,address@hidden subclause summarizes the definitions
+given elsewhere of the language-defined aspects. Aspects are properties of
+entities that can be specified by the Ada program; unless otherwise
+specified below, aspects can be specified
+using an @nt{aspect_specification}.]}
+
address@hidden
+
address@hidden
+
address@hidden,Name=[Language-Defined Attributes]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[annex]}
+summarizes the definitions given elsewhere
+of the language-defined address@hidden,New=[ Attributes are
+properties of entities that can be queried by an Ada program.],Old=[]}
+
address@hidden
address@hidden
\ No newline at end of file
diff --git a/packages/ada-ref-man/source_2012/ds.mss 
b/packages/ada-ref-man/source_2012/ds.mss
new file mode 100755
index 0000000..774bec6
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/ds.mss
@@ -0,0 +1,2441 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/ds.mss,v $ }
address@hidden $Revision: 1.75 $ $Date: 2016/02/12 05:25:38 $ $Author: randy $ }
address@hidden(dist, Root="ada.mss")
address@hidden: 2016/02/12 05:25:38 $}
+
address@hidden Systems}
+
address@hidden
address@hidden Annex defines facilities for supporting the implementation
+of distributed systems using multiple partitions working
+cooperatively as part of a single Ada program.]
address@hidden
+
address@hidden
address@hidden to Ada 83}
+This Annex is new to Ada 95.
address@hidden
+
address@hidden
+
address@hidden node}
address@hidden node}
address@hidden system}
+A @i{distributed system} is an interconnection of one or more
address@hidden nodes} (a system resource that has both computational
+and storage capabilities), and zero or more @i{storage nodes}
+(a system resource that has only storage capabilities, with the storage
+addressable by one or more processing nodes).
+
address@hidden program}
+A @i{distributed program} comprises one or more partitions that
+execute independently (except when they communicate) in a distributed system.
+
address@hidden, Sec=(of the partitions of a program)}
+The process of mapping the partitions of a program
+to the nodes in a distributed system is
+called @i{configuring the partitions of the program}.
address@hidden
+
address@hidden
+
+The implementation shall provide means for explicitly assigning library
+units to a partition and for the configuring and execution of a program
+consisting of multiple partitions on a distributed system;
+the means are implementation defined.
address@hidden means for creating and executing distributed programs.}
+
address@hidden
+
address@hidden
+
+An implementation may require that the set of processing nodes of
+a distributed system be homogeneous.
+
address@hidden
+
address@hidden
+
+
+The partitions comprising a program may be executed on differently
+configured distributed systems or on a nondistributed system without
+requiring recompilation.
+A distributed program may be partitioned differently from the same set of
+library units without recompilation.
+The resulting execution is semantically equivalent.
+
+A distributed program retains the same type safety
+as the equivalent single partition program.
+
+
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden partitions of a distributed program are classified as either
+active or passive.]
address@hidden
+
address@hidden
+
address@hidden partition}
address@hidden partition}
+An @i{active partition} is a partition as defined in
address@hidden Execution}. A @i{passive partition} is a partition
+that has no thread of control of its own, whose
+library units are all preelaborated, and whose data and subprograms are
+accessible to one or more active partitions.
address@hidden
+In most situations, a passive partition does not execute, and does not have
+a @lquotes@;address@hidden@; environment task. Any execution involved in
+its elaboration and initialization occurs before it comes into existence in a
+distributed program (like most preelaborated entities). Likewise,
+there is no concrete meaning to passive partition termination.
address@hidden
+
+A passive partition shall include only @nt{library_item}s that either are
+declared pure or are shared
+passive (see @RefSecNum{Elaboration Control} and
address@hidden Passive Library Units}).
+
+An active partition shall be configured on a processing node.
+A passive partition shall be configured either on a storage node
+or on a processing node.
+
+The configuration of the partitions of a program onto a
+distributed system shall
+be consistent with the possibility for data references or calls
+between the partitions implied by their semantic dependences.
address@hidden access}
+Any reference to data or call of
+a subprogram across partitions is called a @i{remote access}.
address@hidden
+For example, an active partition that includes a unit with a semantic
+dependence on the declaration of another RCI package of some other active
+partition has to be connected to that other partition by some sort
+of a message passing mechanism.
+
+A passive partition that is accessible to an active partition should have
+its storage addressable to the processor(s) of the active partition. The
+processor(s) should be able to read and write from/to that
+storage, as well as
+to perform @lquotes@;address@hidden@; operations (in order to support 
entry-less
+protected objects).
+
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden, Sec=(partition)}
+A @nt{library_item} is elaborated as part of the elaboration
+of each partition that includes it.
+If a normal library unit
+(see @RefSecNum{Categorization of Library Units}) has state, then a separate
+copy of the state exists in each active partition that elaborates it.
address@hidden state evolves independently in each such partition.]
+
+
address@hidden
+Normal library units cannot be included in passive partitions.
address@hidden
+
address@hidden, Sec=(of a partition)}
address@hidden, Sec=(of a partition)}
address@hidden partition}
address@hidden partition}
address@hidden active partition @i{terminates} when its environment task
+terminates.] A partition becomes @i{inaccessible} if it terminates or if
+it is @i{aborted}. An active partition is aborted when its environment
+task is aborted. In addition, if a partition fails during its
+elaboration, it becomes inaccessible to other partitions. Other
+implementation-defined events can also result in a partition becoming
+inaccessible.
address@hidden events that can result in a partition becoming
+inaccessible.}
+
address@hidden,address@hidden be consistent with 8652/0006}
address@hidden@;For @ChgPrefixType{Version=[1],Kind=[Revised],Text=[a
address@hidden@nt{prefix}],Old=[prefix]} D that denotes a
+library-level declaration,
+excepting a declaration of or within a declared-pure library unit]},
+the following attribute is defined:
address@hidden
address@hidden<D>, AttrName=<Partition_Id>,
+  Text=[Denotes a value of the type @i{universal_integer} that
+         identifies the partition in which D was elaborated.
+         If D denotes the declaration of a remote call interface
+         library unit
+         (see @RefSecNum{Remote Call Interface Library Units}) the
+         given partition is the one where the body of D was elaborated.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00226-01]}
address@hidden(bounded error),Sec=(cause)}
+It is a bounded error for there to be cyclic elaboration dependences
+between the active partitions of a single distributed
+program.
address@hidden,Sec=(raised by failure of run-time check)}
+The possible address@hidden,New=[, in each of the partitions involved,],Old=[]}
+are deadlock during elaboration, or the raising of
address@hidden,New=[Communication_Error or ],address@hidden,
+New=[],Old=[ in one or all of the active partitions involved]}.
address@hidden
+
address@hidden
+
+An implementation may allow multiple active or passive partitions
+to be configured on
+a single processing node, and multiple passive partitions to be
+configured on a single storage node.
+In these cases, the scheduling policies, treatment
+of priorities, and management of shared resources between
+these partitions are implementation defined.
address@hidden scheduling policies, treatment
+of priorities, and management of shared resources between
+partitions in certain cases.}
+
+An implementation may allow separate copies of an active partition to be
+configured on different processing nodes, and to provide
+appropriate interactions between the copies to present
+a consistent state of the partition to other active partitions.
address@hidden
+  The language does not specify the nature of these interactions,
+  nor the actual level of consistency preserved.
address@hidden
+
+In an implementation, the partitions of a distributed
+program need not be loaded and elaborated all at the same time;
+they may be loaded and elaborated one at a time over an extended
+period of time. An implementation may provide facilities to abort
+and reload a partition during the execution of a distributed program.
+
+An implementation may allow the state of some of the partitions of
+a distributed program to persist while other partitions of the program
+terminate and are later reinvoked.
address@hidden
+
address@hidden
+
+Library units are grouped into partitions after compile time,
+but before run time.
+At compile time, only the relevant library unit properties are
+identified using categorization pragmas.
+
+
+The value returned by the Partition_Id attribute can be used as a
+parameter to implementation-provided subprograms in order
+to query information about the partition.
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00226-01]}
+  @ChgAdded{Version=[2],Text=[Corrected wording so that a partition that
+  has an elaboration problem will either deadlock or raise an exception.
+  While an Ada 95 implementation could allow some partitions to continue to
+  execute, they could be accessing unelaborated data, which is very bad
+  (and erroneous in a practical sense). Therefore, this isn't listed as an
+  inconsistency.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden of Library Units}
+
address@hidden
address@hidden units can be categorized according to the role
+they play in a distributed program. Certain restrictions
+are associated with each category to ensure that the semantics
+of a distributed program remain close to the semantics for a nondistributed
+program.]
+
address@hidden,Kind=[Revised],ARef=[AI05-0243-1]}
address@hidden pragma}
address@hidden, categorization}
address@hidden unit pragma], Sec=(categorization pragmas)}
address@hidden, library unit], Sec=(categorization pragmas)}
address@hidden,address@hidden aspect}],address@hidden library unit}
+A @i{categorization pragma} is a library unit pragma
+(see @RefSecNum{Pragmas and Program Units})
+that @Chg{Version=[3],New=[specifies a corresponding @i{categorization aspect}.
+A categorization aspect ],Old=[]}restricts the declarations, child units, or
+semantic dependences of the library unit to which it applies. A
address@hidden library unit} is a library unit @Chg{Version=[3],New=[that has a
+categorization aspect that is True],Old=[to which a categorization pragma
+applies]}.
+
address@hidden,Kind=[Revised],ARef=[AI05-0243-1]}
+The pragmas Shared_Passive, Remote_Types, and Remote_Call_Interface
+are categorization address@hidden,New=[,
+and the associated aspects are categorization aspects],Old=[]}.
+In addition, for the purposes of this Annex, the @Chg{Version=[3],New=[aspect
+Pure (see @RefSecNum{Elaboration Control}) is
+considered a categorization aspect and the],Old=[]}
+pragma Pure @Chg{Version=[3],New=[],Old=[(see @RefSecNum{Elaboration Control}) 
]}is
+considered a categorization pragma.
+
address@hidden,Kind=[Revised],Ref=[8652/0078],ARef=[AI95-00048-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0243-1]}
address@hidden@Defn{shared passive library unit}
+A library package or generic library package is called a
address@hidden passive} library unit if @Chg{Version=[3],New=[the],Old=[a]}
+Shared_Passive @Chg{Version=[3],New=[aspect of the unit is True],Old=[pragma
+applies to it]}. @Defn{remote types library unit} A library package or generic
+library package is called a @i{remote types} library unit if
address@hidden,New=[the],Old=[a]} Remote_Types @Chg{Version=[3],New=[aspect of
+the unit is True],Old=[pragma applies to it]}. @Defn{remote call interface} A
+library @Chg{New=[unit],Old=[package or generic library package]} is called a
address@hidden call interface} if @Chg{Version=[3],New=[the],Old=[a]}
+Remote_Call_Interface @Chg{Version=[3],New=[aspect of the unit is
+True],Old=[pragma applies to it]}.]
address@hidden library unit}
+A @i{normal library unit} is one @Chg{Version=[3],New=[for],Old=[to]}
+which no categorization
address@hidden,New=[aspect is True],Old=[pragma applies]}.
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0243-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[These terms (other than @ldquote@;normal
+  library address@hidden) are really defined in the following subclauses.]}
address@hidden
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0078],ARef=[AI95-00048-01]}
address@hidden,Text=[A library subprogram can be a remote call
+interface, but it cannot be a remote types or shared passive library unit.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0206-1],ARef=[AI05-0243-1],ARef=[AI05-0269-1],ARef=[AI05-0299-1]}
address@hidden various categories of library units and the associated
+restrictions are described in this @Chg{Version=[3],New=[and the following],
+Old=[clause and its]} subclauses. The categories are
+related hierarchically in that the library units of one category can depend
+semantically only on library units of that category or an earlier
address@hidden,New=[ in the hierarchy],Old=[]}, except
+that the body of a remote types or remote call interface library unit is
address@hidden,New=[, the declaration of a remote types or
+remote call interface library unit may depend on preelaborated normal library
+units that are mentioned only in private with clauses, and all categories can
+depend on limited views],Old=[]}.
+
address@hidden,Kind=[Revised],ARef=[AI05-0243-1],ARef=[AI05-0269-1]}
address@hidden@;The overall hierarchy (including declared pure) is as
address@hidden,New=[, with a lower-numbered category being
address@hidden@;earlier in the address@hidden in the sense of the
+previous paragraph],Old=[]}:
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[Declared Pure]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Shared Passive]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Remote Types]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Remote Call Interface]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Normal (no restrictions)]}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraphs 7 through 11
+were deleted.>address@hidden message should be
+deleted if the paragraphs are ever renumbered.}
address@hidden
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0243-1]}
address@hidden,Text=[Declared Pure @\Can depend only on other declared
+pure library units;]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0243-1]}
address@hidden,Text=[Shared Passive @\Can depend only on other shared passive
+    or declared pure library units;]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0206-1],ARef=[AI05-0243-1]}
address@hidden,Text=[Remote Types @\The declaration of the library unit can 
depend only
+    on other remote types library units,
+    or one of the
+    above library unit categories, or limited views,
+    or preelaborated normal library units that are mentioned
+    only in private with clauses;
+    the body of the library unit is unrestricted;]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0206-1],ARef=[AI05-0243-1]}
address@hidden,Text=[Remote Call Interface @\The declaration of the library 
unit can depend only
+    on other remote call interfaces, or one
+    of the above;
+    the body of the library unit is unrestricted;]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0243-1]}
address@hidden,Text=[Normal @\Unrestricted.]}
address@hidden
+
+Declared pure and shared passive library units are preelaborated.
+The declaration of a remote types or remote call interface library unit
+is required to be preelaborable.
+]
+
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],Ref=[8652/0079],ARef=[AI95-00208-01]}
address@hidden,Text=[For a given library-level type declared in
+a preelaborated library unit or in the declaration of a remote types or remote
+call interface library unit, the implementation shall choose the same
+representation for the type upon each elaboration of the type's declaration for
+different partitions of the same program.]}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraph 13 was
+deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered.}
address@hidden
+
address@hidden
+
+Implementations are allowed to define other categorization pragmas.
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0078],ARef=[AI95-00048-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that a library
+  subprogram can be a remote call interface unit.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0079],ARef=[AI95-00208-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Removed the requirement 
that
+  types be represented the same in all partitions, because it prevents the
+  definition of heterogeneous distributed systems and goes much further than
+  required.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0206-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[We now allow private withs of preelaborated
+  units in Remote Types and Remote Call Interface units; this is documented
+  as an extension in the subclauses where this is defined normatively.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0243-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[We have introduced categorization aspects; these
+  are documented as extensions in the subclauses where they actually are 
defined.]}
address@hidden
+
+
address@hidden Passive Library Units}
address@hidden
address@hidden shared passive library unit is used for managing global data
+shared between active partitions. The restrictions on shared passive
+library units prevent the data or tasks of one active partition
+from being accessible to another active partition through
+references implicit in objects declared in the shared passive library
+unit.]
address@hidden
+
address@hidden
+The restrictions governing a shared
+passive library unit are
+designed to ensure that objects and
+subprograms declared in the package can be used safely from
+multiple active partitions, even though the active partitions
+live in different address spaces, and have separate run-time systems.
address@hidden
+
address@hidden
address@hidden
address@hidden@PDefn2{Term=[categorization pragma], Sec=(Shared_Passive)}
address@hidden, categorization], Sec=(Shared_Passive)}
+The form of a @nt{pragma} Shared_Passive is as follows:
address@hidden
+
address@hidden@key{pragma} @prag(Shared_Passive)[(@address@hidden)];'
+
address@hidden
+
address@hidden
+
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0243-1]}
address@hidden passive library unit}
address@hidden,New=[ @nt{pragma} Shared_Passive is used to specify that a
+library unit is a],Old=[]} @i{shared passive library address@hidden,New=[,
+namely that the],Old=[ is
+a library unit to which a]}
+Shared_Passive
address@hidden,address@hidden of the library unit is
+True],Old=[pragma applies]}. The following restrictions apply to such a library
+unit:
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Shared_Passive],
+    address@hidden,Text=[A given package is used to represent
+      shared memory in a distributed system.]}]}
+
address@hidden
address@hidden shall be preelaborable (see @RefSecNum{Elaboration Control});]
address@hidden
+  It cannot contain library-level declarations of protected objects
+  with entries, nor of task objects. Task objects are disallowed
+  because passive partitions don't have any threads of control of their
+  own, nor any run-time system of their own.
+  Protected objects with entries are disallowed because an entry queue
+  contains references to calling tasks, and that would require in
+  effect a pointer from a passive partition back to a task in
+  some active partition.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0243-1]}
+it shall depend semantically only upon declared pure or shared passive
address@hidden,address@hidden,Old=[library units]};
address@hidden
+  Shared passive packages cannot depend semantically upon remote types packages
+  because the values of an access type declared in a remote types package
+  refer to the local heap of the active partition including the
+  remote types package.
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0243-1]}
+  @ChgAdded{Version=[3],Text=[We say @nt{library_item} here, so that
+  limited views are allowed; those are not library units, but they are
+  @nt{library_item}.]}
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0080],ARef=[AI95-00003-01]}
address@hidden,Kind=[Revised],ARef=[AI12-0038-1]}
+it shall not contain a library-level declaration of an access type
+that designates a class-wide type,@Chg{Version=[4],New=[ nor a type
+with a part that is of a],Old=[]}
+task address@hidden,New=[],Old=[,]} or protected type with
address@hidden@Chg{Version=[4],New=[;],address@hidden,
+Old=[; if the shared passive library unit is generic, it shall
+not contain a declaration for such an access type unless the
+declaration is nested within a body other than
+a @nt<package_body>]}.]}
address@hidden
+  These kinds of access types are disallowed because the object
+  designated by an access value of such a type could
+  contain an implicit reference back to
+  the active partition on whose behalf the designated object was
+  created.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0038-1]}
address@hidden,Text=[it shall not contain a library-level declaration
+that contains a name that denotes a type declared within a declared-pure
+package, if that type has a part that is of an access type; for the purposes of
+this rule, the parts considered include those of the full views of any private
+types or private extensions.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This rule breaks privacy by looking into the full
+  views of private types. Avoiding privacy breakage here would have required
+  disallowing the use in a shared passive package of any private type
+  declared in a declared-pure package, which would have been severely
+  incompatible.]}
address@hidden
+
address@hidden
+
address@hidden, Sec=(from shared passive library units)}
address@hidden
+Notwithstanding the definition of accessibility given in
address@hidden(Operations of Access Types), the declaration
+of a library unit P1 is not accessible from within the declarative
+region of a shared passive library unit P2,
+unless the shared passive library unit
+P2 depends semantically on P1.
address@hidden
+  We considered a more complex rule, but dropped it. This is
+  the simplest rule that recognizes that a shared passive
+  package may outlive some other library package, unless it
+  depends semantically on that package. In a nondistributed
+  program, all library packages are presumed to have the same lifetime.
+
+  Implementations may define additional pragmas that
+  force two library packages to be in the same partition, or to have
+  the same lifetime, which would allow this rule to be relaxed
+  in the presence of such pragmas.
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden
+A shared passive library unit is
+preelaborated.
+
address@hidden
+
address@hidden
+
+A shared passive library unit shall be
+assigned to at most one partition within a given program.
+
address@hidden units needed], Sec=(shared passive library unit)}
address@hidden, Sec=(shared passive library unit)}
address@hidden
+Notwithstanding the rule given in @RefSecNum{Program Execution},
+a compilation unit in a given partition
+does not @i{need} (in the
+sense of @RefSecNum{Program Execution})
+the shared passive library units
+on which it depends semantically to be included in that same
+partition; they will typically reside in separate passive
+partitions.
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0080],ARef=[AI95-00003-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the wording to 
allow
+  access types in blocks in shared passive generic packages.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0243-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Shared_Passive
+  is now a categorization aspect,
+  so it can be specified by an @nt{aspect_specification} @em
+  although the pragma is still preferred by the Standard.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0038-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Uses of access types declared in declared-pure units are not allowed in
+  library-level shared passive packages. These were allowed by Ada 2005 and
+  Ada 2012, but it is unlikely that they work properly, as active partitions
+  could disappear before the shared-passive partition. As such, the new
+  errors are more likely to catch bugs than to cause them.]}
address@hidden
+
+
address@hidden Types Library Units}
+
address@hidden
address@hidden remote types library unit supports the definition of types
+intended for use in communication between active
+partitions.]
address@hidden
address@hidden
+The restrictions governing a remote types package are similar to those for
+a declared pure package. However, the restrictions are relaxed
+deliberately to allow such a package to contain declarations that violate
+the stateless property of pure packages, though it is presumed
+that any state-dependent properties are essentially invisible
+outside the package.
address@hidden
+
address@hidden
address@hidden
address@hidden@PDefn2{Term=[categorization pragma], Sec=(Remote_Types)}
address@hidden, categorization], Sec=(Remote_Types)}
+The form of a @nt{pragma} Remote_Types is as follows:
address@hidden
+
address@hidden@key{pragma} @prag(Remote_Types)[(@address@hidden)];'
+
address@hidden
+
address@hidden
+
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0243-1]}
address@hidden types library unit}
address@hidden,New=[ @nt{pragma} Remote_Types is used to specify that a library 
unit is a],Old=[]}
address@hidden types library address@hidden,New=[,
+namely that the],Old=[ is a library unit to which the pragma]}
+Remote_Types
address@hidden,address@hidden of the library unit is
+True],Old=[applies]}. The following restrictions apply to the declaration of
+such a library unit:
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Remote_Types],
+    address@hidden,Text=[Types in a given package may be used in
+      remote procedure calls.]}]}
+
address@hidden
address@hidden shall be preelaborable;]
+
address@hidden,Kind=[Revised],ARef=[AI05-0206-1],ARef=[AI05-0243-1]}
+it shall depend semantically only on declared address@hidden,New=[
address@hidden,Old=[]}, shared address@hidden,New=[ library
+units],Old=[]}, @Chg{Version=[3],New=[],Old=[or ]}other remote types library
address@hidden,New=[, or preelaborated normal library units that are
+mentioned only in private with clauses],Old=[]};
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0243-1]}
+  @ChgAdded{Version=[3],Text=[We say declared pure @nt{library_item} here,
+  so that (all) limited views are allowed; those are not library units, but
+  they are declared pure @nt{library_item}s.]}
address@hidden
+
+it shall not contain the declaration of any variable
+within the visible part of the library unit;
address@hidden
+  This is essentially a @lquotes@;address@hidden@; restriction.
+  A separate copy of a remote types package is included
+  in each partition that references it, just like a normal package.
+  Nevertheless, a remote types package is thought of as
+  an @lquotes@;essentially address@hidden@; package for defining types to be 
used
+  for interpartition communication,
+  and it could be misleading to declare visible objects
+  when no remote data access is actually being provided.
address@hidden
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00240-01],ARef=[AI95-00366-01]}
address@hidden,New=[],Old=[if ]}the full view of 
@Chg{Version=[2],New=[each],Old=[a]}
+type declared in the visible part of the
+library unit @Chg{Version=[2],New=[that has any available stream attributes
+shall support external streaming (see
address@hidden Attributes})], Old=[has a part that is of a
+nonremote access type, then that access type, or the type of some
+part that includes the access type subcomponent,
+shall have user-specified Read and Write attributes]}.
address@hidden
+  This is to prevent the use of the predefined Read and Write
+  attributes of an access type as part of the Read and Write
+  attributes of a visible type.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00366-01]}
+  @ChgAdded{Version=[2],Text=[Types that do not have available stream
+  attributes are excluded from this rule; that means that attributes do not
+  need to be specified for most limited types. It is only necessary to specify
+  attributes for nonlimited types that have a part that is of any access type,
+  and for extensions of limited types with available stream attributes where
+  the @nt{record_extension_part} includes a subcomponent of an access type,
+  where the access type does not have specified attributes.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0082],ARef=[AI95-00164-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0060-1]}
address@hidden,Type=[Leading],address@hidden ChgAdded to get conditional 
address@hidden access type}
address@hidden,New=[A named],Old=[An]} access type declared in the
+visible part of a remote types or remote
+call interface library unit is called a @i{remote access type}.
address@hidden access-to-subprogram type}
address@hidden access-to-class-wide type}
+Such a type shall address@hidden:],Old=[ either an access-to-subprogram type
+or a general access type that designates a class-wide limited private
+type.]}
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0082],ARef=[AI95-00164-01]}
address@hidden,Text=[an access-to-subprogram type, or]}
+
address@hidden,Kind=[Added],Ref=[8652/0082],ARef=[AI95-00164-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0060-1]}
address@hidden,Text=[a general access type that designates a class-wide
+limited private address@hidden,New=[, a class-wide limited interface
+type,],Old=[]} or a class-wide
+private @Chg{Version=[3],New=[],Old=[type ]}extension all of whose
+ancestors are either
+private @Chg{Version=[3],New=[],Old=[type address@hidden,New=[,
+limited interface types,],Old=[]} or limited private types.]}
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0081],ARef=[AI95-00004-01]}
address@hidden,Text=[A type that is derived from a remote access type
+is also a remote access type.]}
+
address@hidden@;The following restrictions apply to the use of a
+remote access-to-subprogram type:
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00431-01]}
+A value of a remote access-to-subprogram type
+shall be converted only to @Chg{Version=[2],New=[or from ],Old=[]}another
+(subtype-conformant) remote access-to-subprogram type;
+
+The @nt<prefix> of an Access @nt<attribute_reference> that yields
+a value of a remote access-to-subprogram type shall statically denote a
+(subtype-conformant) remote subprogram.
address@hidden
+
address@hidden@;The following restrictions apply to the use of a
+remote access-to-class-wide type:
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0083],ARef=[AI95-00047-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00240-01],ARef=[AI95-00366-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0060-1],ARef=[AI05-0101-1]}
+The primitive subprograms of the corresponding specific
address@hidden,New=[],Old=[limited private ]}type
+shall only have access parameters if they are controlling formal
address@hidden,New=[. The primitive functions of the corresponding
+specific type shall only have an access result if it is a controlling access
+result.],Old=[;]} @address@hidden,New=[Each],Old=[each]}
+noncontrolling formal parameter],Old=[the types of all the noncontrolling
+formal parameters]} @Chg{Version=[3],New=[and noncontrolling result
+type ],Old=[]}shall @Chg{Version=[2],New=[support external streaming (see
address@hidden Attributes});], Old=[have @Chg{New=[either a
+nonlimited type or a type with],Old=[]} Read and Write address@hidden
+specified via an @nt{attribute_definition_clause};],Old=[.]}]}
+
address@hidden,Kind=[Added],ARef=[AI05-0060-1],ARef=[AI05-0215-1],ARef=[AI05-0269-1]}
address@hidden,Text=[The corresponding specific type shall not have
+a primitive procedure with the Synchronization aspect specified unless the
address@hidden is Optional (see
address@hidden Communication});]}
+
+A value of a remote access-to-class-wide type shall be
+explicitly converted only to another remote access-to-class-wide type;
+
address@hidden,Kind=[Revised],ARef=[AI12-0034-1]}
+A value of a remote access-to-class-wide type shall be dereferenced
+(or implicitly converted to an anonymous access type)
+only as part of a dispatching call @Chg{Version=[4],New=[to a primitive
+operation of the designated type ],Old=[]}where the value designates
+a controlling operand of the call (see @RefSec{Remote Subprogram Calls});
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0034-1]}
+  @ChgAdded{Version=[4],Text=[Stream attributes of the designated type are not
+  primitive operations of the designated type, and thus remote calls to them 
are
+  prohibited by this rule. This is good, as the access parameter of a stream
+  attribute does not have external streaming, and thus cannot be a parameter of
+  a remote call.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0101-1]}
address@hidden,Text=[A controlling access result value for a primitive
+function with any controlling operands of the corresponding specific type shall
+either be explicitly converted to a remote access-to-class-wide type or be part
+of a dispatching call where the value designates a controlling operand of the
+call;]}
+
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised],ARef=[AI95-00366-01]}
address@hidden,Kind=[Revised],ARef=[AI12-0085-1]}
+The Storage_Pool @Chg{Version=[2],New=[attribute is],Old=[and
+Storage_Size attributes are]} not defined address@hidden,New=[ a],Old=[]}
+remote access-to-class-wide @Chg{Version=[2],New=[type],Old=[types]};
+the expected type for an @nt{allocator} shall not be a remote
+access-to-class-wide address@hidden,New=[. A],Old=[; a]} remote
+access-to-class-wide type shall not be an actual parameter for a generic
+formal access address@hidden,Old=[;address@hidden,New=[ The Storage_Size
+attribute of a remote access-to-class-wide type yields address@hidden,
+New=[],Old=[; it is not allowed in an @nt{attribute_definition_clause}]}.],
address@hidden,New=[  The Storage_Pool and Storage_Size aspects
+shall not be specified for a remote access-to-class-wide type.],Old=[]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  All @Chg{Version=[3],New=[],Old=[three address@hidden are more than three!}of
+  these restrictions are because
+  there is no storage pool associated with a remote
+  access-to-class-wide address@hidden,New=[ The Storage_Size is defined
+  to be 0 so that there is no conflict with the rules for pure units.],Old=[]}
address@hidden
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0085-1]}
+  @ChgAdded{Version=[4],Text=[The prohibition against specifying the
+  Storage_Size aspect for an access-to-class-wide type applies to any
+  method of doing that, including via either a @nt{aspect_specification} or
+  an @nt{attribute_definition_clause}.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0076-1]}
+  @ChgAdded{Version=[4],Text=[Execution is erroneous if some operation (other
+  than the initialization or finalization of the object) modifies the value of 
a
+  constant object declared in the visible part of a remote types package.]}
+
+  @begin{Discussion}
+    @ChgRef{Version=[4],Kind=[AddedNormal]}
+    @ChgAdded{Version=[4],Text=[This could be accomplished via a
+    self-referencing pointer or via squirrelling a writable pointer to a
+    controlled object.]}
+  @end{Discussion}
address@hidden
+
address@hidden
+A remote types library unit
+need not be pure, and the types it defines may
+include levels of indirection implemented by using access types.
+User-specified Read and Write attributes
+(see @RefSecNum{Stream-Oriented Attributes})
+provide for sending values of such a type
+between active partitions, with Write marshalling the
+representation, and Read unmarshalling any levels of
+indirection.
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0060-1]}
address@hidden,Text=[The value of a remote access-to-class-wide limited
+interface can designate an object of a nonlimited type derived from the
+interface.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0060-1]}
address@hidden,Text=[A remote access type may designate a class-wide
+synchronized, protected, or task interface type.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Synchronized, protected, and task interfaces
+  are all considered limited interfaces, see @RefSecNum{Interface types}.]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00240-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] The wording was changed from
+  @lquotes@;address@hidden to @lquotes@;address@hidden
+  @Chg{Version=[3],New=[read and write ],Old=[]}attributes. (This was then
+  further changed, see below.) This means that
+  an access type with the attributes specified in the private part would
+  originally have been sufficient to allow the access type to be used in
+  a remote type, but that is no longer allowed. Similarly, the attributes
+  of a remote type that has access components have to be specified in the
+  visible part. These changes were made so that the rules were consistent with
+  the rules introduced for the Corrigendum for stream attributes; moreover,
+  legality should not depend on the contents of the private part.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00366-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Remote types that cannot be streamed (that is, have no available stream
+  attributes) do not require the specification of stream attributes.
+  This is necessary so that most extensions of Limited_Controlled do not
+  need stream attributes defined (otherwise there would be a
+  @Chg{Version=[3],New=[significant],Old=[signficant]}
+  incompatibility, as Limited_Controlled would need stream attributes, and then
+  all extensions of it also would need stream attributes).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0081],ARef=[AI95-00004-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added missing wording so 
that
+  a type derived from a remote access type is also a remote access type.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0083],ARef=[AI95-00047-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that 
user-defined
+  Read and Write attributes are required for the primitive subprograms
+  corresponding to a remote access-to-class-wide type.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0082],ARef=[AI95-00164-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added missing wording so 
that
+  a remote access type can designate an appropriate private extension.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00366-01]}
+  @ChgAdded{Version=[2],Text=[Changed the wording to use the newly defined
+  term @i<type that supports external streaming>, so that various issues
+  with access types in pure units and implicitly declared attributes for
+  type extensions are properly handled.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00366-01]}
+  @ChgAdded{Version=[2],Text=[Defined Storage_Size to be 0 for
+  remote access-to-class-wide types, rather than having it undefined. This
+  eliminates issues with pure units requiring a defined storage size.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00431-01]}
+  @ChgAdded{Version=[2],Text=[Corrected the wording so that a value of a local
+  access-to-subprogram type cannot be converted to a remote
+  access-to-subprogram type, as intended (and required by the ACATS).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0101-1]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Added rules for returning of remote
+  @Chg{Version=[4],New=[access-to-class-wide],Old=[access-to-classwide]} types;
+  this had been missed in the past. While programs that returned unstreamable
+  types from RCI
+  functions were legal, it is not clear what they could have done (as the
+  results could not be marshalled). Similarly, RCI functions that return remote
+  controlling access types could try to save those values, but it is unlikely
+  that a compiler would know how to do that usefully. Thus, it seems unlikely
+  that any real programs will be impacted by these changes.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0060-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada address@hidden<Correction:>
+  Clarified that anonymous access types are never remote access types (and can
+  be used in remote types units subject to the normal restrictions). Added
+  wording to allow limited class-wide interfaces to be designated by remote
+  access types.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0206-1]}
+  @ChgAdded{Version=[3],Text=[Added wording to allow private withs of
+  preelaborated normal units in the specification of a remote types unit.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0243-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Remote_Types
+  is now a categorization aspect,
+  so it can be specified by an @nt{aspect_specification} @em
+  although the pragma is still preferred by the Standard.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0034-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that dispatching
+  remote stream attribute calls are prohibited. We don't document this as
+  an incompatibility, as the stream parameter cannot be marshalled for a
+  remote call (it doesn't have external streaming), so it's impossible that
+  any working program depends on this functionality.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0076-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Explicitly stated that 
modifying
+  a visible constant in a remote types package is erroneous. We don't document
+  this as inconsistent as implementations certainly can still do whatever they
+  were previously doing (no change is required); moreover, this case (and many
+  more) were erroneous in Ada 2005 and before, so we're just restoring the
+  previous semantics.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0085-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that specifying
+  the Storage_Pool or Storage_Size aspect for an access-to-class-wide type is
+  not allowed. The intent is clear, and no implementation has ever allowed
+  specifying the aspects (the attributes already cannot be specified),
+  so we don't document this as an incompatibility.]}
address@hidden
+
+
address@hidden Call Interface Library Units}
+
address@hidden
address@hidden remote call interface library unit can be
+used as an interface for remote procedure calls (RPCs) (or remote
+function calls) between active partitions.]
address@hidden
+
address@hidden
+The restrictions governing a remote call
+interface library unit are intended to ensure that
+the values of the actual parameters in a remote call can be meaningfully
+sent between two active partitions.
address@hidden
+
address@hidden
address@hidden
address@hidden@PDefn2{Term=[categorization pragma], Sec=(Remote_Call_Interface)}
address@hidden, categorization], Sec=(Remote_Call_Interface)}
+The form of a @nt{pragma} Remote_Call_Interface is as follows:
address@hidden
+
address@hidden@key{pragma} @prag(Remote_Call_Interface)[(@address@hidden)];'
+
address@hidden
address@hidden@;The form of a @nt{pragma} All_Calls_Remote is as follows:
address@hidden
+
address@hidden@key{pragma} @prag(All_Calls_Remote)[(@address@hidden)];'
+
address@hidden
address@hidden unit pragma], Sec=(All_Calls_Remote)}
address@hidden, library unit], Sec=(All_Calls_Remote)}
+A @nt{pragma} All_Calls_Remote is a library unit pragma.
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0078],ARef=[AI95-00048-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0243-1]}
address@hidden call interface}
address@hidden,Sec=(library unit)}
address@hidden,Sec=(package)}
address@hidden,Sec=(generic)}
address@hidden subprogram}
address@hidden,New=[ @nt{pragma} Remote_Call_Interface is used to specify that a
+library unit is a],Old=[]} @i{remote call interface (RCI)address@hidden,New=[,
+namely that the],Old=[ is a library unit to which the pragma]}
+Remote_Call_Interface
address@hidden,address@hidden of the library
+unit is True],Old=[applies]}. A subprogram declared in the visible part of such
+a library address@hidden, or declared by such a library unit,],Old=[]} is 
called
+a @i{remote subprogram}.
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Remote_Call_Interface],
+    address@hidden,Text=[Subprograms in a given package may be
+      used in remote procedure calls.]}]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0206-1],ARef=[AI05-0243-1]}
+The declaration of an RCI library unit shall be preelaborable
+(see @RefSecNum{Elaboration Control}), and shall depend semantically
+only upon declared address@hidden,New=[ @nt{library_item}s],Old=[]},
+shared address@hidden,New=[ library units],Old=[]},
+remote address@hidden,New=[ library units],Old=[]},
address@hidden,New=[],Old=[or ]}other remote call interface library
address@hidden,New=[, or preelaborated normal library units that are
+mentioned only in private with clauses],Old=[]}.
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0243-1]}
+  @ChgAdded{Version=[3],Text=[We say declared pure @nt{library_item} here,
+  so that (all) limited views are allowed; those are not library units, but
+  they are declared pure @nt{library_item}s.]}
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0078],ARef=[AI95-00048-01]}
address@hidden@;In addition, the following restrictions apply to 
@Chg{New=[],Old=[the
+visible part of ]}an RCI library unit:
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0078],ARef=[AI95-00048-01]}
address@hidden visible part],Old=[]} shall not contain the declaration of a
+variable;
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0078],ARef=[AI95-00048-01]}
+  Remote call interface @Chg{New=[units],Old=[packages]} do not provide remote
+  data access. A shared passive package has to be used for that.
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0078],ARef=[AI95-00048-01]}
address@hidden visible part],Old=[]} shall not contain the declaration of a
+limited type;
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00240-01],ARef=[AI95-00366-01]}
+  We disallow the declaration of task and protected types,
+  since calling an entry or a protected subprogram implicitly passes
+  an object of a limited type (the target task or protected object).
+  We disallow other limited types since we require that such types
+  have @Chg{Version=[2],New=[available],Old=[user-defined]} Read and Write
+  attributes, but we certainly
+  don't want the Read and Write attributes themselves to involve remote
+  calls (thereby defeating their purpose of marshalling the
+  value for remote calls).
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0078],ARef=[AI95-00048-01]}
address@hidden visible part],Old=[]} shall not contain a nested
address@hidden;
address@hidden
+  This is disallowed because the body of the nested generic
+  would presumably have access to data inside the body of the
+  RCI package, and if instantiated in a different partition, remote
+  data access might result, which is not supported.
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0078],ARef=[AI95-00048-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+it shall not @Chg{New=[be, nor shall its visible part],Old=[]} 
address@hidden,],Old=[]} the
+declaration of a subprogram @Chg{Version=[3],New=[for],Old=[to]} which
address@hidden,New=[aspect],Old=[a pragma]} Inline @Chg{Version=[3],New=[is 
True],
+Old=[applies]};
+
address@hidden,Kind=[Revised],Ref=[8652/0078],ARef=[AI95-00048-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00240-01],ARef=[AI95-00366-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0101-1]}
+it shall not @Chg{New=[be, nor shall its visible part],
+Old=[]} address@hidden,],Old=[]} a
+subprogram (or access-to-subprogram) declaration
+whose profile has @Chg{Version=[2],address@hidden,New=[],
address@hidden access parameter or]]}
+a parameter @Chg{Version=[3],New=[or result ],Old=[]}of a type that
+does not support external streaming
+(see @RefSecNum{Stream-Oriented Attributes})],
+Old=[an access parameter, or a formal parameter of a
+limited type unless that limited type has user-specified Read and Write
+attributes]};
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0101-1]}
address@hidden,Text=[No anonymous access types support external
+streaming, so they are never allowed as parameters or results of
+RCI subprograms.]}
address@hidden
+
+any public child of the library unit shall
+be a remote call interface library unit.
address@hidden
+  No restrictions apply to the private part of an RCI package,
+  and since a public child can @lquotes@;address@hidden@; the private part
+  of its parent, such a child must itself have a
+  Remote_Call_Interface pragma, and be assigned to the same partition
+  (see below).
address@hidden
address@hidden
+  We considered making the public child of an RCI package
+  implicitly RCI, but it seemed better to require an explicit
+  pragma to avoid any confusion.
+
+  Note that there is no need for a private child to be an RCI package,
+  since it can only be seen from the body of its parent
+  or its siblings, all of which are required to be in the
+  same active partition.
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[A],Old=[If a]} pragma All_Calls_Remote
address@hidden,New=[sets the All_Calls_Remote representation aspect of
address@hidden,Old=[applies to a]} library address@hidden,New=[ to which the 
pragma
+applies to the value True. If the All_Calls_Remote aspect of a library unit is 
True],
+Old=[]}, the library unit shall be a remote call interface.
+
+  
@ChgAspectDesc{Version=[4],Kind=[Revised],InitialVersion=[3],Aspect=[All_Calls_Remote],
+    address@hidden,Text=[All @Chg{Version=[4],New=[indirect or
+      dispatching remote subprogram calls and all direct],Old=[]}
+      remote @Chg{Version=[4],New=[subprogram],Old=[procedure]} calls
+      should use the Partition Communication
+      address@hidden,New=[],Old=[, even if they are local]}.]}]}
+
address@hidden
+
address@hidden
+
+A remote call interface library unit shall be
+assigned to at most one partition of a given program.
+A remote call
+interface library unit whose parent is also an RCI library unit
+shall be
+assigned only to the same partition as its parent.
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0078],ARef=[AI95-00048-01]}
+  The declaration of an RCI @Chg{New=[unit],Old=[package]}, with a calling-stub
+  body, is automatically included in all active
+  partitions with compilation units that depend on it.
+  However the whole RCI library unit, including its
+  (non-stub) body, will only be in one of the active partitions.
address@hidden
+
address@hidden units needed], Sec=(remote call interface)}
address@hidden, Sec=(remote call interface)}
address@hidden
+Notwithstanding the rule given in @RefSecNum{Program Execution},
+a compilation unit in a given partition that semantically depends on
+the declaration of an RCI library unit,
address@hidden (in the sense of @RefSecNum{Program Execution})
+only the declaration of the
+RCI library unit, not the body, to be included in that same partition.
address@hidden, the body of an RCI library unit is included
+only in the partition to which the RCI library unit is
+explicitly assigned.]
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0078],ARef=[AI95-00048-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0031-1]}
address@hidden ChgAdded to get conditional address@hidden,
+Type=[Leading],Text=[]}If @Chg{Version=[3],New=[aspect],Old=[a pragma]}
+All_Calls_Remote @Chg{Version=[3],New=[is True for],Old=[applies to]} a
+given RCI library @Chg{New=[unit],Old=[package]}, then the
+implementation shall route any @Chg{Version=[4],New=[of the following calls],
+Old=[call to a subprogram of the RCI @Chg{New=[unit],Old=[package]} from
+outside the declarative region of the @Chg{New=[unit],Old=[package]}]} through
+the Partition Communication Subsystem (PCS); see
address@hidden Communication address@hidden,New=[:],Old=[.
+Calls to such subprograms from within the declarative region of
+the @Chg{New=[unit],Old=[package]} are defined to be local and shall
+not go through the PCS.]}
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0031-1]}
+  @ChgAdded{Version=[4],Text=[A direct call to a subprogram of the RCI unit 
from
+    outside the declarative region of the unit;]}
+
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0031-1]}
+  @ChgAdded{Version=[4],Text=[An indirect call through a remote
+    access-to-subprogram value that designates a subprogram of the RCI unit;]}
+
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0031-1]}
+  @ChgAdded{Version=[4],Text=[A dispatching call with a controlling operand
+    designated by a remote access-to-class-wide value whose tag identifies a
+    type declared in the RCI unit.]}
address@hidden
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0078],ARef=[AI95-00048-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0031-1]}
address@hidden,New=[When this aspect is False (or not used)],Old=[Without
+this pragma]}, it is presumed
+that most implementations address@hidden,New=[ not],Old=[]}
address@hidden,New=[],Old=[ direct]} address@hidden,New=[ through
+the PCS],Old=[]} if the call originates in the same partition
+as that of the RCI @Chg{New=[unit],Old=[package]}. @Chg{Version=[3],New=[When
+this aspect is True],Old=[With this pragma]}, all 
@Chg{Version=[4],New=[indirect
+or dispatching remote subprogram calls to the RCI unit and all
+direct ],Old=[]}calls
+from outside the subsystem rooted at the RCI @Chg{New=[unit],Old=[package]} are
+treated like calls from outside the
+partition, ensuring that the PCS is involved in all such calls
+(for debugging, redundancy, etc.).
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI12-0031-1]}
+There is no point to force local @Chg{Version=[4],New=[direct ],Old=[]}calls
+(@Chg{Version=[4],New=[including],Old=[or]} calls from children) to go through
+the PCS, since on the target address@hidden,New=[],Old=[,]} these calls
+are always local, and all the units are in the same active partition.
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0243-1]}
+An implementation need not support the
+Remote_Call_Interface pragma @Chg{Version=[3],New=[or aspect ],Old=[]}nor
+the All_Calls_Remote pragma.
address@hidden message-based communication between active partitions can
+be supported as an alternative to RPC.]
address@hidden
+  Of course, it is pointless to support the All_Calls_Remote
+  pragma if the Remote_Call_Interface pragma (or some
+  approximate equivalent) is not supported.
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00240-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] The wording was changed from
+  @lquotes@;address@hidden to @lquotes@;address@hidden
+  @Chg{Version=[3],New=[read and write ],Old=[]}attributes. (This was then
+  further changed, see below.) This means that
+  a type with the attributes specified in the private part would
+  originally have been allowed as a formal parameter of an RCI subprogram,
+  but that is no longer allowed.
+  This change was made so that the rules were consistent with the rules
+  introduced for the Corrigendum for stream attributes; moreover, legality
+  should not depend on the contents of the private part.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0078],ARef=[AI95-00048-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Changed the wording to 
allow
+  a library subprogram to be a remote call interface unit.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00366-01]}
+  @ChgAdded{Version=[2],Text=[Changed the wording to use the newly defined
+  term @i<type that supports external streaming>, so that various issues
+  with access types in pure units and implicitly declared attributes for
+  type extensions are properly handled.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0101-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Added a rule to ensure that function results are streamable; this was
+  missing in previous versions of Ada. While programs that returned
+  unstreamable types from RCI functions were legal, it is not clear what
+  they could have done (as the results could not be marshalled). Thus, it seems
+  unlikely that any real programs will be impacted by this change.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0206-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Added wording to
+  allow private withs of preelaborated normal units in the specification of a
+  remote call interface unit.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[All_Calls_Remote
+  is now a representation aspect, so it can be specified by
+  an @nt{aspect_specification} @em
+  although the pragma is still preferred by the Standard.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0243-1]}
+  @ChgAdded{Version=[3],Text=[Remote_Call_Interface
+  is now a categorization aspect, so it can be specified by
+  an @nt{aspect_specification} @em
+  although the pragma is still preferred by the Standard.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0031-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Redefined when indirect and dispatching remote calls have to be remote
+  for a unit for which the aspect All_Calls_Remote is True. With the new rules,
+  a local target called indirectly or via dispatching will be routed through
+  the PCS, while that was not necessarily true in earlier Ada. If a program
+  depended on local targets not being routed through the PCS even when
+  All_Calls_Remote is used, then it might behave differently or fail in
+  corrected Ada 2012. This is highly unlikely as PCS is going to be able to
+  communicate with any partition of the program, including the local 
partition.]}
address@hidden
+
+
address@hidden of a Distributed System}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} defines
+attributes and rules associated with verifying
+the consistency of a distributed program.]
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0248-1]}
+The rules guarantee that remote call interface
+and shared passive @Chg{Version=[3],New=[library units],Old=[packages]}
+are consistent among all partitions
+prior to the execution of a distributed program, so
+that the semantics of the distributed program are well defined.
+
address@hidden
+
address@hidden
+
address@hidden,address@hidden be consistent with 8652/0006}
address@hidden@;For @ChgPrefixType{Version=[1],Kind=[Revised],Text=[a
address@hidden@nt{prefix}],Old=[prefix]} P that statically denotes a
+program unit]}, the following attributes are defined:
address@hidden
address@hidden<P>, AttrName=<Version>,
+  Text=[Yields a value of the predefined type String
+     that identifies the version of the compilation unit that
+     contains the declaration of the program unit.]}
+
address@hidden<P>, AttrName=<Body_Version>,
+  Text=[Yields a value of the predefined type String
+     that identifies the version of the compilation unit that contains
+     the body (but not any subunits) of the program unit.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0084],ARef=[AI95-00104-01]}
address@hidden, Sec=(of a compilation unit)}
+The @i{version} of a compilation unit changes whenever the
address@hidden,Old=[version changes for any ]}compilation unit
address@hidden in a semantically significant way. This International
+Standard does not define the exact meaning of "semantically significant"],
+Old=[on which it depends semantically. The version also changes whenever the
+compilation unit itself changes in a semantically significant way]}.
+It is @Chg{New=[unspecified],Old=[implementation defined]}
+whether there are other events (such as recompilation) that
+result in the version of a compilation unit changing.
address@hidden@PDefn{unspecified}],Old=[]}
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,Old=[Events that
+cause the version of a compilation unit to change.]}]}
+
address@hidden,Kind=[Added],Ref=[8652/0084],ARef=[AI95-00104-01]}
address@hidden,Text=[If P is not a library unit, and P has no completion,
+then P'Body_Version returns the Body_Version of the innermost program unit
+enclosing the declaration of P. If P is a library unit, and P has no
+completion, then P'Body_Version returns a value that is different from
+Body_Version of any version of P that has a completion.]}
address@hidden
+
address@hidden
address@hidden(bounded error),Sec=(cause)}
address@hidden consistency}
+In a distributed program, a library unit is @i{consistent} if the same
+version of its declaration is used throughout.
+It is a bounded error to elaborate a partition of a distributed
+program that contains a compilation unit that depends on a different
+version of the declaration of a shared passive or RCI library
+unit than
+that included in the partition to which the shared passive or
+RCI library unit
+was assigned.
address@hidden,Sec=(raised by failure of run-time check)}
+As a result of this error, Program_Error
+can be raised in one or both partitions during elaboration;
+in any case, the partitions
+become inaccessible to one another.
address@hidden
+  Because a version changes if anything on which it depends undergoes
+  a version change, requiring consistency for shared passive
+  and remote call interface library units is
+  sufficient to ensure
+  consistency for the declared pure and remote types library
+  units that
+  define the types used for the objects and parameters
+  through which interpartition communication takes place.
+
+  Note that we do not require matching Body_Versions; it is
+  irrelevant for shared passive and remote call interface
+  packages, since only one copy of their body exists in a
+  distributed program (in the absence of implicit replication),
+  and we allow the bodies to differ for declared pure and
+  remote types packages from partition to partition, presuming
+  that the differences are due to required error corrections
+  that took place during the execution of a long-running distributed
+  program. The Body_Version attribute provides a means
+  for performing stricter consistency checks.
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0084],ARef=[AI95-00104-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified the meaning of
+  'Version and 'Body_Version.]}
address@hidden
+
+
address@hidden Subprogram Calls}
+
address@hidden
address@hidden subprogram call}
address@hidden remote procedure call}
address@hidden partition}
address@hidden partition}
address@hidden subprogram binding}
+A @i{remote subprogram call} is a subprogram call that invokes the
+execution of a subprogram in another partition.
+The partition that
+originates the remote subprogram call is the @i{calling partition}, and the
+partition that executes the corresponding subprogram body is the @i{called
+partition}.
+Some remote procedure calls are allowed to return prior to the completion of
+subprogram execution. These are called @i{asynchronous remote procedure
+calls}.
+
address@hidden@;There are three different ways of performing a remote 
subprogram call:
address@hidden
+  As a direct call on a (remote) subprogram explicitly declared in a
+  remote call interface;
+
+  As an indirect call through a value of a remote access-to-subprogram type;
+
+  As a dispatching call with a controlling operand designated by
+  a value of a remote access-to-class-wide type.
address@hidden
+
+The first way of calling corresponds to a @i(static) binding between
+the calling and the called partition.
+The latter two ways correspond to a @i(dynamic) binding between
+the calling and the called partition.
+
address@hidden,Kind=[Revised],ARef=[AI05-0101-1]}
address@hidden,New=[Remote types library units (see
address@hidden Types Library Units}) and],Old=[A]} remote
+call interface library @Chg{Version=[3],New=[units],Old=[unit]}
+(see @RefSecNum{Remote Call Interface Library Units})
address@hidden,New=[define],Old=[defines]}
+the remote subprograms or remote access types used for
+remote subprogram calls.
address@hidden
+
address@hidden
+
+Remote subprogram calls are standardized since the RPC paradigm is
+widely-used, and establishing an interface to it in the annex will
+increase the portability and reusability of distributed
+programs.
+
address@hidden
+
address@hidden
+In a dispatching call with two or more controlling operands,
+if one controlling operand is designated by a value of a
+remote access-to-class-wide type, then all shall be.
address@hidden
+
address@hidden
+
address@hidden
address@hidden
address@hidden, Sec=(remote subprogram call)}
+For the execution of a remote subprogram call, subprogram parameters
+(and later the results, if any) are passed using a stream-oriented
+representation
+(see @RefSecNum{The Package Streams}) @Redundant[which is
+suitable for transmission between partitions]. This action is called
address@hidden @i{Unmarshalling} is the reverse action of
+reconstructing the parameters or results from the stream-oriented
+representation.
address@hidden is performed initially as part of the remote subprogram call in
+the calling partition; unmarshalling is done in the called partition.
+After the remote subprogram completes, marshalling is performed in the
+called partition, and finally unmarshalling is done in the calling
+partition.]
+
address@hidden stub}
address@hidden stub}
+A @i{calling stub} is the sequence of code that replaces the subprogram
+body of a remotely called subprogram in the calling partition. A
address@hidden stub} is the sequence of code (the @lquotes@;address@hidden@;) 
that
+receives a remote subprogram call on the called partition and invokes
+the appropriate subprogram body.
address@hidden
+The use of the term @i{stub} in this annex should not be confused with
address@hidden as defined in @RefSecNum{Subunits of Compilation Units}. The
+term @i{stub} is used here because it is a commonly understood term when
+talking about the RPC paradigm.
address@hidden
+
address@hidden execution}
+Remote subprogram calls are executed at most once, that is,
+if the subprogram call returns normally, then the called
+subprogram's body was executed exactly once.
+
+The task executing a remote subprogram call blocks until the subprogram
+in the called partition returns, unless the call is asynchronous. For an
+asynchronous remote procedure call, the calling task can
+become ready before the
+procedure in the called partition returns.
+
address@hidden of a remote subprogram call}
+If a construct containing a remote call is aborted, the
+remote subprogram call is @i{cancelled}.
+Whether the execution of the remote subprogram is immediately aborted
+as a result of the cancellation is address@hidden defined.
address@hidden the execution of the remote subprogram is immediately
+aborted as a result of cancellation.}
+
+If a remote subprogram call is received by a called partition before the
+partition has
+completed its elaboration, the call is kept pending until the called
+partition completes its elaboration (unless the call is
+cancelled by the calling partition prior to that).
+
+If an exception is propagated by a remotely called subprogram,
+and the call is not an asynchronous call,
+the corresponding exception is reraised at the point
+of the remote subprogram call.
+For an asynchronous call, if the remote procedure call returns prior to
+the completion of the remotely called subprogram, any exception is lost.
+
+The exception Communication_Error
+(see @RefSecNum{Partition Communication Subsystem}) is raised if a remote call
+cannot be completed due to difficulties in communicating with the called
+partition.
+
address@hidden blocking operation],Sec=(remote subprogram call)}
address@hidden, potentially],Sec=(remote subprogram call)}
+All forms of remote subprogram calls are potentially blocking operations
+(see @RefSecNum{Protected Subprograms and Protected Actions}).
address@hidden
+Asynchronous remote procedure calls are potentially blocking since the
+implementation may require waiting for the availability of shared resources
+to initiate the remote call.
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0085],ARef=[AI95-00215-01]}
address@hidden
+In a remote subprogram call with a formal parameter of a class-wide
+type, a check is made that the tag of the actual parameter identifies
+a tagged type declared in a declared-pure or shared passive library
+unit, or in the visible part of a remote types or remote call interface
+library unit.
address@hidden,Sec=(raised by failure of run-time check)}
+Program_Error is raised if this check fails.
address@hidden a remote function call which returns a class-wide type, the same
+check is made on the function result.],Old=[]}
address@hidden
+  @ChgRef{Version=[1],Kind=[Revised],Ref=[8652/0085],ARef=[AI95-00215-01]}
+  This check makes certain that the specific type address@hidden or returned],
+  Old=[]} in an RPC
+  satisfies the rules for a "communicable" type. Normally this
+  is guaranteed by the compile-time restrictions on remote call interfaces.
+  However, with class-wide types, it is possible to pass an object
+  whose tag identifies a type declared outside the "safe" packages.
+
+  This is considered an accessibility_check since only the types
+  declared in "safe" packages are considered truly "global" (cross-partition).
+  Other types are local to a single partition. This is analogous
+  to the "accessibility" of global vs. local declarations in
+  a single-partition program.
+
+  This rule replaces a rule from an early version of Ada 9X
+  which was given in the subclause on Remote Types Library Units
+  (now @RefSec{Remote Types Library Units}). That rule tried
+  to prevent "bad" types from being sent by arranging for their
+  tags to mismatch between partitions. However, that interfered
+  with other uses of tags. The new rule allows tags to agree
+  in all partitions, even for those types which are not "safe"
+  to pass in an RPC.
address@hidden
+
address@hidden
+In a dispatching call with two or more controlling operands that are
+designated by values of a remote access-to-class-wide type,
+a check is made @Redundant[(in addition to the normal Tag_Check
address@hidden see @RefSecNum{Suppressing Checks})] that all the remote
+access-to-class-wide values originated from Access
address@hidden<attribute_reference>s that were evaluated by tasks of the
+same active partition.
address@hidden,Sec=(raised by failure of run-time check)}
+Constraint_Error is raised if this check fails.
address@hidden
+  When a remote access-to-class-wide value is created by
+  an Access @nt<attribute_reference>, the identity of the
+  active partition that evaluated the @nt<attribute_reference>
+  should be recorded in the representation of the remote access value.
address@hidden
+
address@hidden
+
address@hidden
+
+The implementation of remote subprogram calls shall conform
+to the PCS interface as defined by the specification of the
+language-defined package System.RPC
+(see @RefSecNum{Partition Communication Subsystem}).
+The calling stub shall use the Do_RPC procedure unless the remote
+procedure call is asynchronous in which case Do_APC shall be used.
+On the receiving side, the corresponding receiving stub shall be
+invoked by the RPC-receiver.
address@hidden
+One possible implementation model is as follows:
+
+The code for calls to subprograms declared in an RCI
+package is generated
+normally, that is, the call-site is the same as for a
+local subprogram call.
+The code for the remotely callable subprogram bodies is also generated
+normally. Subprogram's prologue and epilogue are the same as for a local call.
+
+When compiling the specification of an RCI package, the compiler
+generates calling stubs for each visible subprogram. Similarly, when
+compiling the body of an RCI package, the compiler generates
+receiving stubs for each visible subprogram together with the appropriate
+tables to allow the RPC-receiver to locate the correct receiving stub.
+
+For the statically bound remote calls, the identity of the remote
+partition is statically determined (it is resolved at configuration/link time).
+
address@hidden@;The calling stub operates as follows:
address@hidden(Itemize)
+It allocates (or reuses) a stream of Params_Stream_Type of Initial_Size,
+and initializes it by repeatedly calling Write operations,
+first to identify which remote subprogram in the receiving partition
+is being called, and then to pass the incoming value of each of the
address@hidden(in) and @b(in out) parameters of the call.
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+It allocates (or reuses) a stream for the Result,
+unless @Chg{Version=[3],New=[an aspect],Old=[a pragma]} Asynchronous is
address@hidden,New=[specified as True for],Old=[applied to]} the procedure.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+It calls Do_RPC unless @Chg{Version=[3],New=[an aspect],Old=[a pragma]}
+Asynchronous @Chg{Version=[3],New=[is specified as True for],Old=[applied to]}
+the procedure
+in which case it calls Do_APC. An access value designating the message
+stream allocated and initialized above is passed as the Params parameter.
+An access value designating the Result stream is passed as the Result
+parameter.
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+If the @Chg{Version=[3],New=[aspect],Old=[pragma]} Asynchronous is not 
specified for the procedure,
+Do_RPC blocks until a reply message arrives,
+and then returns to the calling stub.
+The stub returns after extracting
+from the Result stream, using Read operations, the @b(in out) and @b(out)
+parameters or the function result. If the reply message
+indicates that the execution of the remote subprogram propagated
+an exception, the exception is propagated from Do_RPC to the
+calling stub, and thence to the point of the original remote subprogram call.
+If Do_RPC detects that communication with the remote partition has
+failed, it propagates Communication_Error.
+
address@hidden(Itemize)
+
address@hidden@;On the receiving side, the RPC-receiver procedure operates as 
follows:
address@hidden(Itemize)
+It is called from the PCS when a remote-subprogram-call message is received.
+The call originates in some remote call receiver task executed and
+managed in the context of the PCS.
+
+It extracts information from the stream to identify the appropriate
+receiving stub.
+
+The receiving stub extracts the @b(in) and @b(in out) parameters using
+Read from the stream designated by the Params parameter.
+
+The receiving stub calls the actual subprogram body and, upon completion of
+the subprogram, uses Write to insert the results into the
+stream pointed to by the Result parameter. The receiving stub returns to
+the RPC-receiver procedure which in turn returns to the PCS.
+If the actual subprogram body propagates an exception, it is propagated
+by the RPC-receiver to the PCS, which handles the exception,
+and indicates in the reply message that the execution of the
+subprogram body propagated an exception. The exception occurrence
+can be represented in the reply message using the Write attribute
+of Ada.Exceptions.Exception_Occurrence.
address@hidden(Itemize)
+
+For remote access-to-subprogram types:
+
+A value of a remote access-to-subprogram type can be
+represented by the following components: a reference to the remote partition,
+an index to the package containing the remote subprogram, and an index to
+the subprogram within the package. The values of these components are
+determined at run time when the remote access value is created.
+These three components serve the same purpose when calling Do_APC/RPC,
+as in the statically bound remote calls; the only difference is that they
+are evaluated dynamically.
+
+For remote access-to-class-wide types:
+
+For each remote access-to-class-wide type,
+a calling stub is generated for each dispatching operation of
+the designated type. In addition, receiving stubs are generated to perform
+the remote dispatching operations in the called partition. The appropriate
address@hidden is determined as for a local
+dispatching call once the receiving stub has been reached.
+
+A value of a remote access-to-class-wide type
+can be represented with the following components:
+a reference to the remote partition, an index to a table (created one per
+each such access type) containing addresses of all the dispatching operations
+of the designated type, and an access value designating the actual remote
+object.
+
+Alternatively, a remote access-to-class-wide value can be represented as
+a normal access value, pointing to a "stub" object which in turn
+contains the information mentioned above. 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. This approach has the advantage that
+less special-casing is required in the compiler. All access values
+can remain just a simple address.
+
address@hidden,Sec=(raised by failure of run-time check)}
+For a call to Do_RPC or Do_APC: The partition ID of all controlling
+operands are checked for equality (a Constraint_Error is raised if this
+check fails). The partition ID value is used for the Partition parameter.
+An index into the @i{tagged-type-descriptor} is created. This index
+points to the receiving stub of the class-wide operation. This index and
+the index to the table (described above) are
+written to the stream.
+Then, the actual parameters are marshalled into the message
+stream. For a controlling operand, only the access value
+designating the remote object is required (the other two
+components are already present in the other parameters).
+
+On the called partition (after the RPC-receiver has transferred control
+to the appropriate receiving stub) the parameters are first unmarshalled.
+Then, the tags of the controlling operands (obtained by dereferencing the
+pointer to the object) are checked for equality.
address@hidden,Sec=(raised by failure of run-time check)}
+If the check fails Constraint_Error is raised and propagated back to the
+calling partition, unless it is a result of an asynchronous call.
+Finally, a dispatching call to the specific subprogram (based on the
+controlling object's tag) is made. Note that since this subprogram is not
+in an RCI package, no specific stub is generated for it, it is called
+normally from the @i{dispatching stub}.
+
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0086],ARef=[AI95-00159-01]}
address@hidden,Text=[With respect to shared variables in shared
+passive library units, the
+execution of the corresponding subprogram body of a synchronous remote
+procedure call is considered to be part of the execution of the calling task.
+The execution of the corresponding subprogram body of an asynchronous remote
+procedure call proceeds in parallel with the calling task and does not signal
+the next action of the calling task (see @RefSecNum{Shared Variables}).]}
address@hidden
+
address@hidden
+A given active partition can both make and receive remote subprogram calls.
+Thus, an active partition can act as both a client and a server.
+
+If a given exception is propagated by a remote
+subprogram call, but the exception does not exist in the calling
+partition, the exception can be handled by an @key(others) choice
+or be propagated to and handled by a third partition.
address@hidden
+This situation can happen
+in a case of dynamically nested remote subprogram calls, where an
+intermediate call executes in a partition that does
+not include the library unit that defines the exception.
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0086],ARef=[AI95-00159-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added rules so that tasks 
can
+  safely access shared passive objects.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0085],ARef=[AI95-00215-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that the check 
on
+  class-wide types also applies to values returned from remote subprogram call
+  functions.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0101-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected the text to
+  note that remote access types can be defined in remote types units.]}
address@hidden
+
+
address@hidden,New=[Asynchronous Remote Calls],Old=[Pragma Asynchronous]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden subclause introduces the
address@hidden,New=[aspect],Old=[pragma]} Asynchronous which
address@hidden,New=[can be specified to allow],Old=[allows]} a
+remote subprogram call to return prior to completion of the execution
+of the corresponding remote subprogram body.]
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 2
+through 7 were deleted.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[The form of a @nt{pragma}
+Asynchronous is as follows:]}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden<Version=[3],InitialVersion=[0],@ChgDeleted{Version=[3],
address@hidden @prag(Asynchronous)(@Syn2{local_name});]}>
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[The @nt<local_name> of a pragma
+Asynchronous shall denote either:]}
address@hidden
+   @ChgRef{Version=[3],Kind=[DeletedNoDelMsg]}
+   @ChgDeleted{Version=[3],Text=[One or more remote procedures;
+   the formal parameters of the procedure(s) shall all be of
+   mode @key{in};]}
+
+   @ChgRef{Version=[3],Kind=[DeletedNoDelMsg]}
+   @ChgDeleted{Version=[3],Text=[The first subtype of a remote
+   access-to-procedure type; the formal parameters
+   of the designated profile of
+   the type shall all be of mode @key{in};]}
+
+   @ChgRef{Version=[3],Kind=[DeletedNoDelMsg]}
+   @ChgDeleted{Version=[3],Text=[The first subtype of a remote
+   access-to-class-wide type.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],address@hidden to get conditional Leading}
address@hidden,New=[For a remote procedure, the following language-defined
+representation aspect may be specified:],
address@hidden pragma], Sec=(Asynchronous)}
address@hidden, representation], Sec=(Asynchronous)}
+A pragma Asynchronous is a representation pragma.
+When applied to a type, it specifies the type-related @i{asynchronous}
+aspect of the type.]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden type of aspect Asynchronous is
+Boolean. If directly specified, the @nt{aspect_definition} shall be a static
+expression. If not specified, the aspect is address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Asynchronous],
+    address@hidden,Text=[Remote procedure calls are asynchronous;
+      the caller continues without waiting for the call to return.]}]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[For a remote access type, the
+following language-defined representation aspect may be specified:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden type of aspect Asynchronous is
+Boolean. If directly specified, the @nt{aspect_definition} shall be a static
+expression. If not specified (including by inheritance), the aspect is False.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Text=[If aspect Asynchronous is specified for a remote
+procedure, the formal parameters of the procedure shall all be of mode
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Text=[If aspect Asynchronous is specified for a remote
+access type, the type shall be a remote access-to-class-wide type, or the type
+shall be a remote access-to-procedure type with the formal parameters of the
+designated profile of the type all of mode @key[in].]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden procedure call],Sec=(asynchronous)}
address@hidden, Sec=(remote procedure call)}
+A remote call is @i{asynchronous} if it is a call to a procedure,
+or a call through a value of an access-to-procedure type,
address@hidden,New=[for],Old=[to]} which
address@hidden,New=[aspect],Old=[a pragma]} Asynchronous
address@hidden,New=[is True],Old=[applies]}.
+In addition, if @Chg{Version=[3],New=[aspect],Old=[a pragma]} Asynchronous
address@hidden,New=[is True for],Old=[applies to]} a remote
+access-to-class-wide type, then
+a dispatching call on a procedure
+with a controlling operand designated by a value of the type
+is asynchronous if the
+formal parameters of the procedure are all of mode @key{in}.
address@hidden
+
address@hidden
+
+Asynchronous remote procedure calls shall be implemented such that the
+corresponding body executes at most once as a result of the call.
address@hidden
+It is not clear that this rule can be tested or even defined formally.
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Aspect Asynchronous is new; @nt{pragma} Asynchronous is now obsolescent.]}
address@hidden
+
+
address@hidden of Use of a Remote Access-to-Class-Wide Type}
+
address@hidden
address@hidden@i{Example of using a remote access-to-class-wide type to achieve 
dynamic binding
+across active partitions:}
address@hidden
address@hidden Tapes @key{is}
+   @key{pragma} Pure(Tapes);
+   @key{type} Tape @key{is abstract tagged limited private};
+   @RI{-- Primitive dispatching operations where}
+   @RI{-- Tape is controlling operand}
+   @key{procedure} Copy (From, To : @key{access} Tape; Num_Recs : @key[in] 
Natural) @key{is} @key{abstract};
+   @key{procedure} Rewind (T : @key{access} Tape) @key{is} @key{abstract};
+   @RI{-- More operations}
address@hidden
+   @key{type} Tape @key{is} ...
address@hidden Tapes;
+
address@hidden Tapes;
address@hidden Name_Server @key{is}
+   @key{pragma} Remote_Call_Interface;
+   @RI{-- Dynamic binding to remote operations is achieved}
+   @RI{-- using the access-to-limited-class-wide type Tape_Ptr}
+   @key{type} Tape_Ptr @key{is access all} Tapes.Tape'Class;
+   @RI{-- The following statically bound remote operations}
+   @RI{-- allow for a name-server capability in this example}
+   @key{function}  Find     (Name : String) @key{return} Tape_Ptr;
+   @key{procedure} Register (Name : @key[in] String; T : @key[in] Tape_Ptr);
+   @key{procedure} Remove   (T : @key[in] Tape_Ptr);
+   @RI{-- More operations}
address@hidden Name_Server;
+
address@hidden Tape_Driver @key{is}
+  @RI{-- Declarations are not shown, they are irrelevant here}
address@hidden Tape_Driver;
+
address@hidden Tapes, Name_Server;
address@hidden body} Tape_Driver @key{is}
+   @key{type} New_Tape @key{is new} Tapes.Tape @key{with} ...
+   @key{procedure} Copy
+    (From, To : @key{access} New_Tape; Num_Recs: @key[in] Natural) @key{is}
+   @key{begin}
+     . . .
+   @key{end} Copy;
+   @key{procedure} Rewind (T : @key{access} New_Tape) @key{is}
+   @key{begin}
+      . . .
+   @key{end} Rewind;
+   @RI{-- Objects remotely accessible through use}
+   @RI{-- of Name_Server operations}
+   Tape1, Tape2 : @key[aliased] New_Tape;
address@hidden
+   Name_Server.Register ("NINE-TRACK",  Tape1'Access);
+   Name_Server.Register ("SEVEN-TRACK", Tape2'Access);
address@hidden Tape_Driver;
+
address@hidden Tapes, Name_Server;
address@hidden Tape_Driver is not needed and thus not mentioned in the 
@nt{with_clause}}
address@hidden Tape_Client @key{is}
+   T1, T2 : Name_Server.Tape_Ptr;
address@hidden
+   T1 := Name_Server.Find ("NINE-TRACK");
+   T2 := Name_Server.Find ("SEVEN-TRACK");
+   Tapes.Rewind (T1);
+   Tapes.Rewind (T2);
+   Tapes.Copy (T1, T2, 3);
address@hidden Tape_Client;
address@hidden
+
address@hidden@address@hidden on the example}:
address@hidden
+The example does not show the case where tapes are removed from or added to
+the system. In the former case, an appropriate exception needs to be defined
+to instruct the client to use another tape. In the latter, the Name_Server
+should have a query function visible to the clients to inform them about the
+availability of the tapes in the system.
address@hidden
+
address@hidden, Kind=[Deleted]}
address@hidden<>,Old=<@ @;@comment{Empty paragraph to hang junk paragraph 
number from original RM}>]
+
address@hidden
+The package Tapes provides the necessary declarations of the type and its
+primitive operations.
+
+Name_Server is a remote call interface package and is elaborated in a separate
+active partition to provide the necessary naming services (such as Register
+and Find) to the entire distributed program
+through remote subprogram calls.
+
+Tape_Driver is a normal package that is elaborated in a partition configured
+on the processing node that is connected to the tape device(s). The abstract
+operations are overridden to support
+the locally declared tape devices (Tape1, Tape2). The package is not visible
+to its clients, but it exports the tape devices (as remote objects)
+through the services of the Name_Server. This allows for tape devices to be
+dynamically added, removed or replaced without requiring the modification of
+the clients' code.
+
+The Tape_Client procedure references only declarations in the Tapes and
+Name_Server packages. Before using a tape for the first time, it needs to
+query the Name_Server for a system-wide identity for that tape. From then on,
+it can use that identity to access the tape device.
+
+Values of remote access type Tape_Ptr include the necessary information to
+complete the remote dispatching operations that result from
+dereferencing the controlling operands T1 and T2.
+
address@hidden
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Communication Subsystem}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00273-01]}
address@hidden communication subsystem (PCS)}
address@hidden (partition communication subsystem)}
address@hidden @i{Partition Communication Subsystem} (PCS) provides facilities 
for
+supporting communication between the active partitions of a distributed
+program. The package System.RPC is a language-defined interface to the
address@hidden,New=[],Old=[ An implementation conforming to this
+Annex shall use the RPC interface to implement remote subprogram calls.]}
address@hidden
+The prefix RPC is used rather than RSC because the term remote procedure call
+and its acronym are more familiar.
address@hidden
address@hidden
+
address@hidden
+
address@hidden@keepnext@;The following language-defined library package exists:
address@hidden
address@hidden(with) Ada.Streams; @RI{-- see @RefSecNum[The Package Streams]}
address@hidden(package) System.RPC 
@key(is)@ChildUnit{Parent=[System],Child=[RPC]}
+
+   @key(type) @AdaTypeDefn{Partition_Id} @key(is range) 0 .. 
@RI(implementation-defined);
+
+   @AdaExcDefn{Communication_Error} : @key(exception);
+
+   @key(type) @AdaTypeDefn{Params_Stream_Type} (
+      Initial_Size : Ada.Streams.Stream_Element_Count) @key(is) @key(new)
+      Ada.Streams.Root_Stream_Type @key(with) @key(private);
+
+   @key(procedure) @AdaSubDefn{Read}(
+      Stream : @key(in out) Params_Stream_Type;
+      Item : @key(out) Ada.Streams.Stream_Element_Array;
+      Last : @key(out) Ada.Streams.Stream_Element_Offset);
+
+   @key(procedure) @AdaSubDefn{Write}(
+      Stream : @key(in out) Params_Stream_Type;
+      Item : @key(in) Ada.Streams.Stream_Element_Array);
+
+
+   @RI(-- Synchronous call)
+   @key(procedure) @AdaSubDefn{Do_RPC}(
+      Partition  : @key(in) Partition_Id;
+      Params     : @key(access) Params_Stream_Type;
+      Result     : @key(access) Params_Stream_Type);
+
+   @RI(-- Asynchronous call)
+   @key(procedure) @AdaSubDefn{Do_APC}(
+      Partition  : @key(in) Partition_Id;
+      Params     : @key(access) Params_Stream_Type);
+
+   @RI(-- The handler for incoming RPCs)
+   @key(type) @AdaTypeDefn{RPC_Receiver} @key(is access procedure)(
+      Params     : @key(access) Params_Stream_Type;
+      Result     : @key(access) Params_Stream_Type);
+
+   @key(procedure) @AdaSubDefn{Establish_RPC_Receiver}(
+      Partition : @key(in) Partition_Id;
+      Receiver  : @key(in) RPC_Receiver);
+
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden(end) System.RPC;
address@hidden
+
+A value of the type Partition_Id is used to identify a partition.
address@hidden,Kind=[AddedNormal],address@hidden,Text=[
+The range of type System.RPC.Partition_Id.]}]}
+
+An object of the type Params_Stream_Type is used for identifying
+the particular remote subprogram that is being called, as
+well as marshalling and
+unmarshalling the parameters or result of a remote
+subprogram call, as part of sending them between partitions.
+
address@hidden Read and Write procedures override the corresponding abstract 
operations
+for the type Params_Stream_Type.]
+
address@hidden
+
address@hidden
+
+The Do_RPC and Do_APC procedures send a message to the active partition
+identified by the Partition parameter.
address@hidden
+It is assumed that the RPC interface is above the message-passing
+layer of the network protocol stack and is implemented in terms of it.
address@hidden
+
+After sending the message, Do_RPC blocks the calling task until a reply
+message comes back from the called partition or some error is detected by
+the underlying communication system in which case Communication_Error is
+raised at the point of the call to Do_RPC.
address@hidden
+Only one exception is defined in System.RPC, although many sources of errors
+might exist. This is so because it is not always possible
+to distinguish among these errors. In particular, it is often impossible to
+tell the difference between a failing communication link and
+a failing processing node. Additional information might be associated with
+a particular Exception_Occurrence for a Communication_Error.
address@hidden
+
+Do_APC operates in the same way as Do_RPC except that it
+is allowed to return immediately after sending the message.
+
+Upon normal return, the stream designated by the Result parameter
+of Do_RPC contains the reply message.
+
address@hidden, Sec=(partition)}
+The procedure System.RPC.Establish_RPC_Receiver is called
+once, immediately after elaborating
+the library units of an active partition
+(that is, right after the @i{elaboration of the partition}) if the partition
+includes an RCI library unit, but prior to invoking the main
+subprogram, if any.
+The Partition parameter is the Partition_Id of the active partition
+being elaborated.
address@hidden
+The Receiver parameter designates an
+implementation-provided procedure called the
address@hidden which will handle all RPCs received by the
+partition from the PCS.
+Establish_RPC_Receiver saves a reference to the RPC-receiver;
+when a message is received at the called partition, the RPC-receiver
+is called with the Params stream containing
+the message. When the RPC-receiver
+returns, the contents of the stream designated by Result is
+placed in a message and sent back to the calling partition.
address@hidden
+It is defined by the PCS implementation whether one or more threads of control
+should be available to process incoming messages and to wait for their
+completion.
address@hidden
address@hidden
+At link-time, the linker provides the RPC-receiver and the necessary tables
+to support it. A call on Establish_RPC_Receiver is inserted just before
+the call on the main subprogram.
address@hidden
address@hidden
+The interface between the PCS (the System.RPC package) and the
+RPC-receiver is defined to be dynamic in order to allow the elaboration
+sequence to notify the PCS that all packages have been
+elaborated and that it is safe to call the receiving stubs. It is not
+guaranteed that the PCS units will be the last to be elaborated, so some
+other indication that elaboration is complete is needed.
address@hidden
+
+If a call on Do_RPC is aborted, a cancellation message is sent
+to the called partition, to request that the execution of the
+remotely called subprogram be aborted.
address@hidden
+The full effects of this message are dependent on the implementation of
+the PCS.
address@hidden
+
address@hidden blocking operation],Sec=(RPC operations)}
address@hidden, potentially],Sec=(RPC operations)}
+The subprograms declared in System.RPC are potentially
+blocking operations.
address@hidden
+
address@hidden
+The implementation of the RPC-receiver shall be address@hidden,
+thereby allowing concurrent calls on it from the PCS to service
+concurrent remote subprogram calls into the partition].
address@hidden
+  There seems no reason to allow the implementation of RPC-receiver
+  to be nonreentrant, even though we don't require that every
+  implementation of the PCS actually perform concurrent calls
+  on the RPC-receiver.
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0087],ARef=[AI95-00082-01]}
address@hidden,Text=[An implementation shall not restrict the
+replacement of the body of
+System.RPC. An implementation shall not restrict children of System.RPC.
address@hidden related implementation permissions in the introduction to
+Annex A do not apply.]]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[The point of System.RPC is to let the user tailor
+the communications
+mechanism without requiring changes to or other cooperation from the compiler.
+However, implementations can restrict the replacement of language-defined 
units.
+This requirement overrides that permission for System.RPC.]}
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0087],ARef=[AI95-00082-01]}
address@hidden,Text=[If the implementation of System.RPC is provided by
+the user, an implementation shall support remote subprogram calls as 
specified.]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00273-01]}
address@hidden,Text=[If the implementation takes advantage of the
+implementation permission to use a different specification for System.RPC,
+it still needs to use it for remote subprogram calls, and allow the user
+to replace the body of System.RPC. It just isn't guaranteed to be portable
+to do so in Ada 2005 - an advantage which was more theoretical than real
+anyway.]}
address@hidden
address@hidden
+
address@hidden
+
+The implementation of the PCS shall document whether
+the RPC-receiver is invoked from concurrent tasks. If there is an
+upper limit on the number of such tasks, this limit shall be documented as
+well, together with the mechanisms to configure it (if this is supported).
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Implementation-defined aspects of the PCS.]}]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Whether the RPC-receiver is invoked from concurrent tasks, and if so,
+the number of such tasks.]}]}
+
address@hidden
+
address@hidden
+
+The PCS is allowed to contain implementation-defined interfaces for
+explicit message passing, broadcasting, etc. Similarly, it is allowed
+to provide additional
+interfaces to query the state of some remote partition (given its partition
+ID) or of the PCS itself, to set timeouts and retry parameters, to get more
+detailed error status, etc. These
+additional interfaces should be provided in child packages of System.RPC.
address@hidden interfaces in the PCS.}
+
+A body for the package System.RPC need not be supplied by the
+implementation.
address@hidden
+  It is presumed that a body for the package System.RPC might be
+  extremely environment specific. Therefore, we do not require
+  that a body be provided by the (compiler) implementation. The user
+  will have to write a body, or acquire one, appropriate for the
+  target environment.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00273-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0299-1]}
address@hidden,Text=[An alternative declaration is allowed for
+package System.RPC as long as it provides a set of operations that is
+substantially equivalent to the specification defined in this
address@hidden,New=[subclause],Old=[clause]}.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Experience has proved that the definition
+  of System.RPC given here is inadequate for interfacing to existing
+  distribution mechanisms (such as CORBA), especially on heterogeneous
+  systems. Rather than mandate a change in the mechanism (which would
+  break existing systems), require implementations to support multiple
+  mechanisms (which is impractical), or prevent the use of Annex E facilities
+  with existing systems (which would be silly), we simply make this facility
+  optional.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[One of the purposes behind System.RPC was
+  that knowledgeable users, rather than compiler vendors, could create
+  this package tailored to their networks. Experience has shown that
+  users get their RPC from vendors anyway; users have not taken advantage
+  of the flexibility provided by this defined interface. Moreover, one
+  could compare this defined interface to requiring Ada compilers to use
+  a defined interface to implement tasking. No one thinks that the latter is
+  a good idea, why should anyone believe that the former is?]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[Therefore, this
+  @Chg{Version=[3],New=[subclause],Old=[clause]} is made optional. We 
considered
+  deleting the @Chg{Version=[3],New=[subclause],Old=[clause]} outright, but we
+  still require that users may replace the package (whatever its interface).
+  Also, it still provides a useful guide to the implementation of this
+  feature.]}
address@hidden
address@hidden
+
address@hidden
+
+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.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The PCS should allow for multiple tasks to call the RPC-receiver.]}]}
+
+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.
address@hidden,Kind=[Added],address@hidden,
+Text=[The System.RPC.Write operation should raise Storage_Error if it runs out
+of space when writing an item.]}]}
address@hidden
+  An implementation could also dynamically allocate more space
+  as needed, only propagating Storage_Error if the @nt<allocator>
+  it calls raises Storage_Error. This storage could be managed
+  through a controlled component of the stream object, to
+  ensure that it is reclaimed when the stream object
+  is finalized.
address@hidden
+
address@hidden
+
address@hidden
+  The package System.RPC is not designed for direct calls by user
+  programs. It is instead designed for use in the implementation of remote
+  subprograms calls, being called by the calling stubs generated for a
+  remote call interface library unit to initiate a remote call,
+  and in turn calling back to an
+  RPC-receiver that dispatches to the receiving stubs generated
+  for the body of a remote call interface, to handle a remote call
+  received from elsewhere.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00273-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  The specification of System.RPC can now be
+  tailored for an implementation. If a program replaces the body of System.RPC
+  with a user-defined body, it might not compile in a given implementation
+  of Ada 2005 (if the specification of System.RPC has been changed).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0087],ARef=[AI95-00082-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that the user 
can
+  replace System.RPC.]}
address@hidden
diff --git a/packages/ada-ref-man/source_2012/front_matter.mss 
b/packages/ada-ref-man/source_2012/front_matter.mss
new file mode 100755
index 0000000..6e5cd44
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/front_matter.mss
@@ -0,0 +1,1576 @@
address@hidden(frontmatter, root="ada.mss")
address@hidden: e:\\cvsroot/ARM/Source/front_matter.mss,v $}
address@hidden: 1.87 $ $Date: 2016/02/12 05:25:38 $}
+
address@hidden(*Removed the below for Ada 2012, which was a revision*)}
address@hidden is a foreword for the consolidated edition of the RM/AARM.}
address@hidden(Foreword to this version of the Ada Reference Manual)
address@hidden above has to be manually commented out if creating "original" 
RMs.
+We shouldn't need to do that again.}
address@hidden needed boilerplate like this to avoid objections from various
+outside parties. It seems unlikely that the same objections won't be raised
+again.}
address@hidden
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Text=[The International Standard for the
+programming language Ada is ISO/IEC 
8652:@Chg{Version=[4],New=[2012],Old=[1995]}(E).]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Text=[The Ada Working Group ISO/IEC JTC 1/SC 22/WG 9 is tasked 
by ISO with
+the work item to interpret and maintain the International Standard and to
+produce Technical Corrigenda, as appropriate. The technical work on the
+International Standard is performed by the Ada Rapporteur Group (ARG) of WG 9.
+In @Chg{Version=[4],New=[June 2015],Old=[September 2000]}, WG 9 approved and
+forwarded Technical Corrigendum 1 to SC 22 for ISO approval, which was granted
+in @Chg{Version=[4],New=[December 2015],Old=[February 2001]}. Technical
+Corrigendum 1 was published in @Chg{Version=[4],New=[February 2016],Old=[June 
2001]}.]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[DeletedAddedNoDelMsg]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,address@hidden,address@hidden,New=[In
+June 2016, WG 9 approved a tentative schedule for the preparation of
+an Amendment or Revision to the International Standard, with a delivery
+no earlier than 2018. For the purposes of this document, we'll call this
+Ada 202x, even though the final timing and form has not yet been 
determined.],Old=[]}],Old=[In
+October 2002, WG 9 approved a schedule and
+guidelines for the preparation of an Amendment to the International Standard.
+WG 9 approved the scope of the Amendment in June 2004. In April 2006, WG 9
+approved and forwarded the Amendment to SC 22 for approval, which was granted
+in August 2006. Final ISO/IEC approval @Chg{Version=[3],New=[came in January 
2007,
+and the Amendment was published as ISO/IEC 8652:1995/Amd 1:2007(E) in 
March],Old=[is expected
+by early]} 2007.]}]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Text=[The Technical Corrigendum lists the individual
+changes that need to be made to the text of the International Standard to
+correct errors, omissions or inconsistencies. The corrections specified in
+Technical Corrigendum 1 are
+part of the International Standard ISO/IEC 
8652:@Chg{Version=[4],New=[2012],Old=[1995]}(E).]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[DeletedAddedNoDelMsg]}
address@hidden,address@hidden,New=[],Old=[Similarly, Amendment 1 
@Chg{Version=[3],New=[and
+Amendment 2 list],Old=[lists]} the individual changes that
+need to be made to the text of the International Standard to add new features
+as well as correct errors.]}]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden@Chg{Version=[5],New=[It is not known whether ISO will
+publish a document that merges the changes of Ada 202x
+into the text of the International Standard.],
+Old=[When ISO published Technical Corrigendum 1, it did not also publish
+a document that merges the @Chg{Version=[2],New=[changes from the 
],Old=[]}Technical
+Corrigendum @Chg{Version=[2],New=[],Old=[changes ]}into
+the text of the International address@hidden,New=[],address@hidden,New=[ 
@Chg{Version=[3],
+New=[Similarly,],Old=[It is not
+known whether]} ISO @Chg{Version=[3],New=[did not],Old=[will]} publish a
+document that merges the changes from
+Technical Corrigendum and Amendment 1 into the text of the International
+Standard.],address@hidden,New=[ It is not known whether ISO will
+publish a document that merges the changes from Technical Corrigendum 1,
+Amendment 1, and Amendment 2 into the text of the International
+Standard.],Old=[]}]}]}
+However, ISO rules require that the
+project editor for the @Chg{Version=[2],New=[International Standard],
+Old=[Technical Corrigendum]} be able to produce such a document
+on demand.],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden version of the Ada Reference Manual is what the project editor 
would
+provide to ISO in response to such a request. It incorporates the changes
+specified in the Technical Corrigendum @Chg{Version=[4],address@hidden,New=[
+and Ada 202x],Old=[]}],address@hidden,New=[and
address@hidden,New=[Amendments 1 and 2],Old=[Amendment]} ],Old=[]}]}into
+the text of @Chg{Version=[4],New=[ISO/IEC 8652:2012(E)],Old=[ISO/IEC 
8652:1995(E)]}.
+It should be understood that the publication of any ISO document involves
+changes in general format, boilerplate, headers, etc., as well as a review by 
professional
+editors that may introduce editorial changes to the text. This version of the
+Ada Reference Manual is therefore neither an official ISO document, nor a
+version guaranteed to be identical to an official ISO document, should ISO
+decide to reprint the International Standard incorporating an approved 
Technical
address@hidden,address@hidden,New=[ and the
+Amendment],Old=[]}],address@hidden,New=[ and 
@Chg{Version=[3],New=[Amendments],Old=[Amendment]}],
+Old=[]}]}. It is nevertheless a
+best effort to be as close as possible to the
+technical content of such an updated document. In the case of a conflict 
between this
+document and @Chg{Version=[5],New=[Ada 202x (or between this document and
+Technical Corrigendum 1 as approved by ISO in the case of paragraphs not 
changed
+by the Corrigendum; or between this document and ],address@hidden,
+New=[Technical Corrigendum 1 as approved by ISO (or
+between this document and ],address@hidden,New=[Amendment],Old=[Technical 
Corrigendum]}
address@hidden,New=[2],Old=[1]} as approved by ISO (or between this document
address@hidden,New=[ Amendment 1 in the case of paragraphs
+not changed by Amendment 2; or between this document and],Old=[]}
address@hidden,New=[Technical Corrigendum 1 in the case of paragraphs
+not changed by @Chg{Version=[3],New=[either ],address@hidden,New=[],Old=[ 1]};
+or between this document and ],Old=[]}]}]}the
+original 8652:@Chg{Version=[4],New=[2012],Old=[1995]} in the case of paragraphs
+not changed by @Chg{Version=[4],New=[],address@hidden,
+New=[either address@hidden,New=[],Old=[ 1]} or ],
+Old=[]}]}Technical Corrigendum 1), the other documents contain the official
+text of the
+International Standard @Chg{Version=[4],New=[ISO/IEC 8652:2012(E)],Old=[
+ISO/IEC 8652:1995(E)@Chg{Version=[2],New=[ and
+its @Chg{Version=[3],New=[Amendments],Old=[Amendment]}],Old=[]}]}.],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden it is very inconvenient to have the Reference Manual for Ada
+specified in @Chg{Version=[4],address@hidden,New=[three],Old=[two]}],
address@hidden,address@hidden,New=[four],Old=[three]}],
+Old=[two]}]} documents, this
+consolidated version of the Ada Reference
+Manual is made available to the public.],Old=[]}
+
address@hidden
address@hidden
address@hidden(*End of Foreword Foreword, not needed for Ada 2012*)}
+
+
address@hidden(Foreword)
address@hidden
+
address@hidden,address@hidden boilerplate}
+ISO (the International Organization for Standardization)
+and IEC (the International Electrotechnical Commission)
+form the specialized system for worldwide standardization.
+National bodies that are members of ISO or IEC
+participate in the development of International Standards through
+technical committees established by the respective organization to deal
+with particular fields of technical activity.
+ISO and IEC technical committees collaborate in fields of mutual
+interest.
+Other international organizations, governmental and non-governmental,
+in liaison with ISO and IEC, also take part in the address@hidden,New=[ In
+the field of information technology,
+ISO and IEC have established a joint technical committee, ISO/IEC JTC 
1.],Old=[]}
+
address@hidden,address@hidden boilerplate}
address@hidden,Text=[International Standards are drafted in accordance
+with the rules given in the ISO/IEC Directives, Part 2.]}
+
address@hidden,address@hidden boilerplate}
address@hidden,New=[The main task of the],Old=[In the field of information
+technology, ISO and IEC have established a]} joint technical
address@hidden,New=[ is to prepare
+International Standards],Old=[, ISO/IEC JTC 1]}.
+Draft International Standards adopted by the joint technical committee
+are circulated to national bodies for voting.
+Publication as an International Standard requires approval by
+at least 75 % of the national bodies casting a vote.
+
address@hidden,address@hidden boilerplate}
address@hidden,Text=[Attention is drawn to the possibility that some of
+the elements of this document may be the subject of patent rights. ISO and IEC
+shall not be held responsible for identifying any or all such patent rights.]}
+
address@hidden,Kind=[Revised]}
+International Standard ISO/IEC 8652 was prepared by
+Joint Technical Committee ISO/IEC JTC 1,
address@hidden address@hidden,New=[ Subcommittee SC22, @i{Programming
+languages, their environments and system software interfaces}],Old=[]}.
+
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
+This @Chg{Version=[4],New=[consolidated edition updates the third edition
+(ISO/IEC 
8652:2012).],address@hidden,New=[third],address@hidden,New=[consolidated],Old=[second]}]}
+edition @Chg{Version=[3],New=[cancels and replaces],address@hidden,
+New=[updates],Old=[cancels and replaces]}]} the 
@Chg{Version=[2],New=[second],Old=[first]}
+edition (address@hidden,New=[/IEC],Old=[]} 
8652:@Chg{Version=[2],New=[1995)],Old=[1987), of which it constitutes
+a technical address@hidden,New=[, which has been technically revised.
+It also incorporates the Technical Corrigendum ISO/IEC 8652:1995:COR.1:2001
+and Amendment ISO/IEC 8652:1995:AMD 1:2007],Old=[]}.]}
address@hidden,address@hidden@b{This version includes corrections and 
improvements
+intended for a future version of Ada, herein named Ada 202x. Besides the
+corrections included in Technical Corrigendum 1, additional corrections and
+improvements are expected for Ada 202x; the timing and form (Corrigendum,
+Amendment, Revision) of future improvements has not yet been finalized.
+Thus, any proposed feature or correction may be substantially changed or 
withdrawn
+before an updated language begins standardization. These draft documents are 
not
+an official publication or work product of the ARG, but rather are provided by
+the Ada Resource Association
+(@URLLink{URL=[http://www.adaresource.org],Text=[www.adaresource.org]})
+as a service to the Ada community.}}],Old=[]}
+
address@hidden text: At this time, no decisions
+have been made as to when, if, or in what form (Corrigendum, Amendment, 
Revision)
+these corrections and improvements will be added to Ada.}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden,New=[],Old=[The above is
+unofficial wording added just to avoid confusion. If ISO decides
+to publish a new standard, the above would be replaced by @ldquote@;This third
+edition cancels and replaces the second edition (ISO 8652:1995), of which it
+constitutes a technical address@hidden The first three paragraphs in this
+section also would be replaced by the current ISO boilerplate.]}]}
address@hidden
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00440-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0299-1]}
address@hidden,Text=[Annexes A to J form an integral part of this
+International Standard.
+Annexes K to @Chg{Version=[2],New=[Q],Old=[P]} are for information only.]}
+
+
address@hidden
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
+This document is the Annotated Ada Reference Manual (AARM).
+It contains the entire text of the Ada
address@hidden,address@hidden,New=[202x],Old=[2012]}],Old=[95]} standard
+(ISO/IEC 
8652:@Chg{Version=[3],address@hidden,New=[202x],Old=[2012]}],Old=[1995]}),
+plus various annotations.
+It is intended primarily for compiler writers,
+validation test writers, and other language lawyers.
+The annotations include detailed rationale for individual rules
+and explanations of some of the more arcane interactions among the
+rules.
address@hidden
address@hidden
address@hidden (*Was Syntax9XOnly - We don't generate this document anymore*)
+This document lists the syntax rules of Ada 95.
address@hidden
address@hidden (*Was Chg839XOnly - We don't generate this document anymore*)
+
+This document lists in detail the changes introduced in the second
+(Ada 95) edition of the Ada standard (ISO/IEC 8652:1995)
+with respect to the first (Ada 83) edition (ISO 8652:1987).
+
address@hidden
+
+
address@hidden
+
address@hidden
address@hidden
address@hidden
+This is the Annotated Ada Reference Manual.
address@hidden
address@hidden
+This is the Ada Reference Manual.
address@hidden
+
address@hidden@;Other available Ada documents include:
address@hidden have to put the itemize inside of the AARMOnly, because otherwise
+the formatter thinks this is a nested bullet, making a mess. Since this is
+the only place this is used, it is easier to fix the text than the program.
+RLB - 2000-05-17}
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0245-1]}
address@hidden,New=[Ada 2012 Rationale. This gives an introduction to the 
changes and
+new features in Ada 2012, and explains the rationale behind them.
+Programmers should read this rationale before reading this Standard
+in depth. Rationales for Ada 83, Ada 95, and Ada 2005 are also
+available.],address@hidden,New=[Ada 95 Rationale. This],Old=[Rationale for the 
Ada
+Programming Language @em 1995 edition, which]} gives an introduction to the
+new features of address@hidden,New=[ incorporated in the 1995 edition
+of this Standard],Old=[]}, and explains the rationale behind them.
+Programmers @Chg{Version=[2],New=[unfamiliar with Ada 95 ],
+Old=[]}should read this first.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0245-1]}
+  @ChgRef{Version=[4],address@hidden now.}
+  @ChgAdded{Version=[3],address@hidden,New=[],Old=[As of this writing
+  (December 2012), only five
+  chapters of the Ada 2012 Rationale have been published. Additional
+  chapters are in development and should be published during 2013.]}]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00387-01]}
address@hidden,Kind=[DeletedAddedNoDelMsg],ARef=[AI05-0245-1]}
address@hidden,address@hidden,New=[],Old=[Ada 2005 Rationale.
+This gives an introduction to the changes and new features in Ada 2005 
(compared
+with the 1995 edition), and explains the rationale behind them. Programmers
+should read this rationale before reading this Standard in depth.]}]}
+
address@hidden,Kind=[Deleted]}
address@hidden,Text=[Changes to Ada @em 1987 to 1995. This document
+lists in detail the changes made to the 1987 edition of the standard.]}
+
address@hidden,Kind=[Revised]}
+The Ada Reference Manual (RM).
+This is the International Standard @em ISO/IEC 
8652:@Chg{Version=[3],New=[2012],Old=[1995]}.
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[DeletedAddedNoDelMsg]}
address@hidden,address@hidden,New=[],Old=[Technical Corrigendum 1
address@hidden ISO/IEC 8652:1995:COR.1:2001. This document lists corrections to 
the
+International address@hidden is consolidated into the Ada 2012 RM}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[DeletedAddedNoDelMsg]}
address@hidden,address@hidden,New=[],Old=[Amendment 1 @em ISO/IEC
+8652:1995:AMD 1:2007. This document outlines additional features and 
corrections
+to the International address@hidden is consolidated into the Ada 2012 RM}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[DeletedAddedNoDelMsg]}
address@hidden,address@hidden,New=[],Old=[The consolidated Ada Reference 
Manual. An @i{unofficial}
+document combining the above three
+documents into a single document.]}]}
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0245-1]}
address@hidden,New=[Ada 2012 Rationale. This gives an introduction to the 
changes and
+new features in Ada 2012, and explains the rationale behind them.
+Programmers should read this rationale before reading this Standard
+in depth. Rationales for Ada 83, Ada 95, and Ada 2005 are also
+available.],address@hidden,New=[Ada 95 Rationale. This],Old=[Rationale for the 
Ada
+Programming Language @em 1995 edition, which]} gives an introduction to the
+new features of address@hidden,New=[ incorporated in the 1995 edition
+of this Standard],Old=[]}, and explains the rationale behind them.
+Programmers @Chg{Version=[2],New=[unfamiliar with Ada 95 ],
+Old=[]}should read this first.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00387-01]}
address@hidden,Kind=[DeletedAddedNoDelMsg],ARef=[AI05-0245-1]}
address@hidden,address@hidden,New=[],Old=[Ada 2005 Rationale.
+This gives an introduction to the changes and new features in Ada 2005 
(compared
+with the 1995 edition), and explains the rationale behind them. Programmers
+should read this rationale before reading this Standard in depth.]}]}
+
address@hidden,Kind=[Deleted]}
address@hidden, Text=[Changes to Ada @em 1987 to 1995. This document lists in
+detail the changes made to the 1987 edition of the standard.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
address@hidden,Kind=[Revised]}
+The Annotated Ada Reference Manual (AARM)address@hidden Ada Reference Manual}
address@hidden AARM contains all of the text
+in @Chg{Version=[3],New=[this International Standard],
address@hidden,New=[the consolidated Ada Reference Manual],Old=[the RM95]}]},
address@hidden: John had "this International Standard", but it's really
+related to the unofficial document. Change it back if ISO decides to publish
+this consolidated RM.}
address@hidden: Changed back for Ada 2012.}
+plus various annotations. It is intended primarily for compiler writers,
+validation test writers,
+and others who wish to study the fine details.
+The annotations include detailed rationale for individual rules
+and explanations of some of the more arcane interactions among the
+rules.
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden(Design Goals)
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
address@hidden,Kind=[Revised]}
+Ada was originally designed with three overriding concerns:
+program reliability and maintenance, programming as a human
+activity, and efficiency. @Chg{Version=[2],New=[The 1995],Old=[This]} revision
+to the language was designed to provide greater flexibility and extensibility,
+additional control over storage management and
+synchronization, and standardized packages oriented toward
+supporting important application areas, while at the same
+time retaining the original emphasis on reliability,
+maintainability, and address@hidden,New=[ This
address@hidden,New=[third edition],Old=[amended version]}
+provides further flexibility and adds more standardized packages within the
+framework provided by the 1995 revision.],Old=[]}
+
+The need for languages that promote reliability and simplify
+maintenance is well established. Hence emphasis was placed
+on program readability over ease of writing. For example,
+the rules of the language require that program variables be
+explicitly declared and that their type be specified. Since
+the type of a variable is invariant, compilers can ensure
+that operations on variables are compatible with the
+properties intended for objects of the type. Furthermore,
+error-prone notations have been avoided, and the syntax of
+the language avoids the use of encoded forms in favor of
+more English-like constructs. Finally, the language offers
+support for separate compilation of program units in a way
+that facilitates program development and maintenance, and
+which provides the same degree of checking between units as
+within a unit.
+
+Concern for the human programmer was also stressed during
+the design. Above all, an attempt was made to keep to a
+relatively small number of underlying concepts integrated in
+a consistent and systematic way while continuing to avoid
+the pitfalls of excessive involution. The design especially
+aims to provide language constructs that correspond
+intuitively to the normal expectations of users.
+
+Like many other human activities, the development of
+programs is becoming ever more decentralized and
+distributed. Consequently, the ability to assemble a
+program from independently produced software components
+continues to be a central idea in the design. The concepts
+of packages, of private types, and of generic units are
+directly related to this idea, which has ramifications in
+many other aspects of the language. An allied concern is
+the maintenance of programs to match changing requirements;
+type extension and the hierarchical library enable a program
+to be modified while minimizing disturbance to existing
+tested and trusted components.
+
+No language can avoid the problem of efficiency. Languages
+that require over-elaborate compilers, or that lead to the
+inefficient use of storage or execution time, force these
+inefficiencies on all machines and on all programs. Every
+construct of the language was examined in the light of
+present implementation techniques. Any proposed construct
+whose implementation was unclear or that required excessive
+machine resources was rejected.
address@hidden
+
address@hidden Summary}
+
address@hidden
+An Ada program is composed of one or more program units.
+Program units may be subprograms (which define executable
+algorithms), packages (which define collections of
+entities), task units (which define concurrent
+computations), protected units (which define operations for
+the coordinated sharing of data between tasks), or generic
+units (which define parameterized forms of packages and
+subprograms). Each program unit normally consists of two parts: a
+specification, containing the information that must be
+visible to other units, and a body, containing the
+implementation details, which need not be visible to other
+units. Most program units can be compiled separately.
+
+This distinction of the specification and body, and the
+ability to compile units separately, allows a program to be
+designed, written, and tested as a set of largely
+independent software components.
+
+An Ada program will normally make use of a library of
+program units of general utility. The language provides
+means whereby individual organizations can construct their
+own libraries. All libraries are structured in a
+hierarchical manner; this enables the logical decomposition
+of a subsystem into individual components. The text of a
+separately compiled program unit must name the library units
+it requires.
+
+
address@hidden@i(Program Units)
+
+A subprogram is the basic unit for expressing an algorithm.
+There are two kinds of subprograms: procedures and
+functions. A procedure is the means of invoking a series of
+actions. For example, it may read data, update variables,
+or produce some output. It may have parameters, to provide
+a controlled means of passing information between the
+procedure and the point of call.
+A function is the means of invoking the computation of a
+value. It is similar to a procedure, but in addition will
+return a result.
+
+A package is the basic unit for defining a collection of
+logically related entities. For example, a package can be
+used to define a set of type declarations and
+associated operations. Portions of a package can be hidden
+from the user, thus allowing access only to the logical
+properties expressed by the package specification.
+
+Subprogram and package units may be compiled separately and
+arranged in hierarchies of parent and child units giving
+fine control over visibility of the logical properties and
+their detailed implementation.
+
+A task unit is the basic unit for defining a task whose
+sequence of actions may be executed concurrently with those
+of other tasks. Such tasks may be implemented on
+multicomputers, multiprocessors, or with interleaved
+execution on a single processor. A task unit may define
+either a single executing task or a task type permitting the
+creation of any number of similar tasks.
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+A protected unit is the basic unit for defining protected
+operations for the coordinated use of data shared between
+tasks. Simple mutual exclusion is provided automatically,
+and more elaborate sharing protocols can be defined. A
+protected operation can either be a subprogram or an entry.
+A protected entry specifies a Boolean expression (an entry
+barrier) that must be @Chg{Version=[2],New=[True],Old=[true]}
+before the body of the entry is
+executed. A protected unit may define a single protected
+object or a protected type permitting the creation of
+several similar objects.
+
address@hidden@i(Declarations and Statements)
+
+The body of a program unit generally contains two parts: a
+declarative part, which defines the logical entities to be
+used in the program unit, and a sequence of statements,
+which defines the execution of the program unit.
+
+The declarative part associates names with declared
+entities. For example, a name may denote a type, a
+constant, a variable, or an exception. A declarative part
+also introduces the names and parameters of other nested
+subprograms, packages, task units, protected units, and
+generic units to be used in the program unit.
+
+The sequence of statements describes a sequence of actions
+that are to be performed. The statements are executed in
+succession (unless a transfer of control causes execution to continue
+from another place).
+
+An assignment statement changes the value of a variable. A
+procedure call invokes execution of a procedure after
+associating any actual parameters provided at the call with
+the corresponding formal parameters.
+
+Case statements and if statements allow the selection of an
+enclosed sequence of statements based on the value of an
+expression or on the value of a condition.
+
+The loop statement provides the basic iterative mechanism in
+the language. A loop statement specifies that a sequence of
+statements is to be executed repeatedly as directed by an
+iteration scheme, or until an exit statement is encountered.
+
+A block statement comprises a sequence of statements
+preceded by the declaration of local entities used by the
+statements.
+
+Certain statements are associated with concurrent execution.
+A delay statement delays the execution of a task for a
+specified duration or until a specified time. An entry call
+statement is written as a procedure call statement; it
+requests an operation on a task or on a protected
+object, blocking the caller until the operation can be
+performed. A called task may accept an entry call by
+executing a corresponding accept statement, which specifies
+the actions then to be performed as part of the rendezvous
+with the calling task. An entry call on a protected object
+is processed when the corresponding entry barrier evaluates
+to true, whereupon the body of the entry is executed. The
+requeue statement permits the provision of a service as a
+number of related activities with preference control. One
+form of the select statement allows a selective wait for one
+of several alternative rendezvous. Other forms of the
+select statement allow conditional or timed entry calls and
+the asynchronous transfer of control in response to some
+triggering event.
+
+Execution of a program unit may encounter error situations
+in which normal program execution cannot continue. For
+example, an arithmetic computation may exceed the maximum
+allowed value of a number, or an attempt may be made to
+access an array component by using an incorrect index value.
+To deal with such error situations, the statements of a
+program unit can be textually followed by exception handlers
+that specify the actions to be taken when the error
+situation arises. Exceptions can be raised explicitly by a
+raise statement.
+
address@hidden@i(Data Types)
+
+Every object in the language has a type, which characterizes
+a set of values and a set of applicable operations. The
+main classes of types are elementary types (comprising
+enumeration, numeric, and access types) and composite types
+(including array and record types).
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01],ARef=[AI95-00387-01]}
+An enumeration type defines an ordered set of distinct
+enumeration literals, for example a list of states or an
+alphabet of characters. The enumeration types Boolean,
+Character, @Chg{Version=[2],New=[],
+Old=[and address@hidden,New=[, and Wide_Wide_Character],
+Old=[]} are predefined.
+
+Numeric types provide a means of performing exact or
+approximate numerical computations. Exact computations use
+integer types, which denote sets of consecutive integers.
+Approximate computations use either fixed point types, with
+absolute bounds on the error, or floating point types, with
+relative bounds on the error. The numeric types Integer,
+Float, and Duration are predefined.
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01],ARef=[AI95-00387-01]}
+Composite types allow definitions of structured objects with
+related components. The composite types in the language
+include arrays and records. An array is an object with
+indexed components of the same type. A record is an object
+with named components of possibly different types. Task and
+protected types are also forms of composite types. The
+array types address@hidden,New=[,],Old=[ and]}
address@hidden,
+New=[, and Wide_Wide_String],Old=[]} are predefined.
+
+Record, task, and protected types may have special components
+called discriminants which parameterize the type.
+Variant record structures that depend on the values of
+discriminants can be defined within a record type.
+
+Access types allow the construction of linked data
+structures. A value of an access type represents a
+reference to an object declared as aliased or to an object
+created by the evaluation of an allocator. Several
+variables of an access type may designate the same object,
+and components of one object may designate the same or other
+objects. Both the elements in such linked data structures
+and their relation to other elements can be altered during
+program execution. Access types also permit references to
+subprograms to be stored, passed as parameters, and
+ultimately dereferenced as part of an indirect call.
+
+Private types permit restricted views of a type. A private
+type can be defined in a package so that only the logically
+necessary properties are made visible to the users of the
+type. The full structural details that are externally
+irrelevant are then only available within the package and
+any child units.
+
+From any type a new type may be defined by derivation. A type,
+together with its derivatives (both direct and indirect)
+form a derivation class. Class-wide operations may be
+defined that accept as a parameter an operand of any type in
+a derivation class. For record and private types, the derivatives may
+be extensions of the parent type. Types that support these
+object-oriented capabilities of class-wide operations and type extension
+must be tagged, so that
+the specific type of an operand within a derivation class can
+be identified at run time. When an operation of a tagged
+type is applied to an operand whose specific type is not
+known until run time, implicit dispatching is performed
+based on the tag of the operand.
+
address@hidden,Kind=[Added],ARef=[AI95-00387-01]}
address@hidden,Text=[
+Interface types provide abstract models from which other interfaces and
+types may be composed and derived. This provides a reliable form of multiple
+inheritance. Interface types may also be implemented by
+task types and protected types thereby enabling concurrent programming and
+inheritance to be merged.]}
+
+The concept of a type is further refined by the concept of a
+subtype, whereby a user can constrain the set of allowed
+values of a type. Subtypes can be used to define subranges
+of scalar types, arrays with a limited set of index values,
+and records and private types with particular discriminant
+values.
+
address@hidden@i(Other Facilities)
+
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
address@hidden,New=[Aspect],Old=[Representation]} clauses can be
+used to specify the mapping
+between types and features of an underlying machine. For
+example, the user can specify that objects of a given type
+must be represented with a given number of bits, or that the
+components of a record are to be represented using a given
+storage layout. Other features allow the controlled use of
+low level, nonportable, or implementation-dependent aspects,
+including the direct insertion of machine code.
+
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
+The predefined environment of the language provides
+for input-output and other capabilities @Chg{Version=[2],New=[],Old=[(such
+as string manipulation and random number generation) ]}by means of
+standard library packages.
+Input-output is supported for
+values of user-defined as well as of predefined types.
+Standard means of representing values in display form are
+also address@hidden,New=[],Old=[ Other standard library packages are defined
+in annexes of the standard to support systems with
+specialized requirements.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00387-01]}
address@hidden,New=[The predefined standard library packages provide
+facilities such as string manipulation, containers of various kinds (vectors,
+lists, maps, etc.), mathematical functions, random number generation, and 
access
+to the execution environment.],Old=[]}
+
address@hidden,Kind=[Added],ARef=[AI95-00387-01]}
address@hidden,New=[The specialized annexes define further predefined library
+packages and facilities with emphasis on areas such as real-time
+scheduling, interrupt handling, distributed systems, numerical computation, and
+high-integrity systems.],Old=[]}
+
+Finally, the language provides a powerful means of
+parameterization of program units, called generic program
+units. The generic parameters can be types and subprograms
+(as well as objects and packages) and so allow general
+algorithms and data structures to be defined that are
+applicable to all types of a given class.
address@hidden
+
address@hidden Changes}
+
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 44
+through 57 have been removed as they described differences from the first 
edition
+of Ada (Ada 83).>address@hidden message should be
+deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Type=[Leading],Text=[This @Chg{Version=[2],New=[amended 
],Old=[]}International Standard
address@hidden,New=[updates the edition of 1995 which replaced],
+Old=[replaces]} the first edition of 1987.
+In @Chg{Version=[2],New=[the 1995],Old=[this]} edition, the following major
+language changes @Chg{Version=[2],New=[were],Old=[have been]} incorporated:]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[Support for standard 8-bit and 16-bit
address@hidden,New=[s was added],Old=[ sets]}.
+See @Chg{Version=[2],New=[clauses @RefSecNum{Character Set}],Old=[Section 2]},
address@hidden Types},
address@hidden Types},
address@hidden Package Standard},
address@hidden Handling}, and
address@hidden Handling}.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden,New=[The type model was extended to include 
facilities
+for o],Old=[O]}bject-oriented programming
+with @Chg{Version=[2],New=[dynamic],Old=[run-time]} polymorphism.
+See the discussions of classes, derived types, tagged types,
+record extensions, and private extensions
+in clauses @RefSecNum{Derived Types and Classes},
address@hidden Types and Type Extensions}, and
address@hidden Types and Private Extensions}.
address@hidden,New=[Additional],Old=[See also the new]} forms of generic
+formal parameters @Chg{Version=[2],New=[were],Old=[that are]} allowed
address@hidden,New=[as described in clauses
address@hidden Private and Derived Types} and @RefSecNum{Formal Packages}],
+Old=[by @RefSec{Formal Private and Derived Types} and @RefSec{Formal 
Packages}]}.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[Access types @Chg{Version=[2],New=[were],Old=[have been]} 
extended to allow
+an access value to designate a subprogram or an object declared by an
+object declaration @Chg{Version=[2],New=[],Old=[(]}as opposed to just
address@hidden,New=[an object ],Old=[a heap-]}allocated
address@hidden,New=[on a heap],Old=[object)]}.
+See @Chg{Version=[2],New=[clause ],address@hidden Types}.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[Efficient data-oriented synchronization 
@Chg{Version=[2],New=[was],
+Old=[is]} provided @Chg{Version=[2],New=[by the introduction of],
+Old=[via]} protected types. See @Chg{Version=[2],
+New=[clause @RefSecNum{Protected Units and Protected Objects}],Old=[Section 
9]}.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[The library @Chg{Version=[2],New=[structure was extended 
to allow
+library units to],Old=[units of a library may]} be organized into a
+hierarchy of parent and child units.
+See @Chg{Version=[2], New=[clause @RefSecNum{Separate Compilation}],
+Old=[Section 10]}.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[Additional support
address@hidden,New=[was],Old=[has been]} added for interfacing to other
+languages. See @RefSecNum{Interface to Other Languages}.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00387-01]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Type=[Leading],Text=[The Specialized Needs Annexes
address@hidden,New=[were],Old=[have been]} added
+to provide specific support for certain application areas:]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden Programming}]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden Systems}]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden Systems}]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden Systems}]}
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,address@hidden Integrity Systems}]}
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00387-01]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,address@hidden,New=[This International Standard
+replaces the second edition of 1995. It],Old=[Amendment 1]} modifies the
address@hidden,New=[previous edition],Old=[1995 International Standard]} by
+making changes and additions that improve the capability of the language and
+the reliability of programs written in the address@hidden,New=[ This
+edition incorporates the changes from Amendment 1 (ISO/IEC 8652:1995:AMD 
1:2007),
+which],Old=[In particular the changes]}
+were designed to improve the portability of programs, interfacing to other
+languages, and both the object-oriented and real-time capabilities.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00387-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0299-1]}
address@hidden,Type=[Leading],address@hidden,New=[Significant],
+Old=[The following significant]} address@hidden,New=[ originating
+in Amendment 1],Old=[with respect to the 1995 edition]} are incorporated:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,New=[Support for program text is extended to cover the
+entire ISO/IEC 10646:2003 repertoire. Execution support now includes the
+32-bit character set. See @Chg{Version=[3],New=[subclauses],Old=[clauses]}
address@hidden Set},
address@hidden Types},
address@hidden Types},
address@hidden Package Standard},
address@hidden Handling}, and
address@hidden Handling}.],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,New=[
+The object-oriented model has been improved by the addition of an
+interface facility which provides multiple inheritance and additional
+flexibility for type extensions. See 
@Chg{Version=[3],New=[subclauses],Old=[clauses]} @RefSecNum{Derived Types and 
Classes},
address@hidden Types and Type Extensions}, and
address@hidden Types and Private Extensions}. An
+alternative notation for calling operations more akin to that used in
+other languages has also been added. See 
@Chg{Version=[3],New=[subclause],Old=[clause]} @RefSecNum{Selected 
Components}.],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,New=[
+Access types have been further extended to unify properties such as
+the ability to access constants and to exclude null values. See clause
address@hidden Types}. Anonymous access types are now permitted more
+freely and anonymous access-to-subprogram types are introduced. See
address@hidden,New=[subclauses],Old=[clauses]}
address@hidden and Named Numbers}, @RefSecNum{Array Types},
address@hidden Types}, and @RefSecNum{Object Renaming Declarations}.],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,New=[
+The control of structure and visibility has been enhanced to
+permit mutually dependent references between units and finer control
+over access from the private part of a package. See 
@Chg{Version=[3],New=[subclauses],Old=[clauses]}
address@hidden Type Declarations} and @RefSecNum{Context Clauses - With 
Clauses}.
+In addition, limited types have been made more useful by the
+provision of aggregates, constants, and constructor functions. See
address@hidden,New=[subclauses],Old=[clauses]}
address@hidden, @RefSecNum{Return Statements},
+and @RefSecNum{Limited Types}.],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,New=[
+The predefined environment has been extended to include additional time
+and calendar operations,
+improved string handling, a comprehensive container library, file and
+directory management, and access to environment variables. See
address@hidden,New=[subclauses],Old=[clauses]}
address@hidden, Time Zones, and other operations for Time},
address@hidden Handling},
address@hidden Package Directories},
address@hidden Package Environment_Variables},
+and @RefSecNum{Containers}.],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,New=[
+Two of the Specialized Needs Annexes have been considerably enhanced:],Old=[]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,New=[
+The Real-Time Systems Annex now includes the Ravenscar profile for
+high-integrity systems, further dispatching policies such as Round Robin
+and Earliest Deadline First, support for timing events, and support for
+control of CPU time utilization. See
address@hidden,New=[subclauses],Old=[clauses]} @RefSecNum{Priority Scheduling},
address@hidden Ravenscar Profile},
address@hidden Time}, and
address@hidden Events}.],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,New=[
+The Numerics Annex now includes support for real and complex vectors
+and matrices as previously defined in ISO/IEC 13813:1997 plus further basic
+operations for linear algebra.
+See @Chg{Version=[3],New=[subclause],Old=[clause]} @RefSecNum{Vector and 
Matrix Manipulation}.],Old=[]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,New=[
+The overall reliability of the language has been enhanced by
+a number of improvements. These include new syntax which detects
+accidental overloading, as well as pragmas for making assertions and
+giving better control over the suppression of checks. See 
@Chg{Version=[3],New=[subclauses],Old=[clauses]}
address@hidden Declarations},
address@hidden Assert and Assertion_Policy}, and
address@hidden Checks}.],Old=[]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0245-1]}
address@hidden,Text=[In addition, this third edition makes
+enhancements to address two important issues, namely, the particular problems 
of
+multiprocessor architectures, and the need to further increase the capabilities
+regarding assertions for correctness. It also makes additional changes and
+additions that improve the capability of the language and the reliability of
+programs written in the language.]}
+
address@hidden original "Amendment 2" version of this text follows:
+Amendment 2 modifies the 1995 International Standard
+by making changes and additions that improve the capability of the language and
+the reliability of programs written in the language. In particular, 
enhancements
+are made to address two important issues, namely, the particular problems of
+multiprocessor architectures, and the need to further increase the capabilities
+regarding assertions for correctness.}
+
address@hidden,Kind=[Added],ARef=[AI05-0245-1],ARef=[AI05-0299-1]}
address@hidden,Type=[Leading],Text=[The following significant changes
+with respect to the 1995 edition as amended by Amendment 1 are incorporated:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[New syntax (the aspect specification) is introduced
+to enable properties to be specified for various entities in a more structured
+manner than through pragmas. See subclause @RefSecNum{Aspect Specifications}.]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0141-1]}
address@hidden,Text=[The concept of assertions introduced in the 2005
+edition is extended with the ability to specify preconditions and 
postconditions
+for subprograms, and invariants for private address@hidden,New=[ and
+interfaces],Old=[]}. The concept of constraints in
+defining subtypes is supplemented with subtype predicates that enable subsets
+to be specified other than as simple ranges. These properties are all indicated
+using aspect specifications. See subclauses @RefSecNum{Subtype Predicates},
address@hidden and Postconditions}, and @RefSecNum{Type Invariants}.]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0141-1]}
address@hidden,Text=[New forms of expressions are introduced. These are
+if expressions, case expressions, quantified expressions,
address@hidden,New=[],Old=[and ]}expression
address@hidden,New=[, and raise expressions],Old=[]}. As well as
+being useful for programming in general by avoiding the
+introduction of unnecessary assignments, they are especially valuable in
+conditions and invariants since they avoid the need to introduce auxiliary
+functions. See subclauses @RefSecNum{Conditional Expressions},
address@hidden Expressions},
address@hidden,New=[],Old=[and address@hidden address@hidden,New=[,
+and @RefSecNum{Raise Statements and Raise Expressions}],Old=[]}.
+Membership tests are also made more flexible. See subclauses
address@hidden and @RefSecNum{Relational Operators and Membership Tests}.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[A number of changes are made to subprogram parameters.
+Functions may now have parameters of all modes. In order to mitigate consequent
+(and indeed existing) problems of inadvertent order dependence, rules are
+introduced to reduce aliasing. A parameter may now be explicitly marked as
+aliased and the type of a parameter may be incomplete in
+certain circumstances. See subclauses @RefSecNum{Incomplete Type Declarations},
address@hidden Declarations}, and @RefSecNum{Parameter Associations}.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The use of access types is now more flexible. The
+rules for accessibility and certain conversions are improved. See subclauses
address@hidden of Access Types}, @RefSecNum{Relational Operators and Membership 
Tests},
address@hidden Conversions}, and @RefSecNum{The Context of Overload Resolution}.
+Furthermore, better control of storage pools is
+provided. See subclause @RefSecNum{Storage Subpools}.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The Real-Time Systems Annex now includes facilities
+for defining domains of processors and assigning tasks to them. Improvements 
are
+made to scheduling and budgeting facilities. See subclauses 
@RefSecNum{Synchronous Barriers},
address@hidden Time}, and @RefSecNum{Multiprocessor Implementation}.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[A number of important improvements are made to the
+standard library. These include packages for conversions between strings and 
UTF
+encodings, and classification functions for wide and wide wide characters.
+Internationalization is catered for by a package giving locale information. See
+subclauses @RefSecNum{Character Handling}, @RefSecNum{String Encoding}, and
address@hidden Package Locales}. The container library is extended to include
+bounded forms of the existing containers and new containers for indefinite
+objects, multiway trees, and queues. See subclause @RefSecNum{Containers}.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Finally, certain features are added primarily to
+ease the use of containers, such as the ability to iterate over all elements 
in a
+container without having to encode the iteration. These can also be used for
+iteration over arrays, and within quantified expressions. See
+subclauses @RefSecNum{User-Defined References},
address@hidden Indexing}, @RefSecNum{User-Defined Iterator Types},
+and @RefSecNum{Generalized Loop Iteration}.]}
address@hidden
address@hidden
+
address@hidden
address@hidden(Instructions for Comment Submission)
+
address@hidden
+
+
address@hidden,Kind=[Revised]}
address@hidden for comment submission}
address@hidden, instructions for submission}
+Informal comments on this International Standard may be sent via
+e-mail to @address@hidden(ada-comment@@ada-auth.org)],
address@hidden(ada-comment@@sw-eng.falls-church.va.us)]}.
+If appropriate, the Project Editor will initiate
+the defect correction procedure.
+
+
+Comments should use the following format:
address@hidden(display)
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised]}
address@hidden(L6)@address@hidden(!topic) @i[Title summarizing comment]
address@hidden@b(!reference) @Chg{Version=[2],New=[Ada 
@Chg{Version=[3],address@hidden,New=[202x],Old=[2012]}],Old=[2005]} 
RM],address@hidden(pp)}
address@hidden@b(!from) @i{Author Name yy-mm-dd}
address@hidden@b(!keywords) @i{keywords related to topic}
address@hidden@b(!discussion)
address@hidden line}
address@hidden@i{text of discussion}
address@hidden(display)
+
address@hidden,Kind=[Revised]}
+where @i(ss.ss) is the @Chg{Version=[3],New=[],Old=[section, ]}clause or
+subclause number, @i(pp) is the paragraph number where applicable,
+and @i(yy-mm-dd) is the date the comment was sent.
+The date is optional, as is the @b(!keywords) line.
+
address@hidden,Kind=[Revised]}
address@hidden, Old=[Multiple comments per e-mail message are acceptable.]}
+Please use a descriptive @lquotes@;address@hidden@; in your e-mail
address@hidden, and limit each message to a single comment.], Old=[.]}
+
+When correcting typographical errors or making minor wording
+suggestions, please put the correction directly as the topic of the
+comment; use square brackets [ ] to indicate text to be omitted and
+curly braces { } to indicate text to be added, and provide enough
+context to make the nature of the suggestion self-evident or put
+additional information in the body of the comment, for example:
address@hidden
address@hidden(L6)@address@hidden(!topic) [c]{C}haracter
address@hidden@b(!topic) it[']s meaning is not defined
address@hidden
+
+
+Formal requests for interpretations and for reporting defects in this
+International Standard may be made in accordance with the ISO/IEC
+JTC 1 Directives and the ISO/IEC JTC 1/SC 22 policy for interpretations.
+National Bodies may submit a Defect Report to ISO/IEC JTC 1/SC 22 for 
resolution
+under the JTC 1 procedures.
+A response will be provided and, if appropriate,
+a Technical Corrigendum will be issued in accordance with the procedures.
+
+
address@hidden
+
address@hidden
address@hidden
address@hidden,Acknowledgements for the Ada 83 edition}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Ada is the result of a collective effort to design a
+common language for programming large scale and real-time systems.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The common high order language program began in
+1974. The requirements of the United States Department of Defense were
+formalized in a series of documents which were extensively reviewed by the
+Services, industrial organizations, universities, and foreign military
+departments. The Ada language was designed in accordance with the final (1978)
+form of these requirements, embodied in the Steelman specification.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The Ada design team was led by Jean D. Ichbiah and
+has included Bernd Krieg-Brueckner, Brian A. Wichmann, Henry F. Ledgard,
+Jean-Claude Heliard, Jean-Loup Gailly, Jean-Raymond Abrial, John G.P. Barnes,
+Mike Woodger, Olivier Roubine, Paul N. Hilfinger, and Robert Firth.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[At various stages of the project, several people
+closely associated with the design team made major contributions. They include
+J.B. Goodenough, R.F. Brender, M.W. Davis, G. Ferran, K. Lester, L. MacLaren, 
E.
+Morel, I.R. Nassi, I.C. Pyle, S.A. Schuman, and S.C. Vestal.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Two parallel efforts that were started in the second
+phase of this design had a deep influence on the language. One was the
+development of a formal definition using denotational semantics, with the
+participation of V. Donzeau-Gouge, G. Kahn, and B. Lang. The other was the
+design of a test translator with the participation of K. Ripken, P. Boullier, 
P.
+Cadiou, J. Holden, J.F. Hueras, R.G. Lange, and D.T. Cornhill. The entire 
effort
+benefitted from the dedicated assistance of Lyn Churchill and Marion Myers, and
+the effective technical support of B. Gravem, W.L. Heimerdinger, and P. Cleve.
+H.G. Schmitz served as program manager.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Over the five years spent on this project, several
+intense week-long design reviews were conducted, with the participation of P.
+Belmont, B. Brosgol, P. Cohen, R. Dewar, A. Evans, G. Fisher, H. Harte, A.L.
+Hisgen, P. Knueven, M. Kronental, N. Lomuto, E. Ploedereder, G. Seegmueller, V.
+Stenning, D. Taffs, and also F. Belz, R. Converse, K. Correll, A.N. Habermann,
+J. Sammet, S. Squires, J. Teller, P. Wegner, and P.R. Wetherall.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Several persons had a constructive influence with
+their comments, criticisms and suggestions. They include P. Brinch Hansen, G.
+Goos, C.A.R. Hoare, Mark Rain, W.A. Wulf, and also E. Boebert, P. Bonnard, H.
+Clausen, M. Cox, G. Dismukes, R. Eachus, T. Froggatt, H. Ganzinger, C. Hewitt,
+S. Kamin, R. Kotler, O. Lecarme, J.A.N. Lee, J.L. Mansion, F. Minel, T. 
Phinney,
+J. Roehrich, V. Schneider, A. Singer, D. Slosberg, I.C. Wand, the reviewers of
+Ada-Europe, AdaTech, Afcet, those of the LMSC review team, and those of the Ada
+Tokyo Study Group.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[These reviews and comments, the numerous evaluation
+reports received at the end of the first and second phase, the nine hundred
+language issue reports and test and evaluation reports received from fifteen
+different countries during the third phase of the project, the thousands of
+comments received during the ANSI Canvass, and the on-going work of the IFIP
+Working Group 2.4 on system implementation languages and that of the Purdue
+Europe LTPL-E committee, all had a substantial influence on the final 
definition
+of Ada.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The Military Departments and Agencies have provided
+a broad base of support including funding, extensive reviews, and countless
+individual contributions by the members of the High Order Language Working 
Group
+and other interested personnel. In particular, William A. Whitaker provided
+leadership for the program during the formative stages. David A. Fisher was
+responsible for the successful development and refinement of the language
+requirement documents that led to the Steelman specification.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The Ada 83 language definition was developed by Cii
+Honeywell Bull and later Alsys, and by Honeywell Systems and Research Center,
+under contract to the United States Department of Defense. William E. Carlson
+and later Larry E. Druffel served as the technical representatives of the 
United
+States Government and effectively coordinated the efforts of all participants 
in
+the Ada program.]}
+
+
address@hidden(address@hidden,New=[ for the Ada 95 edition],Old=[]})
+
address@hidden
+
+This International Standard was prepared by the Ada 9X Mapping/Revision
+Team based at Intermetrics, Inc., which has included:
+W. Carlson, Program Manager;
+T. Taft, Technical Director;
+J. Barnes (consultant);
+B. Brosgol (consultant);
+R. Duff (Oak Tree Software);
+M. Edwards;
+C. Garrity;
+R. Hilliard;
+O. Pazy (consultant);
+D. Rosenfeld;
+L. Shafer;
+W. White;
+M. Woodger.
+
+The following consultants to the Ada 9X Project
+contributed to the Specialized Needs Annexes:
+T. Baker (Real-Time/Systems Programming @em SEI, FSU);
+K. Dritz (Numerics @em Argonne National Laboratory);
+A. Gargaro (Distributed Systems @em Computer Sciences);
+J. Goodenough (Real-Time/Systems Programming @em SEI);
+J. McHugh (Secure Systems @em consultant);
+B. Wichmann (Safety-Critical Systems @em NPL: UK).
+
+This work was regularly reviewed by
+the Ada 9X Distinguished Reviewers
+and the members of the Ada 9X Rapporteur Group (XRG):
+E. Ploedereder, Chairman of DRs and XRG (University of Stuttgart: Germany);
+B. Bardin (Hughes);
+J. Barnes (consultant: UK); @Comment{XRG - UK}
+B. Brett (DEC);
+B. Brosgol (consultant);
+R. Brukardt (RR Software);
+N. Cohen (IBM);
+R. Dewar (NYU);
+G. Dismukes (TeleSoft);
+A. Evans (consultant);
+A. Gargaro (Computer Sciences);
+M. Gerhardt (ESL);
+J. Goodenough (SEI); @Comment{Also XRG - U.S.}
+S. Heilbrunner (University of Salzburg: Austria); @Comment{Also XRG - Belgium}
+P. Hilfinger (UC/Berkeley); @Comment{No longer a DR.}
+B. address@hidden(228)llberg (CelsiusTech: Sweden); @Comment{XRG - Sweden}
+M. Kamrad II (Unisys);
+J. van Katwijk (Delft University of Technology: The Netherlands); @Comment{XRG 
- The Netherlands}
+V. Kaufman (Russia); @Comment{XRG - Russia}
+P. Kruchten (Rational); @Comment{Also XRG - France}
+R. Landwehr (CCI: Germany); @Comment{Also XRG - Germany}
+C. Lester (Portsmouth Polytechnic: UK);
+L. address@hidden(229)nsson (TELIA Research: Sweden); @Comment{No longer a DR.}
+S. Michell (Multiprocessor Toolsmiths: Canada); @Comment{Also XRG - Canada}
+M. Mills (US Air Force);
+D. Pogge (US Navy);
+K. Power (Boeing);
+O. Roubine (Verdix: France);
+A. Strohmeier (Swiss Fed Inst of Technology: Switzerland); @Comment{XRG - 
Switzerland}
+W. Taylor (consultant: UK);
+J. Tokar (Tartan);
+E. Vasilescu (Grumman);
+J. Vladik (Prospeks s.r.o.:
+   Czech Republic); @Comment{XRG - Czech Republic}
+S. Van Vlierberghe (OFFIS: Belgium). @Comment{XRG - Belgium}
+
+
+Other valuable feedback influencing the revision
+process was provided by
+the Ada 9X Language Precision
+Team (Odyssey Research Associates), the Ada 9X User/Implementer
+Teams (AETECH, Tartan, TeleSoft), the Ada 9X Implementation
+Analysis Team (New York University) and the Ada community-at-large.
+
+
+Special thanks go to R. Mathis,
+Convenor of ISO/IEC JTC 1/SC 22 Working Group 9.
address@hidden XRG - U.S.}
+
+
+The Ada 9X Project was sponsored by the Ada Joint Program Office.
+Christine M. Anderson at the Air Force Phillips Laboratory (Kirtland
+AFB, NM) was the project manager.
+
address@hidden,Acknowledgements for the Corrigendum version}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden<The editor [R. Brukardt (USA)] would like to thank the many 
people
+whose hard work and assistance has made this
address@hidden,New=[update],Old=[revision]} possible.>,Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden go out to all of the members of the ISO/IEC JTC 1/SC 22/WG 9
+Ada Rapporteur Group, whose work on creating and editing the wording
+corrections was critical to the entire process. Especially valuable
+contributions came from the chairman of the ARG, E. Ploedereder (Germany), who
+kept the process moving; J. Barnes (UK) and K. Ishihata (Japan), whose
+extremely detailed reviews kept the editor on his toes; G. Dismukes (USA),
+M. Kamrad (USA), P. Leroy (France), S. Michell (Canada), T. Taft (USA),
+J. Tokar (USA), and other members too numerous to mention.],Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden thanks go to R. Duff (USA) for his explanations of the
+previous system of formatting of these documents during the tedious conversion
+to more modern formats. Special thanks also go to the convenor of
+ISO/IEC JTC 1/SC 22/WG 9, J. Moore (USA), without whose help and support
+the Corrigendum and this consolidated reference manual would not have been 
possible.],Old=[]}
+
address@hidden,Acknowledgements for the Amendment 1 version}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,New=<The editor [R. Brukardt (USA)] would like to thank the many
+people whose hard work and assistance has made this
address@hidden,New=[update],Old=[revision]} possible.>,Old=[]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Thanks go out to all of the members of the
+ISO/IEC JTC 1/SC 22/WG 9
+Ada Rapporteur Group, whose work on creating and editing the wording
+corrections was critical to the entire process. Especially valuable
+contributions came from the chairman of the ARG, P. Leroy (France), who kept
+the process on schedule; J. Barnes (UK) whose careful reviews found many
+typographical errors; T. Taft (USA), who always seemed to have a suggestion
+when we were stuck, and who also was usually able to provide the valuable
+service of explaining why things were as they are; S. Baird (USA), who found
+many obscure problems with the proposals; and A. Burns (UK), who pushed many of
+the real-time proposals to completion. Other ARG members who contributed were:
+R. Dewar (USA), G. Dismukes (USA), R. Duff (USA), K. Ishihata (Japan), S.
+Michell (Canada), E. Ploedereder (Germany), J.P. Rosen (France), E. Schonberg
+(USA), J. Tokar (USA), and T. Vardanega (Italy).]}
+
address@hidden,Kind=[Added]}
address@hidden,New=[Special thanks go to Ada-Europe and the Ada Resource
+Association, without whose help and support the Amendment and this consolidated
+reference manual would not have been possible. M. Heaney (USA) requires special
+thanks for his tireless work on the containers packages. Finally, special
+thanks go to the convenor of ISO/IEC JTC 1/SC 22/WG 9, J. Moore (USA), who
+guided the document through the standardization process.],Old=[]}
+
address@hidden
+
address@hidden,Acknowledgements for the Ada 2012 edition}
+
address@hidden,Kind=[Added]}
address@hidden,Text=<The editor [R. Brukardt (USA)] would like to thank the many
+people whose hard work and assistance has made this revision possible.>}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Thanks go out to all of the members of the
+ISO/IEC JTC 1/SC 22/WG 9
+Ada Rapporteur Group, whose work on creating and editing the wording
+changes was critical to the entire process. Especially valuable
+contributions came from the chairman of the ARG, E. Schonberg (USA), who
+guided the work; T. Taft (USA), whose insights broke many logjams, both in
+design and wording; J. Barnes (UK) whose careful reviews uncovered many
+editorial errors; S. Baird (USA), who
+repeatedly found obscure interactions with the proposals that the rest of
+us missed. Other ARG members who substantially contributed were:
+A. Burns (UK), J. Cousins (UK), R. Dewar (USA), G. Dismukes (USA), R. Duff 
(USA), P. Leroy
+(France), B. Moore (Canada), E. Ploedereder (Germany), J.P. Rosen (France),
+B. Thomas (USA), and T. Vardanega (Italy)address@hidden Leroy worked
+extensively on this work in the early days, although he hasn't participated
+recently.}
+
address@hidden,Kind=[Added]}
address@hidden,New=[Special thanks go to Ada-Europe and the Ada Resource
+Association, without whose help and support this third edition of the
+Ada Standard would not have been possible. A special mention has to go to
+A. Beneschan (USA) for his efforts in eliminating sloppiness in our wording.
+M. Heaney (USA) also deserves a mention for his efforts to improve the
+containers packages. Finally, special thanks go to the convenor of ISO/IEC JTC
+1/SC 22/WG 9, J. Tokar (USA), who guided the document through the
+standardization process.],Old=[]} @Comment{The other financial contributors
+wanted to remain anonymous, so they are not mentioned here.}
+
address@hidden,Acknowledgements for the Ada 2012 Corrigendum 1 version}
+
address@hidden,Kind=[Added]}
address@hidden,Text=<The editor [R. Brukardt (USA)] would like to thank the many
+people whose hard work and assistance has made this update possible.>}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Thanks go out to all of the members of the
+ISO/IEC JTC 1/SC 22/WG 9
+Ada Rapporteur Group, whose work on creating and editing the wording
+changes was critical to the entire process. Especially valuable
+contributions came from the chairman of the ARG, J. Cousins (UK), who
+guided the work; T. Taft (USA), who seems to have the ability to cut any
+Gordian knot we encounter in wording; ; J. Barnes (UK) who continues to be
+able to find editorial errors invisible to most; S. Baird (USA), who
+so frequently finds obscure interactions that we now have named such things
+for him. Other ARG members who substantially contributed were:
+A. Burns (UK), R. Dewar (USA), G. Dismukes (USA), R. Duff (USA),
+B. Moore (Canada), E. Ploedereder (Germany), J.P. Rosen (France),
+E. Schonberg (USA), and T. Vardanega (Italy).]}
+
address@hidden,Kind=[Added]}
address@hidden,New=[Finally, special thanks go to the convenor of ISO/IEC JTC
+1/SC 22/WG 9, J. Tokar (USA), who guided the document through the
+standardization process.],Old=[]} @Comment{The financial contributors
+wanted to remain anonymous, so they are not mentioned here.}
+
address@hidden,Acknowledgements for the Ada 202x version}
+
address@hidden,Kind=[Added]}
address@hidden,Text=<The editor [R. Brukardt (USA)] would like to thank the many
+people whose hard work and assistance has made this update possible.>}
+
address@hidden,Text=<But it's too early to thank people for a project
+that's just barely started.>address@hidden should thank the "Gang of Four",
+if the parallel stuff goes anywhere.}
+
address@hidden
address@hidden
+
address@hidden
+
address@hidden@;The International Standard is the same as this version
+of the Reference Manual, except:
address@hidden
+This list of Changes is not included in the International Standard.
+
+The @lquotes@;address@hidden@; page
+is not included in the International Standard.
+
+The text in the running headers and footers on each page is slightly
+different in the International Standard.
+
+The title page(s) are different in the International Standard.
+
+This document is formatted for 8.5-by-11-inch paper, whereas
+the International Standard is formatted for A4 paper
+(210-by-297mm);
+thus, the page breaks are in different places.
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[DeletedAdded]}
address@hidden,address@hidden @lquotes@;Foreword to this version
+of the Ada Reference address@hidden clause is not included in the 
International Standard.],Old=[]}]}
address@hidden subclause is not used in this revision.}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0299-1]}
address@hidden,Text=[The @lquotes@;Using this version of the Ada
+Reference address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} is not 
included in the International Standard.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Paragraph numbers are not included
+in the International Standard.]}
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden,Using this version of the Ada Reference Manual}
+
address@hidden following text should be redone once we decide what form Ada 202x
+will take.}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden document has been revised with @Chg{Version=[4],New=[
+the corrections specified in Technical Corrigendum 1
+(ISO/IEC 8652:2012/COR.1:2016)@Chg{Version=[5],New=[ and other changes
+specifically for Ada 202x],Old=[]}],
+Old=[the corrections specified in Technical Corrigendum 1
+(ISO/IEC 8652:1995/COR.1:2001)@Chg{Version=[2],New=[ and
+Amendment 1 (ISO/IEC 8652/AMD 1:2007)@Chg{Version=[3],New=[, along with
+changes specifically for this third edition],Old=[]}],Old=[]}]}.
+In addition, a variety of editorial errors have been corrected.],Old=[]}
address@hidden
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden document has been revised with @Chg{Version=[4],New=[
+the corrections specified in Technical Corrigendum 1
+(ISO/IEC 8652:2012/COR.1:2016)@Chg{Version=[5],New=[ and other changes
+specifically for Ada 202x],Old=[]}],
+Old=[the corrections specified in Technical Corrigendum 1
+(ISO/IEC 8652:1995/COR.1:2001)@Chg{Version=[2],New=[ and
+Amendment 1 (ISO/IEC 8652/AMD 1:2007)@Chg{Version=[3],New=[, along with
+changes specifically for this third edition],Old=[]}],Old=[]}]}.
+In addition, @Chg{Version=[3],New=[more],Old=[additional]} annotations
+have been added and a variety of editorial errors have been corrected.],Old=[]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden to the original 8652:1995 can be identified by the version
+number @Chg{Version=[2],New=[],Old=[/1 ]}following the paragraph
address@hidden,New=[ Paragraphs with a version number of /1 were
+changed by Technical Corrigendum 1 @Chg{Version=[4],New=[for Ada 95 ],Old=[]}or
+were editorial corrections at that time,
+while paragraphs with a version number of /2 were changed by Amendment 1 or 
were
+more recent editorial address@hidden,New=[, and paragraphs with a
+version number of /3 were changed by the third (2012) edition of the Standard
+or were still
+more recent editorial corrections],Old=[]}.],address@hidden,New=[ Paragraphs
+with a version number of /4 are changed by Technical Corrigendum 1 for Ada 2012
+or were editorial corrections at that time.],address@hidden,New=[ Paragraphs
+with a version number of /5 are changes or
+editorial corrections for Ada 202x.],Old=[]}
+Paragraphs not so marked are
+unchanged by @Chg{Version=[2],address@hidden,New=[Ada 202x, ],address@hidden,
+New=[Technical Corrigendum 1 for Ada 2012, ],address@hidden,
+New=[the third edition, ],Old=[]}Amendment 1, ],Old=[]}Technical Corrigendum
address@hidden,address@hidden,New=[ for Ada 95],Old=[]},],Old=[]} or editorial 
corrections. Paragraph numbers
+of unchanged paragraphs are the same as in
+the @Chg{Version=[3],New=[1995 edition of the],Old=[original]} Ada Reference
+Manual. In addition, some versions of this document include revision bars near 
the
+paragraph numbers. Where paragraphs are inserted, the paragraph numbers are of
+the form pp.nn, where pp is the number of the preceding paragraph, and nn is an
+insertion number. For instance, the first paragraph inserted after paragraph 8
+is numbered 8.1, the second paragraph inserted is numbered 8.2, and so on.
+Deleted paragraphs are indicated by the text @address@hidden paragraph was
+deleted.}} Deleted paragraphs include empty paragraphs that were numbered in
+the @Chg{Version=[3],New=[1995 edition of the],Old=[original]}
+Ada Reference Manual.],Old=[]}
address@hidden
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden,Kind=[RevisedAdded]}
address@hidden to the original 8652:1995 can be identified by the version
+number @Chg{Version=[2],New=[],Old=[/1 ]}following the paragraph
address@hidden,New=[ Paragraphs with a version number of /1 were
+changed by Technical Corrigendum 1 @Chg{Version=[4],New=[for Ada 95 
],Old=[]}or were editorial corrections at that time,
+while paragraphs with a version number of /2 were changed by Amendment 1 or 
were
+more recent editorial address@hidden,New=[, and paragraphs with a
+version number of /3 were changed by the third (2012) edition of the Standard
+or were still
+more recent editorial corrections],Old=[]}.],address@hidden,New=[ Paragraphs
+with a version number of /4 are changed by Technical Corrigendum 1 for Ada 2012
+or were editorial corrections at that time.],address@hidden,New=[ Paragraphs
+with a version number of /5 are changes or
+editorial corrections for Ada 202x.],Old=[]}
+Paragraphs not so marked are
+unchanged by @Chg{Version=[2],address@hidden,New=[Ada 202x, ],address@hidden,
+New=[Technical Corrigendum 1 for Ada 2012, ],address@hidden,
+New=[the third edition, ],Old=[]}Amendment 1, ],Old=[]}Technical Corrigendum
address@hidden,New=[,],Old=[]} or editorial corrections. Paragraph numbers
+of unchanged paragraphs are the same as in the @Chg{Version=[3],New=[1995
+edition of the],Old=[original]} Ada Reference Manual. Inserted text is 
indicated
+by underlining, and deleted text is
+indicated by strikethroughs. @Chg{Version=[2],New=[Some versions also use
+color to indicate the version of the change.],Old=[]}Where paragraphs are
+inserted, the paragraph numbers are of the form pp.nn, where pp is the number
+of the preceding paragraph, and nn is an insertion number. For instance, the
+first paragraph inserted after paragraph 8 is numbered 8.1, the second
+paragraph inserted is numbered 8.2, and so on. Deleted paragraphs are indicated
+by the text @address@hidden paragraph was deleted.}} Deleted paragraphs include
+empty paragraphs that were numbered in the @Chg{Version=[3],New=[1995 edition 
of
+the],Old=[original]} Ada Reference Manual. Similar markings and numbering
address@hidden,New=[are],Old=[is]} used for changes to annotations.],Old=[]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The paragraph number is considered part of the
+  paragraph; when a paragraph is moved to a different paragraph number, it is
+  marked as changed even if the contents have not changed.]}
address@hidden
address@hidden
address@hidden
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/glossary.mss 
b/packages/ada-ref-man/source_2012/glossary.mss
new file mode 100755
index 0000000..5fa38ed
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/glossary.mss
@@ -0,0 +1,19 @@
address@hidden(glossary, Root="ada.mss")
+
address@hidden: 2005/11/24 02:15:07 $}
address@hidden
+
address@hidden: e:\\cvsroot/ARM/Source/glossary.mss,v $}
address@hidden: 1.16 $}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00437-01]}
address@hidden
+This Annex contains informal descriptions of some @Chg{Version=[2],
+New=[of the ],Old=[]}terms used in this International Standard.
address@hidden,New=[The index provides references to more formal definitions
+of all of the terms used in this International Standard],
+Old=[To find more formal definitions, look the term up in the index]}.
+
address@hidden
address@hidden
\ No newline at end of file
diff --git a/packages/ada-ref-man/source_2012/impldef.mss 
b/packages/ada-ref-man/source_2012/impldef.mss
new file mode 100755
index 0000000..505b0e9
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/impldef.mss
@@ -0,0 +1,83 @@
address@hidden(impldef, Root="ada.mss")
+
address@hidden: 2012/11/28 23:53:05 $}
address@hidden,New=[Summary of Documentation 
Requirements],Old=[Implementation-Defined Characteristics]}
+
address@hidden: e:\\cvsroot/ARM/Source/impldef.mss,v $}
address@hidden: 1.17 $}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,address@hidden requirements}
+The Ada language allows for certain target machine dependences in a controlled
+manner. Each Ada implementation must document many characteristics and
+properties of the target system. This International Standard contains
+specific documentation requirements. In addition, many characteristics
+that require documentation
+are identified throughout this International Standard as being
+implementation defined. Finally, this International Standard requires
+documentation of
+whether implementation advice is followed. The following
address@hidden,New=[subclauses],Old=[clauses]} provide
+summaries of these documentation requirements.]}
address@hidden
+
address@hidden,Name=[Specific Documentation Requirements]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden requirements], Sec=(summary of requirements)}
address@hidden (required of an implementation)}
+In addition to implementation-defined characteristics, each Ada implementation
+must document various properties of the implementation:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Most of the items in this list require
+documentation only for implementations that conform to Specialized Needs
+Annexes.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Name=[Implementation-Defined Characteristics]}
+
address@hidden
address@hidden,Kind=[Revised]}
address@hidden defined], Sec=(summary of characteristics)}
+The Ada language allows for certain machine dependences in a controlled
+manner.
address@hidden (required of an implementation)}
+Each Ada implementation must document all implementation-defined
+characteristics:
address@hidden
address@hidden
address@hidden (not!)}
+It need not document unspecified characteristics.
+
+Some of the items in this list require documentation only for
+implementations that conform to Specialized Needs Annexes.
address@hidden
address@hidden
address@hidden
+
address@hidden,Name=[Implementation Advice]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden advice], Sec=(summary of advice)}
address@hidden (required of an implementation)}
+This International Standard sometimes gives advice about handling certain
+target machine dependences. Each Ada implementation must document whether
+that advice is followed:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Some of the items in this list require documentation only 
for
+implementations that conform to Specialized Needs Annexes.]}
address@hidden
+
address@hidden
+
address@hidden
diff --git a/packages/ada-ref-man/source_2012/index.mss 
b/packages/ada-ref-man/source_2012/index.mss
new file mode 100755
index 0000000..565c8a0
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/index.mss
@@ -0,0 +1,29 @@
address@hidden(index, Root="ada.mss")
+
address@hidden: 2006/01/17 07:20:58 $}
+
address@hidden: e:\\cvsroot/ARM/Source/index.mss,v $}
address@hidden: 1.1 $}
+
address@hidden
+
address@hidden
address@hidden@;Index entries are given by address@hidden,New=[],
+Old=[ A list of all language-defined library units may be found under
+Language-Defined Library Units. A list of all language-defined types may be
+found under Language-Defined address@hidden,New=[ A list of all
+language-defined subprograms may be found under Language-Defined
+Subprograms.],Old=[]}]}
address@hidden
address@hidden
address@hidden@;Index entries are given by paragraph address@hidden,New=[],
+Old=[ A list of all language-defined library units may be found under
+Language-Defined Library Units. A list of all language-defined types may be
+found under Language-Defined address@hidden,New=[ A list of all
+language-defined subprograms may be found under Language-Defined
+Subprograms.],Old=[]}]}
address@hidden
+
address@hidden@ @address@hidden paragraph}
+
address@hidden@Comment{Generate the index}
diff --git a/packages/ada-ref-man/source_2012/infosys.mss 
b/packages/ada-ref-man/source_2012/infosys.mss
new file mode 100755
index 0000000..6c2b705
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/infosys.mss
@@ -0,0 +1,1349 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/infosys.mss,v $ }
address@hidden $Revision: 1.44 $ $Date: 2012/11/28 23:53:05 $ $Author: randy $ }
address@hidden(infosys, Root="ada.mss")
+
address@hidden: 2012/11/28 23:53:05 $}
address@hidden Systems}
+
address@hidden
address@hidden systems}
address@hidden@;This Annex provides a set of facilities relevant to
+Information Systems programming. These fall into several
+categories:
address@hidden
+an attribute definition clause specifying Machine_Radix for a decimal subtype;
+
+the package Decimal, which declares a set of constants defining the
+implementation's capacity for decimal types, and a
+generic procedure
+for decimal division; and
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+the child packages address@hidden,New=[,],Old=[ and]}
address@hidden,New=[, and Wide_Wide_Text_IO.Editing],Old=[]},
+which
+support formatted and localized output of decimal data, based on
address@hidden@;picture address@hidden@; values.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+See also: @RefSec{Fixed Point Types}; @RefSec{Operations of Fixed Point Types};
address@hidden Conversions};
address@hidden and Representation Attributes};
address@hidden(Input-Output for Real Types);@Chg{Version=[2],
+New=[],address@hidden with COBOL};]}
address@hidden with C and C++};@Chg{Version=[2],
+New=[ @RefSec{Interfacing with COBOL};],Old=[]}
address@hidden
+
+The character and string handling packages in
address@hidden Language Environment}
+ are also relevant for Information Systems.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+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
address@hidden to Other Languages}
+and should support a @address@hidden of
+COBOL (respectively, C) @Chg{Version=[3],New=[for],Old=[in]} the
address@hidden,New=[Convention aspect],Old=[interfacing pragmas]}
+(see @RefSecNum{Interface to Other Languages}),
+thus allowing Ada programs to interface with programs written in
+that language.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If COBOL (respectively, C) is supported in the target environment,
+then interfacing to COBOL (respectively, C) should be supported as
+specified in @RefSecNum{Interface to Other Languages}.]}]}
address@hidden
+
address@hidden
address@hidden to Ada 83}
+This Annex is new to Ada 95.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[Added a mention of Wide_Wide_Text_IO.Editing,
+  part of the support for 32-bit characters.]}
address@hidden
+
address@hidden Attribute Definition Clause}
+
address@hidden
address@hidden, Sec=(of Machine_Radix for decimal first subtypes)}
address@hidden clause}
+Machine_Radix may be specified for a decimal first subtype
+(see @RefSecNum{Fixed Point Types})
+via an @nt{attribute_definition_clause};
+the expression of such a clause shall be static,
+and its value shall be 2 or 10.
+A value of 2 implies a binary base range; a
+value of 10 implies a decimal base address@hidden,address@hidden,Old=[]}
address@hidden
+In the absence of a Machine_Radix clause, the choice
+of 2 versus 10 for S'Machine_Radix is not specified.
address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Machine_Radix],
+    address@hidden,Text=[Radix (2 or 10) that is used to
+      represent a decimal fixed point type.]}]}
+
address@hidden
+
address@hidden
+Packed decimal should be used as the internal representation
+for objects of subtype S when S'Machine_Radix = 10.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Packed decimal should be used as the internal representation
+for objects of subtype @i<S> when @i<S>'Machine_Radix = 10.]}]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The intent of a decimal Machine_Radix attribute definition clause
+is to allow the programmer to declare an Ada decimal data object
+whose representation matches a particular COBOL implementation's
+representation of packed decimal items.
+The Ada object may then be passed to an interfaced COBOL program
+that takes a packed decimal data item as a parameter,
+assuming that convention COBOL has been specified for the Ada
+object's type @Chg{Version=[3],New=[with an aspect],Old=[in a @nt[pragma]]}
+Convention.
+
+Additionally, the Ada compiler may choose to generate arithmetic
+instructions that exploit the packed decimal representation.
+
address@hidden
+
address@hidden
address@hidden@address@hidden of Machine_Radix attribute definition clause:}
address@hidden
address@hidden Money @key[is] @key[delta] 0.01 @key[digits] 15;
address@hidden Money'Machine_Radix @key[use] 10;
address@hidden
address@hidden
+
address@hidden Package Decimal}
+
address@hidden
address@hidden@Keepnext@;The library package Decimal has the following 
declaration:
address@hidden
address@hidden(package) Ada.Decimal 
@key(is)@ChildUnit{Parent=[Ada],Child=[Decimal]}
+   @key(pragma) Pure(Decimal);
+
+   @AdaObjDefn{Max_Scale} : @key(constant) := @RI{implementation-defined};
+   @AdaObjDefn{Min_Scale} : @key(constant) := @RI{implementation-defined};
+
+   @AdaObjDefn{Min_Delta} : @key(constant) := 10.0**(-Max_Scale);
+   @AdaObjDefn{Max_Delta} : @key(constant) := 10.0**(-Min_Scale);
+
+   @AdaObjDefn{Max_Decimal_Digits} : @key(constant) := 
@RI{implementation-defined};
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key(generic)
+      @key(type) Dividend_Type  @key(is) @key(delta) <> @key(digits) <>;
+      @key(type) Divisor_Type   @key(is) @key(delta) <> @key(digits) <>;
+      @key(type) Quotient_Type  @key(is) @key(delta) <> @key(digits) <>;
+      @key(type) Remainder_Type @key(is) @key(delta) <> @key(digits) <>;
+   @key(procedure) @AdaSubDefn{Divide} (Dividend  : @key(in) Dividend_Type;
+                     Divisor   : @key(in) Divisor_Type;
+                     Quotient  : @key(out) Quotient_Type;
+                     Remainder : @key(out) 
Remainder_Type)@Chg{Version=[3],New=[
+      @key(with) Convention => Intrinsic],Old=[;
+   @key[pragma] Convention(Intrinsic, Divide)]};
+
address@hidden(end) Ada.Decimal;
address@hidden
address@hidden values of named numbers in the package Decimal.}
+
+Max_Scale is the largest N such that 10.0**(@en@;N) is allowed as a decimal
+  type's delta. Its type is @i{universal_integer}.
+
+Min_Scale is the smallest N such that 10.0**(@en@;N) is allowed as a decimal
+  type's delta. Its type is @i{universal_integer}.
+
+Min_Delta is the smallest value allowed for @i{delta} in a
address@hidden Its type is @i{universal_real}.
+
+Max_Delta is the largest value allowed for @i{delta} in a
address@hidden Its type is @i{universal_real}.
+
+Max_Decimal_Digits is the largest value allowed for @i{digits} in a
address@hidden Its type is @i{universal_integer}.
address@hidden
+The name is Max_Decimal_Digits versus Max_Digits, in order to avoid
+confusion with the named number System.Max_Digits relevant to floating
+point.
address@hidden
address@hidden
+
address@hidden
+The effect of Divide is as follows.
+The value of Quotient is Quotient_Type(Dividend/Divisor).
+The value of Remainder is Remainder_Type(Intermediate),
+where Intermediate is the difference between Dividend and the product of
+Divisor and Quotient; this result is computed exactly.
address@hidden
+
address@hidden(ImplReq)
+Decimal.Max_Decimal_Digits shall be at least 18.
+
+Decimal.Max_Scale shall be at least 18.
+
+Decimal.Min_Scale shall be at most 0.
address@hidden
+
address@hidden(Notes)
+The effect of division yielding a quotient with control over rounding
+versus truncation is obtained by applying either the
+function attribute Quotient_Type'Round or the conversion Quotient_Type
+to the expression Dividend/Divisor.
address@hidden(Notes)
+
+
address@hidden Output for Decimal Types}
address@hidden
address@hidden@;
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+The child packages address@hidden,New=[,],Old=[ and]}
address@hidden,New=[, and Wide_Wide_Text_IO.Editing],Old=[]}
+provide localizable formatted text
+output, known as @i{edited address@hidden output},
+for decimal types. An edited
+output string is a function of a numeric value, program-specifiable
+locale elements, and a format control value. The numeric value is of
+some decimal type. The locale elements are:
address@hidden
+    the currency string;
+
+    the digits group separator character;
+
+    the radix mark character; and
+
+    the fill character that replaces leading zeros of the numeric value.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+For Text_IO.Editing the edited output and currency strings are of
+type String, and the locale characters are of type Character.
+For address@hidden@!Editing their types are address@hidden and address@hidden,
address@hidden,New=[ For address@hidden@!Editing
+their types are address@hidden and address@hidden, respectively.],Old=[]}
+
+Each of the locale elements has a default value that can be replaced or
+explicitly overridden.
+
+A format-control
+value is of the private type Picture; it determines
+the composition of the edited output string and controls the form and
+placement of the sign, the position of the locale elements and the
+decimal digits, the presence or absence of a radix mark, suppression
+of leading zeros, and insertion of particular character values.
+
address@hidden@;A Picture object is composed from a String value, known as a
address@hidden String}, that serves as a template for the
+edited output string, and a
+Boolean value that controls whether a string of all space characters is
+produced when the number's value is zero. A picture String comprises a
+sequence of one- or two-Character symbols, each serving as a placeholder
+for a character or string at a corresponding position in the edited
+output string. The picture String symbols fall into several categories
+based on their effect on the edited output string:
address@hidden()
address@hidden
address@hidden, 21, 27, 33, 39, 45, 51}
address@hidden Digit: @\'9'
address@hidden Control: @\'.' @\'V'
address@hidden Control: @\'+' @\'@en@;' @\'<' @\'>' @\"CR" @\"DB"
address@hidden Control: @\'$' @\'#'
address@hidden Suppression: @\'Z' @\'*'
address@hidden Insertion: @\'_' @\'B' @\'0' @\'/'
address@hidden
+
+The entries are not case-sensitive. Mixed- or lower-case forms
+for "CR" and "DB", and lower-case forms for 'V', 'Z', and 'B',
+have the same effect as the upper-case symbols shown.
+
+An occurrence of a '9' Character in the picture String represents a
+decimal digit position in the edited output string.
+
+A radix control Character in the picture String indicates the position
+of the radix mark in the edited output string: an actual character
+position for '.', or an assumed position for 'V'.
+
+A sign control Character in the picture String affects the form of the
+sign in the edited output string. The '<' and '>' Character values indicate
+parentheses for negative values. A Character '+', '@en@;', or '<' appears
+either singly, signifying a fixed-position sign in the edited output,
+or repeated, signifying a floating-position sign that is preceded by
+zero or more space characters and that replaces a leading 0.
+
+A currency control Character in the picture String indicates an
+occurrence of the currency string in the edited output string. The
+'$' Character represents the complete currency string; the '#'
+Character represents one character of the currency string. A '$'
+Character appears either singly, indicating a fixed-position currency
+string in the edited output, or repeated, indicating a
+floating-position currency string that occurs in place of a leading 0.
+A sequence of '#' Character values indicates either a fixed- or
+floating-position currency string, depending on context.
+
+A zero suppression Character in the picture String allows a leading
+zero to be replaced by either the space character (for 'Z') or
+the fill character (for '*').
+
+A simple insertion Character in the picture String represents, in
+general, either itself (if '/' or '0'), the space character (if 'B'),
+or the digits group separator character (if '_'). In some contexts it
+is treated as part of a floating sign, floating currency, or zero
+suppression string.
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+An example of a picture String is "<###Z_ZZ9.99>". If the currency string
+is "@Chg{Version=[2],New=[kr],Old=[FF]}", the separator character is ',', and
+the radix mark is '.' then the edited output string values for the decimal
+values 32.10 and @en@;5432.10 are
+"address@hidden,New=[kr],Old=[FF]}bbb32.10b" and
+"(address@hidden,New=[kr],Old=[FF]}5,432.10)", respectively, where 'b'
+indicates the space character.
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+The generic packages address@hidden,New=[,],Old=[ and]}
address@hidden,New=[, and Wide_Wide_Text_IO.Decimal_IO],Old=[]}
+(see @RefSec(Input-Output for Real Types))
+provide text input and nonedited text output for decimal types.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+A picture String is of type Standard.String, @Chg{Version=[2],New=[for all of],
+Old=[both for]} address@hidden,New=[,],Old=[ and]}
address@hidden,New=[, and Wide_Wide_Text_IO.Editing],Old=[]}.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[Added descriptions of Wide_Wide_Text_IO.Editing;
+  see @RefSecNum{The Package Wide_Wide_Text_IO.Editing}.]}
address@hidden
+
+
address@hidden String Formation}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden
address@hidden String],sec=[for edited output]}
address@hidden picture String],sec=[for edited output]}
+A @i{well-formed picture String}, or simply @i{picture String},
+is a String value that conforms to the
+syntactic rules, composition constraints, and character replication
+conventions specified in this @Chg{Version=[3],New=[subclause],Old=[clause]}.
address@hidden
+
address@hidden
address@hidden()
address@hidden, Kind=[Deleted]}
address@hidden<>,Old=<@ @;@comment{Empty paragraph to hang junk paragraph 
number from original RM}>]
address@hidden
address@hidden ::=
+   @ntf{fixed_$_picture_string}
+ | @ntf{fixed_#_picture_string}
+ | @ntf{floating_currency_picture_string}
+ | @ntf{non_currency_picture_string}
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=
+   address@hidden @ntf{fixed_$_char} address@hidden address@hidden
+     @ntf{number} address@hidden
address@hidden Line}
+ | address@hidden address@hidden address@hidden
+     @ntf{number} @ntf{fixed_$_char} address@hidden address@hidden
address@hidden Line}
+ | @ntf{floating_LHS_sign} @ntf{number} @ntf{fixed_$_char} address@hidden 
address@hidden
address@hidden Line}
+ | address@hidden @ntf{fixed_$_char} address@hidden
+     @ntf{all_zero_suppression_number} address@hidden  address@hidden
address@hidden Line}
+ | address@hidden address@hidden @ntf{all_zero_suppression_number} 
address@hidden
+     @ntf{fixed_$_char} address@hidden address@hidden
address@hidden Line}
+ | @ntf{all_sign_number} address@hidden @ntf{fixed_$_char} address@hidden 
address@hidden
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=
+   address@hidden @ntf{single_#_currency} address@hidden
+     address@hidden @ntf{number} address@hidden
address@hidden Line}
+ | address@hidden @ntf{multiple_#_currency} address@hidden
+     @ntf{zero_suppression} @ntf{number} address@hidden
address@hidden Line}
+ | address@hidden address@hidden address@hidden
+     @ntf{number} @ntf{fixed_#_currency} address@hidden address@hidden
address@hidden Line}
+ | @ntf{floating_LHS_sign} @ntf{number} @ntf{fixed_#_currency} address@hidden 
address@hidden
address@hidden Line}
+ | address@hidden @ntf{single_#_currency} address@hidden
+     @ntf{all_zero_suppression_number} address@hidden address@hidden
address@hidden Line}
+ | address@hidden @ntf{multiple_#_currency} address@hidden
+     @ntf{all_zero_suppression_number} address@hidden address@hidden
address@hidden Line}
+ | address@hidden address@hidden @ntf{all_zero_suppression_number} 
address@hidden
+     @ntf{fixed_#_currency} address@hidden address@hidden
address@hidden Line}
+ | @ntf{all_sign_number} address@hidden @ntf{fixed_#_currency} address@hidden 
address@hidden
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=
+   address@hidden address@hidden @ntf{floating_$_currency} @ntf{number} 
address@hidden
+ | address@hidden address@hidden @ntf{floating_#_currency} @ntf{number} 
address@hidden
+ | address@hidden address@hidden @ntf{all_currency_number} address@hidden 
address@hidden
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=
+   address@hidden address@hidden @ntf{zero_suppression} @ntf{number} 
address@hidden
+ | address@hidden @ntf{number} address@hidden
+ | address@hidden address@hidden @ntf{all_zero_suppression_number} 
address@hidden
+     address@hidden
+ | @ntf{all_sign_number} address@hidden
+ | @ntf{fixed_LHS_sign} @ntf{direct_insertion} address@hidden @ntf{number} 
address@hidden
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=  @ntf{LHS_Sign}
address@hidden
address@hidden
address@hidden ::=  + | @en | <
address@hidden Line}
address@hidden
address@hidden
address@hidden ::= $
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=  @ntf{simple_insertion}
address@hidden
address@hidden
address@hidden ::=  _ | B | 0 | /
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=  Z {Z | @ntf{context_sensitive_insertion}} | 
@ntf{fill_string}
address@hidden
address@hidden
address@hidden ::=  @ntf{simple_insertion}
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=  * {* | @ntf{context_sensitive_insertion}}
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=
+   @ntf{fore_digits} address@hidden address@hidden address@hidden
+ | @ntf{radix} @ntf{aft_digits} address@hidden
address@hidden
address@hidden
address@hidden ::= 9 {9 | @ntf{direct_insertion}}
address@hidden
address@hidden
address@hidden ::=  {9 | @ntf{direct_insertion}} 9
address@hidden
address@hidden
address@hidden ::= . | V
address@hidden Line}
address@hidden
address@hidden
address@hidden ::= + | @en | > | CR | DB
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=
+   @ntf{LHS_Sign} address@hidden @ntf{LHS_Sign} address@hidden | 
@ntf{context_sensitive_insertion}}
address@hidden Line}
address@hidden
address@hidden
address@hidden ::= #
address@hidden
address@hidden
address@hidden ::= ## {#}
address@hidden Line}
address@hidden
address@hidden
address@hidden ::= @ntf{single_#_currency} | @ntf{multiple_#_currency}
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=
+   $ address@hidden $ {$ | @ntf{context_sensitive_insertion}}
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=
+   # address@hidden # {# | @ntf{context_sensitive_insertion}}
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=  @ntf{all_sign_fore} address@hidden address@hidden [>]
address@hidden
address@hidden
address@hidden ::=
+   @ntf{sign_char} address@hidden @ntf{sign_char} address@hidden | 
@ntf{context_sensitive_insertion}}
address@hidden
address@hidden
address@hidden ::= address@hidden @ntf{sign_char}
address@hidden Line}
address@hidden ::=  @ntf{sign_char} | @ntf{context_sensitive_insertion}
address@hidden
address@hidden
address@hidden ::= + | @en | <
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=  @ntf{all_currency_fore} address@hidden address@hidden
address@hidden
address@hidden
address@hidden ::=
+   @ntf{currency_char} address@hidden
+     @ntf{currency_char} address@hidden | @ntf{context_sensitive_insertion}}
address@hidden
address@hidden
address@hidden ::= address@hidden @ntf{currency_char}
address@hidden Line}
address@hidden ::= @ntf{currency_char} | @ntf{context_sensitive_insertion}
address@hidden
address@hidden
address@hidden ::= $ | #
address@hidden Line}
address@hidden
address@hidden
address@hidden ::=  @ntf{all_zero_suppression_fore} [ @ntf{radix} address@hidden
address@hidden
address@hidden
address@hidden ::=
+   @ntf{zero_suppression_char} address@hidden | 
@ntf{context_sensitive_insertion}}
address@hidden
address@hidden
address@hidden ::= address@hidden @ntf{zero_suppression_char}
address@hidden Line}
address@hidden ::=  @ntf{zero_suppression_char} | 
@ntf{context_sensitive_insertion}
address@hidden
address@hidden
address@hidden@ntf{zero_suppression_char} ::= Z | *
address@hidden
+
address@hidden@;The following composition constraints apply to a picture String:
address@hidden
+A @ntf{floating_LHS_sign} does not have occurrences of different @ntf{LHS_Sign}
+Character values.
+
+If a picture String has '<' as @ntf{fixed_LHS_sign}, then it has '>' as
address@hidden
+
+If a picture String has '<' in a @ntf{floating_LHS_sign} or in an
address@hidden, then it has an occurrence of '>'.
+
address@hidden,Kind=[Revised],Ref=[8652/0088],ARef=[AI95-00153]}
+If a picture String has '+' or '@en@;' as @ntf{fixed_LHS_sign}, in a
address@hidden, or in an @ntf{all_sign_number}, then it has no
address@hidden@Chg{New=[ or '>' character],Old=[]}.
+
+An instance of @ntf{all_sign_number} does not have occurrences of
+different @ntf{sign_char} Character values.
+
+An instance of @ntf{all_currency_number} does not have occurrences of
+different @address@hidden Character values.
+
+An instance of @ntf{all_zero_suppression_number} does not have occurrences
+of different @address@hidden@!char} Character values, except for possible
+case differences between 'Z' and 'z'.
address@hidden
+
+A @i{replicable Character} is a Character that, by the
+above rules, can occur in two consecutive positions in a picture String.
+
address@hidden@;A @i{Character replication} is a String
address@hidden
address@hidden & '(' & @RI{spaces} & @RI{count_string} & ')'
address@hidden
+where @i{char} is a replicable Character,
address@hidden is a String (possibly empty) comprising only space Character 
values,
+and @i{count_string} is a String of one or more decimal digit Character
+values. A Character replication in a picture String has the same effect
+as (and is said to be @i{equivalent to}) a String comprising @i[n]
+consecutive occurrences of @i{char}, where
address@hidden'Value(@i{count_string}).
+
+An @i{expanded picture String} is a picture String containing no
+Character replications.
address@hidden
+
+Since 'B' is not allowed after a RHS sign, there is no need
+for a special rule to disallow "9.99DB(2)" as an abbreviation for
+"9.99DBB"
address@hidden
address@hidden
+
address@hidden
+Although a sign to the left of the number can float, a sign to the right
+of the number is in a fixed position.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0088],ARef=[AI95-00153-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> The picture string rules 
for
+  numbers were tightened.]}
address@hidden
+
+
address@hidden Output Generation}
address@hidden
address@hidden@;The contents of an edited output string are based on:
address@hidden
+     A value, Item, of some decimal type Num,
+
+     An expanded picture String Pic_String,
+
+     A Boolean value, Blank_When_Zero,
+
+     A Currency string,
+
+     A Fill character,
+
+     A Separator character, and
+
+     A Radix_Mark character.
address@hidden
+
+The combination of a True value for Blank_When_Zero and a '*' character
+in Pic_String is inconsistent; no edited output string is defined.
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00114-01]}
+  @ChgAdded{Version=[2],Text=[Such a Pic_String is invalid, and any attempt
+  to use such a string will raise Picture_Error.]}
address@hidden
+
+
+A layout error is identified in the rules below if leading
+nonzero digits of Item, character values of the Currency string,
+or a negative sign would be
+truncated; in such cases no edited output string is defined.
+
+The edited output string has lower bound 1 and upper bound N where
+     N = Pic_String'Length + Currency_Length_Adjustment @en
+         Radix_Adjustment, and
address@hidden
+        Currency_Length_Adjustment =
+           Currency'Length @en@; 1 if there is some occurrence of '$' in
+             Pic_String, and
+           0 otherwise.
+
+        Radix_Adjustment =
+           1 if there is an occurrence of 'V' or 'v' in Pic_Str, and
+           0 otherwise.
address@hidden
+
address@hidden@defn{displayed magnitude (of a decimal value)}
+Let the magnitude of Item be expressed as a base-10 number
address@hidden(p)@address@hidden@Times@;address@hidden(1)address@hidden(1)@address@hidden@Times@;address@hidden(q),
+called the @i{displayed} @i{magnitude} of Item,
+where:
address@hidden
+     q = Min(Max(Num'Scale, 0), n) where n is 0 if Pic_String
+         has no @ntf{radix} and is otherwise the number of digit
+         positions following @ntf{radix} in Pic_String,
+         where a digit position corresponds to an occurrence of
+         '9', a @ntf{zero_suppression_char} (for an
+         @ntf{all_zero_suppression_number}), a @ntf{currency_char}
+         (for an @ntf{all_currency_number}), or a @ntf{sign_char}
+         (for an @ntf{all_sign_number}).
+
+     address@hidden(p) /= 0 if p>0.
address@hidden
+
+If n < Num'Scale, then the above number is the result of rounding
+(away from 0 if exactly midway between values).
+
+If Blank_When_Zero = True and the displayed magnitude of Item
+is zero,
+then the edited output string
+comprises all space character values. Otherwise, the picture String is
+treated as a sequence of instances of syntactic categories based on
+the rules in @RefSecNum[Picture String Formation],
+and the edited output string is the concatenation of
+string values derived from these categories according to the
+following mapping rules.
+
+Table F-1 shows the mapping from a sign control symbol to a
+corresponding character or string in the edited output. In the
+columns showing the edited output, a lower-case 'b' represents the
+space character.
+If there is no sign control symbol but the value of Item
+is negative, a layout error occurs and no edited output string
+is produced.
+
address@hidden<3>,Alignment=<AllCenter>,FirstColWidth=[1],LastColWidth=[1],
+NoBreak=[T],Border=[T],SmallSize=[F],
+Caption=<@b{Table F-1: Edited Output for Sign Control Symbols}>,
+Headers=<@b{Sign Control address@hidden@b{Edited Output for @*Nonnegative 
address@hidden@b{Edited Output for @*Negative Number}>,
+Body=['+'@\'+'@\'@en@;'
+'@en@;'@\'b'@\'@en@;'
+'<'@\'b'@\'('
+'>'@\'b'@\')'
+"CR"@\"bb"@\"CR"@Last
+"DB"@\"bb"@\"DB"]}
+
+An instance of @ntf{fixed_LHS_sign} maps to a character as shown in
+Table F-1.
+
+An instance of @ntf{fixed_$_char} maps to Currency.
+
+An instance of @ntf{direct_insertion} maps to
+Separator if @ntf{direct_insertion} = '_', and to
+the @ntf{direct_insertion} Character otherwise.
+
+
address@hidden@;An instance of @ntf{number} maps to a string
+   @i{integer_part} & @i{radix_part} & @i{fraction_part}
+where:
address@hidden
+   The string for @i{integer_part} is obtained as follows:
address@hidden
+     Occurrences of '9' in @ntf{fore_digits} of @ntf{number} are replaced
+     from right to left with the decimal digit character values for
+     address@hidden(1), ..., address@hidden(p), respectively.
+
+     Each occurrence of '9' in @ntf{fore_digits}
+     to the left of the leftmost '9' replaced according
+     to rule 1 is replaced with '0'.
+
+     If p exceeds the number of occurrences of '9' in
+     @ntf{fore_digits} of @ntf{number}, then the excess leftmost
+     digits are eligible for use in the mapping of
+     an instance of @ntf{zero_suppression}, @ntf{floating_LHS_sign},
+     @ntf{floating_$_currency},
+     or @ntf{floating_#_currency} to the left of @ntf{number};
+     if there is no such instance, then a layout error
+     occurs and no edited output string is produced.
address@hidden
+
+   @leading@;The @i{radix_part} is:
address@hidden
+        "" if @ntf{number} does not include a @ntf{radix}, if @ntf{radix} = 
'V',
+        or if @ntf{radix} = 'v'
+
+        Radix_Mark if @ntf{number} includes '.' as @ntf{radix}
address@hidden
+
address@hidden@;The string for @i{fraction_part} is obtained as follows:
address@hidden
+        Occurrences of '9'
+        in @ntf{aft_digits} of @ntf{number} are replaced
+        from left to right with the decimal digit character values for 
address@hidden(1),
+        ... address@hidden(q).
+
+        Each occurrence of '9' in @ntf{aft_digits}
+        to the right of the rightmost '9' replaced according to rule 1
+        is replaced by '0'.
address@hidden
address@hidden
+
address@hidden@;An instance of @ntf{zero_suppression} maps to the string 
obtained as follows:
address@hidden
+                  The rightmost 'Z', 'z', or '*' Character values
+                  are replaced
+                   with the excess digits (if any)
+                   from the @i{integer_part} of the mapping of the @ntf{number}
+                   to the right of the @ntf{zero_suppression} instance,
+
+                  A @ntf{context_sensitive_insertion} Character is replaced
+                   as though it were a @ntf{direct_insertion} Character, if
+                   it occurs to the right of some 'Z', 'z', or '*' in
+                   @ntf{zero_suppression} that has been mapped to an excess
+                   digit,
+
+                  @leading@;Each Character to the left of the
+                   leftmost Character replaced according to rule 1 above
+                  is replaced by:
address@hidden
+                     the space character if the zero suppression Character is
+                         'Z' or 'z', or
+
+                     the Fill character if the zero suppression Character is 
'*'.
address@hidden
+
+                   A layout error occurs if some excess digits remain
+                   after all 'Z', 'z', and '*' Character values in
+                   @ntf{zero_suppression} have been replaced via rule 1; no
+                   edited output string is produced.
address@hidden
+
+An instance of @ntf{RHS_sign} maps to a character or string
+as shown in Table F-1.
+
+
+An instance of @ntf{floating_LHS_sign} maps to the string obtained as follows.
address@hidden
+                   Up to all but one of the rightmost @ntf{LHS_Sign}
+                   Character values are replaced by the excess digits (if any)
+                   from the @i{integer_part} of the mapping of the @ntf{number}
+                   to the right of the @ntf{floating_LHS_sign} instance.
+
+                  The next Character to the left is replaced
+                   with the character given by the entry in Table F-1
+                   corresponding to the @ntf{LHS_Sign} Character.
+
+                  A @ntf{context_sensitive_insertion} Character is replaced
+                   as though it were a @ntf{direct_insertion} Character, if
+                   it occurs to the right of the leftmost @ntf{LHS_Sign}
+                   character replaced according to rule 1.
+
+                  Any other Character is replaced by the space character..
+
+                   A layout error occurs if some excess digits remain
+                   after replacement via rule 1; no edited output string is
+                   produced.
address@hidden
+
+An instance of @ntf{fixed_#_currency} maps to the Currency string with n
+space character values concatenated on the left (if the instance does
+not follow a @ntf{radix}) or on the right (if the instance does follow a
address@hidden), where n is the difference between the length of the
address@hidden instance and Currency'Length. A layout error
+occurs if Currency'Length exceeds the length of the
address@hidden instance; no edited output string is produced.
+
+
address@hidden@;An instance of @ntf{floating_$_currency} maps to the string
+obtained as follows:
address@hidden
+                  Up to all but one of the rightmost '$'
+                   Character values are replaced
+                 with the excess digits (if any)
+                   from the @i{integer_part} of the mapping of the @ntf{number}
+                   to the right of the @ntf{floating_$_currency} instance.
+
+                  The next Character to the left is replaced
+                   by the Currency string.
+
+                  A @ntf{context_sensitive_insertion} Character is replaced
+                   as though it were a @ntf{direct_insertion} Character, if
+                   it occurs to the right of the leftmost '$' Character
+                   replaced via rule 1.
+
+                  Each other Character is replaced by the space character.
+
+                   A layout error occurs if some excess digits remain
+                   after replacement by rule 1; no edited output string is
+                   produced.
address@hidden
+
address@hidden@;An instance of @ntf{floating_#_currency} maps to the string 
obtained
+as follows:
address@hidden
+                  Up to all but one of the rightmost '#'
+                   Character values are replaced
+                  with the excess digits (if any)
+                   from the @i{integer_part} of the mapping of the @ntf{number}
+                   to the right of the
+                   @ntf{floating_#_currency} instance.
+
+  The substring whose last Character occurs at the position immediately
+   preceding the leftmost Character replaced via rule 1, and whose
+   length is Currency'Length, is replaced by the Currency string.
+
+                  A @ntf{context_sensitive_insertion} Character is replaced
+                   as though it were a @ntf{direct_insertion} Character, if
+                   it occurs to the right of the leftmost '#'
+                   replaced via rule 1.
+
+                  Any other Character is replaced by the space character.
+
+                   A layout error occurs if some excess digits remain
+                   after replacement rule 1, or if there is no substring
+                   with the required length for replacement rule 2; no edited
+                   output string is produced.
address@hidden
+
address@hidden@;An instance of @ntf{all_zero_suppression_number} maps to:
address@hidden
+              a string of all spaces if
+              the displayed magnitude of Item is zero,
+              the @ntf{zero_suppression_char}
+              is 'Z' or 'z', and the instance of
+              @ntf{all_zero_suppression_number} does not have
+              a @ntf{radix} at its last character position;
+
+              a string containing the Fill character in each position except
+              for the character (if any) corresponding to @ntf{radix}, if
+              @ntf{zero_suppression_char} = '*' and the
+              displayed magnitude of Item is zero;
+
+              otherwise,
+              the same result as if each @ntf{zero_suppression_char} in
+              @ntf{all_zero_suppression_aft} were '9', interpreting
+              the instance of @ntf{all_zero_suppression_number} as
+              either @ntf{zero_suppression} @ntf{number} (if a @ntf{radix}
+              and @ntf{all_zero_suppression_aft} are present), or
+              as @ntf{zero_suppression} otherwise.
address@hidden
+
address@hidden@;An instance of @ntf{all_sign_number} maps to:
address@hidden
+              a string of all spaces if
+        the displayed magnitude of Item is zero and the
+        instance of @ntf{all_sign_number} does not have a @ntf{radix}
+        at its last character position;
+
+              otherwise,
+              the same result as if each @ntf{sign_char} in
+              @ntf{all_sign_number_aft} were '9', interpreting
+              the instance of @ntf{all_sign_number} as
+              either @ntf{floating_LHS_sign} @ntf{number} (if a @ntf{radix}
+              and @ntf{all_sign_number_aft} are present), or
+              as @ntf{floating_LHS_sign} otherwise.
address@hidden
+
address@hidden@;An instance of @ntf{all_currency_number} maps to:
address@hidden
+              a string of all spaces if
+        the displayed magnitude of Item is zero and the
+        instance of @ntf{all_currency_number} does not have a @ntf{radix}
+        at its last character position;
+
+              otherwise,
+              the same result as if each @ntf{currency_char} in
+              @ntf{all_currency_number_aft} were '9', interpreting
+              the instance of @ntf{all_currency_number} as
+               @ntf{floating_$_currency} @ntf{number} or
+               @ntf{floating_#_currency} @ntf{number}
+              (if a @ntf{radix}
+              and @ntf{all_currency_number_aft} are present), or
+              as @ntf{floating_$_currency} or @ntf{floating_#_currency}
+              otherwise.
address@hidden
address@hidden
+
address@hidden
+In the result string values shown below, 'b' represents the space character.
address@hidden
+Item:         Picture and Result Strings:
+
address@hidden,Kind=[Revised],ARef=[AI05-0248-1]}
+123456.78     Picture:  "-###**_***_**9.99"
+              @Chg{New=[Result:],Old=[       ]}   "bbb$***123,456.78"
+                        "bbFF***123.456,78" (currency = "FF",
+                                             separator = '.',
+                                             radix mark = ',')
+
address@hidden,Kind=[Revised],Ref=[8652/0089],ARef=[AI95-00070]}
+123456.78     Picture:  "address@hidden,Old=[$$]}$**_***_**9.99"
+              Result:   "@Chg{New=[],Old=[bb]}b$***123,456.78"
+                       "address@hidden,Old=[bb]}FF***123.456,78" (currency = 
"FF",
+                         @Chg{New=[],Old=[  ]}                  separator = 
'.',
+                         @Chg{New=[],Old=[  ]}                  radix mark = 
',')
+
+0.0          Picture: "-$$$$$$.$$"
+             Result:  "bbbbbbbbbb"
+
+0.20         Picture: "-$$$$$$.$$"
+             Result:  "bbbbbb$.20"
+
+-1234.565    Picture: "<<<<_<<<.<<###>"
+             Result:  "bb(1,234.57DMb)"  (currency = "DM")
+
+12345.67     Picture: "###_###_##9.99"
+             Result:  "bbCHF12,345.67"   (currency = "CHF")
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0089],ARef=[AI95-00070-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the picture 
string
+  example.]}
address@hidden
+
+
address@hidden Package Text_IO.Editing}
address@hidden
+The package Text_IO.Editing provides a private type Picture with associated
+operations, and a generic package Decimal_Output.
+An object of type Picture is composed from a well-formed picture String
+(see @RefSecNum(Picture String Formation)) and a Boolean item indicating
+whether a zero numeric value will result in an edited output string
+of all space characters.
+The package Decimal_Output
+contains edited output subprograms implementing the effects defined
+in @RefSecNum(Edited Output Generation).
address@hidden
+
address@hidden
address@hidden@;The library package Text_IO.Editing has the following 
declaration:
address@hidden
address@hidden(package) Ada.Text_IO.Editing 
@key(is)@ChildUnit{Parent=[Ada.Text_IO],Child=[Editing]}
+
+   @key(type) @AdaTypeDefn{Picture} @key(is) @key(private);
+
+   @key(function) @AdaSubDefn{Valid} (Pic_String      : @key(in) String;
+                   Blank_When_Zero : @key(in) Boolean := False) @key(return) 
Boolean;
+
+   @key(function) @AdaSubDefn{To_Picture} (Pic_String      : @key(in) String;
+                        Blank_When_Zero : @key(in) Boolean := False)
+      @key(return) Picture;
+
+   @key(function) @AdaSubDefn{Pic_String}      (Pic : @key(in) Picture) 
@key(return) String;
+   @key(function) @AdaSubDefn{Blank_When_Zero} (Pic : @key(in) Picture) 
@key(return) Boolean;
+
+   @AdaObjDefn{Max_Picture_Length}  : @key(constant) := 
@RI{implementation_defined};
+
+   @AdaExcDefn{Picture_Error}       : @key(exception);
+
+   @AdaObjDefn{Default_Currency}    : @key(constant) String    := "$";
+   @AdaObjDefn{Default_Fill}        : @key(constant) Character := '*';
+   @AdaObjDefn{Default_Separator}   : @key(constant) Character := ',';
+   @AdaObjDefn{Default_Radix_Mark}  : @key(constant) Character := '.';
+
+   @key(generic)
+      @key(type) Num @key(is) @key(delta) <> @key(digits) <>;
+      Default_Currency   : @key(in) String    := 
Text_IO.Editing.Default_Currency;
+      Default_Fill       : @key(in) Character := Text_IO.Editing.Default_Fill;
+      Default_Separator  : @key(in) Character :=
+                              Text_IO.Editing.Default_Separator;
+      Default_Radix_Mark : @key(in) Character :=
+                              Text_IO.Editing.Default_Radix_Mark;
+   @key(package) @AdaPackDefn{Decimal_Output} @key(is)
+      @key(function) @AdaSubDefn{Length} (Pic      : @key(in) Picture;
+                       Currency : @key(in) String := Default_Currency)
+         @key(return) Natural;
+
+      @key(function) @AdaSubDefn{Valid} (Item     : @key(in) Num;
+                      Pic      : @key(in) Picture;
+                      Currency : @key(in) String := Default_Currency)
+         @key(return) Boolean;
+
+      @key(function) @AdaSubDefn{Image} (Item       : @key(in) Num;
+                      Pic        : @key(in) Picture;
+                      Currency   : @key(in) String    := Default_Currency;
+                      Fill       : @key(in) Character := Default_Fill;
+                      Separator  : @key(in) Character := Default_Separator;
+                      Radix_Mark : @key(in) Character := Default_Radix_Mark)
+         @key(return) String;
+
+      @key(procedure) @AdaSubDefn{Put} (File       : @key(in) File_Type;
+                     Item       : @key(in) Num;
+                     Pic        : @key(in) Picture;
+                     Currency   : @key(in) String    := Default_Currency;
+                     Fill       : @key(in) Character := Default_Fill;
+                     Separator  : @key(in) Character := Default_Separator;
+                     Radix_Mark : @key(in) Character := Default_Radix_Mark);
+
+      @key(procedure) @AdaSubDefn{Put} (Item       : @key(in) Num;
+                     Pic        : @key(in) Picture;
+                     Currency   : @key(in) String    := Default_Currency;
+                     Fill       : @key(in) Character := Default_Fill;
+                     Separator  : @key(in) Character := Default_Separator;
+                     Radix_Mark : @key(in) Character := Default_Radix_Mark);
+
address@hidden@;      @key(procedure) @AdaSubDefn{Put} (To         : @key(out) 
String;
+                     Item       : @key(in) Num;
+                     Pic        : @key(in) Picture;
+                     Currency   : @key(in) String    := Default_Currency;
+                     Fill       : @key(in) Character := Default_Fill;
+                     Separator  : @key(in) Character := Default_Separator;
+                     Radix_Mark : @key(in) Character := Default_Radix_Mark);
+   @key(end) Decimal_Output;
address@hidden(private)
+   ... @RI{-- not specified by the language}
address@hidden(end) Ada.Text_IO.Editing;
address@hidden
address@hidden value of Max_Picture_Length in the package Text_IO.Editing}
+
address@hidden@;The exception Constraint_Error is raised
+if the Image function or any of the
+Put procedures is invoked with a null string for Currency.
address@hidden
address@hidden@Keepnext
address@hidden(function) Valid (Pic_String      : @key(in) String;
+                Blank_When_Zero : @key(in) Boolean := False) @key(return) 
Boolean;
address@hidden
address@hidden@;Valid returns True if Pic_String is a well-formed picture String
+(see @RefSecNum(Picture String Formation)) the
+length of whose expansion does not exceed Max_Picture_Length, and if
+either Blank_When_Zero is False or Pic_String contains no '*'.
+
address@hidden@Keepnext
address@hidden(function) To_Picture (Pic_String      : @key(in) String;
+                     Blank_When_Zero : @key(in) Boolean := False)
+   @key(return) Picture;
address@hidden
address@hidden@;To_Picture returns a result Picture such that the application 
of the
+function Pic_String to this result
+yields an expanded picture String equivalent to Pic_String, and such
+that Blank_When_Zero applied to the result Picture is the same value as the
+parameter Blank_When_Zero.
+ Picture_Error is raised if not
+Valid(Pic_String, Blank_When_Zero).
+
address@hidden
address@hidden(function) Pic_String      (Pic : @key(in) Picture) @key(return) 
String;
address@hidden line}
address@hidden(function) Blank_When_Zero (Pic : @key(in) Picture) @key(return) 
Boolean;
address@hidden
address@hidden@;If Pic is To_Picture(String_Item, Boolean_Item) for some 
String_Item and
+Boolean_Item, then:
address@hidden
+Pic_String(Pic) returns an expanded picture String
+equivalent to String_Item and with any lower-case letter
+replaced with its corresponding upper-case form, and
+
+Blank_When_Zero(Pic) returns Boolean_Item.
address@hidden
+
address@hidden@;If Pic_1 and Pic_2 are objects of type Picture, then "="(Pic_1, 
Pic_2)
+is True when
address@hidden
+Pic_String(Pic_1) = Pic_String(Pic_2), and
+
address@hidden@;Blank_When_Zero(Pic_1) = Blank_When_Zero(Pic_2).
address@hidden
+
address@hidden@Keepnext
address@hidden(function) Length (Pic      : @key(in) Picture;
+                 Currency : @key(in) String := Default_Currency)
+   @key(return) Natural;
address@hidden
address@hidden@;Length returns Pic_String(Pic)'Length + 
Currency_Length_Adjustment @en
+Radix_Adjustment where
address@hidden
address@hidden@;Currency_Length_Adjustment =
address@hidden
+           Currency'Length @en@; 1 if there is some occurrence of '$' in
+             Pic_String(Pic), and
+
+           0 otherwise.
address@hidden
+
address@hidden@;Radix_Adjustment =
address@hidden
+           1 if there is an occurrence of 'V' or 'v' in Pic_Str(Pic), and
+
+           @Trailing@;0 otherwise.
address@hidden
address@hidden
+
address@hidden@Keepnext
address@hidden(function) Valid (Item     : @key(in) Num;
+                Pic      : @key(in) Picture;
+                Currency : @key(in) String := Default_Currency)
+   @key(return) Boolean;
address@hidden
address@hidden@;Valid returns True if Image(Item, Pic, Currency) does not raise
+Layout_Error, and returns False otherwise.
+
address@hidden
address@hidden(function) Image (Item       : @key(in) Num;
+                Pic        : @key(in) Picture;
+                Currency   : @key(in) String    := Default_Currency;
+                Fill       : @key(in) Character := Default_Fill;
+                Separator  : @key(in) Character := Default_Separator;
+                Radix_Mark : @key(in) Character := Default_Radix_Mark)
+   @key(return) String;
address@hidden
address@hidden@;Image returns the edited output String as defined in
address@hidden(Edited Output Generation) for Item,
+Pic_String(Pic), Blank_When_Zero(Pic),
+Currency, Fill, Separator,
+and Radix_Mark. If these rules identify a layout error, then Image
+raises the exception Layout_Error.
+
address@hidden
address@hidden(procedure) Put (File       : @key(in) File_Type;
+               Item       : @key(in) Num;
+               Pic        : @key(in) Picture;
+               Currency   : @key(in) String    := Default_Currency;
+               Fill       : @key(in) Character := Default_Fill;
+               Separator  : @key(in) Character := Default_Separator;
+               Radix_Mark : @key(in) Character := Default_Radix_Mark);
address@hidden line}
address@hidden(procedure) Put (Item       : @key(in) Num;
+               Pic        : @key(in) Picture;
+               Currency   : @key(in) String    := Default_Currency;
+               Fill       : @key(in) Character := Default_Fill;
+               Separator  : @key(in) Character := Default_Separator;
+               Radix_Mark : @key(in) Character := Default_Radix_Mark);
address@hidden
address@hidden@;Each of these Put procedures
+outputs Image(Item, Pic, Currency, Fill, Separator, Radix_Mark)
+consistent with the conventions for Put for other real types in case
+of bounded line length (see @RefSec{Get and Put Procedures}).
+
address@hidden
address@hidden(procedure) Put (To         : @key(out) String;
+               Item       : @key(in) Num;
+               Pic        : @key(in) Picture;
+               Currency   : @key(in) String    := Default_Currency;
+               Fill       : @key(in) Character := Default_Fill;
+               Separator  : @key(in) Character := Default_Separator;
+               Radix_Mark : @key(in) Character := Default_Radix_Mark);
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
+Put copies Image(Item, Pic, Currency, Fill, Separator, Radix_Mark)
+to the given string, right justified. address@hidden,New=[,],Old=[]}
+unassigned Character values
+in To are assigned the space character. If To'Length is less than
+the length of the string resulting from Image, then Layout_Error is raised.
address@hidden
address@hidden
+
address@hidden
+Max_Picture_Length shall be at least 30.
+The implementation shall support currency strings of length
+up to at least 10, both for Default_Currency in an instantiation of
+Decimal_Output, and for Currency in an invocation of Image or any
+of the Put procedures.
address@hidden
+This implies that a picture string with character replications
+need not be supported (i.e., To_Picture will raise Picture_Error)
+if its expanded form exceeds 30 characters.
address@hidden
address@hidden
+
address@hidden
address@hidden@;The rules for edited output are based on COBOL (ANSI X3.23:1985,
+endorsed by ISO as ISO 1989-1985), with the
+following differences:
address@hidden
+   The COBOL provisions for picture string localization and for 'P' format
+   are absent from Ada.
+
+   @Leading@;The following Ada facilities are not in COBOL:
address@hidden
+      currency symbol placement after the number,
+
+      localization of edited output string for multi-character
+      currency string values, including support for both length-preserving
+      and length-expanding currency symbols in picture strings
+
+      localization of the radix mark, digits separator, and
+      fill character, and
+
+      parenthesization of negative values.
address@hidden
address@hidden
address@hidden following paragraph is missing a number in the original version.
+To give it a number in the new version, it is marked as an insertion.}
address@hidden,address@hidden
address@hidden,address@hidden@;]}The value of 30 for Max_Picture_Length is the
+same limit as in COBOL.
address@hidden
+
address@hidden
+There are several reasons we have not adopted the COBOL-style permission to
+provide a single-character replacement in the picture string for the `$' as
+currency symbol, or to interchange the roles of `.' and `,' in picture strings
address@hidden
+It would have introduced considerable complexity into Ada, as well as
+confusion between run-time and compile-time character interpretation, since
+picture Strings are dynamically computable in Ada, in contrast with COBOL
+
+Ada's rules for real literals provide a natural interpretation of `_' as
+digits separator and `.' for radix mark; it is not essential to allow these to
+be localized in picture strings, since Ada does not allow them to be localized
+in real literals.
+
+The COBOL restriction for the currency symbol in a picture string to be
+replaced by
+ a single character currency symbol is a compromise
+solution. For general international usage
+ a mechanism is needed to localize the edited output to
+be a multi-character currency string. Allowing a single-Character
+localization for the picture Character, and a multiple-character localization
+for the currency string, would be an unnecessary complication.
address@hidden
address@hidden
+
address@hidden Package Wide_Text_IO.Editing}
+
address@hidden
address@hidden@;@address@hidden
address@hidden@!Text_IO],Child=[Editing]}
+The child package Wide_Text_IO.Editing has
+the same contents as Text_IO.Editing, except that:
address@hidden
+each occurrence of Character is replaced by Wide_Character,
+
+each occurrence of Text_IO is replaced by Wide_Text_IO,
+
+the subtype of Default_Currency is Wide_String rather than String, and
+
+each occurrence of String
+in the generic package Decimal_Output is replaced by
+Wide_String.
address@hidden
address@hidden value of Max_Picture_Length in the package Wide_Text_IO.Editing}
address@hidden
+
address@hidden
+Each of the functions Wide_Text_IO.Editing.Valid, To_Picture, and Pic_String 
has String (versus
+Wide_String) as its parameter or result subtype, since a picture String
+is not localizable.
address@hidden
+
address@hidden,Name=[The Package Wide_Wide_Text_IO.Editing]}
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,Type=[Leading],address@hidden@address@hidden
address@hidden@address@hidden,Child=[Editing]}
+The child package Wide_Wide_Text_IO.Editing has
+the same contents as Text_IO.Editing, except that:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[each occurrence of Character is replaced by
+Wide_Wide_Character,]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[each occurrence of Text_IO is replaced by
+Wide_Wide_Text_IO,]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[the subtype of Default_Currency is Wide_Wide_String
+rather than String, and]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[each occurrence of String
+in the generic package Decimal_Output is replaced by
+Wide_Wide_String.]}
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,New=[The
+value of Max_Picture_Length in the package Wide_Wide_Text_IO.Editing],Old=[]}]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,Text=[Each of the functions
+Wide_Wide_Text_IO.Editing.Valid, To_Picture, and Pic_String has String (versus
+Wide_Wide_String) as its parameter or result subtype, since a picture String is
+not localizable.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Package Wide_Wide_Text_IO.Editing is new; it supports 32-bit character
+  strings. (Shouldn't it have been
+  @lquotes@;address@hidden@;? :-)]}
address@hidden
+
+
diff --git a/packages/ada-ref-man/source_2012/interface.mss 
b/packages/ada-ref-man/source_2012/interface.mss
new file mode 100755
index 0000000..b95f8b5
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/interface.mss
@@ -0,0 +1,3669 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/interface.mss,v $ }
address@hidden $Revision: 1.74 $ $Date: 2015/04/03 04:12:43 $ $Author: randy $ }
address@hidden(interface, Root="ada.mss")
+
address@hidden: 2015/04/03 04:12:43 $}
address@hidden to Other Languages}
+
address@hidden
address@hidden to other languages}
address@hidden, Sec=(interface to non-Ada)}
address@hidden programs}
+This Annex describes features for writing mixed-language programs.
+General interface support is presented first;
+then specific support for C, COBOL, and Fortran is defined,
+in terms of language interface packages for each of
+these languages.
address@hidden
+This Annex is not a @lquotes@;Specialized address@hidden@; annex.
+Every implementation must support all nonoptional features defined here
+(mainly the package Interfaces).
address@hidden
address@hidden
+
address@hidden
+Ada should have strong support for mixed-language programming.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0262-1],ARef=[AI05-0299-1]}
address@hidden,Text=[Support for interfacing to any foreign language is
+optional. However, an implementation shall not provide any optional
+aspect, attribute, library unit, or pragma having the same name as an aspect,
+attribute, library unit, or pragma (respectively) specified in the subclauses 
of
+this Annex unless the provided construct is either as specified in those
+subclauses or is more limited in capability than that required by those
+subclauses. A program that attempts to use an unsupported capability of this
+Annex shall either be identified by the implementation before run time or shall
+raise an exception at run time.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The intent is that the same rules apply for
+  the optional parts of language interfacing as apply for Specialized
+  Needs Annexes. See
+  @RefSecNum{Conformity of an Implementation with the Standard} for a
+  discussion of the purpose of these rules.]}
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Much of the functionality in this Annex is new to Ada 95.
address@hidden
+
address@hidden
+This Annex contains what used to be RM83-13.8.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Text=[Moved the clarification that interfacing to
+  foreign languages is optional and has the same restrictions as a Specialized
+  Needs Annex here.]}
address@hidden
+
+
address@hidden,New=[Interfacing Aspects],Old=[Interfacing Pragmas]}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Text=[An @i<interfacing> aspect is a representation
+aspect that is one of the aspects Import, Export, Link_Name, External_Name, or
address@hidden address@hidden,Sec=[interfacing]}]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1],ARef=[AI05-0269-1]}
address@hidden,address@hidden the],Old=[A @nt{pragma}]} Import
address@hidden,New=[aspect  to have the value True ],Old=[]}is used to import
+an entity defined in a foreign language into an Ada program, thus allowing
+a foreign-language subprogram to be called from Ada,
+or a foreign-language variable to be accessed from Ada.
+In contrast,
address@hidden,address@hidden the],Old=[a @nt{pragma}]}
+Export @Chg{Version=[3],New=[aspect to have the value True ],Old=[]}is used
+to export an Ada entity to a foreign language, thus allowing
+an Ada subprogram to be called from a foreign language,
+or an Ada object to be accessed from a foreign language.
address@hidden,New=[],Old=[ @nt[pragma]s]}
+Import and address@hidden,New=[ aspects],Old=[]}
+are intended primarily for objects and
+subprograms, although implementations are allowed to support other
address@hidden,New=[ The Link_Name and External_Name aspects are
+used to specify the link name and external name, respectively, to be
+used to identify imported or exported entities in the external
address@hidden@AspectDefn{External_Name}
address@hidden aspect], Sec=(convention, calling convention)}
address@hidden aspect], Sec=(import)}
address@hidden aspect], Sec=(export)}
address@hidden aspect], Sec=(external_name)}
address@hidden aspect], Sec=(link_name)}],Old=[]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Import],
+    address@hidden,Text=[Entity is imported from another
+      language.]}]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Export],
+    address@hidden,Text=[Entity is exported to another
+      language.]}]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[External_Name],
+    address@hidden,Text=[Name used to identify an imported or
+      exported entity.]}]}
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Link_Name],
+    address@hidden,Text=[Linker symbol used to identify an imported
+      or exported entity.]}]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[The],Old=[A @nt{pragma}]} Convention
address@hidden,address@hidden ],Old=[]}is used to
address@hidden,New=[indicate],Old=[specify]}
+that an Ada entity should use the conventions of another language.
+It is intended primarily for types and @lquotes@;address@hidden@; subprograms.
+For example,
address@hidden@;@Chg{Version=[3],address@hidden,address@hidden
address@hidden,New=[ => ],Old=[(address@hidden,New=[],Old=[, 
Matrix);address@hidden@;
address@hidden,New=[on the declaration of an array type Matrix ],Old=[]}implies
+that Matrix should be represented according to the
+conventions of the supported Fortran implementation, namely
+column-major order.
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Convention],
+    address@hidden,Text=[Calling convention or other convention
+      used for interfacing to other languages.]}]}
+
+A @nt{pragma} Linker_Options is used to specify the system linker
+parameters needed when a given compilation unit is included in a
+partition.
+
address@hidden
+
address@hidden
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[The form of a],address@hidden pragma}
address@hidden pragma], Sec=(Import)}
address@hidden, interfacing], Sec=(Import)}
address@hidden pragma], Sec=(Export)}
address@hidden, interfacing], Sec=(Export)}
address@hidden pragma], Sec=(Convention)}
address@hidden, interfacing], Sec=(Convention)}
address@hidden, interfacing], Sec=(Linker_Options)}
+An @i{interfacing pragma} is a representation
address@hidden that is
+one of the @nt{pragma}s Import, Export,
+or Convention.
+Their forms, together with that of the related]}
address@hidden address@hidden,New=[ is],Old=[, are]} as follows:
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 5
+through 7 were moved to @RefSec{Obsolescent Features}.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,InitialVersion=[0],@ChgDeleted{Version=[3],
+Text="@key{pragma} @prag(Import)(@*
+@ @ @ @ @ [Convention =>] @address@hidden, [Entity =>] @address@hidden
+@ @ [, [External_Name =>] @address@hidden [, [Link_Name =>] 
@address@hidden);"}'
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,InitialVersion=[0],@ChgDeleted{Version=[3],
+Text="@key{pragma} @prag(Export)(@*
+@ @ @ @ @ [Convention =>] @address@hidden, [Entity =>] @address@hidden
+@ @ [, [External_Name =>] @address@hidden [, [Link_Name =>] 
@address@hidden);"}'
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,InitialVersion=[0],@ChgDeleted{Version=[3],
+Text="@key{pragma} @prag(Convention)([Convention =>] @address@hidden,[Entity 
=>] @Syn2{local_name});"}'
+
address@hidden@key{pragma} @prag(Linker_Options)(@address@hidden);'
+
address@hidden
+A @nt[pragma] Linker_Options is allowed only at the place of a
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0058],ARef=[AI95-00036-01]}
address@hidden,Kind=[DeletedAdded],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[],Old=[For @nt{pragma}s
+Import and Export, the argument
+for Link_Name shall not be given without the
address@hidden@address@hidden@nt{identifier}
+unless the argument for External_Name is given.]}]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Text=[The Import and Export aspects are of
+type Boolean.]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The @Chg{Version=[3],New=[Link_Name and External_Name aspects are
+of],Old=[expected]} type @Chg{Version=[3],New=[],Old=[for a
address@hidden@address@hidden type],
+  Sec=(link name)} in an interfacing pragma or in pragma Linker_Options
+is ]}String.
address@hidden
address@hidden,Kind=[Revised]}
+There is no language-defined support for
+external or link names of type
+Wide_String, or of other string types.
+Implementations may, of course, have additional
address@hidden,New=[aspects],Old=[pragmas]} for that purpose.
+Note that allowing both String and Wide_String in the same
address@hidden,address@hidden,address@hidden would
+cause ambiguities.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,address@hidden type],Sec=(linker options)}
+The expected type for the @address@hidden
+in pragma Linker_Options is String.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden
+The @Chg{Version=[3],New=[aspect Convention shall be specified
+by a ],address@hidden@nt{identifier}
address@hidden,New=[which],Old=[of an interfacing pragma]}
+shall be the name of a @i{convention}.
+The convention names are implementation defined,
+except for certain language-defined ones,
+such as Ada and Intrinsic,
+as explained in @RefSec{Conformance Rules}.
address@hidden convention names generally represent
+the calling conventions of foreign languages,
+language implementations, or specific run-time models.]
address@hidden convention}
+The convention of a callable entity is its @i{calling convention}.
address@hidden convention names.}
address@hidden
+We considered representing the convention names using an enumeration
+type declared in System.
+Then, @address@hidden would be changed to
address@hidden@nt{name},
+and we would make its expected type be the enumeration type.
+We didn't do this because it seems to introduce extra complexity,
+and because the list of available languages is better represented as
+the list of children of package Interfaces @em a more open-ended sort
+of list.
address@hidden
+
address@hidden@Defn2{Term=[compatible],Sec=[a type, with a convention]}
+If @i[L] is a @address@hidden for a language, then a
+type T is said to be @i{compatible with convention L}, (alternatively,
+is said to be an @i[L-compatible type]) if any of the following conditions
+are met:
address@hidden
+T is declared in a language interface package
+corresponding to @i[L] and is defined to be
address@hidden
+(see @refsecnum(Interfacing with C and C++),
address@hidden(The Package Interfaces.C.Strings),
address@hidden(The Generic Package Interfaces.C.Pointers),
address@hidden(Interfacing with COBOL),
address@hidden(Interfacing with Fortran)),
+
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Sec=[a type, for a convention]}
+Convention @i[L] has been specified for address@hidden,New=[],Old=[ in
+a @nt[pragma] Convention]}, and T is @i{eligible for
+convention @i[L]}; that is:
address@hidden
address@hidden,Kind=[Added],ARef=[AI12-0135-1]}
address@hidden,Text=[T is an enumeration type such that all
+internal codes (whether assigned by default or explicitly) are within
+an implementation-defined range that includes at least the range of
+values 0 .. address@hidden@;1;]}
+
+T is an array type with either an
+unconstrained or statically-constrained first subtype, and
+its component type is @i[L]-compatible,
+
+T is a record type that has no discriminants and that only has
+components with statically-constrained subtypes, and
+each component type is @i[L]-compatible,
+
address@hidden,Kind=[Revised],ARef=[AI05-0002-1]}
+T is an access-to-object type, @Chg{Version=[3],New=[],Old=[and ]}its
+designated type is @i[L]-compatible,@Chg{Version=[3],New=[ and
+its designated subtype is not an unconstrained array subtype,],Old=[]}
+
+T is an access-to-subprogram type,
+and its designated profile's parameter and result types are all 
@i[L]-compatible.
address@hidden
+
+T is derived from an @i[L]-compatible type,
+
+The implementation permits T as an @i[L]-compatible type.
+
address@hidden
+  For example, an implementation might permit Integer as a C-compatible
+  type, though the C type to which it corresponds might be different
+  in different environments.
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+If @Chg{Version=[3],New=[the],address@hidden Convention
address@hidden,New=[aspect is specified for],Old=[applies to]} a type,
+then the type shall either be
+compatible with or eligible for
+the @Chg{Version=[3],New=[specified ],address@hidden,
+New=[],Old=[ specified in the pragma]}.
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  If a type is derived from an @i[L]-compatible type, the derived type
+  is by default @i[L]-compatible, but it is also permitted to specify
+  @Chg{Version=[3],New=[the],Old=[pragma]} Convention
+  @Chg{Version=[3],New=[aspect ],Old=[]}for the derived type.
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  It is permitted to specify @Chg{Version=[3],New=[the],Old=[pragma]}
+  Convention @Chg{Version=[3],New=[aspect ],Old=[]}for an incomplete type,
+  but in the complete declaration each component must be
+  @i[L]-compatible.
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  If each component of a record type is @i[L]-compatible, then
+  the record type itself is only @i[L]-compatible if it has
+  @Chg{Version=[3],New=[a specified],Old=[a pragma]}
+  Convention.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[],Old=[A @nt{pragma} Import shall be the completion of
+a address@hidden
+Notwithstanding any rule to the contrary,
address@hidden,New=[a declaration with a True],Old=[a @nt{pragma}]} Import
address@hidden,New=[aspect shall not have a],Old=[may serve as the]}
address@hidden,New=[],Old=[ of any
+kind of (explicit) declaration if supported by an implementation for
+that kind of declaration.
+If a completion is a @nt{pragma} Import,
+then it shall appear in the same
address@hidden, @nt{package_specification}, @nt{task_definition}
+or @nt{protected_definition}
+as the declaration.
+For a library unit, it shall appear in the same @nt{compilation},
+before any subsequent @nt{compilation_unit}s other than @nt{pragma}s.
+If the @nt{local_name} denotes more than one entity,
+then the @nt{pragma} Import is the completion of all of them]}.
address@hidden(Discussion)
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  For declarations of deferred constants and subprograms, we
+  @Chg{Version=[3],New=[explicitly ],Old=[]}mention
+  @Chg{Version=[3],New=[that no completion is allowed when aspect],
+  Old=[pragma]} Import @Chg{Version=[3],New=[is True],Old=[explicitly
+  as a possible completion]}. For other declarations that
+  require completions, we ignore the possibility of
+  @Chg{Version=[3],New=[the aspect],Old=[pragma]} address@hidden,New=[ being
+  True],Old=[]}.
+  Nevertheless, if an implementation chooses to allow
+  @Chg{Version=[3],New=[specifying aspect],Old=[a @nt{pragma}]} Import
+  to @Chg{Version=[3],New=[be True for],Old=[complete]} the declaration
+  of a task, protected type, incomplete type, private type, etc.,
+  it may do so, and the normal completion is then not allowed for that
+  declaration.
address@hidden(Discussion)
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden entity} @Defn{exported entity}
+An entity @Chg{Version=[3],New=[with a True],Old=[specified
+as the Entity argument to a @nt[pragma]]} address@hidden,New=[ aspect],Old=[]}
+(or @Chg{Version=[3],New=[],address@hidden address@hidden,New=[
+aspect],Old=[]}) is said to be @i{imported}
+(respectively, @i{exported})address@hidden,New=[ An entity shall not be both
+imported and exported.],Old=[]}
+
+The declaration of an imported object shall not include an explicit
+initialization expression.
address@hidden initializations are not performed.]
address@hidden
+This follows from the @lquotes@;Notwithstanding address@hidden@;
+wording in the Dynamics Semantics paragraphs below.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The type of an imported or exported object shall be compatible with the
address@hidden,New=[specified Convention
+aspect, if any], Old=[convention specified in the corresponding @nt{pragma}]}.
address@hidden
+This implies, for example, that importing an Integer object might be illegal,
+whereas importing an object of type Interfaces.C.int would be permitted.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+For an imported or exported subprogram, the result and parameter types
+shall each be compatible with the @Chg{Version=[3],New=[specified Convention
+aspect, if any], Old=[convention specified in the corresponding pragma]}.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[The @nt{aspect_definition} (if any) used to directly
+specify an],Old=[The external name and link name @address@hidden
+of a @nt{pragma}]} address@hidden,New=[,],Old=[ or]} Export,
address@hidden,New=[External_Name, or Link_Name aspect shall be a static
+expression. The],Old=[and the]} @address@hidden
+of a @nt[pragma] address@hidden,New=[],Old=[,]} shall be
address@hidden,New=[ An External_Name or Link_Name aspect shall be
+specified only for an entity that is either imported or exported.],Old=[]}
+
address@hidden
+
address@hidden
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 28
+and 29 were deleted.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,address@hidden pragma], Sec=(Import)}
address@hidden, representation], Sec=(Import)}
address@hidden pragma], Sec=(Export)}
address@hidden, representation], Sec=(Export)}
address@hidden pragma], Sec=(Convention)}
address@hidden, representation], Sec=(Convention)}
address@hidden of representation], Sec=(convention, calling convention)}
address@hidden, Sec=(aspect of representation)}
+Import, Export, and Convention @nt{pragma}s are representation pragmas
+that specify the @i{convention} aspect of representation.
address@hidden of representation], Sec=(imported)}
address@hidden, Sec=(aspect of representation)}
address@hidden of representation], Sec=(exported)}
address@hidden, Sec=(aspect of representation)}
+In addition, Import and Export @nt{pragma}s specify the
address@hidden and @i{exported} aspects of representation,
+respectively.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,address@hidden unit pragma], Sec=(Import)}
address@hidden, program unit], Sec=(Import)}
address@hidden unit pragma], Sec=(Export)}
address@hidden, program unit], Sec=(Export)}
address@hidden unit pragma], Sec=(Convention)}
address@hidden, program unit], Sec=(Convention)}
+An interfacing pragma is a program unit pragma
+when applied to a program unit
+(see @RefSecNum{Pragmas and Program Units}).]}
+
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[],Old=[An interfacing pragma defines the convention
+of the entity denoted by the @nt{local_name}. ]}The
address@hidden,New=[Convention aspect],Old=[convention]} represents
+the calling convention or representation convention of the entity.
+For an access-to-subprogram type, it represents the calling
+convention of designated subprograms.
+In addition:
address@hidden
address@hidden,Kind=[Revised]}
+A @Chg{Version=[3],New=[True],address@hidden Import
address@hidden,New=[aspect indicates],Old=[specifies]}
+that the entity is defined externally (that is,
+outside the Ada program)address@hidden,New=[ This aspect is never inherited;
+if not directly specified, the Import aspect is False.],Old=[]}
+
address@hidden,Kind=[Revised]}
+A @Chg{Version=[3],New=[True],address@hidden Export
address@hidden,New=[aspect indicates],Old=[specifies]}
+that the entity is used address@hidden,New=[ This aspect is never
+inherited; if not directly specified, the Export aspect is False.],Old=[]}
+
address@hidden,Kind=[Revised]}
address@hidden,New=[For an entity with a True],Old=[A @nt{pragma}]}
+Import or Export @Chg{Version=[3],New=[aspect, an],Old=[optionally specifies
+an entity's]} external name, link name, or address@hidden,New=[ may also
+be specified],Old=[]}.
address@hidden
+
address@hidden name}
+An @i{external name} is a string value for the
+name used by a foreign language program either for an
+entity that an Ada program imports, or for referring to
+an entity that an Ada program exports.
+
address@hidden name}
+A @i[link name] is a string value for the name of an exported
+or imported entity, based on the conventions of the
+foreign language's compiler in interfacing with the
+system's linker tool.
+
+The meaning of link names is implementation defined.
+If neither a link name nor
+the Address attribute of an imported or exported entity is specified,
+then a link name is chosen in an implementation-defined manner,
+based on the external name if one is specified.
address@hidden meaning of link names.}
address@hidden
+For example,
+an implementation might always prepend "_",
+and then pass it to the system linker.
address@hidden
address@hidden manner of choosing link names when neither the link name
+nor the address of an imported or exported entity is specified.}
address@hidden
+Normally, this will be the entity's defining name,
+or some simple transformation thereof.
address@hidden
+
+Pragma Linker_Options has the
+effect of passing its string argument as a parameter to
+the system linker (if one exists), if the immediately
+enclosing compilation unit is included in the partition
+being linked. The interpretation of the string argument, and the
+ way in which the string arguments from
+multiple Linker_Options pragmas are combined, is implementation
+defined.
address@hidden(The effect of pragma Linker_Options.)
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,address@hidden, Sec=(declaration with a True Import aspect)}],
address@hidden, Sec=(declaration named by a @nt{pragma} Import)}]}
address@hidden
+Notwithstanding what this International Standard says elsewhere,
+the elaboration of a declaration @Chg{Version=[3],New=[with a True Import
+aspect],Old=[denoted by the
address@hidden of
+a @nt{pragma} Import]} does not create the entity.
+Such an elaboration has no other effect than to allow the defining name
+to denote the external entity.
address@hidden
+This implies that default initializations are skipped.
+(Explicit initializations are illegal.)
+For example, an imported access object is @i{not}
+initialized to @key[null].
+
address@hidden,Kind=[Deleted],ARef=[AI05-0229-1]}
address@hidden,Text=[Note that the @nt{local_name}
+ in a @nt{pragma} Import might denote
+more than one declaration; in that case, the entity of all of those
+declarations will be the external entity.]}
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+This @lquotes@;address@hidden@; wording is better than saying
address@hidden@;unless @Chg{Version=[3],New=[aspect],Old=[named by a 
@nt{pragma}]}
address@hidden,New=[ is True],address@hidden@; on every definition of
+elaboration.
+It says we recognize the contradiction, and this rule takes
+precedence.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00320-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0229-1]}
address@hidden,address@hidden(erroneous execution),Sec=(cause)}
+It is the programmer's responsibility to ensure that the use of interfacing
address@hidden,New=[aspects],Old=[pragmas]} does not violate Ada semantics;
+otherwise, program execution is erroneous.]}
address@hidden
+
address@hidden
+    @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+    If an implementation supports @Chg{Version=[3],New=[],Old=[pragma ]}Export
+    @Chg{Version=[3],New=[for],Old=[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.
+    @address@hidden@address@hidden,
+    Sec=[of library units for a foreign language main subprogram]}
+    @Defn2{Term=[Finalization],
+    Sec=[of environment task for a foreign language main subprogram]}],
+    address@hidden AI-00052. Index entries only; no
+      real change, so no Chgref}
address@hidden,Kind=[RevisedAdded],InitialVersion=[2],
address@hidden,
+Text=[If @Chg{Version=[3],New=[],address@hidden ]} Export is supported
+for a language, the main program should
+be able to be written in that language. Subprograms named "adainit" and
+"adafinal"
+should be provided for elaboration and finalization of the environment 
task.]}]}
address@hidden
+  For example, if the main subprogram is written in C,
+  it can call adainit before the first call to an Ada subprogram,
+  and adafinal after the last.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1],ARef=[AI05-0269-1]}
+Automatic elaboration of preelaborated packages should be provided
+when @Chg{Version=[3],New=[specifying the],address@hidden Export
address@hidden,New=[aspect as True ],Old=[]}is supported.
address@hidden,Kind=[RevisedAdded],InitialVersion=[2],
address@hidden,
+Text=[Automatic elaboration of preelaborated packages should be provided
+when @Chg{Version=[3],New=[specifying the],address@hidden Export
address@hidden,New=[aspect as True ],Old=[]}is supported.]}]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0135-1]}
+For each supported convention @i[L] other than Intrinsic,
+an implementation should support @Chg{Version=[3],New=[specifying
+the ],Old=[]}Import and Export @Chg{Version=[3],New=[aspects],address@hidden
+for objects of @i[L]-compatible types and for
+subprograms, and @Chg{Version=[3],New=[the],address@hidden(pragma)]}
+Convention @Chg{Version=[3],New=[aspect ],Old=[]}for @i[L]-eligible types and 
for subprograms,
+presuming the other language has corresponding features.
address@hidden,New=[Specifying the ],address@hidden Convention
address@hidden,New=[aspect ],Old=[]}need not be supported for scalar
address@hidden,New=[, other than enumeration types whose internal codes
+fall within the range 0 .. address@hidden@;1],Old=[]}.
address@hidden,Kind=[RevisedAdded],InitialVersion=[2],
address@hidden,
+Text=[For each supported convention @i[L] other than Intrinsic,
address@hidden,New=[specifying the aspects],address@hidden
+Import and Export should be supported for
+objects of @i[L]-compatible types and for
+subprograms, and @Chg{Version=[3],New=[aspect],address@hidden(pragma)]}
+Convention should be supported for @i[L]-eligible types and for 
subprograms.]}]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[Specifying aspect],Old=[Pragma]} Convention is not
+necessary for scalar types, since the language interface packages declare 
scalar
+types corresponding to those provided by the respective foreign languages.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+If an implementation supports interfacing to @Chg{Version=[2],New=[the ],
address@hidden,New=[ entities not supported by
address@hidden with C and C++}],Old=[]},
+it should do so via the convention identifier C_Plus_Plus
+(in additional to any C++-implementation-specific ones).
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+The reason for giving the advice about C++ is to encourage
+uniformity among implementations, given that the name of the language is
+not syntactically legal as an @address@hidden,New=[],Old=[
+We place this advice in the AARM, rather than the RM95 proper,
+because (as of this writing) C++ is not an international standard,
+and we don't want to refer to a such a language from an international
+standard.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+Implementations may place restrictions on interfacing
address@hidden,New=[aspects],Old=[pragmas]};
+for example, requiring each exported entity to be declared
+at the library level.
address@hidden
+Arbitrary restrictions are allowed by
address@hidden and Representation Aspects}.
address@hidden
address@hidden
+Such a restriction might be to disallow them altogether.
+Alternatively, the implementation might allow them only for certain
+kinds of entities,
+or only for certain conventions.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[The Convention aspect in combination with
+the],Old=[A @nt{pragma}]}
+Import @Chg{Version=[3],New=[aspect indicates],Old=[specifies]}
+the conventions for accessing external
+entities. It is possible that the actual entity is written in assembly
+language, but reflects the conventions of a particular
+language. For example, @Chg{Version=[3],address@hidden@key[with] Convention
+=> Ada}],address@hidden Import(Ada, ...)]} can be used to
+interface to an assembly language routine that obeys the
+Ada compiler's calling conventions.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+To obtain @lquotes@;address@hidden@; to an Ada subprogram from a foreign
+language
+environment, @Chg{Version=[3],New=[the],address@hidden(pragma)]} Convention
address@hidden,New=[aspect ],Old=[]}should be specified both for the
+access-to-subprogram type and the specific subprogram(s) to which 'Access
+is applied.
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 45
+and 46 were deleted.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Text=[It is illegal to specify more than one of
+Import, Export, or Convention for a given entity.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Text=[The @nt{local_name}
+in an interfacing pragma can denote more than one
+entity in the case of overloading.
+Such a @nt{pragma} applies to all of the denoted entities.]}
+
+See also @RefSec{Machine Code Insertions}.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The Intrinsic convention (see @refsecnum(Conformance Rules))
+implies that the entity is somehow @lquotes@;built
address@hidden@; to the implementation.
+Thus, it generally does not make sense for users to specify Intrinsic
address@hidden,New=[along with specifying that the entity is imported],
+Old=[in a @nt{pragma} Import]}.
+The intention is that only implementations will specify
+Intrinsic @Chg{Version=[3],New=[for an imported entity],Old=[in a @nt{pragma}
+Import]}.
+The language also defines certain subprograms to be Intrinsic.
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+There are many imaginable interfacing @Chg{Version=[3],New=[aspects],
+Old=[pragmas]} that don't make any sense.
+For example, setting the Convention of a protected procedure to Ada
+is probably wrong.
+Rather than enumerating all such cases, however,
+we leave it up to implementations to decide what
+is sensible.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+If both External_Name and Link_Name are specified for @Chg{Version=[3],
+New=[a given entity],Old=[an Import or Export pragma]},
+then the External_Name is ignored.
+
address@hidden,Kind=[Deleted],ARef=[AI95-00320-01]}
address@hidden,Text=[An interfacing pragma might result in an effect
+that violates Ada semantics.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI12-0080-1]}
address@hidden@address@hidden of interfacing
address@hidden,New=[aspects],Old=[pragmas]}:}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1],ARef=[AI05-0269-1]}
address@hidden Fortran_Library @key[is]
+  @key[function] Sqrt (X : Float) @key[return] address@hidden,New=[
+    @key[with] Import => True, Convention => Fortran],Old=[]};
+  @Chg{Version=[3],address@hidden Matrix @key[is array] (Natural @key[range] 
<>, Natural @key[range] <>) @key[of] Float
+    @key[with] Convention => Fortran;
+  ],address@hidden @Chg{Version=[3],New=[Invert (M : Matrix],Old=[Exp  (X : 
Float]}) @key[return] @Chg{Version=[3],New=[Matrix
+    @key[with] Import => True, Convention => 
Fortran],Old=[Float]};@Chg{Version=[3],New=[],Old=[
address@hidden
+  @key[pragma] Import(Fortran, Sqrt);
+  @key[pragma] Import(Fortran, Exp);]}
address@hidden Fortran_Library;
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Interfacing pragmas are new to Ada 95.
+Pragma Import replaces Ada 83's pragma Interface.
+Existing implementations can continue to support pragma Interface for
+upward compatibility.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0058],ARef=[AI95-00036-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that 
@nt{pragma}s
+  Import and Export work like a subprogram call; parameters cannot be
+  omitted unless named notation is used. (Reordering is still not permitted,
+  however.)]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00320-01]}
+  @ChgAdded{Version=[2],Text=[Added wording to say all bets are off if
+  foreign code doesn't follow the semantics promised by the Ada
+  specifications.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0002-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Access types that designate unconstrained arrays are no longer defined
+  to be @i[L]-compatible. Such access-to-arrays require bounds information,
+  which is likely to be incompatible with a foreign language. The change
+  will allow (but not require) compilers to reject bad uses, which probably
+  will not work anyway.
+  Note that implementations can still support any type that it wants
+  as @i[L]-compatible; such uses will not be portable, however. As such,
+  there should be little existing code that will be impacted (compilers
+  probably already rejected cases that could not be translated, whether
+  or not the language allowed doing so formally).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Aspects Convention, Import, Export, Link_Name, and External_Name
+  are new; @nt{pragma}s Convention, Import, and Export are now obsolescent.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0135-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada address@hidden<Corrigendum:>
+  Added a suggestion that convention be supported for enumeration types.
+  This will make the use of enumeration types portable for implementations
+  that support interfacing to a particular language.]}
address@hidden
+
+
address@hidden Package Interfaces}
address@hidden
+Package Interfaces is the parent of several library
+packages that declare types and other entities useful for
+interfacing to foreign languages.
+It also contains some implementation-defined
+types that are useful across more than one language
+(in particular for interfacing to assembly
+language).
address@hidden contents of the visible part of package Interfaces
+and its language-defined descendants.}
address@hidden
+
address@hidden
address@hidden@Keepnext@;The library package Interfaces has the following 
skeletal declaration:
address@hidden
address@hidden
address@hidden Interfaces @key[is]
+   @key[pragma] Pure(Interfaces);
+
+   @key[type] address@hidden @key[is] @key[range] -2**(@RI{n}-1) .. 
2**(@RI{n}-1) - 1;  address@hidden's complement}
+
+   @key[type] address@hidden @key[is] @key[mod] address@hidden;
+
+   @key[function] Shift_Left  (Value : address@hidden; Amount : Natural)
+      @key[return] address@hidden;
+   @key[function] Shift_Right (Value : address@hidden; Amount : Natural)
+      @key[return] address@hidden;
+   @key[function] Shift_Right_Arithmetic (Value : address@hidden; Amount : 
Natural)
+      @key[return] address@hidden;
+   @key[function] Rotate_Left  (Value : address@hidden; Amount : Natural)
+      @key[return] address@hidden;
+   @key[function] Rotate_Right (Value : address@hidden; Amount : Natural)
+      @key[return] address@hidden;
+   address@hidden@address@hidden@address@hidden
address@hidden Interfaces;
address@hidden
address@hidden
+
address@hidden
address@hidden@;An implementation shall provide the following declarations in 
the
+visible part of package Interfaces:
address@hidden
+Signed and modular integer types of @i{n} bits,
+if supported by the target architecture,
+for each @i{n} that is at least the size
+of a storage element and that is a factor of the word size.
+The names of these types are of the form address@hidden for the
+signed types, and address@hidden for the modular types;@address@hidden
address@hidden
+For example, for a typical 32-bit machine the corresponding
+types might be Integer_8, Unsigned_8,
+Integer_16, Unsigned_16,
+Integer_32, and Unsigned_32.
+
+The wording above implies, for example, that Integer_16'Size =
+Unsigned_16'Size = 16.
+Unchecked conversions between same-Sized types will work as
+expected.
address@hidden
+
address@hidden@Defn{rotate}
+For each such modular type in Interfaces,
+shifting and rotating subprograms as specified in the declaration of
+Interfaces above.
+These subprograms are Intrinsic.
+They operate on a bit-by-bit basis,
+using the binary representation of the
+ value of the operands
+to yield a binary representation for the result.
+The Amount parameter gives the number of bits by which to shift
+or rotate.
+For shifting, zero bits are shifted in, except in the case of
+Shift_Right_Arithmetic, where one bits are shifted in if Value is
+at least half the modulus.
address@hidden
+We considered making shifting and rotating be primitive operations of
+all modular types.
+However, it is a design principle of Ada that all predefined operations
+should be operators (not functions named by identifiers).
+(Note that an early version of Ada had "@key[abs]" as an identifier,
+but it was changed to a reserved word operator before standardization of
+Ada 83.)
+This is important because the implicit declarations would hide
+nonoverloadable declarations with the same name,
+whereas operators are always overloadable.
+Therefore, we would have had to make shift and rotate
+into reserved words,
+which would have been upward incompatible,
+or else invent new operator symbols,
+which seemed like too much mechanism.
address@hidden
+
+Floating point types corresponding to each floating point format
+fully supported by the hardware.
address@hidden
+
+The names for these floating point types are not specified.
address@hidden floating point arithmetic}
+However, if IEEE arithmetic is supported, then the names
+should be IEEE_Float_32 and IEEE_Float_64 for single and double
+precision, address@hidden@Defn{IEEE_Float_64}
+
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00204-01]}
address@hidden,Kind=[DeletedAddedNoDelMsg],ARef=[AI05-0262-1]}
address@hidden,address@hidden,New=[],Old=[Support for
+interfacing to any foreign language is optional. However, an implementation
+shall not provide any attribute, library
+unit, or pragma having the same name as an attribute, library unit, or pragma
+(respectively) specified in the following clauses
+of this Annex unless the
+provided construct is either as specified in those clauses or is more limited
+in capability than that required by those clauses. A program that attempts to
+use an unsupported capability of this Annex shall either be identified by the
+implementation before run time or shall raise an exception at run time.]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg]}
+  @ChgAdded{Version=[2],address@hidden,New=[],Old=[The intent is that
+  the same rules apply for
+  language interfacing as apply for Specialized Needs Annexes. See
+  @RefSecNum{Conformity of an Implementation with the Standard} for a
+  discussion of the purpose of these rules.]}]}
address@hidden
address@hidden
+
address@hidden
+An implementation may provide implementation-defined library units
+that are children of Interfaces,
+and may add declarations to the visible part of Interfaces
+in addition to the ones defined above.
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[Implementation-defined
+children of package address@hidden,New=[],Old=[ The
+contents of the visible part of package Interfaces.]}]}
address@hidden latter sentence is given previously!}
+
address@hidden,Kind=[Added],ARef=[AI95-00204-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0229-1]}
address@hidden,Text=[A child package of package Interfaces with the name
+of a convention may be provided independently of whether the convention is
+supported by the @Chg{Version=[3],New=[],Old=[pragma ]}Convention
address@hidden,New=[aspect ],Old=[]}and vice versa. Such a child 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.]}
address@hidden
+  @ChgRef{Version=[2],address@hidden from below}
+  @ChgAdded{Version=[2],Text=[For example, package Interfaces.XYZ_Pascal might
+  contain declarations of types that match the data types provided by the XYZ
+  implementation of Pascal, so that it will be more convenient to pass
+  parameters to a subprogram whose convention is XYZ_Pascal.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00204-01]}
address@hidden,Text=[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.]}
address@hidden
address@hidden,Kind=[Deleted]}
address@hidden,Text=[For example, package Interfaces.XYZ_Pascal might contain
+declarations of types that match the data types provided by the
+XYZ implementation of Pascal,
+so that it will be more convenient to pass parameters to a subprogram
+whose convention is XYZ_Pascal.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+An implementation supporting an interface to C, COBOL, or Fortran
+should provide the corresponding
+package or packages described in the following 
@Chg{Version=[3],New=[subclauses],Old=[clauses]}.
address@hidden,Kind=[Added],address@hidden,
+Text=[If an interface to C, COBOL, or Fortran is provided, the corresponding
+package or packages described in @RefSec{Interface to Other Languages}
+should also be provided.]}]}
address@hidden
address@hidden@;The intention is that an implementation might support several
+implementations of the foreign language: Interfaces.This_Fortran and
+Interfaces.That_Fortran might both exist.
+The @lquotes@;address@hidden@; implementation, overridable by the user,
+should be declared as a renaming:
address@hidden
address@hidden Interfaces.Fortran @key[renames] Interfaces.This_Fortran;
address@hidden
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00204-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that interfacing to foreign languages
+  is optional and has the same restrictions as a Specialized Needs Annex.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Text=[Move the restrictions on implementations of
+  optional features to the start of this Annex.]}
address@hidden
+
+
address@hidden,New=[Interfacing with C and C++],
+Old=[Interfacing with C]}
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0059],ARef=[AI95-00131-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00376-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0028-1]}
address@hidden to C}
address@hidden interface}
+The facilities relevant to interfacing with
+the C language @Chg{Version=[2],New=[and the corresponding subset of
+the C++ language ],Old=[]}are the package Interfaces.C and its 
address@hidden,New=[, and ],Old=[;
address@hidden,Old=[and ]}]}support for @Chg{Version=[3],New=[specifying 
],Old=[]}the
address@hidden,New=[],Old=[Import, Export, and]}
+Convention @Chg{Version=[3],New=[aspect],Old=[pragmas]}
+with 
@Chg{Version=[3],address@hidden@nt{identifier}s],address@hidden@nt{identifier}]}
address@hidden@Chg{Version=[3],address@hidden,New=[,],Old=[ and]}],Old=[;
+and support for the Convention pragma with @address@hidden
address@hidden,New=[, and any of the address@hidden<n> conventions
+described below],Old=[]}],Old=[]}.
+
address@hidden,Kind=[Revised],ARef=[AI95-00376-01]}
address@hidden,Kind=[Revised],ARef=[AI95-0262-1],ARef=[AI95-0299-1]}
+The package Interfaces.C contains the basic types,
address@hidden,New=[,],Old=[]} and
+subprograms that allow an Ada program to pass scalars and strings to C
address@hidden,New=[and C++ ],address@hidden,New=[ When
+this @Chg{Version=[3],New=[subclause],Old=[clause]} mentions a C entity,
+the reference also applies to the corresponding entity in C++.],Old=[]}
address@hidden
+
address@hidden
address@hidden@Keepnext@;The library package Interfaces.C has the following 
declaration:
address@hidden
address@hidden(package) Interfaces.C 
@key(is)@ChildUnit{Parent=[Interfaces],Child=[C]}
+   @key(pragma) Pure(C);
+
+   @RI{-- Declarations based on C's <limits.h>}
+
+   @AdaObjDefn{CHAR_BIT}  : @key(constant) := @RI{implementation-defined};  
@RI{-- typically 8}
+   @AdaObjDefn{SCHAR_MIN} : @key(constant) := @RI{implementation-defined};  
@RI{-- typically @en@;128}
+   @AdaObjDefn{SCHAR_MAX} : @key(constant) := @RI{implementation-defined};  
@RI{-- typically 127}
+   @AdaObjDefn{UCHAR_MAX} : @key(constant) := @RI{implementation-defined};  
@RI{-- typically 255}
+
+   @RI{-- Signed and Unsigned Integers}
+   @key(type) @AdaTypeDefn{int}   @key(is) @key(range) 
@RI{implementation-defined};
+   @key(type) @AdaTypeDefn{short} @key(is) @key(range) 
@RI{implementation-defined};
+   @key(type) @AdaTypeDefn{long}  @key(is) @key(range) 
@RI{implementation-defined};
+
+   @key(type) @AdaTypeDefn{signed_char} @key(is) @key(range) SCHAR_MIN .. 
SCHAR_MAX;
+   @key(for) signed_char'Size @key(use) CHAR_BIT;
+
+   @key(type) @AdaTypeDefn{unsigned}       @key(is) @key(mod) 
@RI{implementation-defined};
+   @key(type) @AdaTypeDefn{unsigned_short} @key(is) @key(mod) 
@RI{implementation-defined};
+   @key(type) @AdaTypeDefn{unsigned_long}  @key(is) @key(mod) 
@RI{implementation-defined};
+
+   @key(type) @AdaTypeDefn{unsigned_char} @key(is) @key(mod) (UCHAR_MAX+1);
+   @key(for) unsigned_char'Size @key(use) CHAR_BIT;
+
+   @key(subtype) @AdaTypeDefn{plain_char} @key(is) @RI{implementation-defined};
+
+   @key(type) @AdaTypeDefn{ptrdiff_t} @key(is) @key(range) 
@RI{implementation-defined};
+
+   @key(type) @AdaTypeDefn{size_t} @key(is) @key(mod) 
@RI{implementation-defined};
+
+   @RI{-- Floating Point}
+
+   @key(type) @AdaTypeDefn{C_float}     @key(is) @key(digits) 
@RI{implementation-defined};
+
+   @key(type) @AdaTypeDefn{double}      @key(is) @key(digits) 
@RI{implementation-defined};
+
+   @key(type) @AdaTypeDefn{long_double} @key(is) @key(digits) 
@RI{implementation-defined};
+
+
+   @RI{-- Characters and Strings }
+
+   @key(type) @AdaTypeDefn{char} @key(is) @RI{<implementation-defined 
character type>};
+
address@hidden,Kind=[Revised],Ref=[8652/0060],ARef=[AI95-00037-01]}
+   @AdaObjDefn{nul} : @key(constant) char := @address@hidden,Old=[char'First]};
+
+   @key[function] @AdaSubDefn{To_C}   (Item : @key[in] Character) @key[return] 
char;
+
+   @key[function] @AdaSubDefn{To_Ada} (Item : @key[in] char) @key[return] 
Character;
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1],ARef=[AI05-0269-1]}
+   @key(type) @AdaTypeDefn{char_array} @key(is) @key(array) (size_t 
@key(range) <>) @key(of) @key[aliased] address@hidden,New=[
+      @key[with] Pack],Old=[;
+   @key[pragma] Pack(char_array)]};
+   @key(for) char_array'Component_Size @key(use) CHAR_BIT;
+
+   @key(function) @AdaSubDefn{Is_Nul_Terminated} (Item : @key(in) char_array) 
@key(return) Boolean;
+
+   @key(function) @AdaSubDefn{To_C}   (Item       : @key(in) String;
+                    Append_Nul : @key(in) Boolean := True)
+      @key(return) char_array;
+
+   @key(function) @AdaSubDefn{To_Ada} (Item     : @key(in) char_array;
+                    Trim_Nul : @key(in) Boolean := True)
+      @key(return) String;
+
+   @key(procedure) @AdaSubDefn{To_C} (Item       : @key(in)  String;
+                   Target     : @key(out) char_array;
+                   Count      : @key(out) size_t;
+                   Append_Nul : @key(in)  Boolean := True);
+
+   @key(procedure) @AdaSubDefn{To_Ada} (Item     : @key(in)  char_array;
+                     Target   : @key(out) String;
+                     Count    : @key(out) Natural;
+                     Trim_Nul : @key(in)  Boolean := True);
+
+   @RI{-- Wide Character and Wide String}
+
address@hidden,Kind=[Revised],Ref=[8652/0060],ARef=[AI95-00037-01]}
+   @key(type) @AdaTypeDefn{wchar_t} @key(is) 
@address@hidden<implementation-defined character type>}],
address@hidden;
+
address@hidden,Kind=[Revised],Ref=[8652/0060],ARef=[AI95-00037-01]}
+   @AdaObjDefn{wide_nul} : @key(constant) wchar_t := 
@address@hidden,Old=[wchar_t'First]};
+
+   @key(function) @AdaSubDefn{To_C}   (Item : @key(in) Wide_Character) 
@key(return) wchar_t;
+   @key(function) @AdaSubDefn{To_Ada} (Item : @key(in) wchar_t       ) 
@key(return) Wide_Character;
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key(type) @AdaTypeDefn{wchar_array} @key(is) @key(array) (size_t 
@key(range) <>) @key(of) @key(aliased) address@hidden,New=[
+      @key[with] Pack],Old=[]};
+
address@hidden,Kind=[Deleted],ARef=[AI05-0229-1]}
address@hidden,Text=[   @key(pragma) Pack(wchar_array);]}
+
+   @key(function) @AdaSubDefn{Is_Nul_Terminated} (Item : @key(in) wchar_array) 
@key(return) Boolean;
+
+   @key(function) @AdaSubDefn{To_C}   (Item       : @key(in) Wide_String;
+                    Append_Nul : @key(in) Boolean := True)
+      @key(return) wchar_array;
+
+   @key(function) @AdaSubDefn{To_Ada} (Item     : @key(in) wchar_array;
+                    Trim_Nul : @key(in) Boolean := True)
+      @key(return) Wide_String;
+
+   @key(procedure) @AdaSubDefn{To_C} (Item       : @key(in)  Wide_String;
+                   Target     : @key(out) wchar_array;
+                   Count      : @key(out) size_t;
+                   Append_Nul : @key(in)  Boolean := True);
+
+   @key(procedure) @AdaSubDefn{To_Ada} (Item     : @key(in)  wchar_array;
+                     Target   : @key(out) Wide_String;
+                     Count    : @key(out) Natural;
+                     Trim_Nul : @key(in)  Boolean := True);
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Text=[   -- @RI[ISO/IEC 10646:2003 compatible types defined by 
ISO/IEC TR 19769:2004.]]}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Text=[   @key<type> @AdaTypeDefn{char16_t} @key<is> 
@RI{<implementation-defined character type>};]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[   @AdaObjDefn{char16_nul} : @key<constant> char16_t := 
@RI{implementation-defined};]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[   @key<function> @AdaSubDefn{To_C} (Item : @key<in> 
Wide_Character) @key<return> char16_t;
+   @key<function> @AdaSubDefn{To_Ada} (Item : @key<in> char16_t) @key<return> 
Wide_Character;]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0229-1]}
address@hidden,Text=[   @key<type> @AdaTypeDefn{char16_array} @key<is array> 
(size_t @key<range> <>) @key<of aliased> address@hidden,New=[
+      @key[with] Pack],Old=[]};]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[DeletedAdded],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[],Old=[   @key<pragma> 
Pack(char16_array);]}]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Is_Nul_Terminated} (Item : 
@key<in> char16_array) @key<return> Boolean;
+   @key<function> @AdaSubDefn{To_C} (Item       : @key<in> Wide_String;
+                  Append_Nul : @key<in> Boolean := True)
+      @key<return> char16_array;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[   @key<function> @AdaSubDefn{To_Ada} (Item     : @key<in> 
char16_array;
+                    Trim_Nul : @key<in> Boolean := True)
+      @key<return> Wide_String;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[   @key<procedure> @AdaSubDefn{To_C} (Item       : 
@key<in>  Wide_String;
+                   Target     : @key<out> char16_array;
+                   Count      : @key<out> size_t;
+                   Append_Nul : @key<in>  Boolean := True);]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[   @key<procedure> @AdaSubDefn{To_Ada} (Item     : 
@key<in>  char16_array;
+                     Target   : @key<out> Wide_String;
+                     Count    : @key<out> Natural;
+                     Trim_Nul : @key<in>  Boolean := True);]}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Text=[   @key<type> @AdaTypeDefn{char32_t} @key<is> 
@RI{<implementation-defined character type>};]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[   @AdaObjDefn{char32_nul} : @key<constant> char32_t := 
@RI{implementation-defined};]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[   @key<function> @AdaSubDefn{To_C} (Item : @key<in> 
Wide_Wide_Character) @key<return> char32_t;
+   @key<function> @AdaSubDefn{To_Ada} (Item : @key<in> char32_t) @key<return> 
Wide_Wide_Character;]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0229-1]}
address@hidden,Text=[   @key<type> @AdaTypeDefn{char32_array} @key<is array> 
(size_t @key<range> <>) @key<of aliased> address@hidden,New=[
+      @key[with] Pack],Old=[]};]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[DeletedAdded],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[],Old=[   @key<pragma> 
Pack(char32_array);]}]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Is_Nul_Terminated} (Item : 
@key<in> char32_array) @key<return> Boolean;
+   @key<function> @AdaSubDefn{To_C} (Item       : @key<in> Wide_Wide_String;
+                  Append_Nul : @key<in> Boolean := True)
+      @key<return> char32_array;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[   @key<function> @AdaSubDefn{To_Ada} (Item     : @key<in> 
char32_array;
+                    Trim_Nul : @key<in> Boolean := True)
+      @key<return> Wide_Wide_String;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[   @key<procedure> @AdaSubDefn{To_C} (Item       : 
@key<in>  Wide_Wide_String;
+                   Target     : @key<out> char32_array;
+                   Count      : @key<out> size_t;
+                   Append_Nul : @key<in>  Boolean := True);]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[   @key<procedure> @AdaSubDefn{To_Ada} (Item     : 
@key<in>  char32_array;
+                     Target   : @key<out> Wide_Wide_String;
+                     Count    : @key<out> Natural;
+                     Trim_Nul : @key<in>  Boolean := True);]}
+
+   @AdaExcDefn{Terminator_Error} : @key(exception);
+
address@hidden(end) Interfaces.C;
address@hidden
address@hidden,Kind=[Added],InitialVersion=[1],
address@hidden definitions of
address@hidden,New=[certain ],Old=[]}types and constants in
+Interfaces.C.],Old=[]}]}
+
+Each of the types declared in Interfaces.C is C-compatible.
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+The types int, short, long, unsigned,
+ptrdiff_t, size_t, double,
+char, @Chg{Version=[2],New=[],Old=[and address@hidden,New=[,
+char16_t, and char32_t],Old=[]}
+correspond respectively to the C types having the same names.
+The types signed_char, address@hidden, address@hidden, address@hidden,
+C_float, and address@hidden correspond respectively
+to the C types signed char,
+unsigned short, unsigned long, unsigned char, float, and long double.
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The C types wchar_t and char16_t seem to be the
+same. However, wchar_t has an implementation-defined size, whereas
+char16_t is guaranteed to be an unsigned type of at least 16
+bits. Also, char16_t and char32_t are encouraged to have UTF-16 and UTF-32
+representations; that means that they are not directly the same as the Ada
+types, which most likely don't use any UTF encoding.]}
address@hidden
+
address@hidden@;The type of the subtype plain_char is either signed_char or
+unsigned_char, depending on the C implementation.
address@hidden
address@hidden@Keepnext
address@hidden(function) To_C   (Item : @key(in) Character) @key(return) char;
address@hidden(function) To_Ada (Item : @key(in) char     ) @key(return) 
Character;
address@hidden
address@hidden@;The functions To_C and To_Ada map between the Ada type Character
+and the C type char.
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0114],ARef=[AI95-00038-01]}
address@hidden,Text=[The To_C and To_Ada functions map between
+corresponding characters, not necessarily between characters with the same
+internal representation. Corresponding characters are characters defined by the
+same enumeration literal, if such exist; otherwise, the correspondence
+is address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Type=[Leading],Text=[The following definition is
+equivalent to the above summary:]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden (Latin_1_Char) = 
char'Value(Character'Image(Latin_1_Char))address@hidden
+provided that char'Value does not raise an exception; otherwise the result
+is unspecified.]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden (Native_C_Char) = 
Character'Value(char'Image(Native_C_Char))address@hidden
+provided that Character'Value does not raise an exception;
+otherwise the result is unspecified.]}
address@hidden
+
address@hidden@Keepnext
address@hidden(function) Is_Nul_Terminated (Item : @key(in) char_array) 
@key(return) Boolean;
address@hidden
address@hidden@;The result of Is_Nul_Terminated is True if Item contains nul, 
and is
+False otherwise.
+
address@hidden@Keepnext
address@hidden(function) To_C   (Item : @key(in) String;     Append_Nul : 
@key(in) Boolean := True)
+   @key(return) char_array;
address@hidden line}
address@hidden(function) To_Ada (Item : @key(in) char_array; Trim_Nul   : 
@key(in) Boolean := True)
+   @key(return) String;
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00258-01]}
+The result of To_C is a char_array value of length Item'Length (if
+Append_Nul is False) or Item'Length+1 (if Append_Nul is True).
+The lower bound is 0.
+For each component Item(I), the corresponding component in the result
+is To_C applied to Item(I).
+The value nul is appended if Append_Nul is address@hidden,New=[ If
+Append_Nul is False and Item'Length is 0, then To_C propagates
+Constraint_Error.],Old=[]}
+
address@hidden@;The result of To_Ada is a String whose length is Item'Length 
(if Trim_Nul is
+False) or the length of the slice of Item preceding the first
+nul (if Trim_Nul is True). The lower bound of the result is 1.
+If Trim_Nul is False, then for each component Item(I)
+the corresponding component in the result
+is To_Ada applied to Item(I).
+If Trim_Nul is True, then for each component Item(I) before
+the first nul the corresponding component in the result
+is To_Ada applied to Item(I).
+The function propagates Terminator_Error if Trim_Nul is True and
+Item does not contain nul.
+
address@hidden@Keepnext
address@hidden(procedure) To_C (Item       : @key(in)  String;
+                Target     : @key(out) char_array;
+                Count      : @key(out) size_t;
+                Append_Nul : @key(in)  Boolean := True);
address@hidden line}
address@hidden(procedure) To_Ada (Item     : @key(in)  char_array;
+                  Target   : @key(out) String;
+                  Count    : @key(out) Natural;
+                  Trim_Nul : @key(in)  Boolean := True);
address@hidden
+For procedure To_C, each element of Item is converted (via the To_C function)
+to a char, which is assigned to the corresponding element
+of Target. If Append_Nul is True, nul
+is then assigned to the next
+element of Target. In either case, Count is set to the
+number of Target elements assigned.
address@hidden,Sec=(raised by failure of run-time check)}
+If Target is not long enough, Constraint_Error is propagated.
+
address@hidden@;For procedure To_Ada, each element of Item (if Trim_Nul is 
False) or
+each element of Item preceding the first nul (if Trim_Nul is True) is
+converted (via the To_Ada function) to a Character, which is
+assigned to the corresponding element of Target. Count
+is set to the number of Target elements assigned.
address@hidden,Sec=(raised by failure of run-time check)}
+If Target is not long enough, Constraint_Error is propagated.
+If Trim_Nul is True and Item does not contain nul,
+then Terminator_Error is propagated.
+
address@hidden@Keepnext
address@hidden(function) Is_Nul_Terminated (Item : @key(in) wchar_array) 
@key(return) Boolean;
address@hidden
address@hidden@;The result of Is_Nul_Terminated is True if Item contains 
wide_nul,
+and is False otherwise.
+
address@hidden@Keepnext
address@hidden(function) To_C   (Item : @key(in) Wide_Character) @key(return) 
wchar_t;
address@hidden(function) To_Ada (Item : @key(in) wchar_t       ) @key(return) 
Wide_Character;
address@hidden
address@hidden@;To_C and To_Ada provide the mappings between the Ada and C wide
+character types.
+
address@hidden
address@hidden(function) To_C   (Item       : @key(in) Wide_String;
+                 Append_Nul : @key(in) Boolean := True)
+   @key(return) wchar_array;
address@hidden line}
address@hidden(function) To_Ada (Item     : @key(in) wchar_array;
+                 Trim_Nul : @key(in) Boolean := True)
+   @key(return) Wide_String;
address@hidden line}
address@hidden(procedure) To_C (Item       : @key(in)  Wide_String;
+                Target     : @key(out) wchar_array;
+                Count      : @key(out) size_t;
+                Append_Nul : @key(in)  Boolean := True);
address@hidden line}
address@hidden(procedure) To_Ada (Item     : @key(in)  wchar_array;
+                  Target   : @key(out) Wide_String;
+                  Count    : @key(out) Natural;
+                  Trim_Nul : @key(in)  Boolean := True);
address@hidden
+The To_C and To_Ada subprograms that convert between Wide_String and
+wchar_array have analogous effects to the To_C and To_Ada
+subprograms that convert between String and char_array, except that
+wide_nul is used instead of nul.
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden<function> Is_Nul_Terminated (Item : 
@key<in> char16_array) @key<return> Boolean;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Type=[Trailing],Text=[The result of Is_Nul_Terminated is True if 
Item contains char16_nul,
+and is False otherwise.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden<function> To_C (Item : @key<in> 
Wide_Character) @key<return> char16_t;
address@hidden<function> To_Ada (Item : @key<in> char16_t ) @key<return> 
Wide_Character;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Type=[Trailing],Text=[To_C and To_Ada provide mappings
+between the Ada and C 16-bit character types.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden<function> To_C (Item       : @key<in> Wide_String;
+               Append_Nul : @key<in> Boolean := True)
+   @key<return> char16_array;
address@hidden line}
address@hidden<function> To_Ada (Item     : @key<in> char16_array;
+                 Trim_Nul : @key<in> Boolean := True)
+   @key<return> Wide_String;
address@hidden line}
address@hidden<procedure> To_C (Item       : @key<in>  Wide_String;
+                Target     : @key<out> char16_array;
+                Count      : @key<out> size_t;
+                Append_Nul : @key<in>  Boolean := True);
address@hidden line}
address@hidden<procedure> To_Ada (Item     : @key<in>  char16_array;
+                  Target   : @key<out> Wide_String;
+                  Count    : @key<out> Natural;
+                  Trim_Nul : @key<in>  Boolean := True);]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Type=[Trailing],Text=[The To_C and To_Ada subprograms that
+convert between Wide_String and char16_array have analogous effects to the To_C
+and To_Ada subprograms that convert between String and char_array, except that
+char16_nul is used instead of nul.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden<function> Is_Nul_Terminated (Item : 
@key<in> char32_array) @key<return> Boolean;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Type=[Trailing],Text=[The result of Is_Nul_Terminated is
+True if Item contains char16_nul, and is False otherwise.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden<function> To_C (Item : @key<in> 
Wide_Wide_Character) @key<return> char32_t;
address@hidden<function> To_Ada (Item : @key<in> char32_t ) @key<return> 
Wide_Wide_Character;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Type=[Trailing],Text=[To_C and To_Ada provide mappings
+between the Ada and C 32-bit character types.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden<function> To_C (Item       : @key<in> 
Wide_Wide_String;
+               Append_Nul : @key<in> Boolean := True)
+   @key<return> char32_array;
address@hidden line}
address@hidden<function> To_Ada (Item     : @key<in> char32_array;
+                 Trim_Nul : @key<in> Boolean := True)
+   @key<return> Wide_Wide_String;
address@hidden line}
address@hidden<procedure> To_C (Item       : @key<in>  Wide_Wide_String;
+                Target     : @key<out> char32_array;
+                Count      : @key<out> size_t;
+                Append_Nul : @key<in>  Boolean := True);
address@hidden line}
address@hidden<procedure> To_Ada (Item     : @key<in>  char32_array;
+                  Target   : @key<out> Wide_Wide_String;
+                  Count    : @key<out> Natural;
+                  Trim_Nul : @key<in>  Boolean := True);]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Type=[Trailing],Text=[The To_C and To_Ada subprograms
+that convert between Wide_Wide_String and char32_array have analogous effects
+to the To_C and To_Ada subprograms that convert between String and char_array,
+except that char32_nul is used instead of nul.]}
+
address@hidden
+The Interfaces.C package provides an implementation-defined character type,
+char, designed to model the C run-time character set, and mappings
+between the types char and Character.
+
address@hidden@;One application of the C interface package is
+to compose a C string and pass it to a C function.
+One way to do this is for the programmer to declare an
+object that will hold the C array, and then pass this array to the C
+function. This is realized via the type char_array:
address@hidden
address@hidden(type) char_array @key(is) @key(array) (size_t @key(range) <>) of 
Char;
address@hidden
+
+The programmer can declare an Ada String, convert it to a char_array, and
+pass the char_array as actual parameter to the C function that is expecting
+a char *.
+
+An alternative approach is for the programmer to obtain a C char pointer
+from an Ada String (or from a char_array) by invoking an allocation
+function. The package Interfaces.C.Strings (see below) supplies
+the needed facilities, including a
+private type chars_ptr that corresponds to C's
+char *, and two allocation functions. To avoid storage
+leakage, a Free procedure releases the storage that was
+allocated by one of these allocate functions.
+
+It is typical for a C function that deals with strings to adopt the
+convention that the string is delimited by a nul char. The C interface
+packages support this convention. A constant nul of type Char is declared,
+and the function Value(Chars_Ptr) in Interfaces.C.Strings
+returns a char_array up to and including
+the first nul in the array that the chars_ptr points to. The Allocate_Chars
+function allocates an array that is nul terminated.
+
+Some C functions that deal with strings take an explicit length as a
+parameter, thus allowing strings to be passed that contain nul as
+a data element. Other C functions take an explicit length that is
+an upper bound: the prefix of the string up to the char before nul,
+or the prefix of the given length, is used by the
+function, whichever is shorter.
+The C Interface packages support calling such functions.
address@hidden
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0059],ARef=[AI95-00131-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[The],Old=[A]} Convention
address@hidden,New=[aspect],Old=[pragma]} with @address@hidden
+C_Pass_By_Copy shall only be
address@hidden,New=[specified for],Old=[applied to]} a type.]}
+
address@hidden,Kind=[Added],Ref=[8652/0059],ARef=[AI95-00131-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00216-01]}
address@hidden,Text=[The eligibility rules in @RefSecNum(Interfacing Aspects) 
do not apply
+to convention C_Pass_By_Copy. Instead, a type T is eligible for convention
+C_Pass_By_Copy @Chg{Version=[2],New=[if T is an unchecked union type or ],
+Old=[]}if T is a record type that has no discriminants and that only
+has components with statically constrained subtypes, and each component is
+C-compatible.]}
+
address@hidden,Kind=[Added],Ref=[8652/0059],ARef=[AI95-00131-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0264-1]}
address@hidden,Text=[If a type is
address@hidden,New=[,],Old=[]}
+then it is also C-compatible.]}
+
address@hidden,Kind=[Added],ARef=[AI12-0028-1]}
address@hidden,Text=[The identifiers C_Variadic_0, C_Variadic_1,
+C_Variadic_2, and so on are @address@hidden These conventions
+are said to be @i<C_Variadic>. The convention address@hidden<n> is the calling 
convention
+for a variadic C function taking @i<n> fixed parameters and then a variable
+number of additional parameters. The address@hidden<n> convention shall only be
+specified as the convention aspect for a subprogram, or for an
+access-to-subprogram type, having at least @i<n> parameters. A type is
+compatible with a C_Variadic convention if and only if the type is
address@hidden@Defn2{Term=[variadic],Sec=[C]}]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[It is implementation defined what the largest
+  @i<n> in address@hidden<n> is supported. We don't say this because it
+  complicates the wording and it is true for almost any
+  @address@hidden (only Ada is required to be supported by the
+  language, all others need to be documented in order for programmers to know
+  that they are available).]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0059],ARef=[AI95-00131-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+An implementation shall support @Chg{Version=[3],New=[specifying
+aspect],Old=[pragma]} Convention
+with a C @address@hidden for a
+C-eligible type (see @refsecnum(Interfacing Aspects))@Chg{New=[. An
+implementation shall support @Chg{Version=[3],New=[specifying
+aspect],Old=[pragma]} Convention with a C_Pass_By_Copy
address@hidden@nt{identifier} for a C_Pass_By_Copy-eligible type.],Old=[]}
address@hidden
+
address@hidden
+An implementation may provide additional declarations in the C
+interface packages.
+
address@hidden,Kind=[Added],ARef=[AI05-0002-1],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[An implementation need not support
+specifying the Convention aspect with @SynI<convention_>@nt{identifier} C in 
the
+following cases:]}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0248-1]}
address@hidden,Text=[for a subprogram that has a parameter of an
+unconstrained array subtype, unless the Import aspect has the value True for 
the
+subprogram;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[for a function with an unconstrained array result
+subtype;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[for an object whose nominal subtype is an
+unconstrained array subtype.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0002-1]}
address@hidden,Text=[These rules ensure that an implementation never
+needs to create bounds for an unconstrained array that originates in C (and
+thus does not have bounds). An implementation can do so if it wishes, of
+course. Note that these permissions do not extend to passing an unconstrained
+array as a parameter to a C function; in this case, the bounds can simply be
+dropped and thus support is required.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0060],ARef=[AI95-00037-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00285-01]}
address@hidden,address@hidden change, just a new paragraph number}
address@hidden,Text=[The constants address@hidden,New=[,],Old=[ and]}
address@hidden,New=[, char16_nul, and char32_nul],Old=[]} should
+have a representation of zero.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The constants nul, wide_nul, char16_nul, and char32_nul in package
+Interfaces.C should have a representation of zero.]}]}
+
+An implementation should support the following interface
+correspondences between Ada and C.
address@hidden
+An Ada procedure corresponds to
+a void-returning C function.
address@hidden
+The programmer can also choose an Ada procedure when
+the C function returns an int that is to be address@hidden
+
+An Ada function corresponds to a non-void C function.
+
address@hidden,Kind=[Added],ARef=[AI12-0135-1]}
address@hidden,Text=[An Ada enumeration type corresponds to a C
+enumeration type with corresponding enumeration literals having the same
+internal codes, provided the internal codes fall within the range of the C int
+type.]}
+
+An Ada @key[in] scalar parameter is passed as a scalar argument to a C 
function.
+
+An Ada @key[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.
+
+An Ada @key[access] T parameter,
+or an Ada @key[out] or @key[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 @key[out] or @key[in out]
+parameter, a pointer to a temporary copy is used to preserve
+by-copy semantics.
+
address@hidden,Kind=[Added],Ref=[8652/0059],ARef=[AI95-00131-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00343-01]}
address@hidden,Text=[An Ada parameter of a @Chg{Version=[2],
+New=[(record) type T of convention ],address@hidden,
+New=[],Old=[-compatible (record) type T]}, of
+mode @key{in}, is passed as a t argument to a C function, where t is the
+C struct corresponding to the Ada type T.]}
+
address@hidden,Kind=[Revised],Ref=[8652/0059],ARef=[AI95-00131-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00343-01]}
+An Ada parameter of a record type T, of any mode,
address@hidden than an @key{in} parameter of a @Chg{Version=[2],
+New=[type of convention ],address@hidden,
+New=[],Old=[-compatible type]},],Old=[]}
+is passed as a t* argument to a C function, where t is the
+C struct corresponding to the Ada type T.
+
+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.
+
+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.
+
address@hidden,Kind=[Added],ARef=[AI05-0002-1]}
address@hidden,Text=[An Ada parameter of a
+private type is passed as specified for the full view of the type.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0002-1]}
address@hidden,Text=[The rules of correspondence given above for
+parameters of mode @key[in] also apply to the return object of a function.]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00337-01]}
address@hidden,Kind=[DeletedAdded],ARef=[AI05-0002-1]}
address@hidden,address@hidden,New=[An Ada parameter of a
+private type is passed as specified for the full view of the type.],Old=[]}]}
+
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If C interfacing is supported, the interface correspondences between Ada
+and C should be supported.]}]}
address@hidden
+
address@hidden
+Values of type char_array are not implicitly terminated with nul.
+If a char_array is to be passed as a parameter to an imported
+C function requiring nul termination, it is the programmer's
+responsibility to obtain this effect.
+
+To obtain the effect of C's sizeof(item_type),
+where Item_Type is the corresponding Ada type,
+ evaluate the expression: size_t(Item_Type'Size/CHAR_BIT).
+
address@hidden,Kind=[Deleted],ARef=[AI95-00216-01]}
address@hidden,Text=[There is no explicit support for C's union types.
+Unchecked conversions can be used to obtain
+the effect of C unions.]}
+
address@hidden,Kind=[Revised],ARef=[AI12-0028-1]}
+A @Chg{Version=[4],New=[variadic ],Old=[]}C function
address@hidden,New=[],Old=[that takes a variable number of arguments ]}can
+correspond to several Ada subprograms, taking various
+specific numbers and types of parameters.
address@hidden
+
address@hidden
address@hidden@address@hidden of using the Interfaces.C package:}
address@hidden
address@hidden the C Library Function strcpy}
address@hidden(with) Interfaces.C;
address@hidden(procedure) Test @key(is)
+   @key(package) C @key(renames) Interfaces.C;
+   @key(use) @key(type) C.char_array;
+   @RI{-- Call <string.h>strcpy:}
+   @RI{-- C definition of strcpy:  char *strcpy(char *s1, const char *s2);}
+   @RI{--    This function copies the string pointed to by s2 (including the 
terminating null character)}
+   @RI{--     into the array pointed to by s1. If copying takes place between 
objects that overlap, }
+   @RI{--     the behavior is undefined. The strcpy function returns the value 
of s1.}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @RI{-- Note: since the C function's return value is of no interest, the Ada 
interface is a procedure}
+   @key(procedure) Strcpy (Target : @key(out) C.char_array;
+                     Source : @key(in)  C.char_array)@Chg{Version=[3],New=[
+      @key(with) Import => True, Convention => C, External_Name => 
"strcpy"],Old=[]};
+
address@hidden,Kind=[Deleted],ARef=[AI05-0229-1]}
address@hidden,Text=[   @key(pragma) Import(C, Strcpy, "strcpy");]}
+
+   Chars1 :  C.char_array(1..20);
+   Chars2 :  C.char_array(1..20);
+
address@hidden(begin)
+   Chars2(1..6) := "qwert" & C.nul;
+
+   Strcpy(Chars1, Chars2);
+
address@hidden Now Chars1(1..6) = "qwert" & C.Nul}
+
address@hidden(end) Test;
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  Types char16_t and char32_t and their related
+  types and operations are @Chg{Version=[3],New=[],Old=[newly ]}added to
+  Interfaces.C. If Interfaces.C is
+  referenced in a @nt{use_clause}, and an entity @i<E> with the same
+  @nt{defining_identifier} as a new entity in Interfaces.C is defined in a
+  package that is also referenced in a @nt{use_clause}, the entity @i<E> may no
+  longer be use-visible, resulting in errors. This should be rare and is easily
+  fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0059],ARef=[AI95-00131-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b<Corrigendum:> Convention C_Pass_By_Copy is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0060],ARef=[AI95-00037-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified the intent for
+  Nul and Wide_Nul.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00216-01]}
+  @ChgAdded{Version=[2],Text=[Specified that an unchecked union type (see
+  @RefSecNum{Unchecked Union Types}) is eligible for convention
+  C_Pass_By_Copy.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00258-01]}
+  @ChgAdded{Version=[2],Text=[Specified what happens if the To_C function
+  tries to return a null string.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00337-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that the interface correspondences
+  also apply to private types whose full types have the specified
+  characteristics.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00343-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that a type must have convention
+  C_Pass_By_Copy in order to be passed by copy (not just a type that could
+  have that convention).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00376-01]}
+  @ChgAdded{Version=[2],Text=[Added wording to make it clear that these
+  facilities can also be used with C++.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0002-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Added a definition of correspondences for function results. Also added 
wording
+  to make it clear that we do not expect the implementation to conjure bounds
+  for unconstrained arrays out of thin air. These changes allow (but don't
+  require) compilers to reject unreasonable uses of array types. Such uses
+  probably didn't work anyway (and probably were rejected, no matter what
+  the language definition said), so little existing code should be impacted.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0028-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada address@hidden<Corrigendum:>
+  The @address@hidden C_Variadic_0, C_Variadic_1, and so on
+  are new. These are classified as a correction as any implementation can add
+  such identifiers and it is important that special conventions be available 
for
+  variadic functions as typical x64 conventions are different for normal and
+  variadic C functions.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0135-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Defined the correspondence
+  between an Ada enumeration type and a C enumeration type; implementations
+  should support convention C for enumeration types.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Package Interfaces.C.Strings}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The package Interfaces.C.Strings declares types and subprograms
+allowing an Ada program to allocate, reference, update, and free C-style
+strings.
+In particular, the private type chars_ptr
+ corresponds to a common
+use of @lquotes@;char address@hidden@; in C programs, and an object of this 
type can be
+passed to a subprogram to which @Chg{Version=[3],address@hidden@key[with] 
Import => True,
+Convention => C}],address@hidden(pragma) Import(C,...)]} has been
address@hidden,New=[specified],Old=[applied]},
+and for which @lquotes@;char address@hidden@;
+is the type of the argument of the C function.
address@hidden
+
address@hidden
address@hidden@;The library package Interfaces.C.Strings has the following
+declaration:
address@hidden
address@hidden(package) Interfaces.C.Strings 
@key(is)@ChildUnit{Parent=[Interfaces.C],Child=[Strings]}
+   @key[pragma] Preelaborate(Strings);
+
+   @key(type) @AdaTypeDefn{char_array_access} @key(is) @key(access) @key(all) 
char_array;
+
address@hidden,Kind=[Revised],ARef=[AI95-00161-01]}
+   @key(type) @AdaTypeDefn{chars_ptr} @key(is) 
@key(private);@Chg{Version=[2],New=[
+   @key(pragma) Preelaborable_Initialization(chars_ptr);],Old=[]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00276-01]}
+   @key(type) @AdaTypeDefn{chars_ptr_array} @key(is) @key(array) (size_t 
@key(range) <>) @key(of) @Chg{Version=[2],address@hidden(aliased) 
],Old=[]}chars_ptr;
+
+   @AdaObjDefn{Null_Ptr} : @key(constant) chars_ptr;
+
+   @key(function) @AdaSubDefn{To_Chars_Ptr} (Item      : @key(in) 
char_array_access;
+                          Nul_Check : @key(in) Boolean := False)
+      @key(return) chars_ptr;
+
+   @key(function) @AdaSubDefn{New_Char_Array} (Chars   : @key(in) char_array) 
@key(return) chars_ptr;
+
+   @key(function) @AdaSubDefn{New_String} (Str : @key(in) String) @key(return) 
chars_ptr;
+
+   @key(procedure) @AdaSubDefn{Free} (Item : @key(in) @key(out) chars_ptr);
+
+   @AdaSubDefn{Dereference_Error} : @key(exception);
+
+
+   @key(function) @AdaSubDefn{Value} (Item : @key(in) chars_ptr) @key(return) 
char_array;
+
+   @key(function) @AdaSubDefn{Value} (Item : @key(in) chars_ptr; Length : 
@key(in) size_t)
+      @key(return) char_array;
+
+   @key(function) @AdaSubDefn{Value} (Item : @key(in) chars_ptr) @key(return) 
String;
+
+   @key(function) @AdaSubDefn{Value} (Item : @key(in) chars_ptr; Length : 
@key(in) size_t)
+      @key(return) String;
+
+   @key(function) @AdaSubDefn{Strlen} (Item : @key(in) chars_ptr) @key(return) 
size_t;
+
+   @key(procedure) @AdaSubDefn{Update} (Item   : @key(in) chars_ptr;
+                     Offset : @key(in) size_t;
+                     Chars  : @key(in) char_array;
+                     Check  : @key(in) Boolean := True);
+
+   @key(procedure) @AdaSubDefn{Update} (Item   : @key(in) chars_ptr;
+                     Offset : @key(in) size_t;
+                     Str    : @key(in) String;
+                     Check  : @key(in) Boolean := True);
+
+   @AdaSubDefn{Update_Error} : @key(exception);
+
+
address@hidden(private)
+   ... -- @RI{not specified by the language}
address@hidden(end) Interfaces.C.Strings;
address@hidden
address@hidden
+The string manipulation types and subprograms appear in a
+child of Interfaces.C versus being there directly, since it is
+useful to have Interfaces.C specified as @nt(pragma) Pure.
+
+Differently named functions New_String and New_Char_Array
+are declared, since if there were a single overloaded function
+a call with a string literal as actual parameter would be
+ambiguous.
address@hidden
+
+The type chars_ptr is C-compatible and
+corresponds to the use of C's @lquotes@;char address@hidden@; for
+a pointer to the first char in a char array terminated by nul.
+When an object of type chars_ptr is declared, its value is
+by default set to Null_Ptr, unless the object is imported
+(see @RefSecNum(Interfacing Aspects)).
address@hidden
+
+The type char_array_access is not necessarily C-compatible, since
+an object of this type may carry @lquotes@;address@hidden@; information.
+The programmer should convert from char_array_access to chars_ptr
+for objects imported from, exported to, or passed to address@hidden
address@hidden
address@hidden@Keepnext
address@hidden(function) To_Chars_Ptr (Item      : @key(in) char_array_access;
+                       Nul_Check : @key(in) Boolean := False)
+   @key(return) chars_ptr;
address@hidden
address@hidden@ChgRef{Version=[1],Kind=[Revised],Ref=[8652/0061],ARef=[AI95-00140-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
+If Item is @key(null), then To_Chars_Ptr returns Null_Ptr.
address@hidden Item is not @key(null),], Old=[Otherwise, if]} Nul_Check is
address@hidden,],Old=[]} and address@hidden(all) does not contain nul, then
+the function propagates Terminator_Error;
address@hidden@Chg{Version=[3],New=[,],Old=[]}],
+Old=[if Nul_Check is True and address@hidden(all) does contain nul,]}
+To_Chars_Ptr performs a pointer conversion with no allocation of memory.
+
address@hidden@Keepnext
address@hidden(function) New_Char_Array (Chars   : @key(in) char_array) 
@key(return) chars_ptr;
address@hidden
+This function returns a pointer to an allocated object initialized to
+  Chars(Chars'First .. Index) & nul, where
address@hidden
+Index = Chars'Last if Chars does not contain nul, or
+
+Index is the smallest size_t value I such that Chars(I+1) = nul.
address@hidden
+
address@hidden following paragraph is missing a number in the original version.
+To give it a number in the new version, it is marked as an insertion.}
address@hidden,address@hidden
address@hidden,address@hidden@;]}Storage_Error is propagated if the allocation
+fails.
+
address@hidden@Keepnext
address@hidden(function) New_String (Str : @key(in) String) @key(return) 
chars_ptr;
address@hidden
address@hidden@;This function is equivalent to New_Char_Array(To_C(Str)).
+
address@hidden@Keepnext
address@hidden(procedure) Free (Item : @key(in) @key(out) chars_ptr);
address@hidden
address@hidden@;If Item is Null_Ptr, then Free has no effect.
+Otherwise, Free releases the storage occupied by Value(Item),
+and resets Item to Null_Ptr.
+
address@hidden@Keepnext
address@hidden(function) Value (Item : @key(in) chars_ptr) @key(return) 
char_array;
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+If Item = address@hidden,New=[,],Old=[]} then Value propagates
+Dereference_Error.
address@hidden,New=[,],Old=[]} Value returns the prefix of the
+array of chars pointed to by Item, up to and including the
+first nul.
+The lower bound of the result is 0.
+If Item does not point to a nul-terminated string, then
+execution of Value is erroneous.
+
address@hidden@Keepnext
address@hidden(function) Value (Item : @key(in) chars_ptr; Length : @key(in) 
size_t)
+   @key(return) char_array;
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0062],ARef=[AI95-00139-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden@;If Item = address@hidden,New=[,],Old=[]}
+then address@hidden,Old=[(Item)]} propagates Dereference_Error.
address@hidden,New=[,],Old=[]} Value returns the shorter
+of two address@hidden, either],Old=[:]}
+the first Length chars pointed to by Item, @Chg{New=[or],Old=[and]}
+Value(Item). The lower bound of the result is 0.
address@hidden Length is 0, then Value propagates Constraint_Error.],Old=[]}
address@hidden
+Value(New_Char_Array(Chars)) = Chars if Chars does not contain
+nul; else Value(New_Char_Array( Chars)) is the prefix of Chars
+up to and including the first nul.
address@hidden
+
address@hidden@Keepnext
address@hidden(function) Value (Item : @key(in) chars_ptr) @key(return) String;
address@hidden
address@hidden@;Equivalent to To_Ada(Value(Item), Trim_Nul=>True).
+
address@hidden@Keepnext
address@hidden(function) Value (Item : @key(in) chars_ptr; Length : @key(in) 
size_t)
+   @key(return) String;
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0063],ARef=[AI95-00177-01]}
address@hidden@;Equivalent to To_Ada(Value(Item, Length)@Chg{New=[ & 
nul],Old=[]}, Trim_Nul=>True).
+
address@hidden@Keepnext
address@hidden(function) Strlen (Item : @key(in) chars_ptr) @key(return) size_t;
address@hidden
address@hidden@;Returns @i[Val]'address@hidden@;1 where @i[Val] = Value(Item);
+propagates Dereference_Error if Item = Null_Ptr.
address@hidden
+Strlen returns the number of chars in the array pointed to by Item, up to
+and including the char immediately before the first nul.
+
+Strlen has the same possibility for erroneous execution
+as Value, in cases where the string has not been nul-terminated.
+
+Strlen has the effect of C's strlen function.
address@hidden
+
address@hidden@Keepnext
address@hidden(procedure) Update (Item   : @key(in) chars_ptr;
+                  Offset : @key(in) size_t;
+                  Chars  : @key(in) char_array;
+                  Check  : Boolean := True);
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0064],ARef=[AI95-00039-01]}
address@hidden@;@Chg{New=[If Item = Null_Ptr, then Update propagates
+Dereference_Error. Otherwise, t],Old=[T]}his procedure updates the value
+pointed to by Item, starting at position Offset, using Chars as the data to be
+copied into the array. Overwriting the nul terminator,
+and skipping with the Offset past the nul terminator,
+are both prevented if Check is True, as follows:
address@hidden
+Let N = Strlen(Item).
+If Check is True, then:
address@hidden
+ If Offset+Chars'Length>N, propagate Update_Error.
+
+ Otherwise, overwrite the data in the array pointed to by Item,
+ starting at the char at position Offset, with the data in Chars.
address@hidden
+
address@hidden@;If Check is False, then
+processing is as above, but with no check that Offset+Chars'Length>N.
address@hidden
+If Chars contains nul, Update's effect may be
+to @lquotes@;address@hidden@; the pointed-to char address@hidden
address@hidden
+
address@hidden@Keepnext
address@hidden(procedure) Update (Item   : @key(in) chars_ptr;
+                  Offset : @key(in) size_t;
+                  Str    : @key(in) String;
+                  Check  : @key(in) Boolean := True);
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00242-01]}
+Equivalent to Update(Item, Offset, To_C(address@hidden,
+New=[, Append_Nul => False],Old=[]}), Check).
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00242-01]}
address@hidden,Text=[To truncate the Item to the length of Str, use
+Update(Item, Offset, To_C(Str), Check) instead of Update(Item, Offset, Str, 
Check).
+Note that when truncating Item, Item must be longer than Str.]}
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)}
+Execution of any of the following is erroneous if the Item
+parameter is not null_ptr and Item
+does not point to a nul-terminated array of chars.
address@hidden
+a Value function not taking a Length parameter,
+
+the Free procedure,
+
+the Strlen function.
address@hidden
+
address@hidden(erroneous execution),Sec=(cause)}
+Execution of Free(X) is also erroneous if the chars_ptr X was not returned
+by New_Char_Array or New_String.
+
address@hidden(erroneous execution),Sec=(cause)}
+Reading or updating a freed char_array is erroneous.
+
address@hidden(erroneous execution),Sec=(cause)}
+Execution of Update is erroneous if Check is False and a call with
+Check equal to True would have propagated Update_Error.
address@hidden
+
address@hidden
+New_Char_Array and New_String might be
+implemented either through
+the allocation function from the C environment (@lquotes@;address@hidden@;) or 
through
+Ada dynamic memory allocation (@lquotes@;address@hidden@;). The key points are
address@hidden
+the returned value (a chars_ptr) is
+represented as a C @lquotes@;char address@hidden@; so
+that it may be passed to C functions;
+
+the allocated object should be freed by the programmer via a call of
+Free, not by a called C function.
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00242-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] Update for a String parameter is now defined to not
+  add a nul character. It did add a nul in Ada 95. This means that programs
+  that used this behavior of Update to truncate a string will no longer work
+  (the string will not be truncated). This change makes Update for a string
+  consistent with Update for a char_array (no implicit nul is added to the end
+  of a char_array).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00161-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b[Amendment Correction:] Added @nt{pragma} Preelaborable_Initialization to
+  type chars_ptr, so that it can be used in preelaborated units.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00276-01]}
+  @ChgAdded{Version=[2],address@hidden Correction:] The components of
+  chars_ptr_array are aliased so that it can be used to instantiate
+  Interfaces.C.Pointers (that is its intended purpose, which is otherwise
+  mysterious as it has no operations).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0061],ARef=[AI95-00140-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Fixed the missing 
semantics
+  of To_Char_Ptr when Nul_Check is False.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0062],ARef=[AI95-00139-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Fixed the missing 
semantics
+  of Value when the Length is 0.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0063],ARef=[AI95-00177-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the definition 
of
+  Value to avoid raising Terminator_Error.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0064],ARef=[AI95-00039-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Fixed the missing 
semantics
+  of Update when Item is Null_Ptr.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Generic Package Interfaces.C.Pointers}
address@hidden
+The generic package Interfaces.C.Pointers allows the Ada programmer to
+perform C-style operations on pointers. It includes an access type
+Pointer, Value functions that dereference a Pointer and deliver the
+designated array, several pointer arithmetic operations, and 
@lquotes@;address@hidden@;
+procedures that copy the contents of a source pointer into the array
+designated by a destination pointer. As in C, it treats an object Ptr of
+type Pointer as a pointer to the first element of an array, so that for
+example, adding 1 to Ptr yields a pointer to the
+second element of the array.
+
+The generic allows two styles of usage: one in which the array is
+terminated by a special terminator element; and another in which the
+programmer needs to keep track of the length.
address@hidden
+
address@hidden
address@hidden@;The generic library package Interfaces.C.Pointers has the
+following declaration:
address@hidden
address@hidden(generic)
+   @key(type) Index @key(is) (<>);
+   @key(type) Element @key(is) @key(private);
+   @key(type) Element_Array @key(is) @key(array) (Index @key(range) <>) 
@key(of) @key(aliased) Element;
+   Default_Terminator : Element;
address@hidden(package) Interfaces.C.Pointers 
@key(is)@ChildUnit{Parent=[Interfaces.C],Child=[Pointers]}
+   @key[pragma] Preelaborate(Pointers);
+
+   @key(type) @AdaTypeDefn{Pointer} @key(is) @key(access) @key(all) Element;
+
+   @key(function) @AdaSubDefn{Value}(Ref        : @key(in) Pointer;
+                  Terminator : @key(in) Element := Default_Terminator)
+      @key(return) Element_Array;
+
+   @key(function) @AdaSubDefn{Value}(Ref    : @key(in) Pointer;
+                  Length : @key(in) ptrdiff_t)
+      @key(return) Element_Array;
+
+
+   @AdaExcDefn{Pointer_Error} : @key(exception);
+
+   @RI{-- C-style Pointer arithmetic}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key(function) "+" (Left : @key(in) Pointer;   Right : @key(in) ptrdiff_t) 
@key(return) address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+   @key(function) "+" (Left : @key(in) ptrdiff_t; Right : @key(in) Pointer)   
@key(return) address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+   @key(function) "-" (Left : @key(in) Pointer;   Right : @key(in) ptrdiff_t) 
@key(return) address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+   @key(function) "-" (Left : @key(in) Pointer;   Right : @key(in) Pointer) 
@key(return) address@hidden,New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key(procedure) @AdaSubDefn{Increment} (Ref : @key(in) @key(out) 
Pointer)@Chg{Version=[3],New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+   @key(procedure) @AdaSubDefn{Decrement} (Ref : @key(in) @key(out) 
Pointer)@Chg{Version=[3],New=[
+      @key(with) Convention => Intrinsic],Old=[]};
+
address@hidden,Kind=[Deleted],ARef=[AI05-0229-1]}
address@hidden,Text=[   @key(pragma) Convention (Intrinsic, "+");
+   @key(pragma) Convention (Intrinsic, "-");
+   @key(pragma) Convention (Intrinsic, Increment);
+   @key(pragma) Convention (Intrinsic, Decrement);]}
+
+   @key(function) @AdaSubDefn{Virtual_Length} (Ref        : @key(in) Pointer;
+                            Terminator : @key(in) Element := 
Default_Terminator)
+      @key(return) ptrdiff_t;
+
+   @key(procedure) @AdaSubDefn{Copy_Terminated_Array}
+      (Source     : @key(in) Pointer;
+       Target     : @key(in) Pointer;
+       Limit      : @key(in) ptrdiff_t := ptrdiff_t'Last;
+       Terminator : @key(in) Element :=  Default_Terminator);
+
+   @key(procedure) @AdaSubDefn{Copy_Array} (Source  : @key(in) Pointer;
+                         Target  : @key(in) Pointer;
+                         Length  : @key(in) ptrdiff_t);
+
address@hidden(end) Interfaces.C.Pointers;
address@hidden
+
address@hidden@;The type Pointer is C-compatible and
+corresponds to one use of C's @lquotes@;Element address@hidden@;.
+An object of type Pointer is interpreted as a pointer to the
+initial Element in an Element_Array.
+Two styles are supported:
address@hidden
+Explicit termination of an array value with
+Default_Terminator (a special terminator value);
+
address@hidden@;Programmer-managed length, with
+Default_Terminator treated simply as a data element.
address@hidden
address@hidden
address@hidden@Keepnext
address@hidden(function) Value(Ref        : @key(in) Pointer;
+               Terminator : @key(in) Element := Default_Terminator)
+   @key(return) Element_Array;
address@hidden
address@hidden@;This function returns an Element_Array whose value is the array
+  pointed to by Ref, up to and including the first Terminator; the lower bound
+  of the array is Index'First. Interfaces.C.Strings.Dereference_Error is
+  propagated if Ref is @key(null).
+
address@hidden@Keepnext
address@hidden(function) Value(Ref    : @key(in) Pointer;
+               Length : @key(in) ptrdiff_t)
+   @key(return) Element_Array;
address@hidden
address@hidden@;This function returns an Element_Array comprising the first 
Length
+elements pointed to by Ref. The exception
+Interfaces.C.Strings.Dereference_Error is propagated if Ref is @key(null).
address@hidden
+
address@hidden@;The "+" and "@en@;" functions perform arithmetic on Pointer 
values,
+based on the Size of the array elements. In each of these functions,
+Pointer_Error is propagated if a Pointer parameter is @key(null).
address@hidden
address@hidden@Keepnext
address@hidden(procedure) Increment (Ref : @key(in) @key(out) Pointer);
address@hidden
address@hidden@;Equivalent to Ref := Ref+1.
+
address@hidden@Keepnext
address@hidden(procedure) Decrement (Ref : @key(in) @key(out) Pointer);
address@hidden
address@hidden@;Equivalent to Ref := address@hidden@;1.
+
address@hidden@Keepnext
address@hidden(function) Virtual_Length (Ref        : @key(in) Pointer;
+                         Terminator : @key(in) Element := Default_Terminator)
+   @key(return) ptrdiff_t;
address@hidden
address@hidden@;Returns the number of Elements, up to the one just before the 
first
+Terminator, in Value(Ref, Terminator).
+
address@hidden@Keepnext
address@hidden(procedure) Copy_Terminated_Array
+   (Source     : @key(in) Pointer;
+    Target     : @key(in) Pointer;
+    Limit      : @key(in) ptrdiff_t := ptrdiff_t'Last;
+    Terminator : @key(in) Element := Default_Terminator);
address@hidden
address@hidden@;This procedure copies Value(Source, Terminator) into the array
+pointed to by Target; it stops either after Terminator has been copied, or the
+number of elements copied is Limit, whichever occurs first.
+Dereference_Error is propagated if either Source or Target is @key(null).
address@hidden
+It is the programmer's responsibility to ensure that
+elements are not copied beyond the logical length of the target array.
address@hidden
address@hidden
+  The implementation has to take care to check the Limit first.
address@hidden
+
address@hidden@Keepnext
address@hidden(procedure) Copy_Array (Source  : @key(in) Pointer;
+                      Target  : @key(in) Pointer;
+                      Length  : @key(in) ptrdiff_t);
address@hidden
+This procedure copies the first Length elements from the array pointed
+ to by Source, into the array pointed to by Target.
+ Dereference_Error is propagated if either
+ Source or Target is @key(null).
address@hidden
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)}
+It is erroneous to dereference a Pointer that does not designate
+an aliased Element.
address@hidden
+Such a Pointer could arise via "+", "@en@;", Increment, or
address@hidden
+
address@hidden(erroneous execution),Sec=(cause)}
+Execution of Value(Ref, Terminator) is erroneous if
+Ref does not designate an aliased Element in an Element_Array
+terminated by Terminator.
+
address@hidden(erroneous execution),Sec=(cause)}
+Execution of Value(Ref, Length) is erroneous if
+Ref does not designate an aliased Element in an Element_Array
+containing at least Length Elements between the designated Element and
+the end of the array, inclusive.
+
address@hidden(erroneous execution),Sec=(cause)}
+Execution of Virtual_Length(Ref, Terminator) is erroneous if
+Ref does not designate an aliased Element in an Element_Array
+terminated by Terminator.
+
address@hidden@PDefn2{Term=(erroneous execution),Sec=(cause)}
+Execution of Copy_Terminated_Array(Source, Target, Limit, Terminator)
+is erroneous in either of the following situations:
address@hidden
+Execution of both Value(Source, Terminator) and
+Value(Source, Limit) are erroneous, or
+
+Copying writes past the end of the array containing the Element
+designated by Target.
address@hidden
+
address@hidden(erroneous execution),Sec=(cause)}
+Execution of Copy_Array(Source, Target, Length) is erroneous if either
+Value(Source, Length) is erroneous, or copying writes past the end of
+the array containing the Element designated by Target.
address@hidden
+
address@hidden
address@hidden@;To compose a Pointer from an Element_Array, use 'Access on
+the first element. For example (assuming appropriate instantiations):
address@hidden
+Some_Array   : Element_Array(0..5) ;
+Some_Pointer : Pointer := Some_Array(0)'Access;
address@hidden
address@hidden
+
address@hidden
address@hidden@address@hidden of Interfaces.C.Pointers:}
address@hidden
address@hidden(with) Interfaces.C.Pointers;
address@hidden(with) Interfaces.C.Strings;
address@hidden(procedure) Test_Pointers @key(is)
+   @key(package) C @key(renames) Interfaces.C;
+   @key(package) Char_Ptrs @key(is)
+      @key(new) C.Pointers (Index              => C.size_t,
+                      Element            => C.char,
+                      Element_Array      => C.char_array,
+                      Default_Terminator => C.nul);
+
+   @key(use) @key(type) Char_Ptrs.Pointer;
+   @key(subtype) Char_Star @key(is) Char_Ptrs.Pointer;
+
+   @key(procedure) Strcpy (Target_Ptr, Source_Ptr : Char_Star) @key(is)
+      Target_Temp_Ptr : Char_Star := Target_Ptr;
+      Source_Temp_Ptr : Char_Star := Source_Ptr;
+      Element : C.char;
+   @key(begin)
+      @key(if) Target_Temp_Ptr = @key(null) @key(or) Source_Temp_Ptr = 
@key(null) @key(then)
+         @key(raise) C.Strings.Dereference_Error;
+      @key(end if);
+
address@hidden,Kind=[Revised],Ref=[8652/0065],ARef=[AI95-00142-01]}
+      @key(loop)
+         Element             := address@hidden(all);
+         address@hidden(all) := Element;
+         @key(exit) @key(when) @Chg{New=[C."="(Element, C.nul)],Old=[Element = 
C.nul]};
+         Char_Ptrs.Increment(Target_Temp_Ptr);
+         Char_Ptrs.Increment(Source_Temp_Ptr);
+      @key(end) @key(loop);
+   @key(end) Strcpy;
address@hidden(begin)
+   ...
address@hidden(end) Test_Pointers;
address@hidden
address@hidden
+
+
+
address@hidden,InitialVersion=[2],New=[Unchecked Union Types],Old=[Pragma 
Unchecked_Union]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1],ARef=[AI05-0269-1]}
address@hidden,address@hidden,Sec=[C]}
address@hidden@Chg{Version=[3],New=[Specifying aspect],Old=[A pragma]}
+Unchecked_Union @Chg{Version=[3],New=[to have the value True
+defines],Old=[specifies]} an interface correspondence
+between a given discriminated type and some C union. The
address@hidden,New=[aspect requires],Old=[pragma specifies]}
+that the associated type shall be given a representation
+that @Chg{Version=[3],New=[allocates],Old=[leaves]} no space
+for its discriminant(s).]]}
address@hidden
+
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 2
+through 3 were moved to @RefSec{Obsolescent Features}.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],KeepNext=[T],Text=[
address@hidden,New=[The form of a pragma Unchecked_Union is as 
follows:],Old=[]}]}
address@hidden'd like a conditional insert of Leading, etc., but we don't have 
that.}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden<Version=[3],InitialVersion=[2],@ChgDeleted{Version=[3],
address@hidden,address@hidden @prag{Unchecked_Union} 
(@Syni<first_subtype_>@Syn2<local_name>);],Old=[]}]}>
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[For a discriminated record type
+having a @nt{variant_part}, the following language-defined representation 
aspect
+may be specified:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden type of aspect Unchecked_Union
+is Boolean. If directly specified, the @nt{aspect_definition} shall be a static
+expression. If not specified (including by inheritance), the aspect is
address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Unchecked_Union],
+    address@hidden,Text=[Type is used to interface to a C union
+      type.]}]}
+
address@hidden
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 4
+and 5 were deleted.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[],Old=[Unchecked_Union is a
+representation pragma, specifying the unchecked union aspect of
+representation.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[],Old=[The
address@hidden@nt{local_name} of a @nt{pragma} Unchecked_Union shall
+denote an unconstrained discriminated record subtype having a
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,address@hidden union type}
address@hidden union subtype}
address@hidden union object}
+A type @Chg{Version=[3],New=[for],Old=[to]} which
address@hidden,New=[aspect],Old=[a pragma]} Unchecked_Union
address@hidden,New=[is True],Old=[applies]} is called an
address@hidden<unchecked union type>. A subtype of an
+unchecked union type is defined to be an @i<unchecked union subtype>.
+An object of an unchecked union type is defined to be an @i<unchecked union
+object>.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Text=[All component subtypes of an unchecked union type
+shall be C-compatible.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Text=[If a component subtype of an unchecked union type
+is subject to a per-object constraint, then the component subtype shall be an
+unchecked union subtype.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0026-1]}
address@hidden,Text=[Any name that denotes a discriminant of an object
+of an unchecked union type shall occur within the declarative region of the
address@hidden,New=[, and shall not
+occur within a @nt{record_representation_clause}],Old=[]}.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0026-1]}
address@hidden,address@hidden,New=[The type of a],Old=[A]}
+component declared in a @nt{variant_part} of an
+unchecked union type shall not @Chg{Version=[3],New=[need finalization.
+In addition to the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}),
+this rule also applies in the private part of an instance of a generic 
address@hidden contract issue}
+For an unchecked union type declared within the body of a generic unit, or
+within the body of any of its descendant library units, no part of the type
+of a component declared in a @nt{variant_part} of the unchecked union type 
shall
+be of a formal private type or formal private extension declared within the
+formal part of the generic unit],Old=[have a controlled, protected, or
+task part]}.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0026-1]}
+  @ChgAdded{Version=[3],Text=[The last part is a classic assume-the-worst
+  rule that avoids dependence on the actuals in a generic body. We did
+  not include this in the definition of @ldquote@;needs address@hidden
+  as it has a bad interaction with the use of that term for the
+  No_Nested_Finalization restriction.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Text=[The completion of an incomplete or private type
+declaration having a @nt{known_discriminant_part} shall not be an unchecked
+union type.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Text=[An unchecked union subtype shall only be passed as
+a generic actual parameter if the corresponding formal type has no known
+discriminants or is an unchecked union type.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This includes formal private types without a
+  @nt{known_discriminant_part}, formal derived types that do not inherit any
+  discriminants (formal derived types do not have 
@nt{known_discriminant_part}s),
+  and formal derived types that are unchecked union types.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Text=[An unchecked union type is eligible for convention
+C.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Text=[All objects of an unchecked union type have the
+same size.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Text=[Discriminants of objects of an unchecked union type
+are of size zero.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Type=[Leading],Keepnext=[T],
+Text=[Any check which would require reading a discriminant
+of an unchecked union object is suppressed (see @RefSecNum{Suppressing 
Checks}).
+These checks include:]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The check performed when addressing a variant
+  component (i.e., a component that was declared in a variant part) of an
+  unchecked union object that the object has this component (see
+  @RefSecNum{Selected Components}).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Any checks associated with a type or subtype
+  conversion of a value of an unchecked union type (see
+  @RefSecNum{Type Conversions}). This includes, for example, the check
+  associated with the implicit subtype conversion of an assignment statement.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The subtype membership check associated with the
+  evaluation of a qualified expression (see @RefSecNum{Qualified Expressions})
+  or an uninitialized allocator (see @RefSecNum{Allocators}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If a suppressed check would have failed,
+  execution is erroneous (see @RefSecNum{Suppressing Checks}). An
+  implementation is always allowed to make a suppressed check if it can
+  somehow determine the discriminant value.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Text=[A view of an unchecked union object (including a
+type conversion or function call) has @i<inferable discriminants> if it has a
+constrained nominal subtype, unless the object is a component of an enclosing
+unchecked union object that is subject to a per-object constraint and the
+enclosing object lacks inferable address@hidden discriminants}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Text=[An expression of an unchecked union type has
+inferable discriminants if it is either a name of an object with inferable
+discriminants or a qualified expression whose @nt{subtype_mark} denotes a
+constrained subtype.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Type=[Leading],Keepnext=[T],
+Text=[Program_Error is raised in the following
+cases:@Defn2{Term=[Program_Error],Sec=(raised by failure of run-time check)}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Evaluation of the predefined equality operator
+  for an unchecked union type if either of the operands lacks inferable
+  discriminants.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Evaluation of the predefined equality operator
+  for a type which has a subcomponent of an unchecked union type whose nominal
+  subtype is unconstrained.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Evaluation of a membership test if the
+  @nt{subtype_mark} denotes a constrained unchecked union subtype and the
+  expression lacks inferable discriminants.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Conversion from a derived unchecked union type to
+  an unconstrained non-unchecked-union type if the operand of the conversion
+  lacks inferable discriminants.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Execution of the default implementation of the
+  Write or Read attribute of an unchecked union type.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Execution of the default implementation of the
+  Output or Input attribute of an unchecked union type if the type lacks 
default
+  discriminant values.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[],Old=[An implementation may
+require that @nt{pragma} Controlled be specified for the type of an access
+subcomponent of an unchecked union type.]}]}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraph 29 was
+deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered.}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00216-01]}
address@hidden,Type=[Leading],Keepnext=[T],
+Text=[The use of an unchecked union to obtain the effect of an
+unchecked conversion results in erroneous execution (see 
@RefSecNum{Suppressing Checks}).
+Execution of the following example is erroneous even if
+Float'Size = Integer'Size:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,address@hidden<type> T (Flag : Boolean := False) @key<is>
+   @key<record>
+       @key<case> Flag @key<is>
+           @key<when> False =>
+               F1 : Float := 0.0;
+           @key<when> True =>
+               F2 : Integer := 0;
+       @key<end case>;
+    @key<end record>@Chg{Version=[3],New=[
+    @key[with] Unchecked_Union],Old=[;
address@hidden<pragma> Unchecked_Union (T)]};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[X : T;
+Y : Integer := X.F2; -- @RI[erroneous]]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00216-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @nt{Pragma} Unchecked_Union is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0026-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  The use of discriminants on Unchecked_Union types is now illegal in
+  @nt{record_representation_clause}s, as it makes no sense to
+  specify a position for something that is not supposed to exist. It
+  is very unlikely that this change will have any impact on existing code.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Aspect Unchecked_Union is new; @nt{pragma} Unchecked_Union is
+  now obsolescent.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0026-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Revised the rules
+  to use the @ldquote@;needs address@hidden definition,
+  and eliminated generic contract issues.]}
address@hidden
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden with COBOL}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden to COBOL}
address@hidden interface}
+The facilities relevant to interfacing with
+the COBOL language
+ are the package
+Interfaces.COBOL
+and support for
address@hidden,New=[specifying ],Old=[]}the
address@hidden,New=[],Old=[Import, Export and ]}Convention
address@hidden,New=[aspect],Old=[pragmas]} with
address@hidden@nt{identifier} COBOL.
+
address@hidden@;The COBOL interface package supplies several sets of facilities:
address@hidden
+A set of types corresponding to the native
+COBOL types of the supported COBOL implementation
+(so-called @lquotes@;internal COBOL address@hidden@;),
+allowing Ada data to be passed as parameters to COBOL programs
+
+A set of types and constants reflecting external data representations
+such as might be found in files or databases, allowing COBOL-generated
+data to be read by an Ada program, and Ada-generated data to be read
+by COBOL programs
+
+A generic package for converting between an Ada decimal type value and
+either an internal or external COBOL representation
address@hidden
address@hidden
+
address@hidden
address@hidden@Keepnext@;The library package Interfaces.COBOL has the following 
declaration:
address@hidden
address@hidden(package) Interfaces.COBOL 
@key(is)@ChildUnit{Parent=[Interfaces],Child=[COBOL]}
+   @key[pragma] Preelaborate(COBOL);
+
address@hidden Types and operations for internal data representations}
+
+   @key(type) @AdaTypeDefn{Floating}      @key(is) @key(digits) 
@RI{implementation-defined};
+   @key(type) @AdaTypeDefn{Long_Floating} @key(is) @key(digits) 
@RI{implementation-defined};
+
+   @key(type) @AdaTypeDefn{Binary}      @key(is) @key(range) 
@RI{implementation-defined};
+   @key(type) @AdaTypeDefn{Long_Binary} @key(is) @key(range) 
@RI{implementation-defined};
+
+   @AdaObjDefn{Max_Digits_Binary}      : @key(constant) := 
@RI{implementation-defined};
+   @AdaObjDefn{Max_Digits_Long_Binary} : @key(constant) := 
@RI{implementation-defined};
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key(type) @AdaTypeDefn{Decimal_Element}  @key(is) @key(mod) 
@RI{implementation-defined};
+   @key(type) @AdaTypeDefn{Packed_Decimal} @key(is) @key(array) (Positive 
@key(range) <>) @key(of) address@hidden,New=[
+      @key[with] Pack],Old=[;
+   @key(pragma) Pack(Packed_Decimal)]};
+
+
+   @key(type) @AdaTypeDefn{COBOL_Character} @key(is) 
@RI{implementation-defined character type};
+
+   @AdaObjDefn{Ada_To_COBOL} : @key(array) (Character) @key(of) 
COBOL_Character := @RI{implementation-defined};
+
+   @AdaObjDefn{COBOL_To_Ada} : @key(array) (COBOL_Character) @key(of) 
Character := @RI{implementation-defined};
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key(type) @AdaTypeDefn{Alphanumeric} @key(is) @key(array) (Positive range 
<>) @key(of) address@hidden,New=[
+      @key[with] Pack],Old=[;
+   @key(pragma) Pack(Alphanumeric)]};
+
+   @key(function) @AdaSubDefn{To_COBOL} (Item : @key(in) String) @key(return) 
Alphanumeric;
+   @key(function) @AdaSubDefn{To_Ada}   (Item : @key(in) Alphanumeric) 
@key(return) String;
+
+   @key(procedure) @AdaSubDefn{To_COBOL} (Item       : @key(in) String;
+                       Target     : @key(out) Alphanumeric;
+                       Last       : @key(out) Natural);
+
+   @key(procedure) @AdaSubDefn{To_Ada} (Item     : @key(in) Alphanumeric;
+                     Target   : @key(out) String;
+                     Last     : @key(out) Natural);
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key(type) @AdaTypeDefn{Numeric} @key(is) @key(array) (Positive @key[range] 
<>) @key(of) address@hidden,New=[
+      @key[with] Pack],Old=[;
+   @key(pragma) Pack(Numeric)]};
+
address@hidden Formats for COBOL data representations}
+
+   @key(type) @AdaTypeDefn{Display_Format} @key(is) @key(private);
+
+   @AdaObjDefn{Unsigned}             : @key(constant) Display_Format;
+   @AdaObjDefn{Leading_Separate}     : @key(constant) Display_Format;
+   @AdaObjDefn{Trailing_Separate}    : @key(constant) Display_Format;
+   @AdaObjDefn{Leading_Nonseparate}  : @key(constant) Display_Format;
+   @AdaObjDefn{Trailing_Nonseparate} : @key(constant) Display_Format;
+
+   @key(type) @AdaTypeDefn{Binary_Format} @key(is) @key(private);
+
+   @AdaObjDefn{High_Order_First}  : @key(constant) Binary_Format;
+   @AdaObjDefn{Low_Order_First}   : @key(constant) Binary_Format;
+   @AdaObjDefn{Native_Binary}     : @key(constant) Binary_Format;
+
+   @key(type) @AdaTypeDefn{Packed_Format} @key(is) @key(private);
+
+   @AdaObjDefn{Packed_Unsigned}   : @key(constant) Packed_Format;
+   @AdaObjDefn{Packed_Signed}     : @key(constant) Packed_Format;
+
+
address@hidden Types for external representation of COBOL binary data}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key(type) @AdaTypeDefn{Byte} @key(is) @key(mod) 2**COBOL_Character'Size;
+   @key(type) @AdaTypeDefn{Byte_Array} @key(is) @key(array) (Positive 
@key(range) <>) @key(of) address@hidden,New=[
+      @key[with] Pack],Old=[;
+   @key(pragma) Pack (Byte_Array)]};
+
+   @AdaExcDefn{Conversion_Error} : @key(exception);
+
+   @key(generic)
+      @key(type) Num @key(is) @key(delta) <> @key(digits) <>;
+   @key(package) @AdaPackDefn{Decimal_Conversions} @key(is)
+
+      @RI{-- Display Formats: data values are represented as Numeric}
+
+      @key(function) @AdaSubDefn{Valid} (Item   : @key(in) Numeric;
+                      Format : @key(in) Display_Format) @key(return) Boolean;
+
+      @key(function) @AdaSubDefn{Length} (Format : @key(in) Display_Format) 
@key(return) Natural;
+
+
+      @key(function) @AdaSubDefn{To_Decimal} (Item   : @key(in) Numeric;
+                           Format : @key(in) Display_Format) @key(return) Num;
+
+      @key(function) @AdaSubDefn{To_Display} (Item   : @key(in) Num;
+                           Format : @key(in) Display_Format) @key(return) 
Numeric;
+
+
+      @RI{-- Packed Formats: data values are represented as Packed_Decimal}
+
+      @key(function) @AdaSubDefn{Valid} (Item   : @key(in) Packed_Decimal;
+                      Format : @key(in) Packed_Format) @key(return) Boolean;
+
+      @key(function) @AdaSubDefn{Length} (Format : @key(in) Packed_Format) 
@key(return) Natural;
+
+      @key(function) @AdaSubDefn{To_Decimal} (Item   : @key(in) Packed_Decimal;
+                           Format : @key(in) Packed_Format) @key(return) Num;
+
+      @key(function) @AdaSubDefn{To_Packed} (Item   : @key(in) Num;
+                          Format : @key(in) Packed_Format) @key(return) 
Packed_Decimal;
+
+
+      @RI{-- Binary Formats: external data values are represented as 
Byte_Array}
+
+      @key(function) @AdaSubDefn{Valid} (Item   : @key(in) Byte_Array;
+                      Format : @key(in) Binary_Format) @key(return) Boolean;
+
+      @key(function) @AdaSubDefn{Length} (Format : @key(in) Binary_Format) 
@key(return) Natural;
+      @key(function) @AdaSubDefn{To_Decimal} (Item   : @key(in) Byte_Array;
+                           Format : @key(in) Binary_Format) @key(return) Num;
+
+      @key(function) @AdaSubDefn{To_Binary} (Item   : @key(in) Num;
+                        Format : @key(in) Binary_Format) @key(return) 
Byte_Array;
+
+      @RI{-- Internal Binary formats: data values are of type Binary or 
Long_Binary}
+
+      @key(function) @AdaSubDefn{To_Decimal} (Item : @key(in) Binary)      
@key(return) Num;
+      @key(function) @AdaSubDefn{To_Decimal} (Item : @key(in) Long_Binary) 
@key(return) Num;
+
+      @key(function) @AdaSubDefn{To_Binary}      (Item : @key(in) Num)  
@key(return) Binary;
+      @key(function) @AdaSubDefn{To_Long_Binary} (Item : @key(in) Num)  
@key(return) Long_Binary;
+
+   @key(end) Decimal_Conversions;
+
address@hidden(private)
+   ... -- @RI{not specified by the language}
address@hidden(end) Interfaces.COBOL;
address@hidden
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[The types Floating, Long_Floating, Binary, Long_Binary,
+Decimal_Element, and COBOL_Character; and the initializations
+of the variables Ada_To_COBOL and COBOL_To_Ada, in address@hidden,Old=[]}]}
+
+Each of the types in Interfaces.COBOL is COBOL-compatible.
+
+The types Floating and Long_Floating correspond to the
+native types in COBOL for data items with computational usage
+implemented by floating point.
+The types Binary and Long_Binary correspond to the
+native types in COBOL for data items with binary usage,
+or with computational usage implemented by binary.
+
+Max_Digits_Binary is the largest number of decimal digits in a
+numeric value that is represented as Binary.
+Max_Digits_Long_Binary is the largest number of decimal digits in a
+numeric value that is represented as Long_Binary.
+
+The type Packed_Decimal corresponds to COBOL's packed-decimal
+usage.
+
+The type COBOL_Character defines the run-time character set used in the
+COBOL implementation.
+Ada_To_COBOL and COBOL_To_Ada are the mappings between the Ada and
+COBOL run-time character sets.
address@hidden
+The character mappings are visible variables, since the
+ user needs the ability to modify them at run time.
address@hidden
+
+Type Alphanumeric corresponds to COBOL's alphanumeric data category.
+
+Each of the functions To_COBOL and To_Ada converts its parameter
+based on the mappings Ada_To_COBOL and COBOL_To_Ada, respectively.
+The length of the result for each is the length of the parameter,
+and the lower bound of the result is 1. Each component of the result
+is obtained by applying the relevant mapping to the corresponding
+component of the parameter.
+
+Each of the procedures To_COBOL and To_Ada copies converted elements
+from Item to Target, using the appropriate mapping (Ada_To_COBOL or
+COBOL_To_Ada, respectively). The index in Target of the last element
+assigned is returned in Last (0 if Item is a null array).
address@hidden,Sec=(raised by failure of run-time check)}
+If Item'Length exceeds Target'Length, Constraint_Error is propagated.
+
+Type Numeric corresponds to COBOL's numeric data category with
+display usage.
+
address@hidden@;The types Display_Format, Binary_Format, and Packed_Format
+are used in conversions between Ada decimal type values and
+COBOL internal or external data representations. The value of the
+constant Native_Binary is either High_Order_First or Low_Order_First,
+depending on the implementation.
address@hidden
address@hidden@Keepnext
address@hidden(function) Valid (Item   : @key(in) Numeric;
+                Format : @key(in) Display_Format) @key(return) Boolean;
address@hidden
address@hidden@;The function Valid checks that the
+Item parameter has a value consistent with the value of Format.
+If the value of Format is other than
+Unsigned, Leading_Separate, and Trailing_Separate,
+the effect is implementation defined. If Format does have one
+of these values, the following rules apply:
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0066],ARef=[AI95-00071-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
+Format=Unsigned: if Item comprises @Chg{New=[],Old=[zero or more leading
+space characters followed by ]}one or more decimal digit
address@hidden,New=[,],Old=[]} then
+Valid returns True, else it returns False.
+
address@hidden,Kind=[Revised],Ref=[8652/0066],ARef=[AI95-00071-01]}
+Format=Leading_Separate: if Item comprises
address@hidden,Old=[zero or more leading space characters, followed by ]}a
+single occurrence of the plus or minus sign character, and then one or more
+decimal digit characters, then Valid returns True, else it returns False.
+
address@hidden,Kind=[Revised],Ref=[8652/0066],ARef=[AI95-00071-01]}
address@hidden@;Format=Trailing_Separate: if Item comprises
address@hidden,Old=[zero or more leading space characters, followed by ]}one or
+more decimal digit characters and finally a plus or minus sign character,
+then Valid returns True, else it returns False.
address@hidden
+
address@hidden@Keepnext
address@hidden(function) Length (Format : @key(in) Display_Format) @key(return) 
Natural;
address@hidden
address@hidden@;The Length function returns the minimal length of a Numeric 
value
+sufficient to hold any value of type Num when represented as Format.
+
address@hidden@Keepnext
address@hidden(function) To_Decimal (Item   : @key(in) Numeric;
+                     Format : @key(in) Display_Format) @key(return) Num;
address@hidden
address@hidden@;Produces a value of type Num corresponding to Item as 
represented by
+Format.
+The number of digits after the assumed
+radix point in Item is Num'Scale.
+ Conversion_Error is propagated if the value
+represented by Item is outside the range of Num.
address@hidden
+There is no issue of truncation versus rounding, since
+the number of decimal places is established by Num'address@hidden
+
address@hidden@Keepnext
address@hidden(function) To_Display (Item   : @key(in) Num;
+                     Format : @key(in) Display_Format) @key(return) Numeric;
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0067],ARef=[AI95-00072-01]}
address@hidden@;This function returns the Numeric value for Item, represented in
+accordance with Format.
address@hidden length of the returned value is Length(Format), and the
+lower bound is 1. ],Old=[]}Conversion_Error is propagated if Num is negative
+and Format is Unsigned.
+
address@hidden@Keepnext
address@hidden(function) Valid (Item   : @key(in) Packed_Decimal;
+                Format : @key(in) Packed_Format) @key(return) Boolean;
address@hidden
address@hidden@;This function returns True if Item has a value consistent with 
Format,
+and False otherwise. The rules for the formation of Packed_Decimal
+values are implementation defined.
+
address@hidden@Keepnext
address@hidden(function) Length (Format : @key(in) Packed_Format) @key(return) 
Natural;
address@hidden
address@hidden@;This function returns the minimal length of a Packed_Decimal 
value
+sufficient to hold any value of type Num when represented as Format.
+
address@hidden@Keepnext
address@hidden(function) To_Decimal (Item   : @key(in) Packed_Decimal;
+                     Format : @key(in) Packed_Format) @key(return) Num;
address@hidden
address@hidden@;Produces a value of type Num corresponding to Item as 
represented by
+Format. Num'Scale is the number of digits after the assumed radix point
+in Item. Conversion_Error is propagated if the value represented by Item is
+outside the range of Num.
+
address@hidden@Keepnext
address@hidden(function) To_Packed (Item   : @key(in) Num;
+                    Format : @key(in) Packed_Format) @key(return) 
Packed_Decimal;
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0067],ARef=[AI95-00072-01]}
address@hidden@;This function returns the Packed_Decimal value for Item, 
represented in
+accordance with Format.
address@hidden length of the returned value is Length(Format), and the
+lower bound is 1. ],Old=[]}Conversion_Error is propagated if Num is negative
+and Format is Packed_Unsigned.
+
address@hidden@Keepnext
address@hidden(function) Valid (Item   : @key(in) Byte_Array;
+                Format : @key(in) Binary_Format) @key(return) Boolean;
address@hidden
address@hidden@;This function returns True if Item has a value consistent with 
Format,
+and False otherwise.
address@hidden
+This function returns False only when the represented
+value is outside the range of address@hidden
+
address@hidden@Keepnext
address@hidden(function) Length (Format : @key(in) Binary_Format) @key(return) 
Natural;
address@hidden
address@hidden@;This function returns the minimal length of a Byte_Array value
+sufficient to hold any value of type Num when represented as Format.
+
address@hidden@Keepnext
address@hidden(function) To_Decimal (Item   : @key(in) Byte_Array;
+                     Format : @key(in) Binary_Format) @key(return) Num;
address@hidden
address@hidden@;Produces a value of type Num corresponding to Item as 
represented by
+Format. Num'Scale is the number of digits after the assumed radix point
+in Item. Conversion_Error is propagated if the value represented by Item is
+outside the range of Num.
+
address@hidden@Keepnext
address@hidden(function) To_Binary (Item   : @key(in) Num;
+                    Format : @key(in) Binary_Format) @key(return) Byte_Array;
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0067],ARef=[AI95-00072-01]}
address@hidden@;This function returns the Byte_Array value for Item, 
represented in
+accordance with Format.
address@hidden length of the returned value is Length(Format), and the
+lower bound is 1.],Old=[]}
+
address@hidden@Keepnext
address@hidden(function) To_Decimal (Item : @key(in) Binary)      @key(return) 
Num;
address@hidden line}
address@hidden(function) To_Decimal (Item : @key(in) Long_Binary) @key(return) 
Num;
address@hidden
address@hidden@;These functions convert from COBOL binary format to a 
corresponding
+value of the decimal type Num. Conversion_Error is propagated if Item is
+too large for Num.
address@hidden
+There is no rescaling performed on the conversion. That
+is, the returned value in each case is a @lquotes@;bit address@hidden@; if Num 
has a
+binary radix. The programmer is responsible for maintaining the correct
+scale.
address@hidden
+
address@hidden@Keepnext
address@hidden(function) To_Binary      (Item : @key(in) Num)  @key(return) 
Binary;
address@hidden line}
address@hidden(function) To_Long_Binary (Item : @key(in) Num)  @key(return) 
Long_Binary;
address@hidden
+
+These functions convert from Ada decimal to COBOL binary format.
+Conversion_Error is propagated if the value of Item is too large to be
+represented in the result type.
address@hidden
+One style of interface supported for COBOL, similar to
+what is provided for C, is the ability to call and pass parameters to an
+existing COBOL program. Thus the interface package supplies types
+that can be used in an Ada program as parameters to subprograms whose
+bodies will be in COBOL. These types map to COBOL's alphanumeric and
+numeric data categories.
+
+Several types are provided for support of alphanumeric data.
+Since COBOL's run-time character
+set is not necessarily the same as Ada's, Interfaces.COBOL declares
+an implementation-defined character type
+COBOL_Character, and mappings
+between Character and COBOL_Character.
+These mappings are visible variables (rather than, say,
+functions or constant arrays),
+since in the situation where
+COBOL_Character is EBCDIC, the
+flexibility of dynamically modifying the mappings is needed.
+Corresponding to COBOL's alphanumeric data is the string
+ type Alphanumeric.
+
+Numeric data may have either a @lquotes@;address@hidden@; or 
@lquotes@;address@hidden@; representation
+in COBOL. On the Ada side, the data is of a decimal fixed point type.
+Passing an Ada decimal data item to
+a COBOL program requires conversion from the Ada decimal type to some type
+that reflects the representation expected on the COBOL side.
address@hidden
+Computational Representation
+
address@hidden@;Floating point representation is modeled by Ada floating point 
types,
+Floating and Long_Floating. Conversion between these types and Ada decimal
+types is obtained directly, since the type name serves as a conversion
+function.
+
address@hidden@;Binary representation is modeled by an Ada integer type, 
Binary, and
+possibly other types such as Long_Binary. Conversion between, say, Binary
+and a decimal type is through functions from an instantiation of the
+generic package Decimal_Conversions.
+
address@hidden@;Packed decimal representation is modeled by the Ada array type 
Packed_Decimal.
+Conversion between packed decimal and a decimal type is through functions
+from an instantiation of the generic package Decimal_Conversions.
+
+Display Representation
+
address@hidden@;Display representation for numeric data
+is modeled by the array type Numeric.
+Conversion between display representation and a decimal type is through
+functions from an instantiation of the generic package Decimal_Conversions.
+A parameter to the conversion function indicates the desired interpretation
+of the data (e.g., signed leading separate, etc.)
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[The],Old=[Pragma]}
address@hidden,New=[ of],Old=[(COBOL, T) may be
+applied to]} a record type @Chg{Version=[3],New=[may be specified as
+COBOL],Old=[T]} to direct the compiler to choose a COBOL-compatible
+representation for objects of the type.
+
+The package Interfaces.COBOL allows the
+Ada programmer to deal with data from files (or databases) created by a
+COBOL program. For data that is alphanumeric, or in display
+or packed decimal format, the
+approach is the same as for passing parameters (instantiate
+Decimal_Conversions to obtain the needed conversion functions). For binary
+data, the external representation is treated as a Byte array, and an
+instantiation of Decimal_IO produces a package that declares the needed
+conversion functions. A parameter to the conversion function indicates the
+desired interpretation of the data (e.g., high- versus low-order byte
+first).
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+An implementation shall support
address@hidden,New=[specifying aspect],Old=[pragma]} Convention with
+a COBOL @address@hidden for a COBOL-eligible type
+(see @RefSecNum(Interfacing Aspects)).
address@hidden
+An implementation supporting this package shall ensure that if the bounds of
+a Packed_Decimal, Alphanumeric, or Numeric variable are static,
+then the representation of the
+object comprises solely the array components (that is, there is no implicit
+run-time @lquotes@;address@hidden@;
+that is part of the object).
address@hidden
address@hidden
+
address@hidden
+An implementation may
+ provide additional constants of the private types
+Display_Format, Binary_Format, or Packed_Format.
address@hidden
+This is to allow exploitation of other external formats that may
+be available in the COBOL address@hidden
+
+An implementation may
+ provide further floating point and integer types
+in Interfaces.COBOL to match additional native COBOL types,
+and may also supply corresponding conversion functions in the
+generic package Decimal_Conversions.
address@hidden
+
address@hidden
+An Ada implementation should support the following interface
+correspondences between Ada and COBOL.
address@hidden
+An Ada @key[access] T parameter
+is passed as a
address@hidden@;BY address@hidden@; data item of the COBOL type corresponding
+to T.
+
+An Ada @key[in] scalar parameter is passed as a @lquotes@;BY address@hidden@; 
data item
+of the corresponding COBOL type.
+
+Any other Ada parameter is passed as a
address@hidden@;BY address@hidden@; 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.
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If COBOL interfacing is supported, the interface correspondences between
+Ada and COBOL should be supported.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+An implementation is not required to support
address@hidden,New=[specifying aspect],Old=[pragma]} Convention
+for access types, nor is it required to support
address@hidden,New=[specifying aspects],Old=[pragma]} Import,
address@hidden,New=[,],Old=[]} or Convention for functions.
address@hidden
+COBOL does not have a pointer facility, and a COBOL program
+does not return a address@hidden
+
+If an Ada subprogram is exported to COBOL, then a call from COBOL
+call may specify
+either @lquotes@;BY address@hidden@; or @lquotes@;BY address@hidden@;.
address@hidden
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden
address@hidden@address@hidden of Interfaces.COBOL:}
address@hidden
address@hidden(with) Interfaces.COBOL;
address@hidden(procedure) Test_Call @key(is)
+
+   @RI{-- Calling a foreign COBOL program}
+   @RI{-- Assume that a COBOL program PROG has the following declaration}
+   @RI{--  in its LINKAGE section:}
+   @RI{--  01 Parameter-Area}
+   @RI{--     05 NAME   PIC X(20).}
+   @RI{--     05 SSN    PIC X(9).}
+   @RI{--     05 SALARY PIC 99999V99 USAGE COMP.}
+   @RI{-- The effect of PROG is to update SALARY based on some algorithm}
+
+   @key(package) COBOL @key(renames) Interfaces.COBOL;
+
+   @key(type) Salary_Type @key(is) @key(delta) 0.01 @key(digits) 7;
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key(type) COBOL_Record @key(is)
+      @key(record)
+         Name   : COBOL.Numeric(1..20);
+         SSN    : COBOL.Numeric(1..9);
+         Salary : COBOL.Binary;  @RI{-- Assume Binary = 32 bits}
+      @key(end) @key(record)@Chg{Version=[3],New=[
+      @key[with] Convention => COBOL],Old=[;
+   @key(pragma) Convention (COBOL, COBOL_Record)]};
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key(procedure) Prog (Item : @key(in) @key(out) 
COBOL_Record)@Chg{Version=[3],New=[
+      @key[with] Import => True, Convention => COBOL],Old=[;
+   @key(pragma) Import (COBOL, Prog, "PROG")]};
+
+   @key(package) Salary_Conversions @key(is)
+      @key(new) COBOL.Decimal_Conversions(Salary_Type);
+
+   Some_Salary : Salary_Type := 12_345.67;
+   Some_Record : COBOL_Record :=
+      (Name   => "Johnson, John       ",
+       SSN    => "111223333",
+       Salary => Salary_Conversions.To_Binary(Some_Salary));
+
address@hidden(begin)
+   Prog (Some_Record);
+   ...
address@hidden(end) Test_Call;
address@hidden
+
address@hidden
address@hidden(with) Interfaces.COBOL;
address@hidden(with) COBOL_Sequential_IO; @RI{-- Assumed to be supplied by 
implementation}
address@hidden(procedure) Test_External_Formats @key(is)
+
+   @RI{-- Using data created by a COBOL program}
+   @RI{-- Assume that a COBOL program has created a sequential file with}
+   @RI{--  the following record structure, and that we need to}
+   @RI{--  process the records in an Ada program}
+   @RI{--  01 EMPLOYEE-RECORD}
+   @RI{--     05 NAME    PIC X(20).}
+   @RI{--     05 SSN     PIC X(9).}
+   @RI{--     05 SALARY  PIC 99999V99 USAGE COMP.}
+   @RI{--     05 ADJUST  PIC S999V999 SIGN LEADING SEPARATE.}
+   @RI{-- The COMP data is binary (32 bits), high-order byte first}
+
+   @key(package) COBOL @key(renames) Interfaces.COBOL;
+
+   @key(type) Salary_Type      @key(is) @key(delta) 0.01  @key(digits) 7;
+   @key(type) Adjustments_Type @key(is) @key(delta) 0.001 @key(digits) 6;
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key(type) COBOL_Employee_Record_Type @key(is)  @RI{-- External 
representation}
+      @key(record)
+         Name    : COBOL.Alphanumeric(1..20);
+         SSN     : COBOL.Alphanumeric(1..9);
+         Salary  : COBOL.Byte_Array(1..4);
+         Adjust  : COBOL.Numeric(1..7);  @RI{-- Sign and 6 digits}
+      @key(end) @key(record)@Chg{Version=[3],New=[
+      @key[with] Convention => COBOL],Old=[;
+   @key(pragma) Convention (COBOL, COBOL_Employee_Record_Type)]};
+
+   @key(package) COBOL_Employee_IO @key(is)
+      @key(new) COBOL_Sequential_IO(COBOL_Employee_Record_Type);
+   @key(use) COBOL_Employee_IO;
+
+   COBOL_File : File_Type;
+
+   @key(type) Ada_Employee_Record_Type @key(is)  @RI{-- Internal 
representation}
+      @key(record)
+         Name    : String(1..20);
+         SSN     : String(1..9);
+         Salary  : Salary_Type;
+         Adjust  : Adjustments_Type;
+      @key(end) @key(record);
+
+   COBOL_Record : COBOL_Employee_Record_Type;
+   Ada_Record   : Ada_Employee_Record_Type;
+
+   @key(package) Salary_Conversions @key(is)
+      @key(new) COBOL.Decimal_Conversions(Salary_Type);
+   @key(use) Salary_Conversions;
+
+   @key(package) Adjustments_Conversions @key(is)
+      @key(new) COBOL.Decimal_Conversions(Adjustments_Type);
+   @key(use) Adjustments_Conversions;
+
address@hidden(begin)
+   Open (COBOL_File, Name => "Some_File");
+
+   @key(loop)
+     Read (COBOL_File, COBOL_Record);
+
+     Ada_Record.Name := To_Ada(COBOL_Record.Name);
+     Ada_Record.SSN  := To_Ada(COBOL_Record.SSN);
+     Ada_Record.Salary :=
+        To_Decimal(COBOL_Record.Salary, COBOL.High_Order_First);
+     Ada_Record.Adjust :=
+        To_Decimal(COBOL_Record.Adjust, COBOL.Leading_Separate);
+     ... @RI{-- Process Ada_Record}
+   @key(end) @key(loop);
address@hidden(exception)
+   @key[when] End_Error => ...
address@hidden(end) Test_External_Formats;
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0066],ARef=[AI95-00071-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the definition 
of
+  Valid to match COBOL.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0067],ARef=[AI95-00072-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Specified the bounds of 
the
+  results of To_Display, To_Packed, and To_Binary.]}
address@hidden
+
address@hidden with Fortran}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden to Fortran}
address@hidden interface}
+The facilities relevant to interfacing with the Fortran language
+are the package Interfaces.Fortran and support for
address@hidden,New=[specifying ],Old=[]}the
address@hidden,New=[],Old=[Import, Export and ]}Convention
address@hidden,New=[aspect],Old=[pragmas]} with
address@hidden@nt{identifier} Fortran.
+
+The package Interfaces.Fortran defines Ada types whose representations are
+identical to the default representations of the Fortran intrinsic types
+Integer, Real, Double Precision, Complex, Logical, and Character in a
+supported Fortran implementation. These Ada types can therefore be used to
+pass objects between Ada and Fortran programs.
address@hidden
+
address@hidden
address@hidden@Keepnext@;The library package Interfaces.Fortran has the 
following
+declaration:
address@hidden
address@hidden Ada.Numerics.Generic_Complex_Types;  @RI{-- see 
@RefSecNum{Complex Types}}
address@hidden Elaborate_All(Ada.Numerics.Generic_Complex_Types);
address@hidden Interfaces.Fortran @address@hidden,Child=[Fortran]}
+   @key[pragma] Pure(Fortran);
+
+   @key[type] @AdaTypeDefn{Fortran_Integer} @key[is] @key[range] 
@RI{implementation-defined};
+
+   @key[type] @AdaTypeDefn{Real}             @key[is] @key[digits] 
@RI{implementation-defined};
+   @key[type] @AdaTypeDefn{Double_Precision} @key[is] @key[digits] 
@RI{implementation-defined};
+
+   @key[type] @AdaTypeDefn{Logical} @key[is] @key[new] Boolean;
+
+   @key[package] @AdaPackDefn{Single_Precision_Complex_Types} @key[is]
+      @key[new] Ada.Numerics.Generic_Complex_Types (Real);
+
+   @key[type] @AdaTypeDefn{Complex} @key[is] @key[new] 
Single_Precision_Complex_Types.Complex;
+
+   @key[subtype] @AdaSubtypeDefn{Name=[Imaginary],Of=[Imaginary]} @key[is] 
Single_Precision_Complex_Types.Imaginary;
+   @AdaObjDefn{i} : Imaginary @key[renames] Single_Precision_Complex_Types.i;
+   @AdaObjDefn{j} : Imaginary @key[renames] Single_Precision_Complex_Types.j;
+
+   @key[type] @AdaTypeDefn{Character_Set} @key[is] @RI{implementation-defined 
character type};
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key[type] @AdaTypeDefn{Fortran_Character} @key[is] @key[array] (Positive 
@key[range] <>) @key[of] address@hidden,New=[
+      @key[with] Pack],Old=[;
+   @key[pragma] Pack (Fortran_Character)]};
+
+   @key[function] @AdaSubDefn{To_Fortran} (Item : @key[in] Character) 
@key[return] Character_Set;
+   @key[function] @AdaSubDefn{To_Ada} (Item : @key[in] Character_Set) 
@key[return] Character;
+
+   @key(function) @AdaSubDefn{To_Fortran} (Item : @key(in) String) 
@key(return) Fortran_Character;
+   @key(function) @AdaSubDefn{To_Ada}     (Item : @key(in) Fortran_Character) 
@key(return) String;
+
+   @key(procedure) @AdaSubDefn{To_Fortran} (Item       : @key(in) String;
+                         Target     : @key(out) Fortran_Character;
+                         Last       : @key(out) Natural);
+
+   @key(procedure) @AdaSubDefn{To_Ada} (Item     : @key(in) Fortran_Character;
+                     Target   : @key(out) String;
+                     Last     : @key(out) Natural);
+
address@hidden Interfaces.Fortran;
address@hidden
address@hidden,Kind=[Added],address@hidden types Fortran_Integer,
+Real, Double_Precision, and Character_Set in Interfaces.Fortran.],Old=[]}]}
address@hidden
+   The means by which the Complex type is provided in Interfaces.Fortran
+   creates a dependence of Interfaces.Fortran on Numerics.Generic_Complex_Types
+   (see @RefSecNum{Complex Types}).
+   This dependence is intentional and unavoidable,
+   if the Fortran-compatible Complex type is to be useful in Ada code
+   without duplicating facilities defined elsewhere.
address@hidden
+
+The types Fortran_Integer, Real, Double_Precision, Logical,
+Complex, and Fortran_Character are Fortran-compatible.
+
+The To_Fortran and To_Ada functions map between the
+Ada type Character and the Fortran type Character_Set,
+and also between the Ada type String and the Fortran type
+Fortran_Character.
+ The To_Fortran and To_Ada procedures
+ have analogous effects to the string conversion subprograms
+found in Interfaces.COBOL.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+An implementation shall support @Chg{Version=[3],New=[specifying 
aspect],address@hidden
+Convention with a Fortran @address@hidden for a Fortran-eligible
+type (see @RefSecNum(Interfacing Aspects)).
address@hidden
+
address@hidden
+An implementation may add additional declarations to the Fortran interface
+packages. For example, the Fortran interface package for an implementation of
+Fortran 77 (ANSI X3.9-1978) that defines types like address@hidden, 
address@hidden,
address@hidden, and address@hidden may contain the declarations of types named
address@hidden@i{n}, address@hidden@i{n}, address@hidden@i{n}, and
address@hidden@i{n}. (This convention should not apply to address@hidden, for
+which the Ada analog is the constrained array subtype Fortran_Character
+(address@hidden).) Similarly, the Fortran interface package for an 
implementation of
+Fortran 90 that provides multiple @i{kinds} of intrinsic types, e.g. Integer
+(address@hidden), Real (address@hidden), Logical (address@hidden), Complex 
(address@hidden),
+and Character (address@hidden), may contain the declarations of types
+with the recommended names
address@hidden, address@hidden, address@hidden, address@hidden,
+and address@hidden
address@hidden
+Implementations may add auxiliary declarations as needed to assist in the
+declarations of additional Fortran-compatible types. For example, if a double
+precision complex type is defined, then address@hidden@address@hidden may be
+instantiated for the double precision type. Similarly, if a wide character
+type is defined to match a Fortran 90 wide character type (accessible in
+Fortran 90 with the Kind modifier), then an auxiliary character set may be
+declared to serve as its component type.
address@hidden
address@hidden
+
address@hidden
address@hidden@;An Ada implementation should support the following interface
+correspondences between Ada and Fortran:
address@hidden
+An Ada procedure corresponds to
+a Fortran subroutine.
+
+An Ada function corresponds to a Fortran function.
+
+An Ada parameter of an elementary, array, or
+record type T is passed as a address@hidden(F) argument to a Fortran procedure,
+where address@hidden(F) 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.
+
+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.
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If Fortran interfacing is supported, the interface correspondences
+between Ada and Fortran should be supported.]}]}
address@hidden
+
address@hidden
+An object of a Fortran-compatible record type,
+declared in a library package or subprogram,
+can correspond to a Fortran common
+block; the type also corresponds to
+a Fortran @lquotes@;derived address@hidden@;.
address@hidden
address@hidden
address@hidden@address@hidden of Interfaces.Fortran:}
address@hidden
address@hidden Interfaces.Fortran;
address@hidden Interfaces.Fortran;
address@hidden Ada_Application @key[is]
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key[type] Fortran_Matrix @key[is] @key[array] (Integer @key[range] <>,
+                                 Integer @key[range] <>) @key[of] 
address@hidden,New=[
+      @key[with] Convention => Fortran;              ],Old=[;
+   @key[pragma] Convention (Fortran, Fortran_Matrix);]}    @RI{-- stored in 
Fortran's}
+                                                   @RI{-- column-major order}
+   @key[procedure] Invert (Rank : @key[in] Fortran_Integer; X : @key[in] 
@key[out] Fortran_Matrix)@Chg{Version=[3],New=[
+      @key[with] Import => True, Convention => Fortran;],Old=[;
+   @key[pragma] Import (Fortran, Invert);              ]} @RI{-- a Fortran 
subroutine}
+
+   Rank      : @key[constant] Fortran_Integer := 100;
+   My_Matrix : Fortran_Matrix (1 .. Rank, 1 .. Rank);
+
+
address@hidden
+
+   ...
+   My_Matrix := ...;
+   ...
+   Invert (Rank, My_Matrix);
+   ...
+
address@hidden Ada_Application;
address@hidden
address@hidden
\ No newline at end of file
diff --git a/packages/ada-ref-man/source_2012/iso-rm.msm 
b/packages/ada-ref-man/source_2012/iso-rm.msm
new file mode 100755
index 0000000..9a79aa1
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/iso-rm.msm
@@ -0,0 +1,107 @@
address@hidden file for the RM (ISO version)}
+
address@hidden properties}
address@hidden
address@hidden
address@hidden
address@hidden are not numbered here}
address@hidden,Text=[ISO/IEC 8652:1995(E)]}
address@hidden,Text=[ISO/IEC 8652:1995(E) with COR.1:2001]}
address@hidden,Text=[ISO/IEC 8652:2007(E) Ed. 3]}
address@hidden,Text=[ISO/IEC 8652:2012(E)]}
address@hidden@Title{Version=[3],Text=[ISO/IEC 8652:DIS]}}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden@Comment{For Ada 95 and 2005, use "section" instead}
+
address@hidden properties}
address@hidden @Comment{One large file allows Word to make a TOC}
address@hidden,address@hidden prefix for all versions}
address@hidden,Text=[\'a9 ISO/IEC 1995 \endash  All rights reserved]}
address@hidden,Text=[\'a9 ISO/IEC 2001 \endash  All rights reserved]}
address@hidden,Text=[\'a9 ISO/IEC 2007 \endash  All rights reserved]}
address@hidden,Text=[\'a9 ISO/IEC 2012 \endash  All rights reserved]}
address@hidden,UseClauseName=[F],UseISOFormat=[T]}
address@hidden
address@hidden,address@hidden requires the latter}
address@hidden,Text=[Original Text]}
address@hidden,Text=[Technical Corrigendum 1]}
address@hidden,Text=[Amendment 1]}
address@hidden,Text=[Ada 2012]}
+
+
address@hidden properties - generally, no HTML version is made of the ISO 
version,
+         so these settings aren't important}
address@hidden small files are used, thus no @SingleHTMLOutputFile command}
address@hidden,Unicode=[T]}
address@hidden,SrchName=[8652-SRCH.html],IndexName=[],
+   UseButtons=[T],OnTop=[T],OnBottom=[T]}
address@hidden let the program link to the index}
address@hidden
address@hidden<DIV><SPAN Style="font-size:200%; color: rgb(0,0,153)"><B>Ada 
Reference Manual</B></SPAN> &mdash; <A HREF="8652-TTL.html"><B>Legal 
Information</B></A></DIV>}
address@hidden<DIV Style="margin-top:0.0em"><IMG SRC="AE_logo.gif" height=100 
width=113 align=right ALT="Ada-Europe">
+<SPAN Style="vertical-align: middle">Ada 2005 and 2012 Editions sponsored in 
part by <SPAN Style="font-size: 125%"><A 
HREF="http://www.ada-europe.org/";><B>Ada-Europe</B></A></SPAN></SPAN></DIV>}
address@hidden,Background=[#FFFFF0],Link=[#000080],VLink=[#330033],ALink=[#0000FF]}
+
address@hidden files and related items, in collating order}
address@hidden<Title.MSS>,SectionName=<Ttl>,SectionNumber=[0],NewSection=[T]}
address@hidden @Comment{The table of contents goes here in the collating order}
address@hidden<Front_Matter.MSS>,SectionName=<00>,SectionNumber=[0],NewSection=[T]}
address@hidden<01.MSS>,SectionName=<01>,SectionNumber=[1],NewSection=[T]}
address@hidden<02.MSS>,SectionName=<02>,SectionNumber=[2],NewSection=[T]}
address@hidden<03A.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[T]}
address@hidden<03B.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[F]}
address@hidden<03C.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[F]}
address@hidden<04A.MSS>,SectionName=<04>,SectionNumber=[4],NewSection=[T]}
address@hidden<04B.MSS>,SectionName=<04>,SectionNumber=[4],NewSection=[F]}
address@hidden<05.MSS>,SectionName=<05>,SectionNumber=[5],NewSection=[T]}
address@hidden<06.MSS>,SectionName=<06>,SectionNumber=[6],NewSection=[T]}
address@hidden<07.MSS>,SectionName=<07>,SectionNumber=[7],NewSection=[T]}
address@hidden<08.MSS>,SectionName=<08>,SectionNumber=[8],NewSection=[T]}
address@hidden<09.MSS>,SectionName=<09>,SectionNumber=[9],NewSection=[T]}
address@hidden<10.MSS>,SectionName=<10>,SectionNumber=[10],NewSection=[T]}
address@hidden<11.MSS>,SectionName=<11>,SectionNumber=[11],NewSection=[T]}
address@hidden<12.MSS>,SectionName=<12>,SectionNumber=[12],NewSection=[T]}
address@hidden<13A.MSS>,SectionName=<13>,SectionNumber=[13],NewSection=[T]}
address@hidden<13B.MSS>,SectionName=<13>,SectionNumber=[13],NewSection=[F]}
address@hidden, the "Standard Libraries" separator page}
address@hidden<LIBRARY.MSS>,SectionName=<Lib>,SectionNumber=[0],NewSection=[T]}
address@hidden A; all of the files starting with "Pre_" are part of Annex A.}
address@hidden<PRE.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[T]}
address@hidden<PRE_Standard.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Ada.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Chars.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Strings.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Math.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<Real_Attribs.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_IO.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Cmdln.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Dirs.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Environ.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Containers.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Con2.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Locales.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden normative annexes:}
address@hidden<Interface.MSS>,SectionName=<B>,SectionNumber=[B],NewSection=[T]}
address@hidden<SP.MSS>,SectionName=<C>,SectionNumber=[C],NewSection=[T]}
address@hidden<RT.MSS>,SectionName=<D>,SectionNumber=[D],NewSection=[T]}
address@hidden<DS.MSS>,SectionName=<E>,SectionNumber=[E],NewSection=[T]}
address@hidden<InfoSys.MSS>,SectionName=<F>,SectionNumber=[F],NewSection=[T]}
address@hidden<Numerics.MSS>,SectionName=<G>,SectionNumber=[G],NewSection=[T]}
address@hidden<Safety.MSS>,SectionName=<H>,SectionNumber=[H],NewSection=[T]}
address@hidden don't use Annex I, as ISO requires skipping I and O}
address@hidden<Obsolescent.MSS>,SectionName=<J>,SectionNumber=[J],NewSection=[T]}
address@hidden annexes:}
address@hidden<Attribs.MSS>,SectionName=<K>,SectionNumber=[K],NewSection=[T]}
address@hidden<Pragmas.MSS>,SectionName=<L>,SectionNumber=[L],NewSection=[T]}
address@hidden<Impldef.MSS>,SectionName=<M>,SectionNumber=[M],NewSection=[T]}
address@hidden<Glossary.MSS>,SectionName=<N>,SectionNumber=[N],NewSection=[T]}
address@hidden don't use Annex O, as ISO requires skipping I and O}
address@hidden<Syntax.MSS>,SectionName=<P>,SectionNumber=[P],NewSection=[T]}
address@hidden<Langdef.MSS>,SectionName=<Q>,SectionNumber=[Q],NewSection=[T]}
address@hidden<Index.MSS>,SectionName=<IDX>,SectionNumber=[0],NewSection=[T]}
+
diff --git a/packages/ada-ref-man/source_2012/langdef.mss 
b/packages/ada-ref-man/source_2012/langdef.mss
new file mode 100755
index 0000000..6f8cd76
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/langdef.mss
@@ -0,0 +1,81 @@
address@hidden(glossary, Root="ada.mss")
+
address@hidden: 2012/11/28 23:53:06 $}
address@hidden,Name=[Language-Defined Entities]}
+
address@hidden: e:\\cvsroot/ARM/Source/langdef.mss,v $}
address@hidden: 1.8 $}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00440-01]}
address@hidden,Text=[This annex lists the language-defined entities of
+the language. A list of language-defined library units can be found
+in @RefSec{Predefined Language Environment}.]}
address@hidden
+
address@hidden,Name=[Language-Defined Packages]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00440-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+lists all language-defined address@hidden packages}]}
address@hidden
+
address@hidden
+
address@hidden,Name=[Language-Defined Types and Subtypes]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00440-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+lists all language-defined types and
address@hidden address@hidden subtypes}]}
address@hidden
+
address@hidden
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,Name=[Language-Defined Subprograms]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00440-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+lists all language-defined address@hidden subprograms}]}
address@hidden
+
address@hidden
+
address@hidden,Name=[Language-Defined Exceptions]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00440-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+lists all language-defined address@hidden exceptions}]}
address@hidden
+
address@hidden
+
+
address@hidden,Name=[Language-Defined Objects]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00440-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+lists all language-defined constants,
+variables, named numbers, and enumeration address@hidden address@hidden 
address@hidden values}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Formally, named numbers and enumeration literals
+  aren't objects, but it was thought to be too weird to say 
@lquotes@;Language-Defined
+  Objects and address@hidden
address@hidden
address@hidden
+
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/library.mss 
b/packages/ada-ref-man/source_2012/library.mss
new file mode 100755
index 0000000..07e1b43
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/library.mss
@@ -0,0 +1,9 @@
address@hidden(library, Root="ada.mss")
+
address@hidden: 2000/05/27 04:44:03 $}
+
address@hidden: e:\\cvsroot/ARM/Source/library.mss,v $}
address@hidden: 1.2 $}
address@hidden: This is the library separator page. $}
+
address@hidden Standard Libraries}
diff --git a/packages/ada-ref-man/source_2012/numerics.mss 
b/packages/ada-ref-man/source_2012/numerics.mss
new file mode 100755
index 0000000..182d9fb
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/numerics.mss
@@ -0,0 +1,4383 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/numerics.mss,v $ }
address@hidden $Revision: 1.71 $ $Date: 2012/11/28 23:53:05 $ $Author: randy $ }
address@hidden(numerics, Root="ada.mss")
+
address@hidden: 2012/11/28 23:53:05 $}
+
address@hidden
address@hidden
address@hidden
+The Numerics Annex specifies
address@hidden
+   features for complex arithmetic, including complex I/O;
+
+   a mode (@lquotes@;strict address@hidden@;), in which the predefined 
arithmetic operations of
+   floating point and fixed point types and the functions and operations of
+   various predefined packages have to provide guaranteed accuracy or conform
+   to other numeric performance requirements, which the Numerics Annex also
+   specifies;
+
+   a mode (@lquotes@;relaxed address@hidden@;), in which no accuracy or other 
numeric performance
+   requirements need be satisfied, as for implementations not conforming to the
+   Numerics Annex;
+
+   @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00296-01]}
+   models of floating point and fixed point arithmetic on which the accuracy
+   requirements of strict mode are based;@Chg{Version=[2],New=[],Old=[ and]}
+
+   @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00296-01]}
+   the definitions of the model-oriented attributes of floating point types
+   that apply in the strict address@hidden,New=[; and],Old=[.]}
+
+   @ChgRef{Version=[2],Kind=[Added],address@hidden,
+   Text=[features for the manipulation of real and complex vectors and
+   matrices.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+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
address@hidden to Other Languages}
+and should support a @address@hidden of
+Fortran (respectively, C) @Chg{Version=[3],New=[for],Old=[in]}
+the @Chg{Version=[3],New=[Convention aspect],Old=[interfacing pragmas]}
+(see @RefSecNum{Interface to Other Languages}),
+thus allowing Ada programs to interface with programs written in
+that language.
address@hidden,Kind=[Added],address@hidden,
+Text=[If Fortran (respectively, C) is supported in the target environment,
+then interfacing to Fortran (respectively, C) should be supported as
+specified in @RefSecNum{Interface to Other Languages}.]}]}
+
address@hidden
+
address@hidden
address@hidden to Ada 83}
+This Annex is new to Ada 95.
address@hidden
+
address@hidden Arithmetic}
+
address@hidden
+Types and arithmetic operations for complex arithmetic are provided in
+Generic_Complex_Types, which is defined in @RefSecNum{Complex Types}.
+Implementation-defined approximations to the complex analogs of the 
mathematical
+functions known as the @lquotes@;elementary address@hidden@; are provided by
+the subprograms in address@hidden@address@hidden, which is defined in
address@hidden Elementary Functions}. Both of these library units are generic
+children of the predefined package Numerics (see @RefSecNum{The Numerics 
Packages}).
+Nongeneric equivalents of these generic packages for each of the predefined
+floating point types are also provided as children of Numerics.
address@hidden accuracy actually achieved by the complex elementary
+functions and by other complex arithmetic
+operations.}
address@hidden
+   Complex arithmetic is defined in the Numerics Annex, rather than in the
+   core, because it is considered to be a specialized need of (some) numeric
+   applications.
address@hidden
address@hidden
+
address@hidden Types}
+
address@hidden
address@hidden@;The generic library package
+Numerics.Generic_Complex_Types has the following declaration:
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0020],ARef=[AI95-00126-01]}
address@hidden@ChildUnit{Parent=[Ada.Numerics],address@hidden@!Types]}
+   @key{type} Real @key{is} @key{digits} <>;
address@hidden Ada.Numerics.Generic_Complex_Types @key{is}
+   @address@hidden,Old=[pragma]} Pure(Generic_Complex_Types);
+
+   @key{type} @AdaTypeDefn{Complex} @key{is}
+      @key{record}
+         Re, Im : Real'Base;
+      @key{end} @key{record};
+
address@hidden,Kind=[Revised],ARef=[AI95-00161-01]}
+   @key{type} @AdaTypeDefn{Imaginary} @key{is} 
@key{private};@Chg{Version=[2],New=[
+   @key{pragma} Preelaborable_Initialization(Imaginary);],Old=[]}
+
+   @AdaObjDefn{i} : @key{constant} Imaginary;
+   @AdaObjDefn{j} : @key{constant} Imaginary;
+
+
+   @key{function} @AdaSubDefn{Re} (X : Complex)   @key{return} Real'Base;
+   @key{function} @AdaSubDefn{Im} (X : Complex)   @key{return} Real'Base;
+   @key{function} @AdaSubDefn{Im} (X : Imaginary) @key{return} Real'Base;
+
+   @key{procedure} @AdaSubDefn{Set_Re} (X  : @key{in} @key{out} Complex;
+                     Re : @key{in}     Real'Base);
+   @key{procedure} @AdaSubDefn{Set_Im} (X  : @key{in} @key{out} Complex;
+                     Im : @key{in}     Real'Base);
+   @key{procedure} @AdaSubDefn{Set_Im} (X  :    @key{out} Imaginary;
+                     Im : @key{in}     Real'Base);
+
+   @key{function} @AdaSubDefn{Compose_From_Cartesian} (Re, Im : Real'Base) 
@key{return} Complex;
+   @key{function} @AdaSubDefn{Compose_From_Cartesian} (Re     : Real'Base) 
@key{return} Complex;
+   @key{function} @AdaSubDefn{Compose_From_Cartesian} (Im     : Imaginary) 
@key{return} Complex;
+
+   @key{function} @AdaSubDefn{Modulus} (X     : Complex) @key{return} 
Real'Base;
+   @key{function} "@key{abs}"   (Right : Complex) @key{return} Real'Base 
@key{renames} Modulus;
+
+   @key{function} @AdaSubDefn{Argument} (X     : Complex)   @key{return} 
Real'Base;
+   @key{function} @AdaSubDefn{Argument} (X     : Complex;
+                      Cycle : Real'Base) @key{return} Real'Base;
+
+   @key{function} @AdaSubDefn{Compose_From_Polar} (Modulus, Argument        : 
Real'Base)
+      @key{return} Complex;
+   @key{function} @AdaSubDefn{Compose_From_Polar} (Modulus, Argument, Cycle : 
Real'Base)
+      @key{return} Complex;
+
+
+   @key{function} "+"       (Right : Complex) @key{return} Complex;
+   @key{function} "-"       (Right : Complex) @key{return} Complex;
+   @key{function} @AdaSubDefn{Conjugate} (X     : Complex) @key{return} 
Complex;
+
+
+   @key{function} "+" (Left, Right : Complex) @key{return} Complex;
+   @key{function} "-" (Left, Right : Complex) @key{return} Complex;
+   @key{function} "*" (Left, Right : Complex) @key{return} Complex;
+   @key{function} "/" (Left, Right : Complex) @key{return} Complex;
+
+
+   @key{function} "**" (Left : Complex; Right : Integer) @key{return} Complex;
+
+
+   @key{function} "+"       (Right : Imaginary) @key{return} Imaginary;
+   @key{function} "-"       (Right : Imaginary) @key{return} Imaginary;
+   @key{function} @AdaSubDefn{Conjugate} (X     : Imaginary) @key{return} 
Imaginary @key{renames} "-";
+   @key{function} "@key{abs}"     (Right : Imaginary) @key{return} Real'Base;
+
+
+   @key{function} "+" (Left, Right : Imaginary) @key{return} Imaginary;
+   @key{function} "-" (Left, Right : Imaginary) @key{return} Imaginary;
+   @key{function} "*" (Left, Right : Imaginary) @key{return} Real'Base;
+   @key{function} "/" (Left, Right : Imaginary) @key{return} Real'Base;
+
+
+   @key{function} "**" (Left : Imaginary; Right : Integer) @key{return} 
Complex;
+
+
+   @key{function} "<"  (Left, Right : Imaginary) @key{return} Boolean;
+   @key{function} "<=" (Left, Right : Imaginary) @key{return} Boolean;
+   @key{function} ">"  (Left, Right : Imaginary) @key{return} Boolean;
+   @key{function} ">=" (Left, Right : Imaginary) @key{return} Boolean;
+
+
+   @key{function} "+" (Left : Complex;   Right : Real'Base) @key{return} 
Complex;
+   @key{function} "+" (Left : Real'Base; Right : Complex)   @key{return} 
Complex;
+   @key{function} "-" (Left : Complex;   Right : Real'Base) @key{return} 
Complex;
+   @key{function} "-" (Left : Real'Base; Right : Complex)   @key{return} 
Complex;
+   @key{function} "*" (Left : Complex;   Right : Real'Base) @key{return} 
Complex;
+   @key{function} "*" (Left : Real'Base; Right : Complex)   @key{return} 
Complex;
+   @key{function} "/" (Left : Complex;   Right : Real'Base) @key{return} 
Complex;
+   @key{function} "/" (Left : Real'Base; Right : Complex)   @key{return} 
Complex;
+
+
+   @key{function} "+" (Left : Complex;   Right : Imaginary) @key{return} 
Complex;
+   @key{function} "+" (Left : Imaginary; Right : Complex)   @key{return} 
Complex;
+   @key{function} "-" (Left : Complex;   Right : Imaginary) @key{return} 
Complex;
+   @key{function} "-" (Left : Imaginary; Right : Complex)   @key{return} 
Complex;
+   @key{function} "*" (Left : Complex;   Right : Imaginary) @key{return} 
Complex;
+   @key{function} "*" (Left : Imaginary; Right : Complex)   @key{return} 
Complex;
+   @key{function} "/" (Left : Complex;   Right : Imaginary) @key{return} 
Complex;
+   @key{function} "/" (Left : Imaginary; Right : Complex)   @key{return} 
Complex;
+
+
+   @key{function} "+" (Left : Imaginary; Right : Real'Base) @key{return} 
Complex;
+   @key{function} "+" (Left : Real'Base; Right : Imaginary) @key{return} 
Complex;
+   @key{function} "-" (Left : Imaginary; Right : Real'Base) @key{return} 
Complex;
+   @key{function} "-" (Left : Real'Base; Right : Imaginary) @key{return} 
Complex;
+   @key{function} "*" (Left : Imaginary; Right : Real'Base) @key{return} 
Imaginary;
+   @key{function} "*" (Left : Real'Base; Right : Imaginary) @key{return} 
Imaginary;
+   @key{function} "/" (Left : Imaginary; Right : Real'Base) @key{return} 
Imaginary;
+   @key{function} "/" (Left : Real'Base; Right : Imaginary) @key{return} 
Imaginary;
+
+
address@hidden
+
+   @key{type} Imaginary @key{is} @key{new} Real'Base;
+   i : @key{constant} Imaginary := 1.0;
+   j : @key{constant} Imaginary := 1.0;
+
address@hidden Ada.Numerics.Generic_Complex_Types;
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0020],ARef=[AI95-00126-01]}
address@hidden,address@hidden
+The library package Numerics.Complex_Types
address@hidden declared pure and ],Old=[]}defines the same types, constants,
+and subprograms as Numerics.Generic_Complex_Types, except that the
+predefined type Float is systematically substituted for Real'Base throughout.
+Nongeneric equivalents of Numerics.Generic_Complex_Types for each of the other
+predefined floating point types are defined similarly, with the names
address@hidden@address@hidden, address@hidden@address@hidden, etc.
address@hidden
+   The nongeneric equivalents are provided to allow the programmer to
+   construct simple mathematical applications without being required to
+   understand and use generics.
address@hidden
address@hidden
+   The nongeneric equivalents all export the types Complex and Imaginary and
+   the constants i and j (rather than uniquely named types and constants, such
+   as Short_Complex, Long_Complex, etc.) to preserve their equivalence to
+   actual instantiations of the generic package and to allow the programmer to
+   change the precision of an application globally by changing a single
+   context clause.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
address@hidden is a visible type with
address@hidden,New=[Cartesian],Old=[cartesian]} components.}
address@hidden
+   The @Chg{Version=[2],New=[Cartesian],Old=[cartesian]} representation is
+   far more common than the polar
+   representation, in practice. The accuracy of the results of the complex
+   arithmetic operations and of the complex elementary functions
+   is dependent on the representation; thus, implementers need to know that
+   representation. The type is visible so that complex 
@lquotes@;address@hidden@; can be
+   written in aggregate notation, if desired.
address@hidden
+
address@hidden is a private type; its full type is derived from
+Real'Base.}
address@hidden
+   @Leading@;The Imaginary type and the constants i and j are provided for two 
reasons:
+   @begin{itemize}
+      They allow complex @lquotes@;address@hidden@; to be written in the 
alternate form of
+      @RI{a} + @RI{b}*i (or @RI{a} + @RI{b}*j), if desired. Of course,
+      in some contexts the sum will need to be parenthesized.
+
+      When an Ada binding to IEC 559:1989 that provides (signed) infinities
+      as the result of operations that overflow becomes available, it will be
+      important to allow arithmetic between pure-imaginary and complex operands
+      without requiring the former to be represented as (or promoted to)
+      complex values with a real component of zero. For example, the
+      multiplication of @RI{a} + @RI{b}*i by @RI{d}*i should yield
+      @address@hidden@Times @RI{d} + @address@hidden @RI{d}*i, but if one 
cannot avoid representing the
+      pure-imaginary value @RI{d}*i as the complex value
+      0.0 + @RI{d}*i, then a NaN ("Not-a-Number") could be produced
+      as the result of multiplying @RI{a} by 0.0 (e.g., when @RI{a} is
+      infinite); the NaN could later trigger an exception.
+      Providing the Imaginary type and overloadings of the
+      arithmetic operators for mixtures of Imaginary and Complex operands
+      gives the programmer the same control over avoiding premature coercion of
+      pure-imaginary values to complex as is already provided for pure-real
+      values.
+   @end{itemize}
address@hidden
address@hidden
+   @Leading@;The Imaginary type is private, rather than being visibly derived
+   from Real'Base, for two reasons:
+   @begin{itemize}
+      to preclude implicit conversions of real literals to the Imaginary type
+      (such implicit conversions would make many common arithmetic expressions
+      ambiguous); and
+
+      to suppress the implicit derivation of the multiplication, division, and
+      absolute value operators with Imaginary operands and an Imaginary result
+      (the result type would be incorrect).
+   @end{itemize}
address@hidden
address@hidden
+   The base subtype Real'Base is used for the component type of Complex, the
+   parent type of Imaginary, and the parameter and result types of some of the
+   subprograms to maximize the chances of being able to pass meaningful values
+   into the subprograms and receive meaningful results back. The generic
+   formal parameter Real therefore plays only one role, that of providing the
+   precision to be maintained in complex arithmetic calculations. Thus, the
+   subprograms in Numerics.Generic_Complex_Types share with those in
+   Numerics.Generic_Elementary_Functions, and indeed even with the predefined
+   arithmetic operations (see @RefSecNum{Operators and Expression Evaluation}),
+   the property of being free of range checks on input
+   and output, i.e., of being able to exploit the base range of the relevant
+   floating point type fully. As a result, the user loses the ability to
+   impose application-oriented bounds on the range of values that the
+   components of a complex variable can acquire; however, it can be argued that
+   few, if any, applications have a naturally square domain (as opposed to a
+   circular domain) anyway.
address@hidden
+
address@hidden@;The arithmetic operations and the Re, Im, Modulus, Argument, 
and Conjugate
+functions have their usual mathematical meanings. When applied to a parameter
+of pure-imaginary type, the @lquotes@;address@hidden@; function Im yields the 
value of
+its parameter, as the corresponding real value.
+The remaining subprograms have the following meanings:
address@hidden
+   The middle case can be understood by considering the parameter of
+   pure-imaginary type to represent a complex value with a zero real part.
address@hidden
address@hidden
+   The Set_Re and Set_Im procedures replace the designated component of a
+   complex parameter with the given real value; applied to a parameter of
+   pure-imaginary type, the Set_Im procedure replaces the value of that
+   parameter with the imaginary value corresponding to the given real value.
+
+   The Compose_From_Cartesian function constructs a complex value from the
+   given real and imaginary components. If only one component is given, the
+   other component is implicitly zero.
+
+   The Compose_From_Polar function constructs a complex value from the given
+   modulus (radius) and argument (angle). When the value of the parameter
+   Modulus is positive (resp., negative), the result is the complex value
+   represented by the point in the complex plane lying at a distance from the
+   origin given by the absolute value of Modulus and forming an angle measured
+   counterclockwise from the positive (resp., negative) real axis given by the
+   value of the parameter Argument.
address@hidden(Itemize)
+
+When the Cycle parameter is specified, the result of the Argument function and
+the parameter Argument of the Compose_From_Polar function are measured in units
+such that a full cycle of revolution has the given value; otherwise, they are
+measured in radians.
+
address@hidden@;The computed results of the mathematically multivalued 
functions are rendered
+single-valued by the following conventions, which are meant to imply the
+principal branch:
address@hidden
+   The result of the Modulus function is nonnegative.
+
+   The result of the Argument function is in the quadrant containing the point
+   in the complex plane represented by the parameter X. This may be any
+   quadrant (I through IV); thus, the range of the Argument function is
+   approximately @address@hidden to @Pi
+   (@address@hidden/2.0 to @R[Cycle]/2.0, if the parameter Cycle is
+   specified). When the point represented by the parameter X lies on the
+   negative real axis, the result approximates
+   @begin{InnerItemize}
+      @Pi (resp., @address@hidden) when the sign of the imaginary
+      component of X is positive (resp., negative), if Real'Signed_Zeros is
+      True;
+
+      @Pi, if Real'Signed_Zeros is False.
+   @end{InnerItemize}
+
+   Because a result lying on or near one of the axes may not be exactly
+   representable, the approximation inherent in computing the result may place
+   it in an adjacent quadrant, close to but on the wrong side of the axis.
address@hidden
address@hidden
+
address@hidden
+The exception Numerics.Argument_Error is raised by the Argument and
+Compose_From_Polar functions with specified cycle, signaling a parameter value
+outside the domain of the corresponding mathematical function, when the value
+of the parameter Cycle is zero or negative.
+
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+The exception Constraint_Error is raised by the division operator when the
+value of the right operand is zero, and by the exponentiation operator when
+the value of the left operand is zero and the value of the exponent is
+negative, provided that Real'Machine_Overflows is True; when
+Real'Machine_Overflows is False, the result is
+unspecified.
address@hidden
address@hidden
+can also be raised when a finite result overflows
+(see @RefSecNum{Accuracy Requirements for Complex Arithmetic}).]
address@hidden
+   It is anticipated that an Ada binding to IEC 559:1989 will be developed in
+   the future. As part of such a binding, the Machine_Overflows attribute of a
+   conformant floating point type will be specified to yield False, which will
+   permit implementations of the complex arithmetic operations to deliver
+   results with an infinite component (and set the overflow flag defined by the
+   binding) instead of raising Constraint_Error in overflow situations, when
+   traps are disabled. Similarly, it is appropriate for the complex arithmetic
+   operations to deliver results with infinite components (and set the
+   zero-divide flag defined by the binding) instead of raising Constraint_Error
+   in the situations defined above, when traps are disabled. Finally, such a
+   binding should also specify the behavior of the complex arithmetic
+   operations, when sensible, given operands with infinite components.
address@hidden
address@hidden
+
address@hidden
+In the implementation of Numerics.Generic_Complex_Types,
+the range of intermediate values allowed during the calculation
+of a final result shall not be affected by any
+range constraint of the subtype Real.
address@hidden
+   Implementations of Numerics.Generic_Complex_Types written in Ada should
+   therefore avoid declaring local variables of subtype Real; the subtype
+   Real'Base should be used instead.
address@hidden
+
address@hidden
address@hidden result],
+        Sec=[for the evaluation of a complex arithmetic operation]}
+In the following cases, evaluation of a complex arithmetic operation shall
+yield the @i{prescribed result},
+provided that the preceding rules do not call for an exception to be
+raised:
address@hidden
+   The results of the Re, Im, and Compose_From_Cartesian functions are exact.
+
+   The real (resp., imaginary) component of the result of a binary addition
+   operator that yields a result of complex type is exact when either of its
+   operands is of pure-imaginary (resp., real) type.
+   @begin{Ramification}
+      The result of the addition operator is exact when one of its operands is
+      of real type and the other is of pure-imaginary type. In this particular
+      case, the operator is analogous to the Compose_From_Cartesian function;
+      it performs no arithmetic.
+   @end{Ramification}
+
+   The real (resp., imaginary) component of the result of a binary subtraction
+   operator that yields a result of complex type is exact when its right
+   operand is of pure-imaginary (resp., real) type.
+
+   The real component of the result of the Conjugate function for the complex
+   type is exact.
+
+   When the point in the complex plane represented by the parameter X lies on
+   the nonnegative real axis, the Argument function yields a result of zero.
+   @begin{Discussion}
+      Argument(X + i*Y) is analogous to @i{EF}.Arctan(Y, X), where @i{EF} is an
+      appropriate instance of Numerics.Generic_Elementary_Functions, except
+      when X and Y are both zero, in which case the former yields the value
+      zero while the latter raises Numerics.Argument_Error.
+   @end{Discussion}
+
+   When the value of the parameter Modulus is zero, the Compose_From_Polar
+   function yields a result of zero.
+
+   When the value of the parameter Argument is equal to a multiple of the
+   quarter cycle, the result of the Compose_From_Polar function with specified
+   cycle lies on one of the axes. In this case, one of its components is zero,
+   and the other has the magnitude of the parameter Modulus.
+
+   Exponentiation by a zero exponent yields the value one. Exponentiation by
+   a unit exponent yields the value of the left operand. Exponentiation of
+   the value one yields the value one. Exponentiation of the value zero
+   yields the value zero, provided that the exponent is nonzero. When the
+   left operand is of pure-imaginary type, one component of the result of the
+   exponentiation operator is zero.
address@hidden
+
+When the result, or a result component, of any operator of
+Numerics.Generic_Complex_Types has a mathematical definition in terms of a
+single arithmetic or relational operation, that result or result component
+exhibits the accuracy of the corresponding operation of the type Real.
+
+Other accuracy requirements for the Modulus, Argument, and Compose_From_Polar
+functions, and accuracy requirements for the multiplication of a pair of
+complex operands or for division by a complex operand, all of which apply
+only in the strict mode, are given in
address@hidden Requirements for Complex Arithmetic}.
+
+The sign of a zero result or zero result component yielded by a complex
+arithmetic operation or function is implementation defined when
+Real'Signed_Zeros is True.
address@hidden 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.}
address@hidden
+
address@hidden
+The nongeneric equivalent packages may, but need not, be actual
+instantiations of the generic package for the appropriate predefined type.
+
address@hidden,Kind=[Revised],Ref=[8652/0091]}
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+Implementations may obtain the result of exponentiation of a complex
+or pure-imaginary operand by repeated complex multiplication, with arbitrary
+association of the factors and with a possible final complex reciprocation
+(when the exponent is negative). Implementations are also permitted to obtain
+the result of exponentiation of a complex operand, but not of a pure-imaginary
+operand, by converting the left operand to a polar representation;
+exponentiating the modulus by the given exponent; multiplying the argument by
+the given address@hidden,Old=[, when the exponent is positive, or dividing
+the argument by the absolute value of the given exponent, when the exponent is
+negative]}; and reconverting to a 
@Chg{Version=[2],New=[Cartesian],Old=[cartesian]}
+representation. Because of this
+implementation freedom, no accuracy requirement is imposed on complex
+exponentiation (except for the prescribed results given above, which apply
+regardless of the implementation method chosen).
address@hidden
+
address@hidden
+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.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Mixed real and complex operations (as well as pure-imaginary and complex
+operations) should not be performed by converting
+the real (resp. pure-imaginary) operand to complex.]}]}
+
+Likewise, 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.
+
+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 address@hidden@!Polar function should be the same as (resp., 
the
+opposite of) that of the Argument parameter when that parameter has a value of
+zero and the Modulus parameter has a nonnegative (resp., negative) value.
address@hidden,Kind=[RevisedAdded],InitialVersion=[2],
address@hidden,
+Text=[If Real'Signed_Zeros is @Chg{Version=[3],New=[True],Old=[true]} for 
address@hidden@address@hidden,
+a rational treatment of the signs of
+zero results and result components should be provided.]}]}
address@hidden
+
address@hidden
address@hidden@;The semantics of Numerics.Generic_Complex_Types differs from
+Generic_Complex_Types as defined in ISO/IEC CD 13813
+(for Ada 83) in the following ways:
address@hidden
+   The generic package is a child of the package defining the
+   Argument_Error exception.
+
+   The nongeneric equivalents export types and constants with the same names
+   as those exported by the generic package, rather than with names unique to
+   the package.
+
+   Implementations are not allowed to impose an optional restriction that the
+   generic actual parameter associated with Real be unconstrained. (In view of
+   the ability to declare variables of subtype Real'Base in implementations of
+   Numerics.Generic_Complex_Types, this flexibility is no longer needed.)
+
+   The dependence of the Argument function on the sign of a zero parameter
+   component is tied to the value of Real'Signed_Zeros.
+
+   Conformance to accuracy requirements is conditional.
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00161-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b[Amendment Correction:] Added a @nt{pragma} Preelaborable_Initialization to
+  type Imaginary, so that it can be used in preelaborated units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0020],ARef=[AI95-00126-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Explicitly stated that the
+  nongeneric equivalents of Generic_Complex_Types are pure.]}
address@hidden
+
+
address@hidden Elementary Functions}
+
address@hidden
address@hidden@;The generic library package
+Numerics.Generic_Complex_Elementary_Functions has the following declaration:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
address@hidden Ada.Numerics.Generic_Complex_Types;
address@hidden@ChildUnit{Parent=[Ada.Numerics],address@hidden@address@hidden
+   @key[with] @key[package] Complex_Types @key[is]
+         @key[new] Ada.Numerics.Generic_Complex_Types (<>);
+   @key[use] Complex_Types;
address@hidden Ada.Numerics.Generic_Complex_Elementary_Functions @key[is]
+   @Chg{Version=[2],address@hidden,Old=[pragma]} 
Pure(Generic_Complex_Elementary_Functions);
+
+   @key[function] @AdaSubDefn{Sqrt} (X : Complex)   @key[return] Complex;
+   @key[function] @AdaSubDefn{Log}  (X : Complex)   @key[return] Complex;
+   @key[function] @AdaSubDefn{Exp}  (X : Complex)   @key[return] Complex;
+   @key[function] @AdaSubDefn{Exp}  (X : Imaginary) @key[return] Complex;
+   @key[function] "**" (Left : Complex;   Right : Complex)   @key[return] 
Complex;
+   @key[function] "**" (Left : Complex;   Right : Real'Base) @key[return] 
Complex;
+   @key[function] "**" (Left : Real'Base; Right : Complex)   @key[return] 
Complex;
+
+
+   @key[function] @AdaSubDefn{Sin} (X : Complex) @key[return] Complex;
+   @key[function] @AdaSubDefn{Cos} (X : Complex) @key[return] Complex;
+   @key[function] @AdaSubDefn{Tan} (X : Complex) @key[return] Complex;
+   @key[function] @AdaSubDefn{Cot} (X : Complex) @key[return] Complex;
+
+
+   @key[function] @AdaSubDefn{Arcsin} (X : Complex) @key[return] Complex;
+   @key[function] @AdaSubDefn{Arccos} (X : Complex) @key[return] Complex;
+   @key[function] @AdaSubDefn{Arctan} (X : Complex) @key[return] Complex;
+   @key[function] @AdaSubDefn{Arccot} (X : Complex) @key[return] Complex;
+
+
+   @key[function] @AdaSubDefn{Sinh} (X : Complex) @key[return] Complex;
+   @key[function] @AdaSubDefn{Cosh} (X : Complex) @key[return] Complex;
+   @key[function] @AdaSubDefn{Tanh} (X : Complex) @key[return] Complex;
+   @key[function] @AdaSubDefn{Coth} (X : Complex) @key[return] Complex;
+
+
+   @key[function] @AdaSubDefn{Arcsinh} (X : Complex) @key[return] Complex;
+   @key[function] @AdaSubDefn{Arccosh} (X : Complex) @key[return] Complex;
+   @key[function] @AdaSubDefn{Arctanh} (X : Complex) @key[return] Complex;
+   @key[function] @AdaSubDefn{Arccoth} (X : Complex) @key[return] Complex;
+
address@hidden Ada.Numerics.Generic_Complex_Elementary_Functions;
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0020],ARef=[AI95-00126-01]}
address@hidden,address@hidden@!Functions]}
+The library package Numerics.Complex_Elementary_Functions
address@hidden declared pure and ],Old=[]}defines the same subprograms as
address@hidden@address@hidden@!Functions,
+except that the predefined type Float is systematically substituted for
+Real'Base, and the Complex and Imaginary types exported by 
address@hidden@!Types
+are systematically substituted for Complex and Imaginary, throughout.
+Nongeneric equivalents of address@hidden@address@hidden@!Functions
+corresponding to each of the other predefined floating point types are
+defined similarly, with the names address@hidden@address@hidden@!Functions,
address@hidden@address@hidden@!Functions, etc.
address@hidden
+   The nongeneric equivalents are provided to allow the programmer to
+   construct simple mathematical applications without being required to
+   understand and use generics.
address@hidden
+
+The overloading of the Exp function for the pure-imaginary type is provided
+to give the user an alternate way to compose a complex value from a given
+modulus and argument. In addition to address@hidden@!Polar(Rho, Theta)
+(see @RefSecNum{Complex Types}), the programmer may write Rho * Exp(i * Theta).
+
+The imaginary (resp., real) component of the parameter X of the forward
+hyperbolic (resp., trigonometric) functions and of the Exp function (and the
+parameter X, itself, in the case of the overloading of the Exp function for the
+pure-imaginary type) represents an angle measured in radians, as does the
+imaginary (resp., real) component of the result of the Log and inverse
+hyperbolic (resp., trigonometric) functions.
+
address@hidden@;The functions have their usual mathematical meanings. However, 
the
+arbitrariness inherent in the placement of branch cuts, across which some of
+the complex elementary functions exhibit discontinuities, is eliminated by the
+following conventions:
address@hidden
+   The imaginary component of the result of the Sqrt and Log functions is
+   discontinuous as the parameter X crosses the negative real axis.
+
+   The result of the exponentiation operator when the left operand is of
+   complex type is discontinuous as that operand crosses the negative real
+   axis.
+
+   @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00185-01]}
+   The @Chg{Version=[2],New=[],Old=[real (resp., address@hidden,
+   New=[],Old=[)]} component of the result of the address@hidden,
+   New=[,],Old=[ and]} address@hidden,New=[],Old=[(resp.]},
+   @Chg{Version=[2],New=[and ],address@hidden,
+   New=[],Old=[)]} functions is discontinuous as the parameter X crosses the
+   real axis to the left of @en@;1.0 or the right of 1.0.
+
+   @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00185-01]}
+   The real @Chg{Version=[2],New=[],Old=[(resp., imaginary) ]}component of the
+   result of the Arctan @Chg{Version=[2],New=[and],Old=[(resp.,]}
+   address@hidden, New=[ functions],Old=[) function]} is discontinuous
+   as the parameter X crosses the imaginary axis below @address@hidden or 
above @RI{i}.
+
+   @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00185-01]}
+   The real component of the result of the Arccot function is discontinuous as
+   the parameter X crosses the imaginary axis @Chg{Version=[2],New=[below],
+   Old=[between]} @address@hidden @Chg{Version=[2],New=[or above],Old=[and]} 
@RI{i}.
+
+   The imaginary component of the Arccosh function is discontinuous as the
+   parameter X crosses the real axis to the left of 1.0.
+
+   The imaginary component of the result of the Arccoth function is
+   discontinuous as the parameter X crosses the real axis between @en@;1.0
+   and 1.0.
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00185-01]}
address@hidden,Type=[Leading],Text=[The branch cuts come from the
+fact that the functions in question are
+really multi-valued in the complex domain, and that we have to pick one
address@hidden value} to be the result of the function. Evidently we have
+much freedom in choosing where the branch cuts lie. However, we are
+adhering to the following principles which seem to lead to the more
address@hidden definitions:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[A branch cut should not intersect the real axis
+at a place where the
+corresponding real function is well-defined (in other words, the complex
+function should be an extension of the corresponding real function).]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Because all the functions in question are
+analytic, to ensure power
+series validity for the principal value, the branch cuts should be
+invariant by complex conjugation.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[For odd functions, to ensure that the principal
+value remains an odd
+function, the branch cuts should be invariant by reflection in the origin.]}
address@hidden
address@hidden
+
address@hidden@;@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00185-01]}The
+computed results of the mathematically multivalued functions
+are rendered single-valued by the following conventions, which are meant to
+imply @Chg{Version=[2],New=[that ],Old=[]}the
+principal address@hidden,New=[ is an analytic continuation of
+the corresponding real-valued function in
+Numerics.Generic_Elementary_Functions. (For Arctan and Arccot,
+the single-argument function in question is that obtained from the two-argument
+version by fixing the second argument to be its default value.)],Old=[:]}
address@hidden
+   The real component of the result of the Sqrt and Arccosh functions is
+   nonnegative.
+
+   The same convention applies to the imaginary component of the result of the
+   Log function as applies to the result of the natural-cycle version of the
+   Argument function of Numerics.Generic_Complex_Types
+   (see @RefSecNum{Complex Types}).
+
+   The range of the real (resp., imaginary) component of the result of the
+   Arcsin and Arctan (resp., Arcsinh and Arctanh) functions is
+   approximately @address@hidden/2.0 to @Pi/2.0.
+
+   The real (resp., imaginary) component of the result of the Arccos and Arccot
+   (resp., Arccoth) functions ranges from 0.0 to approximately @Pi.
+
+   The range of the imaginary component of the result of the Arccosh function
+   is approximately @address@hidden to @Pi.
address@hidden
+
+In addition, the exponentiation operator inherits the single-valuedness of the
+Log function.
address@hidden
+
address@hidden
+The exception Numerics.Argument_Error is raised by the exponentiation operator,
+signaling a parameter value outside the domain of the corresponding
+mathematical function, when the value of the left operand is zero and the real
+component of the exponent (or the exponent itself, when it is of real type) is
+zero.
+
address@hidden@IndexCheck{Division_Check}
address@hidden,Sec=(raised by failure of run-time check)}
+The exception Constraint_Error is raised, signaling a pole of the mathematical
+function (analogous to dividing by zero), in the following cases, provided that
+Complex_Types.Real'Machine_Overflows is True:
address@hidden
+   by the Log, Cot, and Coth functions, when the value of the parameter X is
+   zero;
+
+   by the exponentiation operator, when the value of the left operand is zero
+   and the real component of the exponent (or the exponent itself, when it is
+   of real type) is negative;
+
+   by the Arctan and Arccot functions, when the value of the parameter X is
+   @PorM @RI{i};
+
+   by the Arctanh and Arccoth functions, when the value of the parameter X is
+   @PorM 1.0.
address@hidden
+
address@hidden can also be raised
+when a finite result overflows
+(see @RefSecNum{Accuracy Requirements for Complex Arithmetic}); this may
+occur for parameter values sufficiently @i{near} poles, and, in the case of
+some of the functions, for parameter values having components of sufficiently
+large magnitude.]
address@hidden
+When Complex_Types.Real'Machine_Overflows is False, the result at poles is
+unspecified.
address@hidden
+   The purpose of raising Constraint_Error (rather than
+   Numerics.Argument_Error) at the poles of a function, when
+   Float_Type'Machine_Overflows is True, is to provide continuous behavior as
+   the actual parameters of the function approach the pole and finally reach
+   it.
address@hidden
address@hidden
+   It is anticipated that an Ada binding to IEC 559:1989 will be developed
+   in the future. As part of such a binding, the Machine_Overflows attribute
+   of a conformant floating point type will be specified to yield False, which
+   will permit implementations of the complex elementary functions to deliver
+   results with an infinite component (and set the overflow flag defined by the
+   binding) instead of raising Constraint_Error in overflow situations, when
+   traps are disabled. Similarly, it is appropriate for the complex elementary
+   functions to deliver results with an infinite component (and set the
+   zero-divide flag defined by the binding) instead of raising Constraint_Error
+   at poles, when traps are disabled. Finally, such a binding should also
+   specify the behavior of the complex elementary functions, when sensible,
+   given parameters with infinite components.
address@hidden
address@hidden
+
address@hidden
+In the implementation of Numerics.Generic_Complex_Elementary_Functions,
+the range of intermediate values allowed during the calculation
+of a final result shall not be affected by any
+range constraint of the subtype Complex_Types.Real.
address@hidden
+   Implementations of Numerics.Generic_Complex_Elementary_Functions written in 
Ada
+   should therefore avoid declaring local variables of subtype 
Complex_Types.Real; the
+   subtype Complex_Types.Real'Base should be used instead.
address@hidden
+
address@hidden
address@hidden result],
+        Sec=[for the evaluation of a complex elementary function]}
+In the following cases, evaluation of a complex elementary function shall
+yield the @i{prescribed result} (or a result having the prescribed component),
+provided that the preceding rules do not call for an exception to be
+raised:
address@hidden
+   When the parameter X has the value zero, the Sqrt, Sin, Arcsin, Tan, Arctan,
+   Sinh, Arcsinh, Tanh, and Arctanh functions yield a result of zero; the
+   Exp, Cos, and Cosh functions yield a result of one; the Arccos and Arccot
+   functions yield a real result; and the Arccoth function yields an imaginary
+   result.
+
+   When the parameter X has the value one, the Sqrt function yields a result
+   of one; the Log, Arccos, and Arccosh functions yield a result of zero; and
+   the Arcsin function yields a real result.
+
+   When the parameter X has the value @en@;1.0, the Sqrt function yields the
+   result
+   @begin{InnerItemize}
+      @RI{i} (resp., @address@hidden), when the sign of the imaginary 
component of
+      X is positive (resp., negative), if Complex_Types.Real'Signed_Zeros is
+      True;
+
+      @RI{i}, if Complex_Types.Real'Signed_Zeros is False;
+   @end{InnerItemize}
+
+   @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00434-01]}
+   @Chg{Version=[2],New=[When the parameter X has the value @en@;1.0, ],
+   Old=[]}the Log function yields an imaginary result; and the Arcsin and 
Arccos
+   functions yield a real result.
+
+   When the parameter X has the value @PorM @RI{i}, the Log function yields
+   an imaginary result.
+
+   Exponentiation by a zero exponent yields the value one. Exponentiation by
+   a unit exponent yields the value of the left operand (as a complex value).
+   Exponentiation of the value one yields the value one. Exponentiation of
+   the value zero yields the value zero.
address@hidden
address@hidden
+   It is possible to give many other prescribed results restricting the result
+   to the real or imaginary axis when the parameter X is appropriately
+   restricted to easily testable portions of the domain. We follow the
+   proposed ISO/IEC standard for Generic_Complex_Elementary_Functions (for Ada
+   83), CD 13813,
+   in not doing so, however.
address@hidden
+
+Other accuracy requirements for the complex elementary functions, which apply
+only in the strict mode, are given in
address@hidden Requirements for Complex Arithmetic}.
+
+The sign of a zero result or zero result component yielded by a complex
+elementary function is implementation defined when
+Complex_Types.Real'Signed_Zeros is True.
address@hidden sign of a zero result (or a component thereof) from any operator
+or function in Numerics.Generic_Complex_Elementary_Functions, when
+Complex_Types.Real'Signed_Zeros is True.}
address@hidden
+
address@hidden
+The nongeneric equivalent packages may, but need not, be actual
+instantiations of the generic package with the appropriate predefined
+nongeneric equivalent of Numerics.Generic_Complex_Types; if they are, then the
+latter shall have been obtained by actual instantiation of
+Numerics.Generic_Complex_Types.
+
+The exponentiation operator may be implemented in terms of the Exp and Log
+functions. Because this implementation yields poor accuracy in some parts of
+the domain, no accuracy requirement is imposed on complex exponentiation.
+
address@hidden
+The implementation of the Exp function of a complex parameter X is allowed to
+raise the exception Constraint_Error, signaling overflow, when the real
+component of X exceeds an unspecified threshold that
+is approximately
address@hidden(@R[Complex_Types.Real'Safe_Last]).
+This permission recognizes the impracticality of avoiding overflow in
+the marginal
+case that the exponential of the real component of X exceeds the safe range of
+Complex_Types.Real but both components of the final result do not. Similarly,
+the Sin and Cos (resp., Sinh and Cosh) functions are allowed to raise the
+exception Constraint_Error, signaling overflow, when the absolute value of the
+imaginary (resp., real) component of the parameter X exceeds an
+unspecified threshold that is approximately
address@hidden(@R[Complex_Types.Real'Safe_Last]) +
address@hidden(2.0).
address@hidden
+This permission
+recognizes the impracticality of avoiding overflow in the marginal case that
+the hyperbolic sine or cosine of the imaginary (resp., real) component of X
+exceeds the safe range of Complex_Types.Real but both components of the final
+result do not.
address@hidden
+
address@hidden
+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.
address@hidden,Kind=[RevisedAdded],InitialVersion=[2],
address@hidden,
+Text=[If Complex_Types.Real'Signed_Zeros
+is @Chg{Version=[3],New=[True],Old=[true]} for
address@hidden@address@hidden@!Functions,
+a rational treatment of the signs of
+zero results and result components should be provided.]}]}
address@hidden
+
address@hidden
address@hidden@;The semantics of address@hidden@address@hidden@!Functions
+differs from address@hidden@address@hidden as defined in
+ISO/IEC CD 13814 (for Ada 83) in the following ways:
address@hidden
+   The generic package is a child unit of the package defining the
+   Argument_Error exception.
+
+   The proposed Generic_Complex_Elementary_Functions standard (for Ada 83)
+   specified names for the nongeneric equivalents, if provided. Here, those
+   nongeneric equivalents are required.
+
+   The generic package imports an instance of Numerics.Generic_Complex_Types 
rather
+   than a long list of individual types and operations exported by such an
+   instance.
+
+   The dependence of the imaginary component of the Sqrt and Log functions on
+   the sign of a zero parameter component is tied to the value of
+   Complex_Types.Real'Signed_Zeros.
+
+   Conformance to accuracy requirements is conditional.
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0020],ARef=[AI95-00126-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Explicitly stated that the
+  nongeneric equivalents of Generic_Complex_Elementary_Functions are pure.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00185-01]}
+  @ChgAdded{Version=[2],Text=[Corrected various inconsistencies in the
+  definition of the branch cuts.]}
address@hidden
+
+
address@hidden Input-Output}
+
address@hidden
+The generic package Text_IO.Complex_IO defines procedures for the
+formatted input and output of complex values. The generic actual parameter in
+an instantiation of Text_IO.Complex_IO is an instance of
+Numerics.Generic_Complex_Types for some floating point subtype. Exceptional
+conditions are reported by raising the appropriate exception defined in
+Text_IO.
address@hidden
+  An implementation of Text_IO.Complex_IO can
+  be built around an instance of
+  Text_IO.Float_IO for the base subtype of Complex_Types.Real, where
+  Complex_Types is the generic formal package parameter of Text_IO.Complex_IO.
+  There is no need for an implementation of Text_IO.Complex_IO to parse
+  real values.
address@hidden
address@hidden
+
address@hidden
address@hidden@;The generic library package
+Text_IO.Complex_IO has the following declaration:
address@hidden
+  Because this is a child of Text_IO, the declarations of the visible
+  part of Text_IO are directly visible within it.
address@hidden
address@hidden
address@hidden Ada.Numerics.Generic_Complex_Types;
address@hidden@ChildUnit{Parent=[Ada.Text_IO],Child=[Complex_IO]}
+   @key[with] @key[package] Complex_Types @key[is]
+         @key[new] Ada.Numerics.Generic_Complex_Types (<>);
address@hidden Ada.Text_IO.Complex_IO @key[is]
+
+
+   @key[use] Complex_Types;
+
+   @AdaObjDefn{Default_Fore} : Field := 2;
+   @AdaObjDefn{Default_Aft}  : Field := Real'Digits - 1;
+   @AdaObjDefn{Default_Exp}  : Field := 3;
+
+
+   @key[procedure] @AdaSubDefn{Get} (File  : @key[in]  File_Type;
+                  Item  : @key[out] Complex;
+                  Width : @key[in]  Field := 0);
+   @key[procedure] @AdaSubDefn{Get} (Item  : @key[out] Complex;
+                  Width : @key[in]  Field := 0);
+
+
+   @key[procedure] @AdaSubDefn{Put} (File : @key[in] File_Type;
+                  Item : @key[in] Complex;
+                  Fore : @key[in] Field := Default_Fore;
+                  Aft  : @key[in] Field := Default_Aft;
+                  Exp  : @key[in] Field := Default_Exp);
+   @key[procedure] @AdaSubDefn{Put} (Item : @key[in] Complex;
+                  Fore : @key[in] Field := Default_Fore;
+                  Aft  : @key[in] Field := Default_Aft;
+                  Exp  : @key[in] Field := Default_Exp);
+
+
address@hidden@;   @key[procedure] @AdaSubDefn{Get} (From : @key[in]  String;
+                  Item : @key[out] Complex;
+                  Last : @key[out] Positive);
+   @key[procedure] @AdaSubDefn{Put} (To   : @key[out] String;
+                  Item : @key[in]  Complex;
+                  Aft  : @key[in]  Field := Default_Aft;
+                  Exp  : @key[in]  Field := Default_Exp);
+
address@hidden Ada.Text_IO.Complex_IO;
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00328-01]}
address@hidden,Text=[
address@hidden,address@hidden
+The library package Complex_Text_IO defines the
+same subprograms as Text_IO.Complex_IO, except that the predefined type Float
+is systematically substituted for Real, and the type
+Numerics.Complex_Types.Complex is systematically substituted for Complex
+throughout. Nongeneric equivalents of Text_IO.Complex_IO corresponding to each
+of the other predefined floating point types are defined similarly, with the
+names Short_Complex_Text_IO, Long_Complex_Text_IO, etc.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[
+   The nongeneric equivalents are provided to allow the programmer to
+   construct simple mathematical applications without being required to
+   understand and use generics.]}
address@hidden
+
+The semantics of the Get and Put procedures are as follows:
address@hidden
address@hidden
address@hidden Get (File  : @key[in]  File_Type;
+               Item  : @key[out] Complex;
+               Width : @key[in]  Field := 0);
address@hidden Get (Item  : @key[out] Complex;
+               Width : @key[in]  Field := 0);
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0092],ARef=[AI95-00029-01]}
address@hidden@;The input sequence is a pair of
+optionally signed real literals representing
+the real and imaginary components of a complex address@hidden These components
+have the format defined for the corresponding Get procedure of an instance of
+Text_IO.Float_IO (see @RefSecNum{Input-Output for Real Types}) for the base
+subtype of Complex_Types.Real. The],Old=[; optionally, the]} pair of components
+may be separated by a comma @Chg{New=[],Old=[and/]}or surrounded by a pair of
address@hidden or both],Old=[]}. Blanks are freely allowed before each
+of the components and before the parentheses and comma, if either is used.
+If the value of the parameter Width is zero, then
address@hidden
+   line and page terminators are also allowed in these places;
+
+   the components shall be separated by at least one blank or line terminator
+   if the comma is omitted; and
+
+   reading stops when the right parenthesis has been read, if the input
+   sequence includes a left parenthesis, or when the imaginary component has
+   been read, otherwise.
address@hidden
+
address@hidden following paragraph is missing a number in the original version.
+To give it a number in the new version, it is marked as an insertion.}
address@hidden,address@hidden
address@hidden,address@hidden@;]}If a nonzero value of Width is supplied, then
+
address@hidden
+   the components shall be separated by at least one blank if the comma is
+   omitted; and
+
+   exactly Width characters are read, or the characters (possibly none) up to
+   a line terminator, whichever comes first (blanks are included in the count).
address@hidden
address@hidden
+   The parenthesized and comma-separated form is the form produced by Put
+   on output (see below), and also by list-directed output in Fortran. The
+   other allowed forms match several common styles of edit-directed output in
+   Fortran, allowing most preexisting Fortran data files containing complex
+   data to be read easily. When such files contain complex values with no
+   separation between the real and imaginary components, the user will have to
+   read those components separately, using an instance of
+   Text_IO.Float_IO.
address@hidden
+
+Returns, in the parameter Item, the value of type Complex that corresponds to
+the input sequence.
+
address@hidden@;The exception Text_IO.Data_Error
+is raised if the input sequence
+does not have the required syntax or if the components of the complex value
+obtained are not of the base subtype of Complex_Types.Real.
+
address@hidden
address@hidden Put (File : @key[in] File_Type;
+               Item : @key[in] Complex;
+               Fore : @key[in] Field := Default_Fore;
+               Aft  : @key[in] Field := Default_Aft;
+               Exp  : @key[in] Field := Default_Exp);
address@hidden Put (Item : @key[in] Complex;
+               Fore : @key[in] Field := Default_Fore;
+               Aft  : @key[in] Field := Default_Aft;
+               Exp  : @key[in] Field := Default_Exp);
address@hidden
+
+Outputs the value of the parameter Item as a pair of decimal literals
+representing the real and imaginary components of the complex value,
+using the syntax
+of an aggregate.
+More specifically,
address@hidden
+   outputs a left parenthesis;
+
+   outputs the value of the real component of the parameter Item with the
+   format defined by the corresponding Put procedure of an instance of
+   Text_IO.Float_IO for the base subtype of Complex_Types.Real, using the 
given values of
+   Fore, Aft, and Exp;
+
+   outputs a comma;
+
+   outputs the value of the imaginary component of the parameter Item with the
+   format defined by the corresponding Put procedure of an instance of
+   Text_IO.Float_IO for the base subtype of Complex_Types.Real, using the 
given values of
+   Fore, Aft, and Exp;
+
address@hidden@;outputs a right parenthesis.
address@hidden
address@hidden
+   If the file has a bounded line length, a line terminator may be output
+   implicitly before any element of the sequence itemized above.
address@hidden
address@hidden
+   The option of outputting the complex value as a pair of reals without
+   additional punctuation
+   is not provided, since it can be
+   accomplished by outputting the real and imaginary components of the complex
+   value separately.
address@hidden
+
address@hidden
address@hidden Get (From : @key[in]  String;
+               Item : @key[out] Complex;
+               Last : @key[out] Positive);
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+Reads a complex value from the beginning of the given string, following the
+same rule as the Get procedure that reads a complex value from a file, but
+treating the end of the string as a @Chg{Version=[2],New=[file],Old=[line]}
+terminator. Returns, in the parameter
+Item, the value of type Complex that corresponds to the input sequence.
+Returns in Last the index value such that From(Last) is the last character
+read.
+
address@hidden@;The exception Text_IO.Data_Error is raised if the input sequence
+does not have the required syntax or if the components of the complex value
+obtained are not of the base subtype of Complex_Types.Real.
+
address@hidden
address@hidden Put (To   : @key[out] String;
+               Item : @key[in]  Complex;
+               Aft  : @key[in]  Field := Default_Aft;
+               Exp  : @key[in]  Field := Default_Exp);
address@hidden
+
+Outputs the value of the parameter Item to the given string as a pair of
+decimal literals representing the real and imaginary components of the complex
+value, using the syntax of an aggregate.
+More specifically,
address@hidden
+   a left parenthesis, the real component, and a comma are left justified in
+   the given string, with the real component having the format defined by the
+   Put procedure (for output to a file) of an instance of Text_IO.Float_IO
+   for the base subtype of Complex_Types.Real, using a value of zero for Fore 
and the given
+   values of Aft and Exp;
+
+   the imaginary component and a right parenthesis are right justified in the
+   given string, with the imaginary component having the format defined by the
+   Put procedure (for output to a file) of an instance of Text_IO.Float_IO
+   for the base subtype of Complex_Types.Real, using a value for Fore that 
completely fills
+   the remainder of the string, together with the given values of Aft and Exp.
address@hidden
address@hidden
+   This rule is the one proposed in LSN-1051. Other rules were considered,
+   including one that would have read @lquotes@;Outputs the value of the 
parameter Item
+   to the given string, following the same rule as for output to a file, using
+   a value for Fore such that the sequence of characters output exactly fills,
+   or comes closest to filling, the string; in the latter case, the string is
+   filled by inserting one extra blank immediately after the address@hidden@; 
While
+   this latter rule might be considered the closest analogue to the rule for
+   output to a string in Text_IO.Float_IO, it requires a more difficult and
+   inefficient implementation involving special cases when the integer part of
+   one component is substantially longer than that of the other and the string
+   is too short to allow both to be preceded by blanks. Unless such a special
+   case applies, the latter rule might produce better columnar output if
+   several such strings are ultimately output to a file, but very nearly the
+   same output can be produced by outputting to the file directly, with the
+   appropriate value of Fore; in any case, it might validly be assumed that
+   output to a string is intended for further computation rather than for
+   display, so that the precise formatting of the string to achieve a
+   particular appearance is not the major concern.
address@hidden
+
+The exception Text_IO.Layout_Error is raised if the given string is
+too short to hold the formatted output.
address@hidden
address@hidden
+
address@hidden
+Other exceptions declared (by renaming)
+in Text_IO may be raised by the preceding procedures
+in the appropriate circumstances, as for the corresponding
+procedures of Text_IO.Float_IO.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00328-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Nongeneric equivalents for Text_IO.Complex_IO are added, to be consistent
+  with all other language-defined Numerics generic packages.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0092],ARef=[AI95-00029-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that the syntax
+  of values read by Complex_IO is the same as that read by Text_IO.Float_IO.]}
address@hidden
+
+
address@hidden Package Wide_Text_IO.Complex_IO}
+
address@hidden
address@hidden@!Text_IO.Complex_IO}
address@hidden@!Text_IO],Child=[Complex_IO]}
+Implementations shall also provide the generic library package
+Wide_Text_IO.Complex_IO. Its declaration is obtained from that of
+Text_IO.Complex_IO by systematically replacing Text_IO by Wide_Text_IO and
+String by Wide_String; the description of its behavior is obtained by
+additionally replacing references to particular characters (commas,
+parentheses, etc.) by those for the corresponding wide characters.
address@hidden
+
+
address@hidden,Name=[The Package Wide_Wide_Text_IO.Complex_IO]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,address@hidden@!Text_IO.Complex_IO}
address@hidden@!Text_IO],Child=[Complex_IO]}
+Implementations shall also provide the generic library package
+Wide_Wide_Text_IO.Complex_IO. Its declaration is obtained from that of
+Text_IO.Complex_IO by systematically replacing Text_IO by Wide_Wide_Text_IO and
+String by Wide_Wide_String; the description of its behavior is obtained by
+additionally replacing references to particular characters (commas,
+parentheses, etc.) by those for the corresponding wide wide characters.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Package Wide_Wide_Text_IO.Complex_IO is new. (At least it wasn't called
+  Incredibly_Wide_Text_IO.Complex_IO; maybe next time.)]}
address@hidden
+
+
address@hidden Performance Requirements}
+
address@hidden
address@hidden
address@hidden mode}
+Implementations shall provide a user-selectable mode in which the accuracy
+and other numeric performance requirements detailed in the following subclauses
+are observed.
+This mode,
+referred to as the @i{strict mode}, may or may not be the default mode;
+it directly affects the results of the predefined arithmetic operations of real
+types and the results of the subprograms in
+children of the Numerics package, and indirectly affects the operations in
+other language defined packages.
address@hidden mode}
+Implementations shall also provide the opposing mode, which is known as the
address@hidden mode}.
address@hidden
+   On the assumption that the users of an implementation that does not support
+   the Numerics Annex have no particular need for numerical performance, such
+   an implementation has no obligation to meet any particular requirements in
+   this area. On the other hand, users of an implementation that does support
+   the Numerics Annex are provided with a way of ensuring that their programs
+   achieve a known level of numerical performance and that the performance is
+   portable to other such implementations. The relaxed mode is provided to
+   allow implementers to offer an efficient but not fully accurate alternative
+   in the case that the strict mode entails a time overhead that some users may
+   find excessive. In some of its areas of impact, the relaxed mode may be
+   fully equivalent to the strict mode.
address@hidden
address@hidden
+   The relaxed mode may, for example, be used to exploit the implementation of
+   (some of) the elementary functions in hardware, when available. Such
+   implementations often do not meet the accuracy requirements of the strict
+   mode, or do not meet them over the specified range of parameter values,
+   but compensate in other ways that may be important to the user, such as
+   their extreme speed.
address@hidden
address@hidden
+   For implementations supporting the Numerics Annex,
+   the choice of mode has no
+   effect on the selection of a representation for a real type or on the values
+   of attributes of a real type.
address@hidden
address@hidden
+
address@hidden
+Either mode may be the default mode.
address@hidden the strict mode or the relaxed mode is the default.}
+
+The two modes need not actually be different.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The choice between strict and relaxed numeric performance was not available in
+Ada 83.
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden of Floating Point Arithmetic}
+
address@hidden
+In the strict mode, the predefined operations of a floating point type shall
+satisfy the accuracy requirements specified here and shall avoid or signal
+overflow in the situations described. This behavior is presented in terms of
+a model of floating point arithmetic that builds on the concept of the
+canonical form (see @RefSecNum{Attributes of Floating Point Types}).
address@hidden
+
address@hidden
+Associated with each floating point type is an infinite set of
+model numbers. The model numbers of a type are used to define the
+accuracy requirements that have to be satisfied by certain predefined
+operations of the type; through certain attributes of
+the model numbers, they are also used to explain
+the meaning of a user-declared floating point type declaration.
+The model numbers of a derived type are those of the
+parent type; the model numbers of a subtype are those of its type.
+
address@hidden number}
+The @i{model numbers} of a floating point type T are zero and all the values
+expressible in the canonical form (for the type T),
+in which @i{mantissa} has T'Model_Mantissa digits
+and @i{exponent} has a value greater than or equal
+to T'Model_Emin.
+(These attributes are defined in
address@hidden Attributes of Floating Point Types}.)
address@hidden
+   The model is capable of describing the behavior of most existing hardware
+   that has a mantissa-exponent representation. As applied to a type T, it is
+   parameterized by the values of T'Machine_Radix, T'Model_Mantissa,
+   T'Model_Emin, T'Safe_First, and T'Safe_Last. The values of these
+   attributes are determined by how, and how well, the hardware behaves.
+   They in turn determine the set of model numbers and the safe range of the
+   type, which figure in the accuracy and range (overflow avoidance)
+   requirements.
+
+   In hardware that is free of arithmetic anomalies, T'Model_Mantissa,
+   T'Model_Emin, T'Safe_First, and T'Safe_Last will yield the same values as
+   T'Machine_Mantissa, T'Machine_Emin, T'Base'First, and T'Base'Last,
+   respectively, and the
+   model numbers in the safe range of the type T will coincide with the machine
+   numbers of the type T. In less perfect hardware, it is not possible for the
+   model-oriented attributes to have these optimal values, since the hardware,
+   by definition, and therefore the implementation, cannot conform to the
+   stringencies of the resulting model; in this case, the values yielded by the
+   model-oriented parameters have to be made more conservative (i.e., have to
+   be penalized), with the result that the model numbers are more widely
+   separated than the machine numbers, and the safe range is a subrange of the
+   base range. The implementation will then be able to conform to the
+   requirements of the weaker model defined by the sparser set of model numbers
+   and the smaller safe range.
address@hidden
+
address@hidden interval}
+A @i(model interval) of a floating point type is any interval whose bounds
+are model numbers of the type.
address@hidden interval],
+        Sec=[associated with a value]}
+The @i{model interval} of a type T @i{associated with a value} @i{v} is the
+smallest model interval of T that includes @i{v}. (The model interval
+associated with a model number of a type consists of that number only.)
address@hidden
+
address@hidden
+The accuracy requirements for the evaluation of certain predefined
+operations of floating point types are as follows.
address@hidden
+This subclause does not cover the accuracy of an operation of a static
+expression; such operations
+have to be evaluated exactly
+(see @RefSecNum(Static Expressions and Static Subtypes)).
+It also does not cover the accuracy of the predefined attributes of a
+floating point subtype that yield a value of the type;
+such operations also yield exact results
+(see @RefSecNum(Operations of Floating Point Types)
+and @RefSecNum(Attributes of Floating Point Types)).
address@hidden
+
address@hidden interval}
+An @i(operand interval) is the model interval, of the type specified for the
+operand of an operation, associated with the value of the operand.
+
address@hidden@;For any predefined arithmetic operation
+that yields a result of a
+floating point type T, the required bounds on the result are given by
+a model interval of T (called the @i(result interval)) defined in terms of the
+operand values as follows:
address@hidden(Itemize)
+   @Defn2{Term=[result interval],
+           Sec=[for the evaluation of a predefined arithmetic operation]}
+   The result interval is the smallest model interval of T that includes
+   the minimum and the maximum of all the values obtained by applying the
+   (exact) mathematical operation to values arbitrarily selected from the
+   respective operand intervals.
address@hidden(Itemize)
+
+The result interval of an exponentiation is obtained by applying the above rule
+to the sequence of multiplications defined by the exponent, assuming arbitrary
+association of the factors, and to the final division in the case of a negative
+exponent.
+
+The result interval of a conversion of a numeric value to a floating point type
+T is the model interval of T associated with the operand value, except when the
+source expression is of a fixed point type
+with a @i(small) that is not a power
+of T'Machine_Radix or is a fixed point multiplication or division either of
+whose operands has a @i(small) that is not a power of T'Machine_Radix;
+in these cases, the result interval is implementation defined.
address@hidden result interval in certain cases of fixed-to-float conversion.}
+
address@hidden
+For any of the foregoing operations, the implementation shall deliver a value
+that belongs to the result interval when both bounds of the result interval are
+in the safe range of the result type T, as determined by the values of
+T'Safe_First and T'Safe_Last; otherwise,
address@hidden(itemize)
+   @Defn2{Term=[Constraint_Error],Sec=(raised by failure of run-time check)}
+   if T'Machine_Overflows is True, the implementation shall either deliver a
+   value that belongs to the result interval or raise Constraint_Error;
+
+   if T'Machine_Overflows is False, the result is implementation defined.
+   @ImplDef{The result of a floating point arithmetic operation in
+   overflow situations, when the Machine_Overflows attribute of the result
+   type is False.}
address@hidden(itemize)
+
+For any predefined relation on operands of a floating point type T, the
+implementation may deliver any value (i.e., either True or False) obtained by
+applying the (exact) mathematical comparison to values arbitrarily chosen from
+the respective operand intervals.
+
+The result of a membership test is defined in terms of comparisons of the
+operand value with the lower and upper bounds of the given range or type
+mark (the usual rules apply to these comparisons).
address@hidden
+
address@hidden
+If the underlying floating point hardware implements division
+as multiplication by a reciprocal, the result interval
+for division (and exponentiation by a negative exponent) is
+implementation
+defined.
address@hidden result interval for division (or exponentiation by a
+negative exponent), when the floating point hardware implements division as
+multiplication by a reciprocal.}
address@hidden
+
address@hidden
+The Ada 95 model numbers of a floating point type that are in the safe range of
+the type are comparable to the Ada 83 safe numbers of the type. There is no
+analog of the Ada 83 model numbers. The Ada 95 model numbers, when not
+restricted to the safe range, are an infinite set.
address@hidden
+
address@hidden
address@hidden with Ada 83}
+Giving the model numbers the hardware radix, instead of always a radix of two,
+allows (in conjunction with other changes) some borderline declared
+types to be represented with less precision than in Ada 83 (i.e., with single
+precision, whereas Ada 83 would have used double precision). Because the lower
+precision satisfies the requirements of the model (and did so in Ada 83 as
+well), this change is viewed as a desirable correction of an anomaly, rather
+than a worrisome inconsistency. (Of course, the wider representation chosen in
+Ada 83 also remains eligible for selection in Ada 95.)
+
+As an example of this phenomenon, assume that Float is represented in single
+precision and that a double precision type is also available. Also assume
+hexadecimal hardware with clean properties, for example certain IBM hardware.
+Then,
address@hidden
address@hidden T @key[is] @key[digits] Float'Digits @key[range] -Float'Last .. 
Float'Last;
address@hidden
+
+results in T being represented in double precision in Ada 83 and in single
+precision in Ada 95. The latter is intuitively correct; the former is
+counterintuitive. The reason why the double precision type is used in Ada 83
+is that Float has model and safe numbers (in Ada 83) with 21 binary digits in
+their mantissas, as is required to model the hypothesized
+hexadecimal hardware using a binary
+radix; thus Float'Last, which is not a model number, is slightly outside the
+range of safe numbers of the single precision type, making that type ineligible
+for selection as the representation of T even though it provides adequate
+precision. In Ada 95, Float'Last (the same value as before) is a model number
+and is in the safe range of Float on the hypothesized hardware, making Float
+eligible for the representation of T.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Giving the model numbers the hardware radix allows for practical
+implementations on decimal hardware.
address@hidden
+
address@hidden
+The wording of the model of floating point arithmetic has been simplified to a
+large extent.
address@hidden
+
+
address@hidden Attributes of Floating Point Types}
+
address@hidden
+In implementations that support the Numerics Annex, the model-oriented
+attributes of floating point types shall yield the values defined here,
+in both the strict and the relaxed modes.
+These definitions add conditions to those in
address@hidden of Floating Point Types}.
address@hidden
+
address@hidden
address@hidden@keepnext@;For every subtype S of a floating point type @i{T}:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00256-01]}
+S'@Attr{Model_Mantissa} @\Yields the number of digits in the mantissa of
+the canonical form of the model numbers of @i{T}
+(see @RefSecNum{Attributes of Floating Point Types}). The
+value of this attribute shall be greater than or equal address@hidden,New=[],
+Old=[ @address@hidden @Times @Log(10) / @Log(@RI{T}'@R{Machine_Radix})} + 1, 
where @RI{d}
+is the requested decimal precision of @i{T}. In addition, it
+shall be less than or equal to the value of
address@hidden'Machine_Mantissa. This attribute yields a value of the
+type @i{universal_integer}.]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden@RI{d} @Times @Log(10) / 
@Log(@RI{T}'@R{Machine_Radix})} + @RI{g}]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,NoPrefix=[T],Text=[where @RI{d}
+is the requested decimal precision of @i{T}, and @RI{g} is 0 if
address@hidden'Machine_Radix
+is a positive power of 10 and 1 otherwise. In addition, @i{T}'Model_Mantissa
+shall be less than or equal to the value of
address@hidden'Machine_Mantissa. This attribute yields a value of the
+type @i{universal_integer}.]}
+  @begin{Ramification}
+     S'Model_Epsilon, which is defined in terms of S'Model_Mantissa
+     (see @RefSecNum{Attributes of Floating Point Types}), yields the
+     absolute value of the difference between one and the next model number of
+     the type @i{T} above one.
+     It is equal to or larger than the absolute value of the difference
+     between one and the next machine number of the type @i{T} above
+     one.
+  @end{Ramification}
+
+S'@Attr{Model_Emin} @\Yields the minimum exponent of the canonical form
+of the model numbers of @i{T}
+(see @RefSecNum{Attributes of Floating Point Types}). The value of this
+attribute shall be greater than or equal to the value of
address@hidden'Machine_Emin. This attribute yields a value of the type
address@hidden
+  @begin{Ramification}
+     S'Model_Small, which is defined in terms of S'Model_Emin
+     (see @RefSecNum{Attributes of Floating Point Types}), yields the
+     smallest positive (nonzero) model number of the type @i{T}.
+  @end{Ramification}
+
+S'@Attr{Safe_First} @\Yields the lower bound of the safe range of @i{T}.
+The value of this attribute shall be a model number of @i{T} and greater
+than or equal to the lower bound of the base range of @i{T}.
+In addition, if @i{T} is declared by a
address@hidden or is derived from such a type,
+and the @nt{floating_point_definition} includes a
address@hidden specifying a lower bound of @RI{lb},
+then the value of this attribute shall be less than or
+equal to @RI{lb}; otherwise, it shall be less than or equal to
address@hidden@;10.0 @+[4 @Times @RI{d}], where @RI{d} is the requested decimal 
precision
+of @i{T}. This attribute yields a value of the type
address@hidden
+
+S'@Attr{Safe_Last} @\Yields the upper bound of the safe range of @i{T}.
+The value of this attribute shall be a model number of @i{T} and less
+than or equal to the upper bound of the base range of @i{T}.
+In addition, if @i{T} is declared by a
address@hidden or is derived from such a type,
+and the @nt{floating_point_definition} includes a
address@hidden specifying an upper bound of @RI{ub},
+then the value of this attribute shall be greater than or
+equal to @RI{ub}; otherwise, it shall be greater than or equal
+to 10.0 @+[4 @Times @RI{d}], where d is the requested decimal
+precision of @i{T}. This attribute yields a value of the type
address@hidden
+
address@hidden,Sec=(raised by failure of run-time check)}S'@Attr{Model} 
@\Denotes a function (of a parameter @i{X}) whose specification
+is given in
address@hidden of Floating Point Types}.
+If @i{X} is a model number of @i{T}, the
+function yields @i{X}; otherwise, it yields the value obtained
+by rounding or truncating @i{X} to either one of the adjacent
+model numbers of @i{T}.
address@hidden is raised if the
+resulting model number is outside the safe range of S. A
+zero result has the sign of @i{X} when S'Signed_Zeros is True.
address@hidden
+
address@hidden@;Subject to the constraints given above, the values of 
S'Model_Mantissa and
+S'Safe_Last are to be maximized, and the values of S'Model_Emin and
+S'Safe_First minimized, by the implementation as follows:
address@hidden
+First, S'Model_Mantissa is set to the largest value for which values
+of S'Model_Emin, S'Safe_First, and S'Safe_Last can be chosen so that
+the implementation satisfies the strict-mode requirements of
address@hidden of Floating Point Arithmetic} in
+terms of the model numbers and safe range induced by these attributes.
+
+Next, S'Model_Emin is set to the smallest value for which values of
+S'Safe_First and S'Safe_Last can be chosen so that the implementation
+satisfies the strict-mode requirements of
address@hidden of Floating Point Arithmetic} in terms of the model
+numbers and safe range induced by these attributes and the previously
+determined value of S'Model_Mantissa.
+
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
+Finally, S'Safe_First and S'@Chg{Version=[3],New=[Safe_Last],Old=[Safe_last]}
+are set (in either order) to the
+smallest and largest values, respectively, for which the
+implementation satisfies the strict-mode requirements of
address@hidden of Floating Point Arithmetic} in
+terms of the model numbers and safe range induced by these attributes
+and the previously determined values of S'Model_Mantissa and
+S'Model_Emin.
address@hidden
+
address@hidden
+
address@hidden floating point arithmetic}
address@hidden 559:1989}
+The following table shows appropriate attribute values for IEEE basic
+single and double precision types (ANSI/IEEE Std 754-1985, IEC 559:1989).
+Here, we use the names IEEE_Float_32 and IEEE_Float_64,
+the names that would typically be declared in package Interfaces,
+in an implementation that supports IEEE arithmetic.
+In such an implementation,
+the attributes would typically be the same for Standard.Float and
+Long_Float, respectively.
address@hidden
+Attribute                        IEEE_Float_32                 IEEE_Float_64
+
+'Machine_Radix                               2                             2
+'Machine_Mantissa                           24                            53
+'Machine_Emin                             -125                         -1021
+'Machine_Emax                              128                          1024
+'Denorm                                   True                          True
+'Machine_Rounds                           True                          True
+'Machine_Overflows                  True/False                    True/False
+'Signed_Zeros                   should be True                should be True
+
+'Model_Mantissa    (same as 'Machine_Mantissa)   (same as 'Machine_Mantissa)
+'Model_Emin            (same as 'Machine_Emin)       (same as 'Machine_Emin)
+'Model_Epsilon                      2.0**(-23)                    2.0**(-52)
+'Model_Small                       2.0**(-126)                  2.0**(-1022)
+'Safe_First         -2.0**128*(1.0-2.0**(-24))   -2.0**1024*(1.0-2.0**(-53))
+'Safe_Last           2.0**128*(1.0-2.0**(-24))    2.0**1024*(1.0-2.0**(-53))
+
+'Digits                                      6                            15
+'Base'Digits                 (same as 'Digits)             (same as 'Digits)
+
+'First                   (same as 'Safe_First)         (same as 'Safe_First)
+'Last                     (same as 'Safe_Last)          (same as 'Safe_Last)
+'Size                                       32                            64
address@hidden
+
+Note: 'Machine_Overflows can be True or False, depending on whether the Ada
+implementation raises Constraint_Error or delivers a signed infinity in
+overflow and zerodivide situations (and at poles of the elementary functions).
+
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00256-01]}
+  @ChgAdded{Version=[2],Text=[Corrected the definition of Model_Mantissa to
+  match that given in @RefSecNum{Operations of Floating Point Types}.]}
address@hidden
+
+
+
address@hidden of Fixed Point Arithmetic}
+
address@hidden
+In the strict mode, the predefined arithmetic operations of a fixed point type
+shall satisfy the accuracy requirements specified here and shall avoid or
+signal overflow in the situations described.
address@hidden
+
address@hidden
+The accuracy requirements for the predefined fixed point arithmetic operations
+and conversions, and the results of relations on fixed point operands, are
+given below.
address@hidden
+This subclause does not cover the accuracy of an operation of a static
+expression; such operations
+have to be evaluated exactly
+(see @RefSecNum(Static Expressions and Static Subtypes)).
address@hidden
+
+The operands of the fixed point adding operators, absolute value,
+and comparisons have the same type. These operations are required to
+yield exact results, unless they overflow.
+
+Multiplications and divisions are allowed between operands of any two
+fixed point types; the result has to be (implicitly or explicitly)
+converted to some other numeric type.
+For purposes of defining the accuracy rules, the multiplication or
+division and the conversion are treated
+as a single operation whose accuracy depends on three types (those
+of the operands and the result).
+For decimal fixed point types, the
+attribute T'Round may be used to imply explicit conversion with
+rounding (see @RefSecNum(Operations of Fixed Point Types)).
+
+When the result type is a floating point type, the accuracy is
+as given in @RefSecNum(Model of Floating Point Arithmetic).
address@hidden result set}
+For some combinations of the operand and result types in the remaining cases,
+the result is required to belong to a small set of values called the
address@hidden(perfect result set);
address@hidden result set}
+for other combinations, it is required merely to belong to a
+generally larger and implementation-defined set of values called the
address@hidden(close result set).
+When the result type is a decimal fixed point type, the perfect result set
+contains a single value; thus, operations on decimal types are always
+fully specified.
address@hidden definition of @i{close result set}, which determines the
+accuracy of certain fixed point multiplications and
+divisions.}
+
+When one operand of a fixed-fixed multiplication or division is of type
address@hidden(universal_real), that operand is not implicitly converted in the 
usual sense,
+since the context does not determine a unique target type, but the accuracy of
+the result of the multiplication or division (i.e., whether the result has to
+belong to the perfect result set or merely the close result set) depends on the
+value of the operand of type @i(universal_real) and on the types of the other
+operand and of the result.
address@hidden
+We need not consider here the multiplication or
+division of two such operands, since in that case either the operation is
+evaluated exactly (i.e., it is an operation of a static expression all of whose
+operators are of a root numeric type) or it is considered to be an operation of
+a floating point type.
address@hidden
+
address@hidden@;For a fixed point multiplication or division whose (exact)
+mathematical result is @RI{v}, and for the conversion of a value
address@hidden to a fixed point type, the perfect result set and close result 
set
+are defined as follows:
address@hidden(itemize)
+      @address@hidden@;If the result type is an ordinary fixed point
+      type with a @i(small) of @RI{s},
+      @begin(InnerItemize)
+         if @RI{v} is an integer multiple of
+         @RI{s},
+         then the perfect result set contains only the value
+         @RI{v};
+
+         otherwise, it contains the integer multiple of
+         @RI{s} just below
+         @RI{v} and the
+         integer multiple of @RI{s} just above
+         @RI{v}.
+      @end(InnerItemize)
+
+      @NoPrefix@;The close result set is an implementation-defined set of 
consecutive
+      integer multiples of @RI{s} containing the perfect
+      result set as a subset.
+
+      @address@hidden@;If the result type is a decimal type with a @i(small) of
+      @RI{s},
+      @begin(InnerItemize)
+         if @RI{v} is an integer multiple of
+         @RI{s},
+         then the perfect result set contains
+         only the value @RI{v};
+
+         @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+         otherwise, if truncation address@hidden,New=[,],Old=[]}
+         then it contains only the integer
+         multiple of @RI{s} in the direction toward zero,
+         whereas if rounding address@hidden,New=[,],Old=[]}
+         then it contains only the nearest integer multiple of
+         @RI{s} (with ties broken by rounding away from zero).
+      @end(InnerItemize)
+
+      @NoPrefix@;The close result set is an implementation-defined set of 
consecutive
+      integer multiples of @RI{s} containing the perfect
+      result set as a subset.
+      @begin{Ramification}
+        As a consequence of subsequent rules, this case does not arise
+        when the operand types are also decimal types.
+      @end{Ramification}
+
+      @address@hidden@;If the result type is an integer type,
+      @begin(InnerItemize)
+         if @RI{v} is an integer,
+         then the perfect result set contains only the
+         value @RI{v};
+
+         otherwise, it contains the integer nearest to the value
+         @RI{v} (if @RI{v} lies
+         equally distant from two consecutive integers, the perfect result set
+         contains the one that is further from zero).
+      @end(InnerItemize)
+
+      @NoPrefix@;The close result set is an implementation-defined set of 
consecutive
+      integers containing the perfect result set as a subset.
address@hidden(itemize)
+
+The result of a fixed point multiplication or division shall belong either to
+the perfect result set or to the close result set, as described below, if
+overflow does not occur. In the following
+cases, if the result type is a fixed point type,
+let @RI{s} be its @i(small);
+otherwise, i.e. when the result type is an integer type,
+let @RI{s} be 1.0.
address@hidden(itemize)
+   For a multiplication or division neither of whose operands is of type
+   @i(universal_real), let @RI{l} and @RI{r}
+   be the @i(smalls) of the left and right
+   operands. For a multiplication, if (@RI{l} @Times @RI{r}) / @RI{s}
+   is an integer or the
+   reciprocal of an integer (the @i(smalls) are said to be 
@lquotes@;address@hidden@; in
+   this case), the result shall belong to the perfect result set; otherwise, it
+   belongs to the close result set. For a division, if
+   @RI{l} / (@RI{r} @Times @RI{s}) is an
+   integer or the reciprocal of an integer (i.e., the @i(smalls) are
+   compatible), the result shall belong to the perfect result set; otherwise,
+   it belongs to the close result set.
+   @begin{Ramification}
+      When the operand and result types are all decimal types, their @i(smalls)
+      are necessarily compatible; the same is true when they are all ordinary
+      fixed point types with binary @i(smalls).
+   @end{Ramification}
+
+   For a multiplication or division having one @i(universal_real) operand with
+   a value of @RI{v},
+   note that it is always possible to factor
+   @RI{v} as an integer
+   multiple of a @lquotes@;address@hidden@; @i(small), but the integer 
multiple may be
+   @lquotes@;too address@hidden@;
+   If there exists a factorization in which that multiple is less than some
+   implementation-defined limit, the result shall belong to the perfect result
+   set; otherwise, it belongs to the close result set.
+   @ImplDef{Conditions on a @i{universal_real} operand of a fixed point
+   multiplication or division for which the result shall be in the @i{perfect
+   result set}.}
address@hidden(itemize)
+
+A multiplication P * Q of an operand of a fixed point type F by an operand of
+an integer type I, or vice-versa, and a division P / Q of an operand of a
+fixed point type F by an operand of an integer type I, are also allowed.
+In these cases, the result has a type of F; explicit conversion of the
+result is never required. The accuracy required in these cases is the same as
+that required for a multiplication F(P * Q) or a division F(P / Q) obtained by
+interpreting the operand of the integer type to have a fixed point type with a
address@hidden(small) of 1.0.
+
+The accuracy of the result of a conversion from an integer or fixed point type
+to a fixed point type, or from a fixed point type to an integer
+type, is the same as that of a fixed point multiplication of the source value
+by a fixed point operand having a @i(small) of 1.0 and a value of 1.0, as given
+by the foregoing rules. The result of a conversion from a floating point type
+to a fixed point type shall belong to the close result set.
+The result of a conversion of a @i(universal_real) operand to a fixed point
+type shall belong to the perfect result set.
+
+The possibility of overflow in the result of a predefined arithmetic operation
+or conversion yielding a result of a fixed point type T is analogous to that
+for floating point types, except for being related to the base range instead of
+the safe range.
address@hidden
+If all of the permitted results belong to the base range of T,
+then the implementation shall deliver one of the permitted results; otherwise,
address@hidden(itemize)
+   @Defn2{Term=[Constraint_Error],Sec=(raised by failure of run-time check)}
+   if T'Machine_Overflows is True, the implementation shall either deliver one
+   of the permitted results or raise Constraint_Error;
+
+   if T'Machine_Overflows is False, the result is implementation defined.
+   @ImplDef{The result of a fixed point arithmetic operation in overflow
+   situations, when the Machine_Overflows attribute of the result type is
+   False.}
address@hidden(itemize)
address@hidden
+
address@hidden
address@hidden with Ada 83}
+Since the values of a fixed point type are now just the integer multiples of
+its @i{small}, the possibility of using extra bits available in the chosen
+representation for extra accuracy rather than for increasing the base range
+would appear to be removed, raising the possibility that some fixed point
+expressions will yield less accurate results than in Ada 83. However, this is
+partially offset by the ability of an implementation to choose a smaller
+default @i{small} than before. Of course, if it does so for a type T then
+T'Small will have a different value than it previously had.
+
+The accuracy requirements in the case of incompatible @i{smalls} are relaxed to
+foster wider support for nonbinary @i{smalls}. If this relaxation is
+exploited for a type that was previously supported, lower accuracy could
+result; however, there is no particular incentive to exploit the relaxation in
+such a case.
address@hidden
+
address@hidden
address@hidden@;The fixed point accuracy requirements are now expressed without 
reference to
+model or safe numbers, largely because the full generality of the former model
+was never exploited in the case of fixed point types (particularly in regard to
+operand perturbation). Although the new formulation in terms of perfect result
+sets and close result sets is still verbose, it can be seen to distill down to
+two cases:
address@hidden
+   a case where the result must be the exact result, if the exact result is
+   representable, or, if not, then either one of the adjacent values of the
+   type (in some subcases only one of those adjacent values is allowed);
+
+   a case where the accuracy is not specified by the language.
address@hidden
address@hidden
+
+
address@hidden Requirements for the Elementary Functions}
+
address@hidden
+In the strict mode, the performance of Numerics.Generic_Elementary_Functions
+shall be as specified here.
address@hidden
+
address@hidden
address@hidden interval],
+        Sec=[for the evaluation of an elementary function]}
address@hidden relative error],
+        Sec=[for the evaluation of an elementary function]}
+When an exception is not raised, the result of evaluating a function in an
+instance @i{EF} of Numerics.Generic_Elementary_Functions belongs to a @i{result
+interval}, defined as the smallest model interval of @i{EF}.Float_Type that
+contains all the values of the form @RI{f} @Times (1.0 + @RI{d}), where @RI{f} 
is the
+exact value of the corresponding mathematical function at the given parameter
+values, @RI{d} is a real number, and @address@hidden is less than or equal to
+the function's @i{maximum relative error}.
address@hidden
+The function delivers a value that belongs to the result interval when both of
+its bounds belong to the safe range of @i{EF}.Float_Type; otherwise,
address@hidden
+   @Defn2{Term=[Constraint_Error],Sec=(raised by failure of run-time check)}
+   if @i{EF}.Float_Type'Machine_Overflows is True, the function either delivers
+   a value that belongs to the result interval or raises Constraint_Error,
+   signaling overflow;
+
+   @Trailing@;if @i{EF}.Float_Type'Machine_Overflows is False, the result is
+   implementation defined.
+   @ImplDef{The result of an elementary function reference in overflow
+   situations, when the Machine_Overflows attribute of the result type is
+   False.}
address@hidden
+
address@hidden@;The maximum relative error exhibited by each function is as 
follows:
address@hidden
+   2.0 @Times @address@hidden'Model_Epsilon], in the case of the Sqrt, Sin,
+   and Cos functions;
+
+   4.0 @Times @address@hidden'Model_Epsilon], in the case of the Log, Exp,
+   Tan, Cot, and inverse trigonometric functions; and
+
+   8.0 @Times @address@hidden'Model_Epsilon], in the case of the forward and
+   inverse hyperbolic functions.
address@hidden
+
+The maximum relative error exhibited by the exponentiation operator, which
+depends on the values of the operands, is
+(4.0 + @address@hidden @Times @Log(@R[Left])} / 32.0) @Times
address@hidden@R[.Float_Type'Model_Epsilon].
+
+The maximum relative error given above applies throughout the domain of
+the forward trigonometric functions when the Cycle parameter is specified.
address@hidden threshold}
+When the Cycle parameter is omitted, the maximum relative error given above
+applies only when the absolute value of the angle parameter X is less than or
+equal to some implementation-defined @i{angle threshold}, which shall be at
+least
address@hidden@address@hidden'address@hidden 
@+<@Floor(@address@hidden@!Type'address@hidden/2)>.
+Beyond the angle threshold, the accuracy of the forward trigonometric functions
+is implementation defined.
address@hidden value of the @i{angle threshold}, within which certain elementary
+functions, complex arithmetic operations, and complex elementary functions
+yield results conforming to a maximum relative error bound.}
address@hidden accuracy of certain elementary functions for parameters beyond 
the
+angle threshold.}
address@hidden
+   The angle threshold indirectly determines the amount of precision that the
+   implementation has to maintain during argument reduction.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+The prescribed results specified in @RefSecNum{Elementary Functions} for 
certain
+functions at particular parameter values take precedence over the maximum
+relative error bounds; effectively, they narrow to a single value the result
+interval allowed by the maximum relative error bounds. Additional rules with a
+similar effect are given by @Chg{Version=[2],New=[],Old=[the ]}table
address@hidden,New=[G-1],Old=[below]} for the inverse trigonometric
+functions, at particular parameter values for which the mathematical result is
+possibly not a model number of @i{EF}.Float_Type (or is, indeed, even
+transcendental). In each table entry, the values of the parameters are such
+that the result lies on the axis between two quadrants; the corresponding
+accuracy rule, which takes precedence over the maximum relative error bounds,
+is that the result interval is the model interval of @i{EF}.Float_Type
+associated with the exact mathematical result given in the table.
+
address@hidden, Kind=[Deleted]}
address@hidden<>,Old=<@ @;@comment{Empty paragraph to hang junk paragraph 
number (12) from original RM}>]
+
address@hidden@Comment{For ISO version of Ada 2012 Standard}
+The last line of the table is meant to apply when
address@hidden'Signed_Zeros is False; the two lines just above it, when
address@hidden'Signed_Zeros is True and the parameter Y has a zero value
+with the indicated sign.
+
address@hidden<5>,Alignment=<AllCenter>,FirstColWidth=[2],LastColWidth=[1],
+NoBreak=[T],Border=[T],SmallSize=[F],
+Caption=<@address@hidden,New=[Table G-1: ],Old=[]}Tightly Approximated 
Elementary Function Results}>,
+Headers=<@address@hidden@b{Value of address@hidden@b{Value of 
address@hidden@b{Exact Result @*when Cycle @address@hidden@b{Exact Result 
@*when Cycle @*Omitted}>,
+Body=<address@hidden@address@hidden/address@hidden@Pi/2.0
address@hidden@en@;address@hidden@address@hidden@R[Cycle]/address@hidden@address@hidden/2.0
address@hidden@address@hidden/address@hidden@Pi/2.0
address@hidden@en@;address@hidden@\Cycle/address@hidden@Pi
+Arctan and address@hidden@address@hidden/address@hidden@Pi/2.0
+Arctan and 
address@hidden@address@hidden@address@hidden/address@hidden@address@hidden/2.0
+Arctan and address@hidden@address@hidden/address@hidden@Pi
+Arctan and 
address@hidden@address@hidden@;address@hidden@address@hidden/address@hidden@address@hidden@Last
+Arctan and address@hidden@address@hidden/address@hidden@Pi>]
+The amount by which the result of an inverse trigonometric function is allowed
+to spill over into a quadrant adjacent to the one corresponding to the
+principal branch, as given in @RefSecNum{Elementary Functions}, is limited.
+The rule is that the result belongs to the smallest model interval of
address@hidden that contains both boundaries of the quadrant corresponding
+to the principal branch. This rule also takes precedence over the maximum
+relative error bounds, effectively narrowing the result interval allowed by
+them.
+
address@hidden Ada 95 with Corr, table G-1 appears here}
+
address@hidden@;Finally, the following specifications also take precedence over 
the maximum
+relative error bounds:
address@hidden
+   The absolute value of the result of the Sin, Cos, and Tanh functions never
+   exceeds one.
+
+   The absolute value of the result of the Coth function is never less than
+   one.
+
+   The result of the Cosh function is never less than one.
address@hidden
address@hidden
+
address@hidden
+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.
address@hidden,Kind=[Added],address@hidden,
+Text=[For elementary functions, the forward trigonometric functions without a
+Cycle parameter should not be implemented by calling the corresponding version
+with a Cycle parameter. Log without a Base parameter should not be implemented
+by calling Log with a Base parameter.]}]}
address@hidden
+
address@hidden
address@hidden@;The semantics of Numerics.Generic_Elementary_Functions differs 
from
+Generic_Elementary_Functions as defined in ISO/IEC DIS 11430 (for Ada 83) in
+the following ways related to the accuracy specified for strict mode:
address@hidden
+   The maximum relative error bounds use the Model_Epsilon attribute instead of
+   the Base'Epsilon attribute.
+
+   The accuracy requirements are expressed in terms of result intervals that
+   are model intervals. On the one hand, this facilitates the description of
+   the required results in the presence of underflow; on the other hand, it
+   slightly relaxes the requirements expressed in ISO/IEC DIS 11430.
address@hidden
address@hidden
+
+
address@hidden Requirements for Random Number Generation}
+
address@hidden
+In the strict mode, the performance of Numerics.Float_Random and
+Numerics.Discrete_Random shall be as specified here.
address@hidden
+
address@hidden
+Two different calls to the time-dependent Reset procedure shall reset the
+generator to different states, provided that the calls are separated in time by
+at least one second and not more than fifty
+years.
+
+The implementation's representations of generator states and its algorithms for
+generating random numbers shall yield a period of at least 
address@hidden@en@;2;
+much longer periods are desirable but not required.
+
+The implementations of Numerics.Float_Random.Random and
+Numerics.Discrete_Random.Random shall pass at least 85% of the individual
+trials in a suite of statistical tests. For Numerics.Float_Random, the tests
+are applied directly to the floating point values generated (i.e., they are not
+converted to integers first), while for Numerics.Discrete_Random they are
+applied to the generated values of various discrete types. Each test suite
+performs 6 different tests, with each test repeated 10 times, yielding a total
+of 60 individual trials. An individual trial is deemed to pass if the
+chi-square value (or other statistic) calculated for the observed counts or
+distribution falls within the range of values corresponding to the 2.5 and 97.5
+percentage points for the relevant degrees of freedom (i.e., it shall be
+neither too high nor too low). For the purpose of determining the degrees of
+freedom, measurement categories are combined whenever the expected counts are
+fewer than 5.
address@hidden
+   In the floating point random number test suite, the generator is reset to a
+   time-dependent state at the beginning of the run. The test suite
+   incorporates the following tests, adapted from D. E. Knuth, @i{The Art of
+   Computer Programming, vol. 2: Seminumerical Algorithms.}  In the
+   descriptions below, the given number of degrees of freedom is the number
+   before reduction due to any necessary combination of measurement categories
+   with small expected counts; it is one less than the number of measurement
+   categories.
+   @begin{itemize}
+      Proportional Distribution Test (a variant of the Equidistribution Test).
+      The interval 0.0 .. 1.0 is partitioned into @RI{K} subintervals.
+      @RI{K} is chosen randomly between 4 and 25 for each repetition of the
+      test, along with the boundaries of the subintervals (subject to the
+      constraint that at least 2 of the subintervals have a width of 0.001 or
+      more). 5000 random floating point numbers are generated. The counts of
+      random numbers falling into each subinterval are tallied and compared
+      with the expected counts, which are proportional to the widths of the
+      subintervals. The number of degrees of freedom for the chi-square test
+      is @address@hidden@;1.
+
+      Gap Test. The bounds of a range @RI{A} .. @RI{B}, with
+      0.0 @leq @RI{A} @Lt @RI{B} @leq 1.0, are chosen randomly for each 
repetition
+      of the test, subject to the constraint that 0.2 @leq 
@address@hidden@RI{A} @leq 0.6.
+      Random floating point numbers are generated until 5000 falling into the
+      range @RI{A} .. @RI{B} have been encountered. Each of these 5000 is
+      preceded by a @lquotes@;address@hidden@; (of length greater than or 
equal to 0) of
+      consecutive random numbers not falling into the range
+      @RI{A} .. @RI{B}. The counts of gaps of each length from 0 to 15,
+      and of all lengths greater than 15 lumped together, are tallied and
+      compared with the expected counts. Let @RI{P} = @address@hidden@RI{A}. 
The
+      probability that a gap has a length of @RI{L} is (address@hidden@RI{P}) 
@address@hidden
+      @Times @RI{P} for @RI{L} @leq 15, while the probability that a gap has a
+      length of 16 or more is (address@hidden@RI{P}) @+[16]. The number of 
degrees of
+      freedom for the chi-square test is 16.
+
+      Permutation Test. 5000 tuples of 4 different random floating point
+      numbers are generated. (An entire 4-tuple is discarded in the unlikely
+      event that it contains any two exactly equal components.) The counts of
+      each of the 4! = 24 possible relative orderings of the
+      components of the 4-tuples are tallied and compared with the expected
+      counts. Each of the possible relative orderings has an equal
+      probability. The number of degrees of freedom for the chi-square test
+      is 23.
+
+      Increasing-Runs Test. Random floating point numbers are generated until
+      5000 increasing runs have been observed. An @lquotes@;increasing 
address@hidden@; is a
+      sequence of random numbers in strictly increasing order; it is followed
+      by a random number that is strictly smaller than the preceding random
+      number. (A run under construction is entirely discarded in the unlikely
+      event that one random number is followed immediately by an exactly equal
+      random number.) The decreasing random number that follows an increasing
+      run is discarded and not included with the next increasing run. The
+      counts of increasing runs of each length from 1 to 4, and of all lengths
+      greater than 4 lumped together, are tallied and compared with the
+      expected counts. The probability that an increasing run has a length of
+      @RI{L} is 1/@RI{L}! @en 1/(@RI{L}+1)! for @RI{L} @leq 4, while
+      the probability that an increasing run has a length of 5 or more is
+      1/5!. The number of degrees of freedom for the chi-square test
+      is 4.
+
+      Decreasing-Runs Test. The test is similar to the Increasing Runs Test,
+      but with decreasing runs.
+
+      address@hidden Test (with @RI{t} = 5). 5000 tuples of
+      5 random floating point numbers are generated. The maximum of the
+      components of each 5-tuple is determined and raised to the 5th power.
+      The uniformity of the resulting values over the range 0.0 .. 1.0 is
+      tested as in the Proportional Distribution Test.
+   @end{itemize}
address@hidden
address@hidden
+   In the discrete random number test suite, Numerics.Discrete_Random is
+   instantiated as described below. The generator is reset to a time-dependent
+   state after each instantiation. The test suite incorporates the following
+   tests, adapted from D. E. Knuth (@i{op. cit.}) and other sources. The given
+   number of degrees of freedom for the chi-square test is reduced by any
+   necessary combination of measurement categories with small expected counts,
+   as described above.
+   @begin{Itemize}
+      Equidistribution Test. In each repetition of the test, a number @RI{R}
+      between 2 and 30 is chosen randomly, and Numerics.Discrete_Random is
+      instantiated with an integer subtype whose range is 1 .. @RI{R}. 5000
+      integers are generated randomly from this range. The counts of
+      occurrences of each integer in the range are tallied and compared with
+      the expected counts, which have equal probabilities. The number of
+      degrees of freedom for the chi-square test is @address@hidden@;1.
+
+      Simplified Poker Test. Numerics.Discrete_Random is instantiated once
+      with an enumeration subtype representing the 13 denominations (Two
+      through Ten, Jack, Queen, King, and Ace) of an infinite deck of playing
+      cards. 2000 @lquotes@;address@hidden@; hands (5-tuples of values of this 
subtype) are
+      generated randomly. The counts of hands containing exactly @RI{K}
+      different denominations (1 @leq @RI{K} @leq 5) are tallied and compared
+      with the expected counts. The probability that a hand contains exactly
+      @RI{K} different denominations is given by a formula in Knuth. The
+      number of degrees of freedom for the chi-square test is 4.
+
+      Coupon Collector's Test. Numerics.Discrete_Random is instantiated in
+      each repetition of the test with an integer subtype whose range is
+      1 .. @RI{R}, where @RI{R} varies systematically from 2 to 11.
+      Integers are generated randomly from this range until each value in the
+      range has occurred, and the number @RI{K} of integers generated is
+      recorded. This constitutes a @lquotes@;coupon collector's 
address@hidden@; of length
+      @RI{K}. 2000 such segments are generated. The counts of segments of
+      each length from @RI{R} to @RI{R}+29, and of all lengths greater than
+      @RI{R}+29 lumped together, are tallied and compared with the expected
+      counts. The probability that a segment has any given length is given by
+      formulas in Knuth. The number of degrees of freedom for the chi-square
+      test is 30.
+
+      Craps Test (Lengths of Games). Numerics.Discrete_Random is instantiated
+      once with an integer subtype whose range is 1 .. 6 (representing the six
+      numbers on a die). 5000 craps games are played, and their lengths are
+      recorded. (The length of a craps game is the number of rolls of the pair
+      of dice required to produce a win or a loss.
+      A game is won on the first roll if
+      the dice show 7 or 11; it is lost if they show 2, 3, or 12. If the dice
+      show some other sum on the first roll, it is called the @i{point}, and
+      the game is won if and only if the point is rolled again before a 7 is
+      rolled.) The counts of games of each length from 1 to 18, and of all
+      lengths greater than 18 lumped together, are tallied and compared with
+      the expected counts. For 2 @leq @RI{S} @leq 12, let
+      @RI{D} @address@hidden be the probability that a roll of a pair of dice 
shows
+      the sum @RI{S}, and let
+      @RI{Q} @address@hidden(@RI{L}) = @RI{D} @address@hidden @Times
+      (1 @en (@RI{D} @address@hidden + @RI{D} @-[7])) @address@hidden@en@;2] 
@Times
+      (@RI{D} @address@hidden + @RI{D} @-[7]). Then, the probability that a
+      game has a length of 1 is @RI{D} @-[7] +
+      @RI{D} @-[11] + @RI{D} @-[2] +
+      @RI{D} @-[3] + @RI{D} @-[12]
+      and, for @RI{L} @Gt 1, the probability that a game has a length of
+      @RI{L} is @RI{Q} @-[4](@RI{L}) +
+      @RI{Q} @-[5](@RI{L}) + @RI{Q} @-[6](@RI{L}) + @RI{Q} @-[8](@RI{L})
+      + @RI{Q} @-[9](@RI{L}) + @RI{Q}
+      @-[10](@RI{L}). The number of degrees of freedom for the chi-square test
+      is 18.
+
+      Craps Test (Lengths of Passes). This test is similar to the last, but
+      enough craps games are played for 3000 losses to occur. A string of wins
+      followed by a loss is called a @i{pass}, and its length is the
+      number of wins preceding the loss. The counts of passes of each length
+      from 0 to 7, and of all lengths greater than 7 lumped together, are
+      tallied and compared with the expected counts. For @RI{L} @geq 0, the
+      probability that a pass has a length of @RI{L} is
+      @RI{W} @address@hidden @Times (address@hidden@RI{W}), where @RI{W}, the 
probability that a game
+      ends in a win, is 244.0/495.0. The number of degrees of freedom for the
+      chi-square test is 8.
+
+      Collision Test. Numerics.Discrete_Random is instantiated once with an
+      integer or enumeration type representing binary bits. 15 successive
+      calls on the Random function are used to obtain the bits of a 15-bit
+      binary integer between 0 and 32767. 3000 such integers are generated,
+      and the number of collisions (integers previously generated) is counted
+      and compared with the expected count. A chi-square test is not used to
+      assess the number of collisions; rather, the limits on the number of
+      collisions, corresponding to the 2.5 and 97.5 percentage points, are
+      (from formulas in Knuth) 112 and 154. The test passes if and only if the
+      number of collisions is in this range.
+   @end{Itemize}
address@hidden
address@hidden
+
address@hidden Requirements for Complex Arithmetic}
+
address@hidden
+In the strict mode, the performance of address@hidden and
address@hidden@address@hidden shall be as specified here.
address@hidden
+
address@hidden
+When an exception is not raised, the result of evaluating a real function of
+an instance @i{CT} of Numerics.Generic_Complex_Types (i.e., a function that
+yields a value of subtype @i{CT}.Real'Base or @i{CT}.Imaginary) belongs to a
+result interval defined as for a real elementary function
+(see @RefSecNum{Accuracy Requirements for the Elementary Functions}).
+
address@hidden interval],
+        Sec=[for a component of the result of evaluating a complex function]}
+When an exception is not raised, each component of the result of evaluating a
+complex function of such an instance, or of an instance of
+Numerics.Generic_Complex_Elementary_Functions obtained by instantiating the
+latter with @i{CT} (i.e., a function that yields a value of subtype
address@hidden), also belongs to a @i{result interval}. The result intervals
+for the components of the result are either defined by a
address@hidden relative error} bound or by a @i{maximum box error} bound.
address@hidden relative error],
+        Sec=[for a component of the result of evaluating a complex function]}
+When the result interval for the real (resp., imaginary) component is defined 
by
+maximum relative error, it is defined as for that of a real function, relative
+to the exact value of the real (resp., imaginary) part of the result of the
+corresponding mathematical function.
address@hidden box error],
+        Sec=[for a component of the result of evaluating a complex function]}
+When defined by maximum box error, the result interval for a component of the
+result is the smallest model interval of @i{CT}.Real that contains all the
+values of the corresponding part of @RI{f} @Times (1.0 + @RI{d}), where @RI{f} 
is the
+exact complex value of the corresponding mathematical function at the given
+parameter values, @RI{d} is complex, and @address@hidden is less than or equal
+to the given maximum box error.
address@hidden
+The function delivers a value that belongs to the result interval (or a value
+both of whose components belong to their respective result intervals) when both
+bounds of the result interval(s) belong to the safe range of @i{CT}.Real;
+otherwise,
address@hidden
+   The maximum relative error could be specified separately for each
+   component, but we do not take advantage of that freedom here.
address@hidden
address@hidden
+  Note that
+  @RI{f} @Times (1.0 + @RI{d}) defines a small circular region of the complex
+  plane centered at @RI{f}, and the result intervals for
+  the real and imaginary
+  components of the result define a small rectangular box containing that
+  circle.
address@hidden
address@hidden
+   Box error is used when the computation of the result risks loss of
+   significance in a component due to cancellation.
address@hidden
address@hidden
+   The components of a complex function that exhibits bounded relative error in
+   each component have to have the correct sign. In contrast, one of
+   the components of a complex function that exhibits bounded box error may
+   have the wrong sign, since the dimensions of the box containing the result
+   are proportional to the modulus of the mathematical result and not to either
+   component of the mathematical result individually. Thus, for example, the
+   box containing the computed result of a complex function whose mathematical
+   result has a large modulus but lies very close to the imaginary axis might
+   well straddle that axis, allowing the real component of the computed result
+   to have the wrong sign. In this case, the distance between the computed
+   result and the mathematical result is, nevertheless, a small fraction of the
+   modulus of the mathematical result.
address@hidden
address@hidden
+   @Defn2{Term=[Constraint_Error],Sec=(raised by failure of run-time check)}
+   if @i{CT}.Real'Machine_Overflows is True, the function either delivers a
+   value that belongs to the result interval (or a value both of whose
+   components belong to their respective result intervals) or raises
+   Constraint_Error, signaling overflow;
+
+   if @i{CT}.Real'Machine_Overflows is False, the result is
+   implementation defined.
+   @ImplDef{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.}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+The error bounds for particular complex functions are tabulated 
@Chg{Version=[2],New=[in table G-2],Old=[below]}.
+In the table, the error bound is given as the coefficient of
address@hidden'Model_Epsilon.
+
address@hidden, Kind=[Deleted]}
address@hidden<>,Old=<@ @;@comment{Empty paragraph to hang junk paragraph 
number (7) from original RM}>]
+
address@hidden@Comment{For ISO version of Ada 2012 Standard}
address@hidden<4>,Alignment=<AllCenter>,FirstColWidth=[2],LastColWidth=[1],
+NoBreak=[T],Border=[T],SmallSize=[F],
+Caption=<@address@hidden,New=[Table G-2: ],Old=[]}Error Bounds for Particular 
Complex Functions}>,
+Headers=<@b{Function or address@hidden@b{Nature of @address@hidden@b{Nature of 
@address@hidden@b{Error Bound}>,
+Body=<address@hidden@\max. rel. address@hidden
address@hidden@\max. rel. address@hidden
address@hidden@\max. rel. address@hidden
+"*" (both operands complex)@address@hidden box address@hidden
+"/" (right operand complex)@address@hidden box address@hidden
address@hidden@\max. rel. address@hidden
address@hidden@\max. box address@hidden
+Exp (complex parameter)@address@hidden rel. address@hidden
+Exp (imaginary parameter)@address@hidden rel. address@hidden
+Sin, Cos, Sinh, and address@hidden@\max. rel. address@hidden
+Tan, Cot, Tanh, and address@hidden@\max. rel. address@hidden
+inverse address@hidden@\max. rel. address@hidden@Last
+inverse address@hidden@\max. rel. address@hidden>]
+
+The maximum relative error given above applies throughout the domain of the
+Compose_From_Polar function when the Cycle parameter is specified. When the
+Cycle parameter is omitted, the maximum relative error applies only when the
+absolute value of the parameter Argument is less than or equal to the angle
+threshold (see @RefSecNum{Accuracy Requirements for the Elementary Functions}).
+For the Exp function, and for the forward hyperbolic (resp., trigonometric)
+functions, the maximum relative error given above likewise applies only when
+the absolute value of the imaginary (resp., real) component of the parameter X
+(or the absolute value of the parameter itself, in the case of the Exp function
+with a parameter of pure-imaginary type) is less than or equal to the angle
+threshold. For larger angles, the accuracy is
+implementation defined.
address@hidden accuracy of certain complex arithmetic operations and certain
+complex elementary functions for parameters (or components thereof) beyond
+the angle threshold.}
+
address@hidden Ada 95 with Corr, table G-2 appears here}
+
address@hidden@;The prescribed results specified in
address@hidden Elementary Functions} for certain functions at particular
+parameter values take precedence over the error bounds;
+effectively, they narrow to a single value the result interval allowed by
+the error bounds for a component of the result. Additional rules with a similar
+effect are given below for certain inverse trigonometric and inverse hyperbolic
+functions, at particular parameter values for which a component of the
+mathematical result is transcendental. In each case, the accuracy rule,
+which takes precedence over the error bounds, is that the result interval
+for the stated result component is the model interval of @i{CT}.Real
+associated with the component's exact mathematical value. The cases in
+question are as follows:
address@hidden
+   When the parameter X has the value zero, the real (resp., imaginary)
+   component of the result of the Arccot (resp., Arccoth) function is in the
+   model interval of @i{CT}.Real associated with the value @Pi/2.0.
+
+   When the parameter X has the value one, the real component of the result of
+   the Arcsin function is in the model interval of @i{CT}.Real associated with
+   the value @Pi/2.0.
+
+   When the parameter X has the value @en@;1.0, the real component of the
+   result of the Arcsin (resp., Arccos) function is in the model interval of
+   @i{CT}.Real associated with the value @address@hidden/2.0 (resp.,
+   @Pi).
address@hidden
address@hidden
+   It is possible to give many other prescribed results in which a component of
+   the parameter is restricted to a similar model interval when the parameter X
+   is appropriately restricted to an easily testable portion of the domain.
+   We follow the proposed ISO/IEC standard for
+   Generic_Complex_Elementary_Functions (for Ada 83) in not doing so, however.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+The amount by which a component of the result of an inverse trigonometric or
+inverse hyperbolic function is allowed to spill over into a quadrant adjacent
+to the one corresponding to the principal branch, as given in
address@hidden Elementary Functions}, is limited. The rule is that the
+result belongs to the smallest model interval of @i{CT}.Real that contains both
+boundaries of the quadrant corresponding to the principal branch. This rule
+also takes precedence @Chg{Version=[2],New=[over],Old=[to]} the maximum error
+bounds, effectively narrowing the result interval allowed by them.
+
+Finally, the results allowed by the error bounds are narrowed by one further
+rule: The absolute value of each component of the result of the Exp function,
+for a pure-imaginary parameter, never exceeds one.
address@hidden
+
address@hidden
+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.
address@hidden,Kind=[Added],address@hidden,
+Text=[For complex arithmetic, the Compose_From_Polar function without a Cycle
+parameter should not be implemented by calling Compose_From_Polar with a Cycle
+parameter.]}]}
address@hidden
+
address@hidden
+The semantics of Numerics.Generic_Complex_Types and
+Numerics.Generic_Complex_Elementary_Functions differs from
+Generic_Complex_Types and Generic_Complex_Elementary_Functions as defined in
+ISO/IEC CDs
+13813 and 13814 (for Ada 83) in ways analogous to
+those identified for the elementary functions in
address@hidden Requirements for the Elementary Functions}.
+In addition,
+we do not generally specify the signs of zero results (or result
+components), although those proposed standards do.
address@hidden
+
+
address@hidden,Name=[Vector and Matrix Manipulation]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Types and operations for the manipulation
+of real vectors and matrices are provided in Generic_Real_Arrays, which is
+defined in @RefSecNum[Real Vectors and Matrices]. Types and
+operations for the manipulation of complex vectors and matrices are provided
+in Generic_Complex_Arrays, which is defined in
address@hidden Vectors and Matrices]. Both of these library units
+are generic children of the predefined package Numerics (see
address@hidden Numerics Packages]). Nongeneric
+equivalents of these packages for each of the predefined floating point types
+are also provided as children of Numerics.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Vector and matrix manipulation is defined in
+  the Numerics Annex, rather than in the core, because it is considered
+  to be a specialized need of (some) numeric applications.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[These packages provide facilities that are
+  similar to and replace those found in ISO/IEC 13813:1998
+  @i{Information technology @em Programming languages @em
+  Generic packages of real and complex type declarations and basic
+  operations for Ada (including vector and matrix types)}.
+  (The other facilities provided by that Standard were already provided in Ada
+  95.) In addition to the main facilities of that Standard, these packages also
+  include subprograms for the solution of linear equations, matrix inversion,
+  determinants, and the determination of the eigenvalues and eigenvectors of
+  real symmetric matrices and Hermitian matrices.]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00296-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  This @Chg{Version=[3],New=[subclause],Old=[clause]}
+  It just provides an introduction to the following subclauses.]}
address@hidden
+
+
address@hidden,Name=[Real Vectors and Matrices]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01],ARef=[AI95-00418-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+package Numerics.Generic_Real_Arrays has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key{type} Real @key{is digits} <>;
address@hidden Ada.Numerics.Generic_Real_Arrays 
@address@hidden,Child=[Generic_Real_Arrays]}
+   @key{pragma} Pure(Generic_Real_Arrays);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Types}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Real_Vector} @key{is array} 
(Integer @key{range} <>) @key{of} Real'Base;
+   @key{type} @AdaTypeDefn{Real_Matrix} @key{is array} (Integer @key{range} 
<>, Integer @key{range} <>)
+                                                   @key{of} Real'Base;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Subprograms for Real_Vector types}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Real_Vector arithmetic operations}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "+"   (Right : Real_Vector)       
@key{return} Real_Vector;
+   @key{function} "-"   (Right : Real_Vector)       @key{return} Real_Vector;
+   @key{function} "@key{abs}" (Right : Real_Vector)       @key{return} 
Real_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "+"   (Left, Right : Real_Vector) 
@key{return} Real_Vector;
+   @key{function} "-"   (Left, Right : Real_Vector) @key{return} Real_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*"   (Left, Right : Real_Vector) 
@key{return} Real'Base;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "@key{abs}" (Right : Real_Vector)       
@key{return} Real'Base;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Real_Vector scaling operations]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*" (Left : Real'Base;   Right : 
Real_Vector)
+      @key{return} Real_Vector;
+   @key{function} "*" (Left : Real_Vector; Right : Real'Base)
+      @key{return} Real_Vector;
+   @key{function} "/" (Left : Real_Vector; Right : Real'Base)
+      @key{return} Real_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Other Real_Vector operations]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Unit_Vector} (Index : 
Integer;
+                         Order : Positive;
+                         First : Integer := 1) @key{return} Real_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Subprograms for Real_Matrix types]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Real_Matrix arithmetic operations]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "+"       (Right : Real_Matrix) 
@key{return} Real_Matrix;
+   @key{function} "-"       (Right : Real_Matrix) @key{return} Real_Matrix;
+   @key{function} "@key{abs}"     (Right : Real_Matrix) @key{return} 
Real_Matrix;
+   @key{function} @AdaSubDefn{Transpose} (X     : Real_Matrix) @key{return} 
Real_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "+" (Left, Right : Real_Matrix) 
@key{return} Real_Matrix;
+   @key{function} "-" (Left, Right : Real_Matrix) @key{return} Real_Matrix;
+   @key{function} "*" (Left, Right : Real_Matrix) @key{return} Real_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*" (Left, Right : Real_Vector) 
@key{return} Real_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*" (Left : Real_Vector; Right : 
Real_Matrix)
+      @key{return} Real_Vector;
+   @key{function} "*" (Left : Real_Matrix; Right : Real_Vector)
+      @key{return} Real_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Real_Matrix scaling operations]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*" (Left : Real'Base;   Right : 
Real_Matrix)
+      @key{return} Real_Matrix;
+   @key{function} "*" (Left : Real_Matrix; Right : Real'Base)
+      @key{return} Real_Matrix;
+   @key{function} "/" (Left : Real_Matrix; Right : Real'Base)
+      @key{return} Real_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Real_Matrix inversion and related operations]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Solve} (A : Real_Matrix; X : 
Real_Vector) @key{return} Real_Vector;
+   @key{function} @AdaSubDefn{Solve} (A, X : Real_Matrix) @key{return} 
Real_Matrix;
+   @key{function} @AdaSubDefn{Inverse} (A : Real_Matrix) @key{return} 
Real_Matrix;
+   @key{function} @AdaSubDefn{Determinant} (A : Real_Matrix) @key{return} 
Real'Base;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Eigenvalues and vectors of a real symmetric 
matrix]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Eigenvalues} (A : 
Real_Matrix) @key{return} Real_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Eigensystem} (A       : 
@key{in}  Real_Matrix;
+                          Values  : @key{out} Real_Vector;
+                          Vectors : @key{out} Real_Matrix);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Other Real_Matrix operations]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Unit_Matrix} (Order          
  : Positive;
+                         First_1, First_2 : Integer := 1)
+                                            @key{return} Real_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Numerics.Generic_Real_Arrays;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,address@hidden,address@hidden
+The library package Numerics.Real_Arrays is declared pure and defines the
+same types and subprograms as Numerics.Generic_Real_Arrays, except that
+the predefined type Float is systematically substituted for Real'Base
+throughout. Nongeneric equivalents for each of the other predefined floating
+point types are defined similarly, with the names Numerics.Short_Real_Arrays,
+Numerics.Long_Real_Arrays, etc.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[
+   The nongeneric equivalents are provided to allow the programmer to
+   construct simple mathematical applications without being required to
+   understand and use generics, and to be consistent with other
+   Numerics packages.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Two types are defined and exported by
+Numerics.Generic_Real_Arrays. The composite type Real_Vector is provided to
+represent a vector with components of type Real; it is defined as an
+unconstrained, one-dimensional array with an index of type Integer. The
+composite type Real_Matrix is provided to represent a matrix with components of
+type Real; it is defined as an unconstrained, two-dimensional array with
+indices of type Integer.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[The effect of the various subprograms is as described
+below. In most cases the subprograms are described in terms of corresponding
+scalar operations of the type Real; any exception raised by those operations is
+propagated by the array operation. Moreover, the accuracy of the result for
+each individual component is as defined for the scalar operation unless stated
+otherwise.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[In the case of those operations which are defined
+to @i{involve an inner product}, Constraint_Error may be raised if an 
intermediate
+result is outside the range of Real'Base even though the mathematical final
+result would not address@hidden an inner product],Sec=[real]}]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "+"   (Right : Real_Vector) 
@key{return} Real_Vector;
address@hidden "-"   (Right : Real_Vector) @key{return} Real_Vector;
address@hidden "@key{abs}" (Right : Real_Vector) @key{return} Real_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Type=[Trailing],Text=[Each operation returns the result
+of applying the corresponding operation of the type Real to each component of
+Right. The index range of the result is Right'Range.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "+" (Left, Right : Real_Vector) 
@key{return} Real_Vector;
address@hidden "-" (Left, Right : Real_Vector) @key{return} Real_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation of the type Real to each component of Left and the
+matching component of Right. The index range of the result is Left'Range.
+Constraint_Error is raised if Left'Length is not equal to Right'Length.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left, Right : Real_Vector) 
@key{return} Real'Base;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation returns the inner product of Left
+and Right. Constraint_Error is raised if Left'Length is not equal to
+Right'Length. This operation involves an inner product.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "@key{abs}" (Right : Real_Vector) 
@key{return} Real'Base;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00418-01]}
address@hidden,Text=[This operation returns the L2-norm of Right (the
+square root of the inner product of the vector with itself).]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Normalization of vectors is a frequent enough
+  operation that it is useful to provide the norm as a basic operation.
+  Furthermore, implementing the norm is not entirely straightforward, because
+  the inner product might overflow while the final norm does not. An
+  implementation cannot merely return Sqrt (X * X), it has to cope with a
+  possible overflow of the inner product.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[While the definition is given in terms of
+  an inner product, the norm doesn't @lquotes@;involve an inner 
address@hidden@;
+  in the technical sense. The reason is that it has accuracy requirements
+  substantially different from those applicable to inner products; and that
+  cancellations cannot occur, because all the terms are positive, so there
+  is no possibility of intermediate overflow.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Real'Base; Right : 
Real_Vector) @key{return} Real_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation returns the result of multiplying
+each component of Right by the scalar Left using the "*" operation of the type
+Real. The index range of the result is Right'Range.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Real_Vector; Right : 
Real'Base) @key{return} Real_Vector;
address@hidden "/" (Left : Real_Vector; Right : Real'Base) @key{return} 
Real_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation of the type Real to each component of Left and to the
+scalar Right. The index range of the result is Left'Range.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Unit_Vector (Index : Integer;
+                      Order : Positive;
+                      First : Integer := 1) @key{return} Real_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns a @i<unit vector>@Defn2{Term=[unit 
vector],Sec=[real vector]}
+with Order components and a lower bound of First. All components are set to 0.0
+except for the Index component which is set to 1.0. Constraint_Error is raised
+if Index < First, Index > First + Order @en 1 or if First + Order @en 1 >
+Integer'Last.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "+"   (Right : Real_Matrix) 
@key{return} Real_Matrix;
address@hidden "-"   (Right : Real_Matrix) @key{return} Real_Matrix;
address@hidden "@key{abs}" (Right : Real_Matrix) @key{return} Real_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation of the type Real to each component of Right. The index
+ranges of the result are those of Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Transpose (X : Real_Matrix) 
@key{return} Real_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns the transpose of a matrix X.
+The first and second index ranges of the result are X'Range(2) and X'Range(1)
+respectively.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "+" (Left, Right : Real_Matrix) 
@key{return} Real_Matrix;
address@hidden "-" (Left, Right : Real_Matrix) @key{return} Real_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation of the type Real to each component of Left and the
+matching component of Right. The index ranges of the result are those of Left.
+Constraint_Error is raised if Left'Length(1) is not equal to Right'Length(1) or
+Left'Length(2) is not equal to Right'Length(2).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left, Right : Real_Matrix) 
@key{return} Real_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation provides the standard mathematical
+operation for matrix multiplication. The first and second index ranges of the
+result are Left'Range(1) and Right'Range(2) respectively. Constraint_Error is
+raised if Left'Length(2) is not equal to Right'Length(1). This operation
+involves inner products.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left, Right : Real_Vector) 
@key{return} Real_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation returns the outer product of a
+(column) vector Left by a (row) vector Right using the operation "*" of the
+type Real for computing the individual components. The first and second index
+ranges of the result are Left'Range and Right'Range respectively.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Real_Vector; Right : 
Real_Matrix) @key{return} Real_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation provides the standard mathematical
+operation for multiplication of a (row) vector Left by a matrix Right. The
+index range of the (row) vector result is Right'Range(2). Constraint_Error is
+raised if Left'Length is not equal to Right'Length(1). This operation involves
+inner products.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Real_Matrix; Right : 
Real_Vector) @key{return} Real_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation provides the standard mathematical
+operation for multiplication of a matrix Left by a (column) vector Right. The
+index range of the (column) vector result is Left'Range(1). Constraint_Error is
+raised if Left'Length(2) is not equal to Right'Length. This operation involves
+inner products.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Real'Base; Right : 
Real_Matrix) @key{return} Real_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation returns the result of multiplying
+each component of Right by the scalar Left using the "*" operation of the type
+Real. The index ranges of the result are those of Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Real_Matrix; Right : 
Real'Base) @key{return} Real_Matrix;
address@hidden "/" (Left : Real_Matrix; Right : Real'Base) @key{return} 
Real_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation of the type Real to each component of Left and to the
+scalar Right. The index ranges of the result are those of Left.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Solve (A : Real_Matrix; X : 
Real_Vector) @key{return} Real_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns a vector Y such that X is
+(nearly) equal to A * Y. This is the standard mathematical operation for
+solving a single set of linear equations. The index range of the result is
+A'Range(2). Constraint_Error is raised if A'Length(1), A'Length(2), and 
X'Length
+are not equal. Constraint_Error is raised if the matrix A is ill-conditioned.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The text says that Y is such that @lquotes@;X is
+  (nearly) equal to A * address@hidden rather than @lquotes@;X is equal to A *
+  address@hidden because rounding errors may mean that there is no value of Y 
such
+  that X is exactly equal to A * Y. On the other hand it does not mean that any
+  old rough value will do. The algorithm given under @ImplAdviceTitle
+  should be followed.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The requirement to raise Constraint_Error if the
+  matrix is ill-conditioned is really a reflection of what will happen if the
+  matrix is ill-conditioned. See @ImplAdviceTitle.
+  We do not make any attempt to define ill-conditioned formally.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[These remarks apply to all versions of Solve and
+  Inverse.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Solve (A, X : Real_Matrix) 
@key{return} Real_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns a matrix Y such that X is
+(nearly) equal to A * Y. This is the standard mathematical operation for
+solving several sets of linear equations. The index ranges of the result are
+A'Range(2) and X'Range(2). Constraint_Error is raised if A'Length(1), 
A'Length(2), and
+X'Length(1) are not equal. Constraint_Error is raised if the matrix A is
+ill-conditioned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Inverse (A : Real_Matrix) 
@key{return} Real_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns a matrix B such that A * B is
+(nearly) equal to the unit matrix. The index ranges of the result are 
A'Range(2)
+and A'Range(1). Constraint_Error is raised if A'Length(1) is not equal to
+A'Length(2). Constraint_Error is raised if the matrix A is ill-conditioned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Determinant (A : Real_Matrix) 
@key{return} Real'Base;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns the determinant of the matrix
+A. Constraint_Error is raised if A'Length(1) is not equal to A'Length(2).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Eigenvalues(A : Real_Matrix) 
@key{return} Real_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns the eigenvalues of the
+symmetric matrix A as a vector sorted into order with the largest first.
+Constraint_Error is raised if A'Length(1) is not equal to A'Length(2). The
+index range of the result is A'Range(1). Argument_Error is raised if the matrix
+A is not symmetric.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Eigensystem(A       : @key{in}  
Real_Matrix;
+                      Values  : @key{out} Real_Vector;
+                      Vectors : @key{out} Real_Matrix);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0047-1]}
address@hidden,Text=[This procedure computes both the eigenvalues and
+eigenvectors of the symmetric matrix A. The out parameter Values is the same as
+that obtained by calling the function Eigenvalues. The out parameter Vectors is
+a matrix whose columns are the eigenvectors of the matrix A. The order of the
+columns corresponds to the order of the eigenvalues. The eigenvectors are
+normalized and mutually orthogonal (they are orthonormal), including when there
+are repeated eigenvalues. Constraint_Error is raised if A'Length(1) is not
+equal to A'Length(2)@Chg{Version=[3],New=[, or if Values'Range is not equal to
+A'Range(1), or if the],Old=[. The]} index ranges of the parameter Vectors are
address@hidden,New=[not equal to ],Old=[]}those of A. Argument_Error is
+raised if the matrix A is not address@hidden,New=[ Constraint_Error
+is also raised in implementation-defined circumstances if the algorithm used
+does not converge quickly enough.],Old=[]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0047-1]}
+  @ChgAdded{Version=[3],Text=[There is no requirement on the absolute direction
+  of the returned eigenvectors. Thus they might be multiplied by -1. It is only
+  the ratios of the components that matter. This is standard practice.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Unit_Matrix (Order            : 
Positive;
+                      First_1, First_2 : Integer := 1) @key{return} 
Real_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns a square
address@hidden address@hidden matrix],Sec=[real matrix]}
+with Order**2 components and lower bounds of
+First_1 and First_2 (for the first and second index ranges respectively). All
+components are set to 0.0 except for the main diagonal, whose components are
+set to 1.0. Constraint_Error is raised if First_1 + Order @en 1 > Integer'Last 
or
+First_2 + Order @en 1 > Integer'Last.]}
+
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Accuracy requirements for the subprograms Solve,
+Inverse, Determinant, Eigenvalues and Eigensystem are implementation defined.]}
address@hidden,Kind=[AddedNormal],address@hidden,Text=[The
+accuracy requirements for the subprograms Solve,
+Inverse, Determinant, Eigenvalues and Eigensystem for type Real_Matrix.]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[For operations not involving an inner product, the
+accuracy requirements are those of the corresponding operations of the type
+Real in both the strict mode and the relaxed mode
+(see @RefSecNum{Numeric Performance Requirements}).]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[For operations involving an inner
+product, no
+requirements are specified in the relaxed mode. In the strict mode the modulus
+of the absolute error of the inner product @i<X>address@hidden<Y> shall not 
exceed
address@hidden<g>address@hidden<abs>(@i<X>)address@hidden<abs>(@i<Y>) where 
@i<g> is defined as]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<g> = @i<X>'Length * Real'Machine_Radix**(1 @en@; 
Real'Model_Mantissa)]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00418-01]}
address@hidden,Text=[For the L2-norm, no accuracy
+requirements are specified in the relaxed mode. In the strict mode the relative
+error on the norm shall not exceed @i<g> / 2.0 + 3.0 * Real'Model_Epsilon where
address@hidden<g> is defined as above.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is simply the combination of the error on
+  the inner product with the error on Sqrt. A first order computation would
+  lead to 2.0 * Real'Model_Epsilon above, but we are adding an extra
+  Real'Model_Epsilon to account for higher order effects.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Implementations shall document any techniques used
+to reduce cancellation errors such as extended precision arithmetic.]}
address@hidden,Kind=[AddedNormal],address@hidden,Text=[Any
+techniques used to reduce cancellation errors in
+Numerics.Generic_Real_Arrays shall be documented.]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The above accuracy requirement is met by the
+  canonical implementation of the inner product by multiplication and addition
+  using the corresponding operations of type Real'Base and performing the
+  cumulative addition using ascending indices. Note however, that some hardware
+  provides special operations for the computation of the inner product and
+  although these may be fast they may not meet the accuracy requirement
+  specified. See Accuracy and Stability of Numerical Algorithms By N J Higham
+  (ISBN 0-89871-355-2), Section 3.1.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0047-1]}
+  @ChgAdded{Version=[3],Text=[Note moreover that the componentwise accuracy
+  requirements are not met by subcubic methods for matrix multiplication such
+  as that devised by Strassen. These methods, which are typically used for the
+  fast multiplication of very large matrices (e.g. order more than a few
+  thousands), have normwise accuracy properties. If it is desired to use such
+  methods, then distinct subprograms should be provided (perhaps in a child
+  package). See Section 22.2.2 in the above reference.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[The nongeneric equivalent packages may, but need
+not, be actual instantiations of the generic package for the appropriate
+predefined type.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[Implementations should implement the Solve and
+Inverse functions using established techniques such as LU decomposition with
+row interchanges followed by back and forward substitution. Implementations are
+recommended to refine the result by performing an iteration on the residuals;
+if this is address@hidden,New=[,],Old=[]} then it should be documented.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Solve and Inverse for Numerics.Generic_Real_Arrays should be
+implemented using established techniques such as LU decomposition and
+the result should be refined by an iteration on the residuals.]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[It is not the intention that any special provision
+should be made to determine whether a matrix is ill-conditioned or not. The
+naturally occurring overflow (including division by zero) which will result
+from executing these functions with an ill-conditioned matrix and thus raise
+Constraint_Error is sufficient.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[There isn't any advice for the implementation to
+document with this paragraph.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The test that a matrix is symmetric should be
+performed by using the equality operator to compare the relevant components.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The equality operator should be used to test that a matrix in
+Numerics.Generic_Real_Arrays is symmetric.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0047-1]}
address@hidden,Text=[An implementation should minimize the circumstances
+under which the algorithm used for Eigenvalues and Eigensystem fails to
+converge.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[An implementation should minimize the circumstances
+under which the algorithm used for Numerics.Generic_Real_Arrays.Eigenvalues
+and Numerics.Generic_Real_Arrays.Eigensystem fails to converge.]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[J. H. Wilkinson is the acknowledged expert in
+  this area. See for example
+  Wilkinson, J. H., and Reinsch, C. , Linear Algebra , vol II of Handbook
+  for Automatic Computation, Springer-Verlag, or Wilkinson, J. H., The
+  Algebraic Eigenvalue Problem, Oxford University Press.]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00296-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The package Numerics.Generic_Real_Arrays and its nongeneric equivalents
+  are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0047-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected various
+  accuracy and definition issues.]}
address@hidden
+
+
address@hidden,Name=[Complex Vectors and Matrices]}
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+package Numerics.Generic_Complex_Arrays has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Numerics.Generic_Real_Arrays, 
Ada.Numerics.Generic_Complex_Types;
address@hidden
+   @key{with package} Real_Arrays   @key{is new}
+      Ada.Numerics.Generic_Real_Arrays   (<>);
+   @key{use} Real_Arrays;
+   @key{with package} Complex_Types @key{is new}
+      Ada.Numerics.Generic_Complex_Types (Real);
+   @key{use} Complex_Types;
address@hidden Ada.Numerics.Generic_Complex_Arrays 
@address@hidden,address@hidden@!Arrays]}
+   @key{pragma} Pure(Generic_Complex_Arrays);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Types}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Complex_Vector} @key{is array} 
(Integer @key{range} <>) @key{of} Complex;
+   @key{type} @AdaTypeDefn{Complex_Matrix} @key{is array} (Integer @key{range} 
<>,
+                                 Integer @key{range} <>) @key{of} Complex;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Subprograms for Complex_Vector types}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Complex_Vector selection, conversion and 
composition operations}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Re} (X : Complex_Vector) 
@key{return} Real_Vector;
+   @key{function} @AdaSubDefn{Im} (X : Complex_Vector) @key{return} 
Real_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Set_Re} (X  : @key{in out} 
Complex_Vector;
+                     Re : @key{in}     Real_Vector);
+   @key{procedure} @AdaSubDefn{Set_Im} (X  : @key{in out} Complex_Vector;
+                     Im : @key{in}     Real_Vector);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Compose_From_Cartesian} (Re  
   : Real_Vector)
+      @key{return} Complex_Vector;
+   @key{function} @AdaSubDefn{Compose_From_Cartesian} (Re, Im : Real_Vector)
+      @key{return} Complex_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Modulus}  (X     : 
Complex_Vector) @key{return} Real_Vector;
+   @key{function} "@key{abs}"    (Right : Complex_Vector) @key{return} 
Real_Vector
+                                                 @key{renames} Modulus;
+   @key{function} @AdaSubDefn{Argument} (X     : Complex_Vector) @key{return} 
Real_Vector;
+   @key{function} @AdaSubDefn{Argument} (X     : Complex_Vector;
+                      Cycle : Real'Base)      @key{return} Real_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Compose_From_Polar} 
(Modulus, Argument : Real_Vector)
+      @key{return} Complex_Vector;
+   @key{function} @AdaSubDefn{Compose_From_Polar} (Modulus, Argument : 
Real_Vector;
+                                Cycle             : Real'Base)
+      @key{return} Complex_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Complex_Vector arithmetic operations}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "+"       (Right  : Complex_Vector) 
@key{return} Complex_Vector;
+   @key{function} "-"       (Right  : Complex_Vector) @key{return} 
Complex_Vector;
+   @key{function} @AdaSubDefn{Conjugate} (X      : Complex_Vector) 
@key{return} Complex_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "+"  (Left, Right : Complex_Vector) 
@key{return} Complex_Vector;
+   @key{function} "-"  (Left, Right : Complex_Vector) @key{return} 
Complex_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*"  (Left, Right : Complex_Vector) 
@key{return} Complex;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0047-1]}
address@hidden,Text=[   @key{function} "@key{abs}"     (Right : Complex_Vector) 
@key{return} @Chg{Version=[3],New=[Real'Base],Old=[Complex]};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Mixed Real_Vector and Complex_Vector arithmetic 
operations}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "+" (Left  : Real_Vector;
+                 Right : Complex_Vector) @key{return} Complex_Vector;
+   @key{function} "+" (Left  : Complex_Vector;
+                 Right : Real_Vector)    @key{return} Complex_Vector;
+   @key{function} "-" (Left  : Real_Vector;
+                 Right : Complex_Vector) @key{return} Complex_Vector;
+   @key{function} "-" (Left  : Complex_Vector;
+                 Right : Real_Vector)    @key{return} Complex_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*" (Left  : Real_Vector;    Right : 
Complex_Vector)
+      @key{return} Complex;
+   @key{function} "*" (Left  : Complex_Vector; Right : Real_Vector)
+      @key{return} Complex;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Complex_Vector scaling operations}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*" (Left  : Complex;
+                 Right : Complex_Vector) @key{return} Complex_Vector;
+   @key{function} "*" (Left  : Complex_Vector;
+                 Right : Complex)        @key{return} Complex_Vector;
+   @key{function} "/" (Left  : Complex_Vector;
+                 Right : Complex)        @key{return} Complex_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*" (Left  : Real'Base;
+                 Right : Complex_Vector) @key{return} Complex_Vector;
+   @key{function} "*" (Left  : Complex_Vector;
+                 Right : Real'Base)      @key{return} Complex_Vector;
+   @key{function} "/" (Left  : Complex_Vector;
+                 Right : Real'Base)      @key{return} Complex_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Other Complex_Vector operations}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Unit_Vector} (Index : 
Integer;
+                         Order : Positive;
+                         First : Integer := 1) @key{return} Complex_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Subprograms for Complex_Matrix types}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Complex_Matrix selection, conversion and 
composition operations}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Re} (X : Complex_Matrix) 
@key{return} Real_Matrix;
+   @key{function} @AdaSubDefn{Im} (X : Complex_Matrix) @key{return} 
Real_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Set_Re} (X  : @key{in out} 
Complex_Matrix;
+                     Re : @key{in}     Real_Matrix);
+   @key{procedure} @AdaSubDefn{Set_Im} (X  : @key{in out} Complex_Matrix;
+                     Im : @key{in}     Real_Matrix);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Compose_From_Cartesian} (Re  
   : Real_Matrix)
+      @key{return} Complex_Matrix;
+   @key{function} @AdaSubDefn{Compose_From_Cartesian} (Re, Im : Real_Matrix)
+      @key{return} Complex_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Modulus}  (X     : 
Complex_Matrix) @key{return} Real_Matrix;
+   @key{function} "@key{abs}"    (Right : Complex_Matrix) @key{return} 
Real_Matrix
+                                                 @key{renames} Modulus;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Argument} (X     : 
Complex_Matrix) @key{return} Real_Matrix;
+   @key{function} @AdaSubDefn{Argument} (X     : Complex_Matrix;
+                      Cycle : Real'Base)      @key{return} Real_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Compose_From_Polar} 
(Modulus, Argument : Real_Matrix)
+      @key{return} Complex_Matrix;
+   @key{function} @AdaSubDefn{Compose_From_Polar} (Modulus, Argument : 
Real_Matrix;
+                                Cycle             : Real'Base)
+      @key{return} Complex_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Complex_Matrix arithmetic operations}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "+"       (Right : Complex_Matrix) 
@key{return} Complex_Matrix;
+   @key{function} "-"       (Right : Complex_Matrix) @key{return} 
Complex_Matrix;
+   @key{function} @AdaSubDefn{Conjugate} (X     : Complex_Matrix) @key{return} 
Complex_Matrix;
+   @key{function} @AdaSubDefn{Transpose} (X     : Complex_Matrix) @key{return} 
Complex_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "+" (Left, Right : Complex_Matrix) 
@key{return} Complex_Matrix;
+   @key{function} "-" (Left, Right : Complex_Matrix) @key{return} 
Complex_Matrix;
+   @key{function} "*" (Left, Right : Complex_Matrix) @key{return} 
Complex_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*" (Left, Right : Complex_Vector) 
@key{return} Complex_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*" (Left  : Complex_Vector;
+                 Right : Complex_Matrix) @key{return} Complex_Vector;
+   @key{function} "*" (Left  : Complex_Matrix;
+                 Right : Complex_Vector) @key{return} Complex_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Mixed Real_Matrix and Complex_Matrix arithmetic 
operations}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "+" (Left  : Real_Matrix;
+                 Right : Complex_Matrix) @key{return} Complex_Matrix;
+   @key{function} "+" (Left  : Complex_Matrix;
+                 Right : Real_Matrix)    @key{return} Complex_Matrix;
+   @key{function} "-" (Left  : Real_Matrix;
+                 Right : Complex_Matrix) @key{return} Complex_Matrix;
+   @key{function} "-" (Left  : Complex_Matrix;
+                 Right : Real_Matrix)    @key{return} Complex_Matrix;
+   @key{function} "*" (Left  : Real_Matrix;
+                 Right : Complex_Matrix) @key{return} Complex_Matrix;
+   @key{function} "*" (Left  : Complex_Matrix;
+                 Right : Real_Matrix)    @key{return} Complex_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*" (Left  : Real_Vector;
+                 Right : Complex_Vector) @key{return} Complex_Matrix;
+   @key{function} "*" (Left  : Complex_Vector;
+                 Right : Real_Vector)    @key{return} Complex_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*" (Left  : Real_Vector;
+                 Right : Complex_Matrix) @key{return} Complex_Vector;
+   @key{function} "*" (Left  : Complex_Vector;
+                 Right : Real_Matrix)    @key{return} Complex_Vector;
+   @key{function} "*" (Left  : Real_Matrix;
+                 Right : Complex_Vector) @key{return} Complex_Vector;
+   @key{function} "*" (Left  : Complex_Matrix;
+                 Right : Real_Vector)    @key{return} Complex_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Complex_Matrix scaling operations}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*" (Left  : Complex;
+                 Right : Complex_Matrix) @key{return} Complex_Matrix;
+   @key{function} "*" (Left  : Complex_Matrix;
+                 Right : Complex)        @key{return} Complex_Matrix;
+   @key{function} "/" (Left  : Complex_Matrix;
+                 Right : Complex)        @key{return} Complex_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "*" (Left  : Real'Base;
+                 Right : Complex_Matrix) @key{return} Complex_Matrix;
+   @key{function} "*" (Left  : Complex_Matrix;
+                 Right : Real'Base)      @key{return} Complex_Matrix;
+   @key{function} "/" (Left  : Complex_Matrix;
+                 Right : Real'Base)      @key{return} Complex_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Complex_Matrix inversion and related 
operations}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Solve} (A : Complex_Matrix; 
X : Complex_Vector)
+      @key{return} Complex_Vector;
+   @key{function} @AdaSubDefn{Solve} (A, X : Complex_Matrix) @key{return} 
Complex_Matrix;
+   @key{function} @AdaSubDefn{Inverse} (A : Complex_Matrix) @key{return} 
Complex_Matrix;
+   @key{function} @AdaSubDefn{Determinant} (A : Complex_Matrix) @key{return} 
Complex;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Eigenvalues and vectors of a Hermitian matrix}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Eigenvalues}(A : 
Complex_Matrix) @key{return} Real_Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Eigensystem}(A       : 
@key{in}  Complex_Matrix;
+                         Values  : @key{out} Real_Vector;
+                         Vectors : @key{out} Complex_Matrix);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Other Complex_Matrix operations}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Unit_Matrix} (Order          
  : Positive;
+                         First_1, First_2 : Integer := 1)
+                                            @key{return} Complex_Matrix;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Numerics.Generic_Complex_Arrays;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,address@hidden,address@hidden
+The library package Numerics.Complex_Arrays is declared pure and defines
+the same types and subprograms as Numerics.Generic_Complex_Arrays, except
+that the predefined type Float is systematically substituted for Real'Base,
+and the Real_Vector and Real_Matrix types exported by Numerics.Real_Arrays
+are systematically substituted for Real_Vector and Real_Matrix, and the
+Complex type exported by Numerics.Complex_Types is systematically
+substituted for Complex, throughout. Nongeneric equivalents for each of
+the other predefined floating point types are defined similarly, with the
+names Numerics.Short_Complex_Arrays, Numerics.Long_Complex_Arrays, etc.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Two types are defined and exported by
+Numerics.Generic_Complex_Arrays. The composite type Complex_Vector is
+provided to represent a vector with components of type Complex; it is defined
+as an unconstrained one-dimensional array with an index of type Integer. The
+composite type Complex_Matrix is provided to represent a matrix with components
+of type Complex; it is defined as an unconstrained, two-dimensional array with
+indices of type Integer.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[The effect of the various subprograms is as
+described below. In many cases they are described in terms of corresponding
+scalar operations in Numerics.Generic_Complex_Types. Any exception raised by
+those operations is propagated by the array subprogram. Moreover, any
+constraints on the parameters and the accuracy of the result for each
+individual component are as defined for the scalar operation.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[In the case of those operations which are defined
+to @i{involve an inner product}, Constraint_Error may be raised if an 
intermediate
+result has a component outside the range of Real'Base even though the final
+mathematical result would address@hidden an inner product],Sec=[complex]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0047-1]}
+  @ChgAdded{Version=[3],Text=[An inner product never involves implicit complex
+  conjugation. If the product of a vector with the conjugate of another (or the
+  same) vector is required, then this has to be stated explicitly by writing 
for
+  example X * Conjugate(Y). This mimics the usual mathematical notation.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Re (X : Complex_Vector) @key{return} 
Real_Vector;
address@hidden Im (X : Complex_Vector) @key{return} Real_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each function returns a vector of the specified
+Cartesian components of X. The index range of the result is X'Range.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Set_Re (X  : @key{in out} 
Complex_Vector; Re : @key{in} Real_Vector);
address@hidden Set_Im (X  : @key{in out} Complex_Vector; Im : @key{in} 
Real_Vector);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each procedure replaces the specified (Cartesian)
+component of each of the components of X by the value of the matching component
+of Re or Im; the other (Cartesian) component of each of the components is
+unchanged. Constraint_Error is raised if X'Length is not equal to Re'Length or
+Im'Length.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Compose_From_Cartesian (Re     : 
Real_Vector)
+   @key{return} Complex_Vector;
address@hidden Compose_From_Cartesian (Re, Im : Real_Vector)
+   @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each function constructs a vector of Complex
+results (in Cartesian representation) formed from given vectors of Cartesian
+components; when only the real components are given, imaginary components of
+zero are assumed. The index range of the result is Re'Range. Constraint_Error
+is raised if Re'Length is not equal to Im'Length.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Modulus  (X     : Complex_Vector) 
@key{return} Real_Vector;
address@hidden "@key{abs}"    (Right : Complex_Vector) @key{return} Real_Vector
+                                              @key{renames} Modulus;
address@hidden Argument (X     : Complex_Vector) @key{return} Real_Vector;
address@hidden Argument (X     : Complex_Vector;
+                   Cycle : Real'Base)      @key{return} Real_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each function calculates and returns a vector of
+the specified polar components of X or Right using the corresponding function
+in address@hidden The index range of the result is X'Range or
+Right'Range.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Compose_From_Polar (Modulus, 
Argument : Real_Vector)
+   @key{return} Complex_Vector;
address@hidden Compose_From_Polar (Modulus, Argument : Real_Vector;
+                             Cycle             : Real'Base)
+   @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each function constructs a vector of Complex
+results (in Cartesian representation) formed from given vectors of polar
+components using the corresponding function in address@hidden
+on matching components of Modulus and Argument. The index range of the result
+is Modulus'Range. Constraint_Error is raised if Modulus'Length is not equal to
+Argument'Length.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "+" (Right : Complex_Vector) 
@key{return} Complex_Vector;
address@hidden "-" (Right : Complex_Vector) @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation in address@hidden to each component of
+Right. The index range of the result is Right'Range.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Conjugate (X : Complex_Vector) 
@key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns the result of applying the
+appropriate function Conjugate in address@hidden to each
+component of X. The index range of the result is X'Range.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "+" (Left, Right : Complex_Vector) 
@key{return} Complex_Vector;
address@hidden "-" (Left, Right : Complex_Vector) @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation in address@hidden to each component of
+Left and the matching component of Right. The index range of the result is
+Left'Range. Constraint_Error is raised if Left'Length is not equal to
+Right'Length.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left, Right : Complex_Vector) 
@key{return} Complex;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation returns the inner product of Left
+and Right. Constraint_Error is raised if Left'Length is not equal to
+Right'Length. This operation involves an inner product.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0047-1]}
address@hidden,KeepNext=[T],address@hidden "@key{abs}" (Right : Complex_Vector) 
@key{return} @Chg{Version=[3],New=[Real'Base],Old=[Complex]};]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00418-01]}
address@hidden,Text=[This operation returns the Hermitian L2-norm of
+Right (the square root of the inner product of the vector with its
+conjugate).]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[While the definition is given in terms of
+  an inner product, the norm doesn't @lquotes@;involve an inner address@hidden
+  in the technical sense. The reason is that it has accuracy requirements
+  substantially different from those applicable to inner products; and that
+  cancellations cannot occur, because all the terms are positive, so there
+  is no possibility of intermediate overflow.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "+" (Left  : Real_Vector;
+              Right : Complex_Vector) @key{return} Complex_Vector;
address@hidden "+" (Left  : Complex_Vector;
+              Right : Real_Vector)    @key{return} Complex_Vector;
address@hidden "-" (Left  : Real_Vector;
+              Right : Complex_Vector) @key{return} Complex_Vector;
address@hidden "-" (Left  : Complex_Vector;
+              Right : Real_Vector)    @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation in address@hidden to each component of
+Left and the matching component of Right. The index range of the result is
+Left'Range. Constraint_Error is raised if Left'Length is not equal to
+Right'Length.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Real_Vector;    Right : 
Complex_Vector) @key{return} Complex;
address@hidden "*" (Left : Complex_Vector; Right : Real_Vector)    @key{return} 
Complex;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the inner product of Left
+and Right. Constraint_Error is raised if Left'Length is not equal to
+Right'Length. These operations involve an inner product.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Complex; Right : 
Complex_Vector) @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation returns the result of multiplying
+each component of Right by the complex number Left using the appropriate
+operation "*" in address@hidden The index range of the result
+is Right'Range.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Complex_Vector; Right : 
Complex) @key{return} Complex_Vector;
address@hidden "/" (Left : Complex_Vector; Right : Complex) @key{return} 
Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation in address@hidden to each component of
+the vector Left and the complex number Right. The index range of the result is
+Left'Range.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Real'Base;
+              Right : Complex_Vector) @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation returns the result of multiplying
+each component of Right by the real number Left using the appropriate operation
+"*" in address@hidden The index range of the result is
+Right'Range.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Complex_Vector;
+              Right : Real'Base) @key{return} Complex_Vector;
address@hidden "/" (Left : Complex_Vector;
+              Right : Real'Base) @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation in address@hidden to each component of
+the vector Left and the real number Right. The index range of the result is
+Left'Range.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Unit_Vector (Index : Integer;
+                      Order : Positive;
+                      First : Integer := 1) @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns a @i{unit
address@hidden vector],Sec=[complex vector]} with Order components
+and a lower bound of First. All components are set to (0.0, 0.0) except for the
+Index component which is set to (1.0, 0.0). Constraint_Error is raised if Index
+< First, Index > First + Order @en 1, or if First + Order @en 1 > 
Integer'Last.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Re (X : Complex_Matrix) @key{return} 
Real_Matrix;
address@hidden Im (X : Complex_Matrix) @key{return} Real_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each function returns a matrix of the specified
+Cartesian components of X. The index ranges of the result are those of X.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Set_Re (X : @key{in out} 
Complex_Matrix; Re : @key{in} Real_Matrix);
address@hidden Set_Im (X : @key{in out} Complex_Matrix; Im : @key{in} 
Real_Matrix);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each procedure replaces the specified (Cartesian)
+component of each of the components of X by the value of the matching component
+of Re or Im; the other (Cartesian) component of each of the components is
+unchanged. Constraint_Error is raised if X'Length(1) is not equal to
+Re'Length(1) or Im'Length(1) or if X'Length(2) is not equal to Re'Length(2) or
+Im'Length(2).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Compose_From_Cartesian (Re     : 
Real_Matrix)
+   @key{return} Complex_Matrix;
address@hidden Compose_From_Cartesian (Re, Im : Real_Matrix)
+   @key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each function constructs a matrix of Complex
+results (in Cartesian representation) formed from given matrices of Cartesian
+components; when only the real components are given, imaginary components of
+zero are assumed. The index ranges of the result are those of Re.
+Constraint_Error is raised if Re'Length(1) is not equal to Im'Length(1) or
+Re'Length(2) is not equal to Im'Length(2).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Modulus  (X     : Complex_Matrix) 
@key{return} Real_Matrix;
address@hidden "@key{abs}"    (Right : Complex_Matrix) @key{return} Real_Matrix
+                                              @key{renames} Modulus;
address@hidden Argument (X     : Complex_Matrix) @key{return} Real_Matrix;
address@hidden Argument (X     : Complex_Matrix;
+                   Cycle : Real'Base)      @key{return} Real_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each function calculates and returns a matrix of
+the specified polar components of X or Right using the corresponding function
+in address@hidden The index ranges of the result are those of
+X or Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Compose_From_Polar (Modulus, 
Argument : Real_Matrix)
+   @key{return} Complex_Matrix;
address@hidden Compose_From_Polar (Modulus, Argument : Real_Matrix;
+                             Cycle             : Real'Base)
+   @key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each function constructs a matrix of Complex
+results (in Cartesian representation) formed from given matrices of polar
+components using the corresponding function in address@hidden
+on matching components of Modulus and Argument. The index ranges of the result
+are those of Modulus. Constraint_Error is raised if Modulus'Length(1) is not
+equal to Argument'Length(1) or Modulus'Length(2) is not equal to
+Argument'Length(2).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "+" (Right : Complex_Matrix) 
@key{return} Complex_Matrix;
address@hidden "-" (Right : Complex_Matrix) @key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation in address@hidden to each component of
+Right. The index ranges of the result are those of Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Conjugate (X : Complex_Matrix) 
@key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns the result of applying the
+appropriate function Conjugate in address@hidden to each
+component of X. The index ranges of the result are those of X.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Transpose (X : Complex_Matrix) 
@key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns the transpose of a matrix X.
+The first and second index ranges of the result are X'Range(2) and X'Range(1)
+respectively.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "+" (Left, Right : Complex_Matrix) 
@key{return} Complex_Matrix;
address@hidden "-" (Left, Right : Complex_Matrix) @key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation in address@hidden to each component of
+Left and the matching component of Right. The index ranges of the result are
+those of Left. Constraint_Error is raised if Left'Length(1) is not equal to
+Right'Length(1) or Left'Length(2) is not equal to Right'Length(2).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left, Right : Complex_Matrix) 
@key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation provides the standard mathematical
+operation for matrix multiplication. The first and second index ranges of the
+result are Left'Range(1) and Right'Range(2) respectively. Constraint_Error is
+raised if Left'Length(2) is not equal to Right'Length(1). This operation
+involves inner products.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left, Right : Complex_Vector) 
@key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation returns the outer product of a
+(column) vector Left by a (row) vector Right using the appropriate operation
+"*" in address@hidden for computing the individual components.
+The first and second index ranges of the result are Left'Range and
+Right'Range respectively.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left  : Complex_Vector;
+              Right : Complex_Matrix) @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation provides the standard mathematical
+operation for multiplication of a (row) vector Left by a matrix Right. The
+index range of the (row) vector result is Right'Range(2). Constraint_Error is
+raised if Left'Length is not equal to Right'Length(1). This operation involves
+inner products.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left  : Complex_Matrix;
+              Right : Complex_Vector) @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation provides the standard mathematical
+operation for multiplication of a matrix Left by a (column) vector Right. The
+index range of the (column) vector result is Left'Range(1). Constraint_Error is
+raised if Left'Length(2) is not equal to Right'Length. This operation involves
+inner products.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "+" (Left  : Real_Matrix;
+              Right : Complex_Matrix) @key{return} Complex_Matrix;
address@hidden "+" (Left  : Complex_Matrix;
+              Right : Real_Matrix)    @key{return} Complex_Matrix;
address@hidden "-" (Left  : Real_Matrix;
+              Right : Complex_Matrix) @key{return} Complex_Matrix;
address@hidden "-" (Left  : Complex_Matrix;
+              Right : Real_Matrix)    @key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation in address@hidden to each component of
+Left and the matching component of Right. The index ranges of the result are
+those of Left. Constraint_Error is raised if Left'Length(1) is
+not equal to Right'Length(1) or Left'Length(2) is not equal to
+Right'Length(2).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left  : Real_Matrix;
+              Right : Complex_Matrix) @key{return} Complex_Matrix;
address@hidden "*" (Left  : Complex_Matrix;
+              Right : Real_Matrix)    @key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation provides the standard mathematical
+operation for matrix multiplication. The first and second index ranges of the
+result are Left'Range(1) and Right'Range(2) respectively. Constraint_Error is
+raised if Left'Length(2) is not equal to Right'Length(1). These operations
+involve inner products.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left  : Real_Vector;
+              Right : Complex_Vector) @key{return} Complex_Matrix;
address@hidden "*" (Left  : Complex_Vector;
+              Right : Real_Vector)    @key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the outer product of a
+(column) vector Left by a (row) vector Right using the appropriate operation
+"*" in address@hidden for computing the individual components.
+The first and second index ranges of the result are Left'Range and
+Right'Range respectively.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left  : Real_Vector;
+              Right : Complex_Matrix) @key{return} Complex_Vector;
address@hidden "*" (Left  : Complex_Vector;
+              Right : Real_Matrix)    @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation provides the standard mathematical
+operation for multiplication of a (row) vector Left by a matrix Right. The
+index range of the (row) vector result is Right'Range(2). Constraint_Error is
+raised if Left'Length is not equal to Right'Length(1). These operations involve
+inner products.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left  : Real_Matrix;
+              Right : Complex_Vector) @key{return} Complex_Vector;
address@hidden "*" (Left  : Complex_Matrix;
+              Right : Real_Vector)    @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation provides the standard mathematical
+operation for multiplication of a matrix Left by a (column) vector Right. The
+index range of the (column) vector result is Left'Range(1). Constraint_Error is
+raised if Left'Length(2) is not equal to Right'Length. These operations involve
+inner products.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Complex; Right : 
Complex_Matrix) @key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation returns the result of multiplying
+each component of Right by the complex number Left using the appropriate
+operation "*" in address@hidden The index ranges of the result
+are those of Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Complex_Matrix; Right : 
Complex) @key{return} Complex_Matrix;
address@hidden "/" (Left : Complex_Matrix; Right : Complex) @key{return} 
Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation in address@hidden to each component of
+the matrix Left and the complex number Right. The index ranges of the result
+are those of Left.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Real'Base;
+              Right : Complex_Matrix) @key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This operation returns the result of multiplying
+each component of Right by the real number Left using the appropriate operation
+"*" in address@hidden The index ranges of the result are those
+of Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "*" (Left : Complex_Matrix;
+              Right : Real'Base) @key{return} Complex_Matrix;
address@hidden "/" (Left : Complex_Matrix;
+              Right : Real'Base) @key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Each operation returns the result of applying the
+corresponding operation in address@hidden to each component of
+the matrix Left and the real number Right. The index ranges of the result are
+those of Left.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Solve (A : Complex_Matrix; X : 
Complex_Vector) @key{return} Complex_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns a vector Y such that X is
+(nearly) equal to A * Y. This is the standard mathematical operation for
+solving a single set of linear equations. The index range of the result is
+A'Range(2). Constraint_Error is raised if A'Length(1), A'Length(2), and 
X'Length
+are not equal. Constraint_Error is raised if the matrix A is ill-conditioned.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The text says that Y is such that @lquotes@;X is
+  (nearly) equal to A * address@hidden rather than @lquotes@;X is equal to A *
+  address@hidden because rounding errors may mean that there is no value of Y 
such
+  that X is exactly equal to A * Y. On the other hand it does not mean that any
+  old rough value will do. The algorithm given under @ImplAdviceTitle
+  should be followed.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The requirement to raise Constraint_Error if the
+  matrix is ill-conditioned is really a reflection of what will happen if the
+  matrix is ill-conditioned. See @ImplAdviceTitle.
+  We do not make any attempt to define ill-conditioned formally.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[These remarks apply to all versions of Solve and
+  Inverse.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Solve (A, X : Complex_Matrix) 
@key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns a matrix Y such that X is
+(nearly) equal to A * Y. This is the standard mathematical operation for
+solving several sets of linear equations. The index ranges of the result are
+A'Range(2) and X'Range(2). Constraint_Error is raised if A'Length(1), 
A'Length(2), and
+X'Length(1) are not equal. Constraint_Error is raised if the matrix A is
+ill-conditioned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Inverse (A : Complex_Matrix) 
@key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns a matrix B such that A * B is
+(nearly) equal to the unit matrix. The index ranges of the result are 
A'Range(2)
+and A'Range(1). Constraint_Error is raised if A'Length(1) is not equal to
+A'Length(2). Constraint_Error is raised if the matrix A is ill-conditioned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Determinant (A : Complex_Matrix) 
@key{return} Complex;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns the determinant of the matrix
+A. Constraint_Error is raised if A'Length(1) is not equal to A'Length(2).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Eigenvalues(A : Complex_Matrix) 
@key{return} Real_Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns the eigenvalues of the
+Hermitian matrix A as a vector sorted into order with the largest first.
+Constraint_Error is raised if A'Length(1) is not equal to A'Length(2). The
+index range of the result is A'Range(1). Argument_Error is raised if the matrix
+A is not Hermitian.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[A Hermitian matrix is one whose transpose is
+  equal to its complex conjugate. The eigenvalues of a Hermitian matrix are
+  always real. We only support this case because algorithms for solving the
+  general case are inherently unstable.]}
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Eigensystem(A       : @key{in}  
Complex_Matrix;
+                      Values  :  @key{out} Real_Vector;
+                      Vectors :  @key{out} Complex_Matrix);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0047-1]}
address@hidden,Text=[This procedure computes both the eigenvalues and
+eigenvectors of the Hermitian matrix A. The out parameter Values is the same as
+that obtained by calling the function Eigenvalues. The out parameter Vectors is
+a matrix whose columns are the eigenvectors of the matrix A. The order of the
+columns corresponds to the order of the eigenvalues. The eigenvectors are
+mutually orthonormal, including when there are repeated eigenvalues.
+Constraint_Error is raised if A'Length(1) is not
+equal to A'Length(2)@Chg{Version=[3],New=[, or if Values'Range is not equal to
+A'Range(1), or if the],Old=[. The]} index ranges of the parameter Vectors are
address@hidden,New=[not equal to ],Old=[]}those of A. Argument_Error is
+raised if the matrix A is not address@hidden,New=[ Constraint_Error
+is also raised in implementation-defined circumstances if the algorithm used
+does not converge quickly enough.],Old=[]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0047-1]}
+  @ChgAdded{Version=[3],Text=[There is no requirement on the absolute direction
+  of the returned eigenvectors. Thus they might be multiplied by any complex
+  number whose modulus is 1. It is only the ratios of the components that
+  matter. This is standard practice.]}
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Unit_Matrix (Order            : 
Positive;
+                      First_1, First_2 : Integer := 1)
+                                         @key{return} Complex_Matrix;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[This function returns a square
address@hidden address@hidden matrix],Sec=[complex matrix]}
+with Order**2 components and
+lower bounds of First_1 and First_2 (for the first and second index ranges
+respectively). All components are set to (0.0, 0.0) except for the main 
diagonal,
+whose components are set to (1.0, 0.0). Constraint_Error is raised
+if First_1 + Order @en 1 > Integer'Last or First_2 + Order @en 1 > 
Integer'Last.]}
+
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Accuracy requirements for the subprograms Solve,
+Inverse, Determinant, Eigenvalues and Eigensystem are implementation defined.]}
address@hidden,Kind=[AddedNormal],address@hidden,Text=[The
+accuracy requirements for the subprograms Solve,
+Inverse, Determinant, Eigenvalues and Eigensystem for type Complex_Matrix.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[For operations not involving an inner product, the
+accuracy requirements are those of the corresponding operations of the type
+Real'Base and Complex in both the strict mode and the relaxed mode
+(see @RefSecNum{Numeric Performance Requirements}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[For operations involving an inner product, no
+requirements are specified in the relaxed mode. In the strict mode the modulus
+of the absolute error of the inner product @address@hidden shall not exceed
address@hidden@key{abs}(@i{X})address@hidden(@i{Y}) where @i{g} is defined as]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden = @i{X}'Length * Real'Machine_Radix**(1 @en@; 
Real'Model_Mantissa)
+    for mixed complex and real operands]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden = sqrt(2.0) * @i{X}'Length * 
Real'Machine_Radix**(1 @en@; Real'Model_Mantissa)
+    for two complex operands]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00418-01]}
address@hidden,Text=[For the L2-norm, no accuracy requirements are
+specified in the relaxed mode. In
+the strict mode the relative error on the norm shall not
+exceed @i<g> / 2.0 + 3.0 * Real'Model_Epsilon
+where @i<g> has the definition appropriate for two complex operands.]}
+
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Implementations shall document any techniques used
+to reduce cancellation errors such as extended precision arithmetic.]}
address@hidden,Kind=[AddedNormal],address@hidden,Text=[Any
+techniques used to reduce cancellation errors in
+Numerics.Generic_Complex_Arrays shall be documented.]}]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The above accuracy requirement is met by the
+  canonical implementation of the
+  inner product by multiplication and addition using the corresponding
+  operations of type Complex and performing the cumulative addition using
+  ascending indices. Note however, that some hardware provides special
+  operations for the computation of the inner product and although these may be
+  fast they may not meet the accuracy requirement specified. See Accuracy and
+  Stability of Numerical Algorithms by N J Higham (ISBN 0-89871-355-2),
+  Sections 3.1 and 3.6.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[The nongeneric equivalent packages may, but need
+not, be actual instantiations of the generic package for the appropriate
+predefined type.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Although many operations are defined in terms of
+operations from address@hidden, they need not be implemented by
+calling those operations provided that the effect is the same.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[Implementations should implement the Solve and
+Inverse functions using established techniques. Implementations are recommended
+to refine the result by performing an iteration on the residuals; if this is
address@hidden,New=[,],Old=[]} then it should be documented.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Solve and Inverse for Numerics.Generic_Complex_Arrays should be
+implemented using established techniques and the result should be refined
+by an iteration on the residuals.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[It is not the intention that any special provision
+should be made to determine whether a matrix is ill-conditioned or not. The
+naturally occurring overflow (including division by zero) which will result
+from executing these functions with an ill-conditioned matrix and thus raise
+Constraint_Error is sufficient.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[There isn't any advice for the implementation to
+document with this paragraph.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[The test that a matrix is Hermitian should use the
+equality operator to compare the real components and negation followed by
+equality to compare the imaginary components
+(see @RefSecNum{Model of Floating Point Arithmetic}).]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The equality and negation operators should be used to test that a matrix 
is
+Hermitian.]}]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[An implementation should minimize the circumstances
+under which the algorithm used for Eigenvalues and Eigensystem fails to
+converge.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[An implementation should minimize the circumstances
+under which the algorithm used for Numerics.Generic_Complex_Arrays.Eigenvalues
+and Numerics.Generic_Complex_Arrays.Eigensystem fails to converge.]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[J. H. Wilkinson is the acknowledged expert in
+  this area. See for example
+  Wilkinson, J. H., and Reinsch, C. , Linear Algebra , vol II of Handbook
+  for Automatic Computation, Springer-Verlag, or Wilkinson, J. H., The
+  Algebraic Eigenvalue Problem, Oxford University Press.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00296-01]}
address@hidden,Text=[Implementations should not perform operations on
+mixed complex and real operands by first converting the real operand to
+complex. See @RefSecNum{Complex Types}.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Mixed real and complex operations should not be performed by converting
+the real operand to complex.]}]}
+
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00296-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The package Numerics.Generic_Complex_Arrays and its nongeneric equivalents
+  are address@hidden It would be better if this was called
+  "Ada.Numerics.Generic_Imitation_Arrays", 'cause that's the opposite of Real. 
:-)
+  Just checking if anyone reads this stuff.}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0047-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected various
+  accuracy and definition issues.]}
address@hidden
diff --git a/packages/ada-ref-man/source_2012/obsolescent.mss 
b/packages/ada-ref-man/source_2012/obsolescent.mss
new file mode 100755
index 0000000..263cd6e
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/obsolescent.mss
@@ -0,0 +1,1873 @@
address@hidden(obsolescent, Root="ada.mss")
+
address@hidden: 2015/03/03 05:38:25 $}
address@hidden Features}
+
address@hidden: e:\\cvsroot/ARM/Source/obsolescent.mss,v $}
address@hidden: 1.59 $}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00368-01]}
address@hidden@Defn{obsolescent feature}
+This Annex contains descriptions of features of the
+language whose functionality is largely redundant with other features
+defined by this International Standard.
+Use of these features is not recommended in newly written programs.
address@hidden,New=[Use of these features can be prevented by using pragma
+Restrictions (No_Obsolescent_Features), see
address@hidden Restrictions and Profiles}.],
+Old=[]}]
address@hidden
+These features are still part of the language,
+and have to be implemented by conforming implementations.
+The primary reason for putting these descriptions here
+is to get redundant features out of the way of most readers.
+The designers of the next version of address@hidden,New=[],
+Old=[ after Ada 95]} will have to
+assess whether or not it makes sense to drop these features from the
+language.
address@hidden
address@hidden
+
address@hidden
address@hidden@;The following features have been removed from the language,
+rather than declared to be obsolescent:
address@hidden
+The package Low_Level_IO
+(see @RefSecNum{Input-Output}).
+
+The Epsilon, Mantissa, Emax, Small, Large, Safe_Emax, Safe_Small, and
+Safe_Large attributes of floating point types
+(see @RefSecNum{Attributes of Floating Point Types}).
+
address@hidden,Kind=[Deleted],ARef=[AI95-00284-02]}
address@hidden,Text=[The pragma Interface
+(see @RefSecNum{Interfacing Aspects}).]}
+
+The pragmas System_Name, Storage_Unit, and Memory_Size
+(see @RefSecNum{The Package System}).
+
+The pragma Shared
+(see @RefSecNum{Shared Variable Control}).
address@hidden
+
+Implementations can continue to support the above features for upward
+compatibility.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00368-01]}
+  @ChgAdded{Version=[2],Text=[A mention of the No_Obsolescent_Features
+  restriction was added.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden Controlled has been removed from
+  the language, rather than declared to be obsolescent. No existing
+  implementation gives it any effect. An implementation could continue to
+  support the pragma as an implementation-defined pragma for upward
+  compatibility.]}
address@hidden
+
+
address@hidden,New=[Renamings of Library Units],
+Old=[Renamings of Ada 83 Library Units]}
+
address@hidden
+The following @nt{library_unit_renaming_declaration}s exist:
address@hidden
address@hidden Ada.Unchecked_Conversion;
address@hidden @key[function] Unchecked_Conversion @key[renames] 
Ada.Unchecked_Conversion;
+
address@hidden Ada.Unchecked_Deallocation;
address@hidden @key[procedure] Unchecked_Deallocation @key[renames] 
Ada.Unchecked_Deallocation;
+
address@hidden Ada.Sequential_IO;
address@hidden @key[package] Sequential_IO @key[renames] Ada.Sequential_IO;
+
address@hidden Ada.Direct_IO;
address@hidden @key[package] Direct_IO @key[renames] Ada.Direct_IO;
+
address@hidden Ada.Text_IO;
address@hidden Text_IO @key[renames] Ada.Text_IO;
+
address@hidden Ada.IO_Exceptions;
address@hidden IO_Exceptions @key[renames] Ada.IO_Exceptions;
+
address@hidden Ada.Calendar;
address@hidden Calendar @key[renames] Ada.Calendar;
+
address@hidden System.Machine_Code;
address@hidden Machine_Code @key[renames] System.Machine_Code; address@hidden 
If supported.}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0004-1]}
+  @ChgAdded{Version=[3],Text=[These library units correspond to those declared
+  in Ada 83, which did not have the child unit concept or the parent package
+  Ada.]}
address@hidden
address@hidden
+
address@hidden
+The implementation shall allow the user to replace these renamings.
address@hidden
+
+
address@hidden Replacements of Characters}
+
address@hidden
address@hidden
address@hidden@;The following replacements are allowed for the vertical line, 
number sign,
+and quotation mark characters:
address@hidden
+A vertical line character (|) can be replaced by an exclamation mark
+(!) where used as a delimiter.
+
+
+The number sign characters (#) of a @nt{based_literal} can be replaced
+by colons (:) provided that the replacement is done for both
+occurrences.
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00285-01]}
+  The intent is that such a replacement works in the
+  address@hidden,New=[,],Old=[ and]}
+  address@hidden,New=[, and Wide_Wide_Value],Old=[]} attributes,
+  and in the Get procedures of address@hidden,New=[ (and Wide_Text_IO
+  and Wide_Wide_Text_IO as well)],Old=[]}},
+  so that things like @lquotes@;16:.123:@rquotes@; is acceptable.
address@hidden
+
+The quotation marks (") used as string brackets at both ends of
+a string literal can be replaced by percent signs (%) provided
+that the enclosed sequence of characters contains no quotation mark, and
+provided that both string brackets are replaced. Any
+percent sign within the sequence of characters shall then be
+doubled and each such doubled percent sign is interpreted as a
+single percent sign character value.
address@hidden
+
+These replacements do not change the meaning of the program.
address@hidden
+The original purpose of this feature was to support hardware (for
+example, teletype machines) that has long been obsolete.
+The feature is no longer necessary for that reason.
+Another use of the feature has been to replace the vertical line
+character (|) when using certain hardware that treats that character
+as a (non-English) letter.
+The feature is no longer necessary for that reason, either,
+since Ada 95 has full support for international character sets.
+Therefore, we believe this feature is no longer necessary.
+
+Users of equipment that still uses | to represent a letter will
+continue to do so.
+Perhaps by next the time Ada is revised,
+such equipment will no longer be in use.
+
address@hidden@;Note that it was never legal to use this feature as a convenient
+method of including double quotes in a string without doubling them
address@hidden the string literal:
address@hidden
+%"This is quoted."%
address@hidden
+
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0248-1]}
+is not legal in Ada @Chg{Version=[3],New=[(and never was legal)],Old=[83,
+nor will it be in Ada 95]}. One has to write:
address@hidden
+"""This is quoted."""
address@hidden
address@hidden
address@hidden
address@hidden
+
address@hidden Accuracy Subtypes}
+
address@hidden
+A @nt<digits_constraint> may be used to define
+a floating point subtype with a new
+value for its requested decimal precision, as reflected
+by its Digits attribute. Similarly, a @nt<delta_constraint>
+may be used to define an ordinary fixed point subtype with
+a new value for its @i(delta), as reflected by its Delta
+attribute.
address@hidden(Discussion)
+  It might be more direct to make these attributes
+  specifiable via an @nt<attribute_definition_clause>, and eliminate the
+  syntax for these @ntf<_constraint>s.
address@hidden(Discussion)
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI12-0152-1]}
address@hidden<delta_constraint>,
+  rhs="@key{delta} @address@hidden,address@hidden,address@hidden 
address@hidden"}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI12-0152-1]}
address@hidden type], Sec=(delta_constraint expression)}
+The 
@Chg{Version=[4],address@hidden<simple_expression>],address@hidden<expression>]}
+of a @nt<delta_constraint> is expected to be of any real type.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI12-0152-1]}
+The 
@Chg{Version=[4],address@hidden<simple_expression>],address@hidden<expression>]}
 of a
address@hidden<delta_constraint> shall be static.
+
+For a @nt<subtype_indication> with a @nt<delta_constraint>, the
address@hidden<subtype_mark> shall denote an ordinary fixed point subtype.
+
address@hidden
+For a @nt<subtype_indication> with a @nt<digits_constraint>,
+the @nt<subtype_mark> shall denote either a decimal fixed point subtype
+or a floating point subtype
+(notwithstanding the rule given in @RefSecNum(Fixed Point Types)
+that only allows a decimal fixed point subtype).
address@hidden(Discussion)
+  @ChgRef{Version=[2],Kind=[Deleted],ARef=[AI95-00114-01]}
+  @ChgDeleted{Version=[2],Text=[We may need a better way to deal with
+  obsolescent features with rules that contradict those of the nonobsolescent
+  parts of the standard.]}
address@hidden(Discussion)
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI12-0152-1]}
+A @nt<subtype_indication> with a @nt<subtype_mark> that
+denotes an ordinary fixed point subtype and a @nt<delta_constraint>
+defines an ordinary fixed point subtype with a @i(delta)
+given by the value of the 
@Chg{Version=[4],address@hidden<simple_expression>],address@hidden<expression>]}
 of the
address@hidden<delta_constraint>.
+If the @nt<delta_constraint> includes a @nt<address@hidden>, then
+the ordinary fixed point subtype is constrained by the @nt<address@hidden>.
+
address@hidden,Kind=[Revised],ARef=[AI12-0152-1]}
+A @nt<subtype_indication> with a @nt<subtype_mark> that
+denotes a floating point subtype and a @nt<digits_constraint>
+defines a floating point subtype with a requested decimal precision
+(as reflected by its Digits attribute)
+given by the value of the 
@Chg{Version=[4],address@hidden<simple_expression>],address@hidden<expression>]}
 of the @nt<digits_constraint>.
+If the @nt<digits_constraint> includes a @nt<address@hidden>, then
+the floating point subtype is constrained by the @nt<address@hidden>.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI12-0152-1]}
address@hidden,
+  Sec=(delta_constraint with an ordinary fixed point subtype)}
+A @nt<delta_constraint> is @i(compatible) with an ordinary
+fixed point subtype if the value of the
address@hidden,address@hidden<simple_expression>],address@hidden<expression>]} 
is no less
+than the @i(delta) of the subtype, and the @nt<range_constraint>, if any,
+is compatible with the subtype.
+
address@hidden,Kind=[Revised],ARef=[AI12-0152-1]}
address@hidden,
+  Sec=(digits_constraint with a floating point subtype)}
+A @nt<digits_constraint> is @i(compatible) with a
+floating point subtype if the value of the
address@hidden,address@hidden<simple_expression>],address@hidden<expression>]} 
is no greater
+than the requested decimal precision of the subtype, and
+the @nt<range_constraint>, if any,
+is compatible with the subtype.
+
address@hidden, Sec=(delta_constraint)}
+The elaboration of a @nt<delta_constraint> consists of the
+elaboration of the @nt<range_constraint>, if any.
address@hidden
+A numeric subtype is considered @lquotes@;address@hidden@; only if a range 
constraint
+applies to it. The only effect of a @nt<digits_constraint> or a
address@hidden<delta_constraint> without a @nt<range_constraint> is to specify
+the value of the corresponding Digits or Delta attribute in
+the new subtype. The set of values of the subtype is not 
@lquotes@;address@hidden@;
+in any way by such @ntf<_constraint>s.
address@hidden
address@hidden
+
address@hidden
+In Ada 83, a @nt<delta_constraint> is called a fixed_point_constraint,
+and a @nt<digits_constraint> is called a floating_point_constraint.
+We have adopted other terms because @nt<digits_constraint>s apply
+primarily to decimal fixed point types now (they apply to
+floating point types only as an obsolescent feature).
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0152-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:>
+  Changed the syntax so that the value following @key[delta] in a
+  @nt<delta_constraint> is a @nt<simple_expression>. This is compatible
+  as any expressions that would require extra parentheses are already
+  illegal. The change is necessary to eliminate
+  syntax ambguities in @nt<derived_type_definition>s. The similar change
+  for @nt<digits_constraint> is documented in @RefSecNum{Fixed Point Types}.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Constrained Attribute}
+
address@hidden
address@hidden@;For every private subtype S, the following attribute is defined:
address@hidden
+This includes generic formal private subtypes.
address@hidden
address@hidden
+S'@address@hidden the value False if S denotes an unconstrained
+              nonformal private subtype with discriminants; also yields the
+              value False if S denotes a generic formal private subtype, and
+              the associated actual subtype is either an unconstrained subtype
+              with discriminants or an unconstrained array subtype; yields
+              the value True otherwise. The value of this attribute is of
+              the predefined subtype Boolean.
address@hidden
+Because Ada 95 has @nt{unknown_discriminant_part}s,
+the Constrained attribute of private subtypes is obsolete.
+This is fortunate, since its Ada 83 definition was confusing,
+as explained below. Because this attribute is obsolete,
+we do not bother to extend its definition to private extensions.
+
+The Constrained attribute of an object is @i(not) obsolete.
+
+Note well: S'Constrained matches the Ada 95 definition of 
@lquotes@;address@hidden@;
+only for composite subtypes. For elementary subtypes,
+S'Constrained is always true, whether or not S is constrained.
+(The Constrained attribute of an object does not have this problem,
+as it is only defined for objects of a discriminated type.)
+So one should think of its designator as being 'Constrained_Or_Elementary.
address@hidden
address@hidden
address@hidden
+
address@hidden
+
address@hidden
address@hidden@;The following declaration exists in the declaration of package
+Standard:
address@hidden
address@hidden ASCII @key[is]
+
+
+  address@hidden  Control characters:}
+
+
address@hidden()@tabset(P47)
+  NUL   : @key[constant] Character := @RI{nul}; @\SOH   : @key[constant] 
Character := @RI{soh};
+  STX   : @key[constant] Character := @RI{stx}; @\ETX   : @key[constant] 
Character := @RI{etx};
+  EOT   : @key[constant] Character := @RI{eot}; @\ENQ   : @key[constant] 
Character := @RI{enq};
+  ACK   : @key[constant] Character := @RI{ack}; @\BEL   : @key[constant] 
Character := @RI{bel};
+  BS    : @key[constant] Character := @RI{bs}; @\HT    : @key[constant] 
Character := @RI{ht};
+  LF    : @key[constant] Character := @RI{lf}; @\VT    : @key[constant] 
Character := @RI{vt};
+  FF    : @key[constant] Character := @RI{ff}; @\CR    : @key[constant] 
Character := @RI{cr};
+  SO    : @key[constant] Character := @RI{so}; @\SI    : @key[constant] 
Character := @RI{si};
+  DLE   : @key[constant] Character := @RI{dle}; @\DC1   : @key[constant] 
Character := @RI{dc1};
+  DC2   : @key[constant] Character := @RI{dc2}; @\DC3   : @key[constant] 
Character := @RI{dc3};
+  DC4   : @key[constant] Character := @RI{dc4}; @\NAK   : @key[constant] 
Character := @RI{nak};
+  SYN   : @key[constant] Character := @RI{syn}; @\ETB   : @key[constant] 
Character := @RI{etb};
+  CAN   : @key[constant] Character := @RI{can}; @\EM    : @key[constant] 
Character := @RI{em};
+  SUB   : @key[constant] Character := @RI{sub}; @\ESC   : @key[constant] 
Character := @RI{esc};
+  FS    : @key[constant] Character := @RI{fs}; @\GS    : @key[constant] 
Character := @RI{gs};
+  RS    : @key[constant] Character := @RI{rs}; @\US    : @key[constant] 
Character := @RI{us};
+  DEL   : @key[constant] Character := @RI{del};
+
+
+  address@hidden Other characters:}
+
+  Exclam   : @key[constant] Character:= '!';@\Quotation : @key[constant] 
Character:= '"';
+  Sharp    : @key[constant] Character:= '#';@\Dollar    : @key[constant] 
Character:= '$';
+  Percent  : @key[constant] Character:= '%';@\Ampersand : @key[constant] 
Character:= '&';
+  Colon    : @key[constant] Character:= ':';@\Semicolon : @key[constant] 
Character:= ';';
+  Query    : @key[constant] Character:= '?';@\At_Sign   : @key[constant] 
Character:= '@@';
+  L_Bracket: @key[constant] Character:= '[';@\Back_Slash: @key[constant] 
Character:= '\';
+  R_Bracket: @key[constant] Character:= ']';@\Circumflex: @key[constant] 
Character:= '^';
+  Underline: @key[constant] Character:= '_';@\Grave     : @key[constant] 
Character:= '`';
+  L_Brace  : @key[constant] Character:= '{';@\Bar       : @key[constant] 
Character:= '|';
+  R_Brace  : @key[constant] Character:= '}';@\Tilde     : @key[constant] 
Character:= '~';
+
+  address@hidden Lower case letters:}
+
+
+  LC_A: @key[constant] Character:= 'a';
+  ...
+  LC_Z: @key[constant] Character:= 'z';
+
+
address@hidden ASCII;
address@hidden
address@hidden
+
+
address@hidden
+
address@hidden
address@hidden@;The following declaration exists in the declaration
+of package Standard:
address@hidden
+Numeric_Error : @key[exception] @key[renames] Constraint_Error;
address@hidden
address@hidden
+This is true even though it is not shown in
address@hidden Package Standard}.
address@hidden
address@hidden
+In Ada 83, it was unclear which situations should raise
+Numeric_Error, and which should raise Constraint_Error.
+The permissions of RM83-11.6 could often be used to allow
+the implementation to raise Constraint_Error in a situation
+where one would normally expect Numeric_Error.
+To avoid this confusion, all situations that raise Numeric_Error in
+Ada 83 are changed to raise Constraint_Error in Ada 95.
+Numeric_Error is changed to be a renaming of Constraint_Error
+to avoid most of the upward compatibilities associated with
+this change.
+
+In new code, Constraint_Error should be used instead of Numeric_Error.
address@hidden
address@hidden
+
address@hidden Clauses}
+
address@hidden
address@hidden<at_clause>,rhs="@key{for} @Syn2{direct_name} @key{use} @key{at} 
@Syn2{expression};"}
address@hidden
+
address@hidden
+An @nt{at_clause} of the form @lquotes@;for @i{x} use at @i{y};@rquotes@; is
+equivalent to an @nt{attribute_definition_clause} of the form
address@hidden@;for @i{x}'Address use @i{y};@rquotes@;.
address@hidden
+The preferred syntax for specifying the address of an entity is an
address@hidden specifying the Address attribute.
+Therefore, the special-purpose @nt{at_clause} syntax is now obsolete.
+
+The above equivalence implies, for example, that only one @nt{at_clause}
+is allowed for a given entity.
+Similarly, it is illegal to give both
+an @nt{at_clause}
+and an @nt{attribute_definition_clause} specifying the Address attribute.
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+We now allow to define the address of an entity using an
address@hidden
+This is because Ada 83's @nt{at_clause} is so hard to
+remember: programmers often tend to write @lquotes@;for X'Address 
use...;@rquotes@;.
address@hidden
+
address@hidden
+Ada 83's @ntf{address_clause} is now called an @nt{at_clause} to avoid
+confusion with the new term @lquotes@;Address address@hidden@; (that is, an
address@hidden for the Address attribute).
address@hidden
+
address@hidden Entries}
+
address@hidden
address@hidden are permitted to allow the attachment of task entries to
+interrupts via the address clause. Such an entry is referred to as an
address@hidden entry}.
+
+The address of the task entry corresponds to a hardware interrupt in an
+implementation-defined manner. (See Ada.Interrupts.Reference in
address@hidden Package Interrupts}.)]
address@hidden
+
address@hidden
address@hidden@;The following attribute is defined:
+
address@hidden@;For any task entry X:
address@hidden
address@hidden entry}
+X'@attr{Address} @\For a task entry whose address is specified
+               (an @i{interrupt entry}), the value
+               refers to the corresponding hardware interrupt. For such
+               an entry, as for any other task entry, the meaning of this
+               value is implementation defined. The value of this attribute
+               is of the type of the subtype System.Address.
+
address@hidden@;@PDefn2{Term=[specifiable], Sec=(of Address for entries)}
+               Address may be specified for single entries
+               via an @nt{attribute_definition_clause}.
address@hidden
+Because of the equivalence of @nt{at_clause}s and
address@hidden, an interrupt entry may be
+specified via either notation.
address@hidden
address@hidden
address@hidden
+
address@hidden
+
address@hidden, Sec=[of a task object]}
+As part of the initialization of a task object, the
+address clause for an interrupt entry is
address@hidden, which evaluates the
address@hidden<expression> of the address clause].
+A check is made that the address specified is
+associated with some interrupt to which a task entry may be attached.
address@hidden,Sec=(raised by failure of run-time check)}
+If this check fails, Program_Error is raised.
+Otherwise, the interrupt entry
+is attached to the interrupt associated with the specified address.
+
address@hidden, Sec=[of a task object]}
+Upon finalization of the task object, the interrupt entry, if any, is
+detached from the corresponding interrupt and the default treatment is
+restored.
+
+While an interrupt entry is attached to an interrupt,
+the interrupt is reserved (see @RefSecNum{Interrupt Support}).
+
+An interrupt delivered to a task entry acts as a call to the entry issued by
+a hardware task whose priority is in the System.Interrupt_Priority range.
+It is implementation defined whether the call is performed as
+an ordinary entry call, a timed entry
+call, or a conditional entry call; which kind of call is performed
+can depend on the specific interrupt.
+
address@hidden
+
address@hidden
address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to evaluate
+E'Caller (see @RefSecNum(The Package Task_Identification))
+in an @nt{accept_statement} for an interrupt
+entry. The possible effects are
+the same as for calling Current_Task from an entry body.
address@hidden
+
address@hidden
+
+The implementation shall document to which interrupts a
+task entry may be attached.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The interrupts to which a task entry may be attached.]}]}
+
+The implementation shall document whether the invocation of an interrupt entry
+has the effect of an ordinary entry call, conditional call, or a timed call,
+and whether the effect varies in the presence of pending interrupts.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The type of entry call invoked for an interrupt entry.]}]}
+
address@hidden
+
address@hidden
+The support for this subclause is optional.
+
+Interrupts to which the implementation allows a task entry to be
+attached may be designated as reserved for the entire duration
+of program address@hidden; that is, not just when they have an
+interrupt entry attached to them].
+
address@hidden,Kind=[Revised],Ref=[8652/0077],ARef=[AI95-00111-01]}
+Interrupt entry calls may be implemented by having the hardware execute
+directly the appropriate @address@hidden,Old=[accept body]}.
+Alternatively, the implementation is allowed to provide an internal interrupt
+handler to simulate the effect of a normal task calling the entry.
+
+The implementation is allowed to impose restrictions on the specifications
+and bodies of tasks that have interrupt entries.
+
+It is implementation defined whether direct calls (from the program) to
+interrupt entries are allowed.
+
+If a @nt{select_statement} contains both a @nt{terminate_alternative} and an
address@hidden for an interrupt entry, then an implementation is
+allowed to impose further requirements for the selection of the
address@hidden in addition to those given in
address@hidden Dependence - Termination of Tasks}.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0077],ARef=[AI95-00111-01]}
+Queued interrupts correspond to ordinary entry calls. Interrupts that are
+lost if not immediately processed correspond to conditional entry calls. It
+is a consequence of the priority rules that an @address@hidden,
+Old=[accept body]} executed in response to an interrupt can be executed with
+the active priority at which the hardware generates the interrupt, taking
+precedence over lower priority tasks, without a scheduling action.
+
+Control information that is supplied upon an interrupt can be passed to an
+associated interrupt entry as one or more parameters of mode @key[in].
address@hidden
+
address@hidden
address@hidden@address@hidden of an interrupt entry:}
address@hidden
address@hidden Interrupt_Handler @key[is]
+  @key[entry] Done;
+  @key[for] Done'Address @key[use] 
Ada.Interrupts.Reference(Ada.Interrupts.Names.Device_Done);
address@hidden Interrupt_Handler;
+
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+RM83-13.5.1 did not adequately address the problems
address@hidden,New=[associated],Old=[associate]} with
+interrupts. This feature is now obsolescent and is replaced by the Ada 95
+interrupt model as specified in the Systems Programming Annex.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],Ref=[8652/0077],ARef=[AI95-00111-01]}
address@hidden,address@hidden<Corrigendum:> The undefined term @i{accept body}
+was replaced by @nt{accept_statement}.], Old=[]}
address@hidden
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Clauses}
+
address@hidden
address@hidden<mod_clause>,rhs="@key{at} @key{mod} @address@hidden;"}
address@hidden
+
address@hidden
address@hidden@keepnext@;A @nt{record_representation_clause} of the form:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
address@hidden @RI{r} @key[use]
+    @key[record] @key[at] @key[mod] @address@hidden,New=[;],Old=[]}
+        ...
+    @key[end] @key[record];
address@hidden
+
address@hidden@keepnext@;is equivalent to:
address@hidden
address@hidden @RI{r}'Alignment @key[use] @RI{a};
address@hidden @RI{r} @key[use]
+    @key[record]
+        ...
+    @key[end] @key[record];
address@hidden
address@hidden
+The preferred syntax for specifying the alignment of an entity is an
address@hidden specifying the Alignment attribute.
+Therefore, the special-purpose @nt{mod_clause} syntax is now
+obsolete.
+
+The above equivalence implies, for example, that it is illegal to give both
+a @nt{mod_clause}
+and an @nt{attribute_definition_clause} specifying the Alignment attribute
+for the same type.
address@hidden
address@hidden
+
address@hidden
+Ada 83's @ntf{alignment_clause} is now called a @nt{mod_clause} to avoid
+confusion with the new term @lquotes@;Alignment address@hidden@; (that is, an
address@hidden for the Alignment attribute).
address@hidden
+
address@hidden Storage_Size Attribute}
+
address@hidden
address@hidden@;For any task subtype T, the following attribute is defined:
address@hidden
+T'@attr{Storage_Size} @\Denotes an implementation-defined value
+of type @i{universal_integer}
+representing the number of storage
+elements reserved for a task of the subtype T.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+T'Storage_Size cannot be particularly meaningful in the presence of
address@hidden,New=[the specification of the aspect],Old=[a @nt{pragma}]}
+Storage_Size, especially when the expression is dynamic, or
+depends on a discriminant of the task,
+because the Storage_Size will be different for different objects of the type.
+Even without such a @Chg{Version=[3],New=[specification],address@hidden,
+the Storage_Size can be different for different objects of the type,
+and in any case, the value is implementation defined.
+Hence, it is always implementation defined.
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00345-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden, Sec=(of Storage_Size for a task
+first subtype)}
address@hidden@;Storage_Size may be specified for a task first subtype
address@hidden,New=[that is not an interface ],Old=[]}via
+an @address@hidden,New=[
+When the attribute is specified, the Storage_Size aspect
+is specified to be the value of the given @nt{expression}.],Old=[]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[When this attribute is specified with an
+  @nt{attribute_definition_clause}, the associated aspect is set to the
+  @i<value> of the @nt{expression} given in the 
@nt{attribute_definition_clause},
+  rather than the @nt{expression} itself.
+  This value is therefore the same for all objects of the type; in particular,
+  it is not re-evaluated when objects are created. This is different than
+  when the aspect is specified with an @nt{aspect_specification}
+  (see @RefSecNum{Operational and Representation Attributes}).]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00345-01]}
+  @ChgAdded{Version=[2],Text=[We don't allow specifying Storage_Size on
+  task interfaces. We don't need to mention class-wide task types, because
+  these cannot be a first subtype.]}
address@hidden
+
address@hidden,Name=[Specific Suppression of Checks]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00224-01]}
address@hidden,Text=[Pragma Suppress can be used to suppress checks on
+specific entities.]}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00224-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The form of a specific
+Suppress @nt{pragma} is as follows:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,
+New=`@ @ @key{pragma} @prag{Suppress}(@Syn2{identifier}, [On =>] 
@Syn2{name});',
+Old=<>}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00224-01]}
address@hidden,Text=[The @nt{identifier} shall be the name of a check
+(see @RefSecNum{Suppressing Checks}). The @nt{name} shall
+statically denote some entity.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00224-01]}
address@hidden,Text=[For a specific Suppress @nt{pragma} that is
+immediately within a @nt{package_specification}, the @nt{name} shall denote an
+entity (or several overloaded subprograms) declared immediately within the
address@hidden@!specification}.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00224-01]}
address@hidden,Text=[A specific Suppress @nt{pragma} applies to the
+named check from the place of the @nt{pragma} to the end of the innermost
+enclosing declarative region, or, if the @nt{pragma} is given in a
address@hidden, to the end of the scope of the named entity. The
address@hidden applies only to the named entity, or, for a subtype, on objects 
and
+values of its type. A specific Suppress @nt{pragma} suppresses the named check
+for any entities to which it applies (see @RefSecNum{Suppressing Checks}).
+Which checks are associated with a specific entity is not defined by this
+International Standard.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden
address@hidden,Text=[The language doesn't specify exactly which entities
+control whether a check is performed. For example, in]}
address@hidden
address@hidden,address@hidden Suppress (Range_Check, On => A);
+A := B;],Old=[]}
address@hidden
address@hidden,Text=[whether or not the range check is performed is not
+specified. The compiler may require that checks are suppressed on B or on the
+type of A in order to omit the range check.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00224-01]}
address@hidden,Text=[An implementation is allowed to place restrictions on
+specific Suppress @nt{pragma}s.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00224-01]}
address@hidden,Text=[An implementation may support a similar On parameter on
address@hidden Unsuppress (see @RefSecNum{Suppressing Checks}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00224-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[This 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+  is new. This feature was moved here
+  because it is important for pragma Unsuppress that there be an unambiguous
+  meaning for each checking pragma. For instance, in the example]}
address@hidden
address@hidden,address@hidden Suppress (Range_Check);
address@hidden Unsuppress (Range_Check, On => A);
+A := B;]}
address@hidden
+  @ChgAdded{Version=[2],Text=[the user needs to be able to depend on the range 
check
+  being made on the assignment. But a compiler survey showed that the
+  interpretation of this feature varied widely; trying to define this carefully
+  was likely to cause a lot of user and implementer pain. Thus the feature was
+  moved here, to emphasize that its use is not portable.]}
address@hidden
+
+
address@hidden,Name=[The Class Attribute of Untagged Incomplete Types]}
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00326-01]}
address@hidden,Type=[Leading],Text=[For the first subtype S of a type
address@hidden<T> declared by an @nt<incomplete_type_declaration> that is not 
tagged, the
+following attribute is defined:]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00326-01]}
address@hidden,New=[S'@attr{Class} @\Denotes the first subtype of the
+incomplete class-wide type rooted at @i<T>. The completion of @i<T> shall
+declare a tagged type. Such an attribute reference shall occur in the same
+library unit as the @nt<incomplete_type_declaration>.],Old=[]}
address@hidden
+  @begin{Reason}
+    @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00326-01]}
+    @ChgAdded{Version=[2],Text=[This must occur in the same unit to prevent
+    children from imposing requirements on their ancestor library
+    units for deferred incomplete types.]}
+  @end{reason}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00326-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[This 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+  is new. This feature was moved here
+  because the tagged incomplete type provides a better way to provide this
+  capability (it doesn't put requirements on the completion based on uses that
+  could be anywhere). Pity we didn't think of it in 1994.]}
address@hidden
+
+
address@hidden,Name=[Pragma Interface]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00284-02]}
address@hidden,Text=[In addition to an identifier, the reserved word
address@hidden is allowed as a pragma name, to provide compatibility with a 
prior
+edition of this International Standard.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00284-02]}
address@hidden,Text=[All implementations need to at least recognize and
+ignore this pragma. A syntax error is not an acceptable implementation of
+this pragma.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00326-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[This 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+  is new. This is necessary as @key{interface}
+  is now a reserved word, which would prevent pragma Interface from being an
+  implementation-defined pragma. We don't define any semantics for this
+  pragma, as we expect that implementations will continue to use whatever they
+  currently implement - requiring any changes would be counter-productive.]}
address@hidden
+
+
address@hidden,Name=[Dependence Restriction Identifiers]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00394-01]}
address@hidden,Text=[The following restrictions involve dependence
+on specific language-defined units. The more general restriction No_Dependence
+(see @RefSecNum{Language-Defined Restrictions and Profiles}) should be
+used for this purpose.]}
address@hidden
+
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00394-01]}
address@hidden,Type=[Leading],
+Text=[The following @Syni<restriction_>@nt<identifier>s exist:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00394-01]}
address@hidden,address@hidden,
+Sec=(No_Asynchronous_Control)}No_Asynchronous_Control @\Semantic dependence
+on the predefined package Asynchronous_Task_Control is not allowed.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00394-01]}
address@hidden,address@hidden,
+Sec=(No_Unchecked_Conversion)}No_Unchecked_Conversion @\Semantic
+dependence on the predefined generic function Unchecked_Conversion is not
+allowed.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00394-01]}
address@hidden,address@hidden,
+Sec=(No_Unchecked_Deallocation)}No_Unchecked_Deallocation @\Semantic
+dependence on the predefined generic procedure Unchecked_Deallocation is
+not allowed.]}
+
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00394-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[This 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+  is new. These restrictions
+  are replaced by the more general No_Dependence
+  (see @RefSecNum{Language-Defined Restrictions and Profiles}).]}
address@hidden
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,Name=[Character and Wide_Character Conversion Functions]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Leading],
+Text=[The following declarations exist in the declaration of package
+Ada.Characters.Handling:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} Is_Character (Item : @key{in} 
Wide_Character) @key{return} Boolean
+      @key{renames} Conversions.Is_Character;
+   @key{function} Is_String    (Item : @key{in} Wide_String)    @key{return} 
Boolean
+      @key{renames} Conversions.Is_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} To_Character (Item       : @key{in} 
Wide_Character;
+                         Substitute : @key{in} Character := ' ')
+                         @key{return} Character
+      @key{renames} Conversions.To_Character;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} To_String    (Item       : @key{in} 
Wide_String;
+                          Substitute : @key{in} Character := ' ')
+                          @key{return} String
+      @key{renames} Conversions.To_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} To_Wide_Character (Item : @key{in} 
Character) @key{return} Wide_Character
+      @key{renames} Conversions.To_Wide_Character;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} To_Wide_String    (Item : @key{in} 
String)    @key{return} Wide_String
+      @key{renames} Conversions.To_Wide_String;]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00394-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[This 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+  is new. These subprograms were moved to Characters.Conversions
+  (see @RefSecNum{The Package Characters.Conversions}).]}
address@hidden
+
address@hidden,Name=[Aspect-related Pragmas]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[Pragmas can be used as an alternative to
+aspect_specifications to specify certain aspects.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[This subclause is new. Many existing pragmas have
+  been converted into aspects; the pragmas have moved here.]}
address@hidden
+
address@hidden,Name=[Pragma Inline]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[The form of a @nt{pragma}
+Inline, which is a program unit pragma (see @RefSecNum{Pragmas and Program 
Units}),
+is as follows:@PDefn2{Term=[program unit pragma], Sec=(Inline)}
address@hidden, program unit], Sec=(Inline)}]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Inline> (@Syn2[name]{, @Syn2[name]});]}>
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The @nt{pragma} shall apply to one or more
+callable entities or generic subprograms.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,address@hidden Inline specifies that the Inline aspect
+(see @RefSecNum{Inline Expansion of Subprograms}) for each
+entity denoted by each @nt{name} given in the @nt{pragma} has the value True.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[Note that inline expansion is
+  desired no matter what @nt{name} is used in the call. This allows one to 
request
+  inlining for only one of several overloaded subprograms as follows:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden IO @key[is]
+   @key[procedure] Put(X : @key[in] Integer);
+   @key[procedure] Put(X : @key[in] String);
+   @key[procedure] Put(X : @key[in] Character);
address@hidden
+   @key[procedure] Character_Put(X : @key[in] Character) @key[renames] Put;
+   @key[pragma] Inline(Character_Put);
address@hidden IO;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden IO; @key[use] IO;
address@hidden Main @key[is]
+   I : Integer;
+   C : Character;
address@hidden
+   ...
+   Put(C); address@hidden Inline expansion is desired.}
+   Put(I); address@hidden Inline expansion is NOT desired.}
address@hidden Main;]}
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[An implementation may allow a @nt{pragma} Inline
+that has an argument which is a @nt{direct_name} denoting a
address@hidden of the same @nt{declarative_part}.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is allowed for Ada 83 compatibility. This is
+  only a permission as this usage was considered obsolescent even for Ada 95.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We only need to allow this in 
@nt{declarative_part}s,
+  because a @nt{body} is only allowed in another @nt{body}, and these all have
+  @nt{declarative_part}s.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The name in a @nt{pragma} Inline may denote more
+than one entity in the case of overloading. Such a @nt{pragma} applies to
+all of the denoted entities.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI95-00309-01],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 83}
+  A pragma Inline cannot refer to a @nt{subprogram_body} outside of that
+  body. The pragma can be given inside of the subprogram body. Ada 2005
+  adds an @ImplPermName to allow this usage for compatibility (and
+  Ada 95 implementations also can use this permission), but
+  implementations do not have to allow such @nt{pragma}s.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 83}
+  A @nt{pragma} Inline is allowed inside a @nt{subprogram_body} if there
+  is no corresponding @nt{subprogram_declaration}.
+  This is for uniformity with other program unit pragmas.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI95-00309-01],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 95}
+  @b[Amendment Correction:] Implementations are allowed to let @nt{Pragma}
+  Inline apply to a @nt{subprogram_body}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[This subclause is new. Pragma Inline was moved
+  here from @RefSecNum{Inline Expansion of Subprograms}; aspect Inline lives
+  there now.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,Name=[Pragma No_Return]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[The form of a @nt{pragma}
+No_Return, which is a representation pragma
+(see @RefSecNum{Operational and Representation Aspects}),
+is as follows:@PDefn2{Term=[representation pragma], Sec=(No_Return)}
address@hidden, representation], Sec=(No_Return)}]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<No_Return> (@address@hidden, @address@hidden);]}>
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[Each @address@hidden
+shall denote one or more procedures or generic procedures.
address@hidden @address@hidden shall not denote a null
+procedure nor an instance of a generic unit.]]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,address@hidden No_Return specifies that the No_Return
+aspect (see @RefSecNum{Nonreturning Procedures}) for each procedure denoted
+by each @nt{local_name} given in the @nt{pragma} has the value True.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[This subclause is new. Pragma No_Return was moved
+  here from @RefSecNum{Nonreturning Procedures}; aspect No_Return lives
+  there now.]}
address@hidden
+
+
address@hidden,Name=[Pragma Pack]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[The form of a @nt{pragma}
+Pack, which is a representation pragma
+(see @RefSecNum{Operational and Representation Aspects}),
+is as follows:@PDefn2{Term=[representation pragma], Sec=(Pack)}
address@hidden, representation], Sec=(Pack)}]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Pack> (@address@hidden);]}>
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The @SynI<first_subtype_>@nt{local_name} of a
address@hidden Pack shall denote a composite subtype.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,address@hidden
+Pack specifies that the Pack aspect (see @RefSecNum{Packed Types}) for the type
+denoted by @SynI<first_subtype_>@nt{local_name} has the value True.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[This subclause is new. Pragma Pack was moved
+  here from @RefSecNum{Packed Types}; aspect Pack lives
+  there now.]}
address@hidden
+
+
address@hidden,Name=[Pragma Storage_Size]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[The form of a @nt{pragma}
+Storage_Size is as follows:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Storage_Size> (@Syn2[expression]);]}>
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[A @nt{pragma} Storage_Size is allowed only
+immediately within a @nt{task_definition}.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The @nt{expression} of a @nt{pragma} Storage_Size
+is expected to be of any integer address@hidden type], Sec=(Storage_Size 
pragma argument)}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The @nt{pragma} Storage_Size sets the
+Storage_Size aspect (see @RefSecNum{Operational and Representation Attributes})
+of the type defined by the immediately enclosing @nt{task_definition}
+to the value of the @nt{expression} of the @nt{pragma}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[This subclause is new. Pragma Storage_Size was 
moved
+  here from @RefSecNum{Operational and Representation Attributes};
+  aspect Storage_Size lives there now.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,Name=[Interfacing Pragmas]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],address@hidden pragma}
address@hidden pragma], Sec=(Import)}
address@hidden, interfacing], Sec=(Import)}
address@hidden pragma], Sec=(Export)}
address@hidden, interfacing], Sec=(Export)}
address@hidden pragma], Sec=(Convention)}
address@hidden, interfacing], Sec=(Convention)}
address@hidden pragma], Sec=(Import)}
address@hidden, representation], Sec=(Import)}
address@hidden pragma], Sec=(Export)}
address@hidden, representation], Sec=(Export)}
address@hidden pragma], Sec=(Convention)}
address@hidden, representation], Sec=(Convention)}
+An @i{interfacing pragma} is a representation pragma that is
+one of the @nt{pragma}s Import, Export,
+or Convention. Their forms are as follows:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag(Import)(@*
+@ @ @ @ @ [Convention =>] @address@hidden, [Entity =>] @address@hidden
+@ @ [, [External_Name =>] @address@hidden@*
+@ @ [, [Link_Name =>] @address@hidden);'}>
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag(Export)(@*
+@ @ @ @ @ [Convention =>] @address@hidden, [Entity =>] @address@hidden
+@ @ [, [External_Name =>] @address@hidden@*
+@ @ [, [Link_Name =>] @address@hidden);'}>
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag(Convention)([Convention =>] @address@hidden,[Entity =>] 
@Syn2{local_name});'}>
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[For @nt{pragma}s Import and Export, the argument
+for Link_Name shall not be given without the
address@hidden@address@hidden@nt{identifier}
+unless the argument for External_Name is given.]}
address@hidden
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,address@hidden type],Sec=(link name)}
address@hidden type],Sec=(external name)} The expected type for an
address@hidden@nt{expression} and a
address@hidden@nt{expression} in an interfacing pragma is String.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The @address@hidden of an
+interfacing pragma shall be the name of a convention
+(see @RefSecNum{Interfacing Aspects}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[A @nt{pragma} Import shall be the completion of a
+declaration. @PDefn{Notwithstanding}Notwithstanding any rule to the
+contrary, a @nt{pragma} Import may serve as the completion of any kind of
+(explicit) declaration if supported by an implementation for that kind of
+declaration. If a completion is a @nt{pragma} Import, then it shall appear in
+the same @nt{declarative_part}, @nt{package_specification},
address@hidden, or @nt{protected_definition} as the declaration. For a
+library unit, it shall appear in the same @nt{compilation}, before any
+subsequent @nt{compilation_unit}s other than @nt{pragma}s. If the
address@hidden denotes more than one entity, then the @nt{pragma} Import is the
+completion of all of them.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The @address@hidden and
address@hidden@nt{expression} of a @nt{pragma} Import or Export shall
+be static.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The @nt{local_name} of each of these pragmas
+shall denote a declaration that may have the similarly named aspect 
specified.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[An interfacing pragma specifies
+various aspects of the entity denoted by the @nt{local_name} as follows:]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The Convention aspect (see
+  @RefSecNum{Interfacing Aspects}) is @address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[A @nt{pragma} Import specifies that the Import
+  aspect (see @RefSecNum{Interfacing Aspects}) is True.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[A @nt{pragma} Export specifies that the Export
+  aspect (see @RefSecNum{Interfacing Aspects}) is True.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[For both @nt{pragma} Import and Export, if an 
external
+  name is given in the pragma, the External_Name aspect (see
+  @RefSecNum{Interfacing Aspects}) is specified to be
+  @address@hidden If a link name is given in the
+  pragma, the Link_Name aspect (see @RefSecNum{Interfacing Aspects}) is
+  specified to be the @address@hidden
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[This subclause is new. Pragmas Import, Export, 
and
+  Convention were moved here from @RefSecNum{Interfacing Aspects}; aspects
+  Import, Export, Convention, Link_Name, and External_Name live there now.]}
address@hidden
+
+
address@hidden,Name=[Pragma Unchecked_Union]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[The form of a @nt{pragma}
+Unchecked_Union, which is a representation pragma
+(see @RefSecNum{Operational and Representation Aspects}),
+is as follows:@PDefn2{Term=[representation pragma], Sec=(Unchecked_Union)}
address@hidden, representation], Sec=(Unchecked_Union)}]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Unchecked_Union> (@address@hidden);]}>
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The @SynI<first_subtype_>@nt{local_name} of a
address@hidden Unchecked_Union shall denote an
+unconstrained discriminated record subtype having a @nt{variant_part}.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[A @nt{pragma} Unchecked_Union specifies that
+the Unchecked_Union aspect (see @RefSecNum{Unchecked Union Types})
+for the type denoted by @SynI<first_subtype_>@nt{local_name} has the value
+True.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[This subclause is new. Pragma Unchecked_Union was
+  moved here from @RefSecNum{Unchecked Union Types}; aspect Unchecked_Union
+  lives there now.]}
address@hidden
+
+
address@hidden,Name=[Pragmas Interrupt_Handler and Attach_Handler]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[The form of a @nt{pragma}
+Interrupt_Handler is as follows:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Interrupt_Handler> (@address@hidden);]}>
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[The form of a @nt{pragma}
+Attach_Handler is as follows:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Attach_Handler> (@address@hidden, @Syn2[expression]);]}>
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[For the Interrupt_Handler and Attach_Handler
+pragmas, the @address@hidden shall resolve to denote a protected
+procedure with a parameterless profile.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[For the Attach_Handler pragma, the expected type for
+the expression is Interrupts.Interrupt_Id (see @RefSecNum{The Package 
Interrupts}).
address@hidden type], Sec=(Attach_Handler pragma second argument)}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0033-1],ARef=[AI05-0229-1]}
address@hidden,Text=[The Attach_Handler and Interrupt_Handler pragmas
+are only allowed immediately within the @nt{protected_definition} where the 
corresponding subprogram is declared.
+The corresponding @nt{protected_type_declaration} or 
@nt{single_protected_declaration}
+shall be a library-level declaration, and shall not be declared within a 
generic
+body.
address@hidden contract issue}
+In addition to the places where Legality Rules normally apply (see
address@hidden Instantiation}), these rules also apply in the private part
+of an instance of a generic unit.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[In the case of a @nt{protected_type_declaration},
+an @nt{object_declaration} of an object of that type
+need not be at library level.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0033-1]}
address@hidden,Text=[We cannot allow these pragmas in a generic body,
+because legality rules are not checked for instance bodies, and these should
+not be allowed if the instance is not at the library level. The protected types
+can be declared in the private part if this is desired. Note that while the
+'Access to use the handler would provide the check in the case of
+Interrupt_Handler, there is no other check for Attach_Handler. Since these
+pragmas are so similar, we want the rules to be the same.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[For an implementation that supports Annex C, a
+pragma Interrupt_Handler specifies the Interrupt_Handler aspect (see
address@hidden Procedure Handlers}) for
+the protected procedure @SynI<handler_>@nt{name} to have the value True. For an
+implementation that supports Annex C, a pragma Attach_Handler specifies the
+Attach_Handler aspect (see @RefSecNum{Protected Procedure Handlers}) for
+the protected procedure @address@hidden to
+have the value of the given @address@hidden as evaluated at object
+creation time].]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0033-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Added missing generic contract wording for the pragma Attach_Handler and
+  Interrupt_Handler. This means that nested instances with these pragmas in the
+  private part are now illegal. This is not likely to occur in practice.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[This subclause is new. Pragmas Interrupt_Handler
+  and Attach_Handler were moved here from @RefSecNum{Protected Procedure 
Handlers};
+  aspects Interrupt_Handler and Attach_Handler live there now.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,Name=[Shared Variable Pragmas]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[The form for @nt{pragma}s
+Atomic, Volatile, Independent, Atomic_Components, and
+Volatile_Components, and Independent_Components is as follows:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Atomic> (@Syn2[local_name]);]}>
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Volatile> (@Syn2[local_name]);]}>
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0009-1]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Independent> (@address@hidden);]}>
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Atomic_Components> (@address@hidden);]}>
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Volatile_Components> (@address@hidden);]}>
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0009-1]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Independent_Components> (@Syn2[local_name]);]}>
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0009-1],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[Pragmas Independent and Independent_Components
+  are born obsolescent; they are defined to provide consistency with the 
existing
+  shared variable pragmas. As with all obsolescent
+  features, these pragmas are not optional; all Ada implementations need to
+  implement them. Also note that these pragmas were defined as a 
@b<Correction>;
+  as such, they are expected to be implemented as part of Ada 2005
+  implementations (and they would not be obsolescent there).]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0009-1],ARef=[AI05-0229-1]}
address@hidden,Text=[The @nt{local_name} in an Atomic or Volatile pragma
+shall resolve to denote either an @nt{object_declaration}, a noninherited
address@hidden, or a @nt{full_type_declaration}. The
address@hidden@nt{local_name} in an Independent pragma shall resolve to
+denote a noninherited @nt{component_declaration}. The @address@hidden
+in an Atomic_Components or Volatile_Components pragma shall resolve to denote
+the declaration of an array type or an array object of an anonymous type. The
address@hidden in an Independent_Components pragma shall resolve to denote the
+declaration of an array or record type or an array object of an anonymous
+type.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[These @nt{pragma}s are representation pragmas
+(see @RefSecNum{Operational and Representation Aspects}).
+Each of these @nt{pragma}s specifies that the similarly named aspect
+(see @RefSecNum{Shared Variable Control}) of the
+type, object, or component denoted by its argument is True.
address@hidden pragma], Sec=(Atomic)}
address@hidden, representation], Sec=(Atomic)}
address@hidden pragma], Sec=(Volatile)}
address@hidden, representation], Sec=(Volatile)}
address@hidden pragma], Sec=(Atomic_Components)}
address@hidden, representation], Sec=(Atomic_Components)}
address@hidden pragma], Sec=(Volatile_Components)}
address@hidden, representation], Sec=(Volatile_Components)}
address@hidden pragma], Sec=(Independent)}
address@hidden, representation], Sec=(Independent)}
address@hidden pragma], Sec=(Independent_Components)}
address@hidden, representation], Sec=(Independent_Components)}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The @nt{local_name} of each of these @nt{pragma}s
+shall denote a declaration that may have the similarly named aspect 
specified.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[This subclause is new. These pragmas
+  were moved here from @RefSecNum{Shared Variable Control};
+  various aspects live there now.]}
address@hidden
+
+
address@hidden,Name=[Pragma CPU]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[This pragma is born obsolescent; it is defined to
+  provide consistency with existing real-time pragmas. As with all obsolescent
+  features, this pragma is not optional; all Ada implementations need to
+  implement it.]}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[The form of a @nt{pragma}
+CPU is as follows:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<CPU> (@Syn2[expression]);]}>
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The expected type for the @nt{expression} of a
address@hidden CPU is
address@hidden type], Sec=(CPU pragma argument)}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[A CPU pragma is allowed only immediately within a
address@hidden, or the @nt{declarative_part} of a @nt{subprogram_body}.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[For a CPU pragma that appears in the
address@hidden of a @nt{subprogram_body}, the @nt{expression} shall be
+static.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[For an implementation that supports Annex D, a
address@hidden CPU specifies the value of the CPU aspect (see
address@hidden Implementation}). If the @nt{pragma} appears in a
address@hidden, the @nt{expression} is associated with the aspect for the
+task type or @nt{single_task_declaration} that contains the @nt{pragma};
+otherwise, the @nt{expression} is associated with the aspect for the subprogram
+that contains the @nt{pragma}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0009-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Pragma
+  CPU is new.]}
address@hidden
+
+
address@hidden,Name=[Pragma Dispatching_Domain]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0167-1]}
+  @ChgAdded{Version=[3],Text=[This pragma is born obsolescent; it is defined to
+  provide consistency with existing real-time pragmas. As with all obsolescent
+  features, this pragma is not optional; all Ada implementations need to
+  implement it.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The form of a
address@hidden Dispatching_Domain is as follows:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Dispatching_Domain> (@nt{expression});]}>
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Text=[The expected type for the @nt{expression} is
+System.Multiprocessors.Dispatching_Domains.Dispatching_Domain.
address@hidden type], Sec=(Dispatching_Domains pragma argument)}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Text=[A Dispatching_Domain pragma is allowed only
+immediately within a @nt{task_definition}.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Text=[For an implementation that supports Annex D, a
+pragma Dispatching_Domain specifies the value of the Dispatching_Domain aspect
+(see @RefSecNum{Multiprocessor Dispatching Domains}). The @nt{expression} is
+associated with the aspect for the task type or @nt{single_task_declaration}
+that contains the pragma.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0009-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Pragma
+  Dispatching_Domain is new.]}
address@hidden
+
+
address@hidden,Name=[Pragmas Priority and Interrupt_Priority]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The form of a
address@hidden Priority is as follows:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Priority> (@nt{expression});]}>
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The form of a
address@hidden Interrupt_Priority is as follows:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Interrupt_Priority> [(@nt{expression})];]}>
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The expected type for the @nt{expression}
+in a Priority or Interrupt_Priority pragma is
address@hidden type], Sec=(Priority pragma argument)}
address@hidden type], Sec=(Interrupt_Priority pragma argument)}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[A Priority pragma is allowed only immediately
+within a @nt{task_definition}, a @nt{protected_definition}, or the
address@hidden of a @nt{subprogram_body}. An Interrupt_Priority pragma is
+allowed only immediately within a @nt{task_definition} or a
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[For a Priority pragma that appears in the
address@hidden of a @nt{subprogram_body},
+the @nt{expression} shall be static, and its value shall be in the range of
+System.Priority.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[For an implementation that supports
+Annex D, a @nt{pragma} Priority specifies the value of the Priority aspect (see
address@hidden Priorities}) and a @nt{pragma} Interrupt_Priority specifies the
+value of the Interrupt_Priority aspect as follows:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If the @nt{pragma} appears in a @nt{task_definition},
+  the @nt{expression} is associated with the aspect for the task type or
+  @nt{single_task_declaration} that contains the @nt{pragma};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If the @nt{pragma} appears in a @nt{protected_definition},
+  the @nt{expression} is associated with the aspect for the protected type or
+  @nt{single_protected_declaration} that contains the @nt{pragma};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If the @nt{pragma} appears in the @nt{declarative_part}
+  of a @nt{subprogram_body}, the @nt{expression} is associated with the
+  aspect for the subprogram that contains the @nt{pragma}.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[If there is no @nt{expression} in an
+Interrupt_Priority pragma, the Interrupt_Priority aspect has the value
+Interrupt_Priority'Last.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[This subclause is new. Pragmas Interrupt_Priority
+  and Priority were moved here from @RefSecNum{Task Priorities};
+  aspects Interrupt_Priority and Priority live there now.]}
address@hidden
+
+
address@hidden,Name=[Pragma Relative_Deadline]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The form of a
address@hidden Relative_Deadline is as follows:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Relative_Deadline> (@address@hidden);]}>
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The expected type for a
address@hidden@nt{expression} is
address@hidden type], Sec=(Relative_Deadline pragma argument)}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[A Relative_Deadline pragma is allowed only
+immediately within a @nt{task_definition} or the @nt{declarative_part}
+of a @nt{subprogram_body}.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[For an implementation that supports Annex D, a
address@hidden Relative_Deadline specifies the value of the Relative_Deadline
+aspect (see @RefSecNum{Earliest Deadline First Dispatching}). If the 
@nt{pragma}
+appears in a @nt{task_definition}, the @nt{expression} is associated with the
+aspect for the task type or @nt{single_task_declaration} that contains the
address@hidden; otherwise, the @nt{expression} is associated with the aspect
+for the subprogram that contains the @nt{pragma}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[This subclause is new. Pragma Relative_Deadline
+  was moved here from @RefSecNum{Earliest Deadline First Dispatching};
+  aspect Relative_Deadline lives there now.]}
address@hidden
+
+
address@hidden,Name=[Pragma Asynchronous]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[The form of a @nt{pragma}
+Asynchronous, which is a representation pragma
+(see @RefSecNum{Operational and Representation Aspects}),
+is as follows:@PDefn2{Term=[representation pragma], Sec=(Asynchronous)}
address@hidden, representation], Sec=(Asynchronous)}]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[3],@ChgAdded{Version=[3],
address@hidden @prag<Asynchronous> (@Syn2[local_name]);]}>
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[For an implementation that supports Annex E, a
+pragma Asynchronous specifies that the Asynchronous aspect (see
address@hidden Remote Calls}) for the procedure or type denoted by
address@hidden has the value True.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The @nt{local_name} of a pragma Asynchronous shall
+denote a declaration that may have aspect Asynchronous specified.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[This subclause is new. Pragma Asynchronous
+  was moved here from @RefSecNum{Asynchronous Remote Calls};
+  aspect Asynchronous lives there now.]}
address@hidden
+
+
diff --git a/packages/ada-ref-man/source_2012/pragmas.mss 
b/packages/ada-ref-man/source_2012/pragmas.mss
new file mode 100755
index 0000000..55594ae
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pragmas.mss
@@ -0,0 +1,20 @@
address@hidden(pragmas, Root="ada.mss")
+
address@hidden: 2000/08/12 00:40:17 $}
address@hidden Pragmas}
+
address@hidden: e:\\cvsroot/ARM/Source/pragmas.mss,v $}
address@hidden: 1.14 $}
+
address@hidden
address@hidden
+This Annex summarizes the definitions given elsewhere of the
+language-defined pragmas.
+
address@hidden
address@hidden
+
address@hidden
+Pragmas List, Page, and Optimize are now officially defined in
address@hidden
address@hidden
\ No newline at end of file
diff --git a/packages/ada-ref-man/source_2012/pre.mss 
b/packages/ada-ref-man/source_2012/pre.mss
new file mode 100755
index 0000000..e25788b
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pre.mss
@@ -0,0 +1,426 @@
address@hidden(predef, Root="ada.mss")
+
address@hidden: 2015/04/03 04:12:43 $}
address@hidden Language Environment}
+
address@hidden: e:\\cvsroot/ARM/Source/pre.mss,v $}
address@hidden: 1.53 $}
address@hidden: Eliminated includes. $}
+
address@hidden
address@hidden@keepnext
address@hidden@Defn{Language-Defined Library Units}
address@hidden environment}
+This Annex contains the specifications of library units that shall be
+provided by every implementation.
+There are three root library units:
+Ada, Interfaces, and System;
+other library units are children of these:]
+
address@hidden@Keepnext
address@hidden(1),Kind=(Revised),Ref=(8652/0047),ARef=(AI95-00081-01)}
address@hidden,Kind=[Revised],ARef=[AI95-00424-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0001-1],ARef=[AI05-0049-1],ARef=[AI05-0069-1],ARef=[AI05-0111-3],ARef=[AI05-0136-1],ARef=[AI05-0137-1],ARef=[AI05-0166-1],ARef=[AI05-0168-1]}
+@ @*@ @;@comment{paragraph number here, paragraph numbers seem to intrude on
+the RHS column, misaligning it. Thus we have two lines, as small as possible.}
address@hidden
address@hidden@TabSet{L2, L4, L6, L8, L10, L12, L14, L16}
address@hidden
address@hidden@address@hidden<Standard @em @RefSecNum{The Package Standard}
address@hidden @em @RefSecNum{The Package Ada}
address@hidden,New=(@address@hidden @em @RefSecNum{Pragmas Assert and 
Assertion_Policy}
+), Old=()address@hidden@\Asynchronous_Task_Control @em @RefSecNum{Asynchronous 
Task Control}
address@hidden@\Calendar @em @RefSecNum{Delay Statements, Duration, and Time}
address@hidden,New=(@address@hidden@\Arithmetic @em @RefSecNum{Formatting, Time 
Zones, and other operations for Time}
address@hidden@address@hidden @em @RefSecNum{Formatting, Time Zones, and other 
operations for Time}
address@hidden@address@hidden @em @RefSecNum{Formatting, Time Zones, and other 
operations for Time}
+), Old=()address@hidden@\Characters @em @RefSecNum{The Packages Characters, 
Wide_Characters, and Wide_Wide_Characters}
address@hidden,New=(@address@hidden@\Conversions @em @RefSecNum{The Package 
Characters.Conversions}
+), Old=()address@hidden@address@hidden @em @RefSecNum{The Package 
Characters.Handling}
address@hidden@address@hidden @em @RefSecNum{The Package Characters.Latin_1}
address@hidden@\Command_Line @em @RefSecNum{The Package Command_Line}
address@hidden,New=(@address@hidden @em @RefSecNum{Complex Input-Output}
address@hidden@\Containers @em @RefSecNum{The Package Containers}
address@hidden,New=(@address@hidden@\Bounded_Doubly_Linked_Lists
address@hidden@address@hidden@address@hidden@address@hidden @RefSecNum{The 
Generic Package Containers.Bounded_Doubly_Linked_Lists}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Bounded_Hashed_Maps}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Bounded_Hashed_Sets}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Bounded_Multiway_Trees}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Bounded_Ordered_Maps}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Bounded_Ordered_Sets}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Bounded_Priority_Queues}
address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@\ @em @RefSecNum{The Generic 
Package Containers.Bounded_Synchronized_Queues}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Bounded_Vectors}
+), Old=()address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Doubly_Linked_Lists}
address@hidden@address@hidden @em @RefSecNum{Array Sorting}
address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden @RefSecNum{Array 
Sorting}
address@hidden,New=(@address@hidden@\Generic_Sort @em @RefSecNum{Array Sorting}
+), Old=()address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Hashed_Maps}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Hashed_Sets}
address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden @RefSecNum{The 
Generic Package Containers.Indefinite_Doubly_Linked_Lists}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Indefinite_Hashed_Maps}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Indefinite_Hashed_Sets}
address@hidden,New=(@address@hidden@\Indefinite_Holders @em @RefSecNum{The 
Generic Package Containers.Indefinite_Holders}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Indefinite_Multiway_Trees}
+), Old=()address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Indefinite_Ordered_Maps}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Indefinite_Ordered_Sets}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Indefinite_Vectors}), 
Old=()}>@address@hidden@shrink<@Chg{Version=[2],
address@hidden,New=[Standard (@i{...continued})
address@hidden (@i{...continued})
address@hidden@\Containers (@i{...continued})
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Multiway_Trees}
+], Old=()address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Ordered_Maps}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Ordered_Sets}
address@hidden,New=(@address@hidden@\Synchronized_Queue_Interfaces
address@hidden@address@hidden@address@hidden@address@hidden @RefSecNum{The 
Generic Package Containers.Synchronized_Queue_Interfaces}
address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden @RefSecNum{The 
Generic Package Containers.Unbounded_Priority_Queues}
address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden @RefSecNum{The 
Generic Package Containers.Unbounded_Synchronized_Queues}
+), Old=()address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Containers.Vectors}
+], Old=()}>@address@hidden@shrink<@Chg{Version=[2],
address@hidden,New=[],Old=[Standard (@i{...continued})
address@hidden (@i{...continued})
+]}],address@hidden@\Decimal @em @RefSecNum{The Package Decimal}
address@hidden@\Direct_IO @em @RefSecNum{The Generic Package Direct_IO}
address@hidden,New=(@address@hidden @em @RefSecNum{The Package Directories}
address@hidden,New=(@address@hidden@\Hierarchical_File_Names @em @RefSecNum{The 
Package Directories.Hierarchical_File_Names}
+), Old=()address@hidden@address@hidden @em @RefSecNum{The Package Directories}
address@hidden@\Dispatching @em @RefSecNum{The Task Dispatching Model}
address@hidden@address@hidden @em @RefSecNum{Earliest Deadline First 
Dispatching}
address@hidden,address@hidden@address@hidden @em @RefSecNum{Non-Preemptive 
Dispatching}
+], address@hidden@address@hidden @em @RefSecNum{Round Robin Dispatching}
+), Old=()address@hidden@\Dynamic_Priorities @em @RefSecNum{Dynamic Priorities 
for Tasks}
address@hidden,New=(@address@hidden @em @RefSecNum{The Package 
Environment_Variables}
+), Old=()address@hidden@\Exceptions @em @RefSecNum{The Package Exceptions}
address@hidden,New=(@address@hidden @em @RefSecNum{Execution Time}
address@hidden@address@hidden @em @RefSecNum{Group Execution Time Budgets}
address@hidden,New=(@address@hidden@\Interrupts @em @RefSecNum{Execution Time 
of Interrupt Handlers}
+), Old=()address@hidden@address@hidden @em @RefSecNum{Execution Time Timers}
+), Old=()address@hidden@\Finalization @em @RefSecNum{Assignment and 
Finalization}
address@hidden(@address@hidden @em @RefSecNum{Input-Output for Real Types}
address@hidden@\Float_Wide_Text_IO @em @RefSecNum{Wide Text Input-Output and 
Wide Wide Text Input-Output}
address@hidden,New=(@address@hidden @em @RefSecNum{Wide Text Input-Output and 
Wide Wide Text Input-Output}
+), Old=()address@hidden@\Integer_Text_IO @em @RefSecNum{Input-Output for 
Integer Types}
address@hidden@\Integer_Wide_Text_IO @em @RefSecNum{Wide Text Input-Output and 
Wide Wide Text Input-Output}
address@hidden,New=(@address@hidden @em @RefSecNum{Wide Text Input-Output and 
Wide Wide Text Input-Output}
+), Old=()}), Old=()address@hidden@\Interrupts @em @RefSecNum{The Package 
Interrupts}
address@hidden@address@hidden @em @RefSecNum{The Package Interrupts}
address@hidden@\IO_Exceptions @em @RefSecNum{Exceptions in Input-Output}
address@hidden,New=(@address@hidden @em @RefSecNum{User-Defined Iterator Types}
address@hidden@\Locales @em @RefSecNum{The Package Locales}
+), Old=()}>@address@hidden@shrink<@Chg{Version=[3],
+New=[Standard (@i{...continued})
address@hidden (@i{...continued})
+],address@hidden@\Numerics @em @RefSecNum{The Numerics Packages}
address@hidden,New=(@address@hidden@\Complex_Arrays @em @RefSecNum{Complex 
Vectors and Matrices}
+), Old=()address@hidden@address@hidden @em @RefSecNum{Complex Elementary 
Functions}
address@hidden@address@hidden @em @RefSecNum{Complex Types}
address@hidden@address@hidden @em @RefSecNum{Random Number Generation}
address@hidden@address@hidden @em @RefSecNum{Elementary Functions}
address@hidden@address@hidden @em @RefSecNum{Random Number Generation}
address@hidden,New=(@address@hidden@\Generic_Complex_Arrays @em 
@RefSecNum{Complex Vectors and Matrices}
+), Old=()address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden @RefSecNum{Complex 
Elementary Functions}
address@hidden@address@hidden @em @RefSecNum{Complex Types}
address@hidden@address@hidden @em @RefSecNum{Elementary Functions}
address@hidden,New=(@address@hidden@\Generic_Real_Arrays @em @RefSecNum{Real 
Vectors and Matrices}
address@hidden@address@hidden @em @RefSecNum{Real Vectors and Matrices}
+), Old=()address@hidden@\Real_Time @em @RefSecNum{Monotonic Time}
address@hidden,New=(@address@hidden@\Timing_Events @em @RefSecNum{Timing Events}
+), Old=()address@hidden@\Sequential_IO @em @RefSecNum{The Generic Package 
Sequential_IO}
address@hidden@\Storage_IO @em @RefSecNum{The Generic Package Storage_IO}
address@hidden@\Streams @em @RefSecNum{The Package Streams}
address@hidden@address@hidden @em @RefSecNum{The Package Streams.Stream_IO}
+>@address@hidden@address@hidden@shrink<@Chg{Version=[3],
+New=[],Old=[Standard (@i{...continued})
address@hidden (@i{...continued})
address@hidden@\Strings @em @RefSecNum{The Package Strings}
address@hidden@address@hidden @em @RefSecNum{Bounded-Length String Handling}
address@hidden,New=(@address@hidden@address@hidden @em @RefSecNum{String 
Comparison}
+), Old=()address@hidden,New=(@address@hidden@address@hidden @em 
@RefSecNum{String Hashing}
address@hidden,New=(@address@hidden@address@hidden @em @RefSecNum{String 
Hashing}
address@hidden@address@hidden@\Less_Case_Insensitive @em @RefSecNum{String 
Comparison}
+), Old=()}), Old=()address@hidden@address@hidden @em @RefSecNum{Fixed-Length 
String Handling}
address@hidden,New=(@address@hidden@address@hidden @em @RefSecNum{String 
Comparison}
+), Old=()address@hidden,New=(@address@hidden@address@hidden @em 
@RefSecNum{String Hashing}
address@hidden,New=(@address@hidden@address@hidden @em @RefSecNum{String 
Hashing}
address@hidden@address@hidden@\Less_Case_Insensitive @em @RefSecNum{String 
Comparison}
address@hidden@address@hidden @em @RefSecNum{String Comparison}
+), Old=()}), Old=()address@hidden@address@hidden @em @RefSecNum{String Hashing}
address@hidden,New=(@address@hidden@\Hash_Case_Insensitive @em 
@RefSecNum{String Hashing}
address@hidden@address@hidden @em @RefSecNum{String Comparison}
+), Old=()address@hidden@address@hidden @em @RefSecNum{The Package Strings.Maps}
address@hidden@address@hidden@\Constants @em @RefSecNum{String-Handling Sets 
and Mappings}
address@hidden@address@hidden @em @RefSecNum{Unbounded-Length String Handling}
address@hidden,New=(@address@hidden@address@hidden @em @RefSecNum{String 
Comparison}
+), Old=()address@hidden,New=(@address@hidden@address@hidden @em 
@RefSecNum{String Hashing}
address@hidden,New=(@address@hidden@address@hidden @em @RefSecNum{String 
Hashing}
address@hidden@address@hidden@\Less_Case_Insensitive @em @RefSecNum{String 
Comparison}
address@hidden@address@hidden @em @RefSecNum{String Encoding}
address@hidden@address@hidden@\Conversions @em @RefSecNum{String Encoding}
address@hidden@address@hidden@\Strings @em @RefSecNum{String Encoding}
address@hidden@address@hidden@\Wide_Strings @em @RefSecNum{String Encoding}
address@hidden@address@hidden@\Wide_Wide_Strings @em @RefSecNum{String Encoding}
+), Old=()}), Old=()}>@address@hidden@shrink<@Chg{Version=[3],
+New=[Standard (@i{...continued})
address@hidden (@i{...continued})
address@hidden@\Strings (@i{...continued})
+],address@hidden@address@hidden @em @RefSecNum{Wide_String Handling}
address@hidden,New=(@address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden@em 
@RefSecNum{Wide_String Handling}
+), Old=()address@hidden,New=(@address@hidden@address@hidden @em 
@RefSecNum{Wide_String Handling}
address@hidden,New=(@address@hidden@address@hidden @em @RefSecNum{Wide_String 
Handling}
+), Old=()}), 
Old=()address@hidden,New=(@address@hidden@\Wide_Equal_Case_Insensitive @em 
@RefSecNum{Wide_String Handling}
+), Old=()address@hidden@address@hidden @em @RefSecNum{Wide_String Handling}
address@hidden,New=(@address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden@em 
@RefSecNum{Wide_String Handling}
+), Old=()address@hidden,New=(@address@hidden@address@hidden @em 
@RefSecNum{Wide_String Handling}
address@hidden,New=(@address@hidden@address@hidden @em @RefSecNum{Wide_String 
Handling}
+), Old=()address@hidden@address@hidden @em @RefSecNum{Wide_String Handling}
address@hidden,New=(@address@hidden@\Wide_Hash_Case_Insensitive @em 
@RefSecNum{Wide_String Handling}
+), Old=()}), Old=()address@hidden@address@hidden @em @RefSecNum{Wide_String 
Handling}
address@hidden@address@hidden@\Wide_Constants @em @RefSecNum{Wide_String 
Handling}
address@hidden@address@hidden @em @RefSecNum{Wide_String Handling}
address@hidden,New=(@address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden@em 
@RefSecNum{Wide_String Handling}
+), Old=()address@hidden,New=(@address@hidden@address@hidden @em 
@RefSecNum{Wide_String Handling}
address@hidden,New=(@address@hidden@address@hidden @em @RefSecNum{Wide_String 
Handling}
+), Old=()address@hidden@address@hidden @em @RefSecNum{Wide_Wide_String 
Handling}
address@hidden,New=(@address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden@em 
@RefSecNum{Wide_Wide_String Handling}
+), Old=()address@hidden@address@hidden@\Wide_Wide_Hash @em 
@RefSecNum{Wide_Wide_String Handling}
address@hidden,New=(@address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden@em 
@RefSecNum{Wide_Wide_String Handling}
address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden 
@RefSecNum{Wide_Wide_String Handling}
+), address@hidden@address@hidden @em @RefSecNum{Wide_Wide_String Handling}
address@hidden,New=(@address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden@em 
@RefSecNum{Wide_Wide_String Handling}
+), Old=()address@hidden@address@hidden@\Wide_Wide_Hash @em 
@RefSecNum{Wide_Wide_String Handling}
address@hidden,New=(@address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden@em 
@RefSecNum{Wide_Wide_String Handling}
+), address@hidden@address@hidden @em @RefSecNum{Wide_Wide_String Handling}
address@hidden,New=(@address@hidden@\Wide_Wide_Hash_Case_Insensitive
address@hidden@address@hidden@address@hidden@address@hidden@em 
@RefSecNum{Wide_Wide_String Handling}
+), Old=()address@hidden@address@hidden @em @RefSecNum{Wide_Wide_String 
Handling}
address@hidden@address@hidden@\Wide_Wide_Constants @em 
@RefSecNum{Wide_Wide_String Handling}
address@hidden@address@hidden @em @RefSecNum{Wide_Wide_String Handling}
address@hidden,New=(@address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden@em 
@RefSecNum{Wide_Wide_String Handling}
+), Old=()address@hidden@address@hidden@\Wide_Wide_Hash @em 
@RefSecNum{Wide_Wide_String Handling}
address@hidden,New=(@address@hidden@address@hidden
address@hidden@address@hidden@address@hidden@address@hidden@em 
@RefSecNum{Wide_Wide_String Handling}
address@hidden@\Synchronous_Barriers @em @RefSecNum{Synchronous Barriers}
+), Old=[]}), Old=()address@hidden@\Synchronous_Task_Control @em 
@RefSecNum{Synchronous Task Control}
address@hidden,address@hidden@address@hidden @em @RefSecNum{Synchronous Task 
Control}
+], Old=[]}>@address@hidden@shrink<@Chg{Version=[3],
+New=[Standard (@i{...continued})
address@hidden (@i{...continued})
+],address@hidden@\Tags @em @RefSecNum{Tagged Types and Type Extensions}
address@hidden,New=(@address@hidden@\Generic_Dispatching_Constructor @em 
@RefSecNum{Tagged Types and Type Extensions}
+), Old=()address@hidden@\Task_Attributes @em @RefSecNum{The Package 
Task_Attributes}
address@hidden@\Task_Identification @em @RefSecNum{The Package 
Task_Identification}
address@hidden,New=(@address@hidden @em @RefSecNum{The Package 
Task_Termination}), Old=()}>
address@hidden@address@hidden<@Chg{Version=[2],
address@hidden,New=[],Old=[Standard (@i{...continued})
address@hidden (@i{...continued})
+]}], Old=()address@hidden@\Text_IO @em @RefSecNum{The Package Text_IO}
address@hidden,New=(@address@hidden@\Bounded_IO @em @RefSecNum{Input-Output for 
Bounded Strings}
+),Old=()address@hidden@address@hidden @em @RefSecNum{Complex Input-Output}
address@hidden@address@hidden @em @RefSecNum{The Package Text_IO.Editing}
address@hidden@address@hidden @em @RefSecNum{The Package Text_IO.Text_Streams}
address@hidden,New=(@address@hidden@\Unbounded_IO @em @RefSecNum{Input-Output 
for Unbounded Strings}
+), Old=()address@hidden@\Unchecked_Conversion @em @RefSecNum{Unchecked Type 
Conversions}
address@hidden,New=(@address@hidden @em @RefSecNum{Subpool Reclamation}
+), Old=()address@hidden@\Unchecked_Deallocation @em @RefSecNum{Unchecked 
Storage Deallocation}
address@hidden,New=(@address@hidden @em @RefSecNum{The Packages Characters, 
Wide_Characters, and Wide_Wide_Characters}
address@hidden,New=(@address@hidden@\Handling @em @RefSecNum{The Package 
Wide_Characters.Handling}
+),Old=()}),Old=()address@hidden@\Wide_Text_IO @em @RefSecNum{Wide Text 
Input-Output and Wide Wide Text Input-Output}
address@hidden@address@hidden @em @RefSecNum{The Package 
Wide_Text_IO.Complex_IO}
address@hidden@address@hidden @em @RefSecNum{The Package Wide_Text_IO.Editing}
address@hidden@address@hidden @em @RefSecNum{The Package 
Wide_Text_IO.Text_Streams}
address@hidden,New=(@address@hidden@\Wide_Bounded_IO @em @RefSecNum{Wide Text 
Input-Output and Wide Wide Text Input-Output}
address@hidden@address@hidden @em @RefSecNum{Wide Text Input-Output and Wide 
Wide Text Input-Output}
address@hidden@\Wide_Wide_Characters @em @RefSecNum{The Packages Characters, 
Wide_Characters, and Wide_Wide_Characters}
address@hidden,New=(@address@hidden@\Handling @em @RefSecNum{The Package 
Wide_Wide_Characters.Handling}
+),Old=()address@hidden@\Wide_Wide_Text_IO @em @RefSecNum{Wide Text 
Input-Output and Wide Wide Text Input-Output}
address@hidden@address@hidden @em @RefSecNum{The Package 
Wide_Wide_Text_IO.Complex_IO}
address@hidden@address@hidden @em @RefSecNum{The Package 
Wide_Wide_Text_IO.Editing}
address@hidden@address@hidden @em @RefSecNum{The Package 
Wide_Wide_Text_IO.Text_Streams}
address@hidden@address@hidden @em @RefSecNum{Wide Text Input-Output and Wide 
Wide Text Input-Output}
address@hidden@address@hidden @em @RefSecNum{Wide Text Input-Output and Wide 
Wide Text Input-Output}), Old=()}>
+
address@hidden@address@hidden<@\Interfaces @em @RefSecNum{The Package 
Interfaces}
address@hidden@\C @em @RefSecNum{Interfacing with C and C++}
address@hidden@address@hidden @em @RefSecNum{The Generic Package 
Interfaces.C.Pointers}
address@hidden@address@hidden @em @RefSecNum{The Package Interfaces.C.Strings}
address@hidden@\COBOL @em @RefSecNum{Interfacing with COBOL}
address@hidden@\Fortran @em @RefSecNum{Interfacing with Fortran}>
+
address@hidden@shrink<@\System @em @RefSecNum{The Package System}
address@hidden@\Address_To_Access_Conversions @em @RefSecNum{The Package 
System.Address_To_Access_Conversions}
address@hidden@\Machine_Code @em @RefSecNum{Machine Code Insertions}
address@hidden,New=(@address@hidden @em @RefSecNum{Multiprocessor 
Implementation}
address@hidden@address@hidden @em @RefSecNum{Multiprocessor Dispatching Domains}
+),Old=()address@hidden@\RPC @em @RefSecNum{Partition Communication Subsystem}
address@hidden@\Storage_Elements @em @RefSecNum{The Package 
System.Storage_Elements}
address@hidden@\Storage_Pools @em @RefSecNum{Storage address@hidden,New=(
address@hidden@address@hidden @em @RefSecNum{Storage Subpools}), Old=()}>]
address@hidden
address@hidden
address@hidden
+In running text, we generally leave out the @lquotes@;address@hidden@; when 
referring to a
+child of Ada.
address@hidden
address@hidden
+We had no strict rule for which of Ada, Interfaces, or System should be
+the parent of a given library unit.
+However, we have tried to place as many things as possible under Ada,
+except that interfacing is a separate category,
+and we have tried to place library units whose use is highly
+nonportable under System.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
address@hidden,Kind=[Revised],ARef=[AI12-0052-1],ARef=[AI12-0114-1]}
+The implementation shall ensure that each
address@hidden,New=[-],Old=[]}defined subprogram is
address@hidden,address@hidden,address@hidden by Gary Dismukes} in
+the sense that concurrent calls on @Chg{Version=[4],New=[any language-defined],
+Old=[the same]} subprogram perform as specified,
+so long as address@hidden,New=[ objects that are denoted by],Old=[]}
+parameters that could be passed by reference @Chg{Version=[4],New=[or
+designated by parameters of an access type are],Old=[denote]}
address@hidden,New=[],Old=[ objects]}.
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0052-1],ARef=[AI12-0114-1]}
+  @ChgAdded{Version=[4],Text=[So long as the parameters are disjoint, 
concurrent
+  calls on the same language-defined subprogram, and concurrent calls on two
+  different language-defined subprograms are required to work. But concurrent
+  calls operating on overlapping objects (be they of the same or different
+  language-defined subprograms) are @i<not> required to work (being an
+  erroneous use of shared variables) unless both subprograms are required to
+  pass the associated parameter by-copy.]}
+
+  For example, simultaneous calls to Text_IO.Put will work properly,
+  so long as they are going to two different files.
+  On the other hand, simultaneous output to the same file constitutes
+  erroneous use of shared variables.
address@hidden
address@hidden
+  Here, @lquotes@;language defined address@hidden@; means a language defined 
library
+  subprogram, a subprogram declared in the visible part of a language
+  defined library package, an instance of a language defined
+  generic library subprogram,
+  or a subprogram declared in the visible part
+  of an instance of a language defined generic library package.
address@hidden
address@hidden
+  @ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0052-1]}
+  @ChgAdded{Version=[4],Text=[This rule applies to all language-defined
+  subprograms, including those defined in packages that manage some global 
state
+  (like environment variables or the current directory). Unless specified 
above,
+  such subprograms need to work when the explicit parameters are not
+  overlapping; in particular, the existence of the global state is not
+  considered.]}
+
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0052-1]}
+  The rule implies that any data local to the private part or
+  body of the package @Chg{Version=[4],New=[(including global state as 
described
+  above) ],Old=[]}has to be somehow protected against simultaneous access.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI12-0052-1],ARef=[AI12-0159-1]}
address@hidden,Text=[For the purpose of determining whether concurrent
+calls on text input-output subprograms are required to perform as specified
+above, when calling a subprogram within Text_IO or its children that implicitly
+operates on one of the default input-output files, the subprogram is considered
+to have a parameter of Current_Input or Current_Output (as appropriate).]}
+
address@hidden,Kind=[Added],ARef=[AI05-0048-1]}
address@hidden,Text=[If a descendant of a language-defined tagged
+type is declared, the implementation
+shall ensure that each inherited language-defined subprogram behaves as
+described in this International Standard. In particular, overriding
+a language-defined subprogram shall
+not alter the effect of any inherited language-defined subprogram.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This means that internally the implementation
+  must not do redispatching unless it is required by the Standard.
+  So when we say that some subprogram Bar is equivalent to
+  Foo, overriding Foo for a derived type doesn't change the semantics of
+  Bar, and in particular it means that Bar may no longer be equivalent to
+  Foo. The word @ldquote@;address@hidden is always a bit of a lie anyway.]}
address@hidden
address@hidden
+
address@hidden
+The implementation may restrict the replacement of language-defined
+compilation units.
+The implementation may restrict children of language-defined library
+units (other than Standard).
address@hidden
+For example, the implementation may say,
address@hidden@;you cannot compile a library unit called address@hidden@;
+or @lquotes@;you cannot compile a child of package address@hidden@;
+or @lquotes@;if you compile a library unit called System,
+it has to be a package, and it has to contain at least
+the following declarations: address@hidden@;.
address@hidden
address@hidden
+
address@hidden
+Many of Ada 83's language-defined library units are now children of Ada
+or System.
+For upward compatibility, these are renamed as root library units
+(see @RefSecNum{Renamings of Library Units}).
+
+The order and lettering of the annexes has been changed.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0047],ARef=[AI95-00081-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Units missing from the 
list of
+  predefined units were added.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00424-01]}
+  @ChgAdded{Version=[2],Text=[Added new units to the list of
+  predefined units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0048-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added wording to ban
+  redispatching unless it is explicitly required, in order to safeguard
+  portability when overriding language-defined routines.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0060-1],ARef=[AI05-0206-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a permission to
+  omit pragma Remote_Types from language-defined units if Annex E is
+  not supported. This was later removed, as a better method of supporting
+  the reason is now available.
+  Note that this requires all implementations to provide minimal support for
+  the Remote_Types categorization even if Annex E is not supported; being
+  unable to compile language-defined units is not allowed.]}
+
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0049-1],ARef=[AI05-0069-1],ARef=[AI05-0111-3],ARef=[AI05-0136-1],ARef=[AI05-0137-1],ARef=[AI05-0166-1],ARef=[AI05-0168-1]}
+  @ChgAdded{Version=[3],Text=[Added various new units to the
+  list of predefined units.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[4],Kind=[Added],ARef=[AI12-0052-1],ARef=[AI12-0114-1],ARef=[AI12-0159-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> The rules requiring 
concurrent
+  access of language-defined subprograms were expanded to include implicit
+  Text_IO objects, overlapping objects designated by parameters of an access
+  type, and simultaneous calls on different language-defined subprograms. While
+  this might change behavior of some programs, it would do so by eliminating
+  erroneous execution, so we don't consider this an inconsistency.]}
address@hidden
diff --git a/packages/ada-ref-man/source_2012/pre_ada.mss 
b/packages/ada-ref-man/source_2012/pre_ada.mss
new file mode 100755
index 0000000..89ddb6c
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pre_ada.mss
@@ -0,0 +1,53 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/pre_ada.mss,v $ }
address@hidden $Revision: 1.16 $ $Date: 00/03/08 Created by RLB to avoid 
Includes }
address@hidden(predefstandard, Root="ada.mss")
+
address@hidden: 2012/11/28 23:53:05 $}
+
address@hidden Package Ada}
+
address@hidden
address@hidden@keepnext@;The following language-defined library package exists:
address@hidden
address@hidden@key[package] Ada @key[is]
+    @key[pragma] Pure(Ada);
address@hidden Ada;
address@hidden
+
+Ada serves as the parent of most of the other language-defined library
+units; its declaration is empty (except for the @nt{pragma} Pure).
address@hidden
+
address@hidden
+In the standard mode, it is illegal to compile a child of package
+Ada.
address@hidden
+The intention is that mentioning, say, Ada.Text_IO in a
address@hidden is guaranteed (at least in the standard mode) to refer
+to the standard version of Ada.Text_IO.
+The user can compile a root library unit Text_IO that has no relation to
+the standard version of Text_IO.
address@hidden
address@hidden
+Note that Ada can have non-language-defined grandchildren,
+assuming the implementation allows it.
+Also, packages System and Interfaces can have children,
+assuming the implementation allows it.
address@hidden
address@hidden
+An implementation will typically support a nonstandard mode in
+which compiling the language defined library units is allowed.
+Whether or not this mode is made available to users is up to the
+implementer.
+
+An implementation could theoretically have private children of
+Ada, since that would be semantically neutral.
+However, a programmer cannot compile such a library unit.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden to Ada 83}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} is new to Ada 95.
address@hidden
diff --git a/packages/ada-ref-man/source_2012/pre_chars.mss 
b/packages/ada-ref-man/source_2012/pre_chars.mss
new file mode 100755
index 0000000..2d89ebe
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pre_chars.mss
@@ -0,0 +1,1346 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/pre_chars.mss,v $ }
address@hidden $Revision: 1.48 $ $Date: 2012/11/28 23:53:06 $ $Author: randy $ }
address@hidden(predefchars, Root="ada.mss")
+
address@hidden: 2012/11/28 23:53:06 $}
+
address@hidden Handling}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0243-1],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} presents the packages
+related to character processing:
+an empty @Chg{Version=[3],New=[declared ],Old=[]}pure package Characters
+and child packages Characters.Handling and Characters.Latin_1.
+The package Characters.Handling provides classification and conversion
+functions for Character data, and some simple functions for
+dealing with Wide_Character @Chg{Version=[2],New=[and Wide_Wide_Character ],
+Old=[]}data.
+The child package Characters.Latin_1 declares a set of
+constants initialized to values of type Character.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden to Ada 83}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} is new to Ada 95.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[Included Wide_Wide_Character in this description;
+  the individual changes are documented as extensions as needed.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,New=[The Packages Characters, Wide_Characters, and 
Wide_Wide_Characters],Old=[The Package Characters]}
+
address@hidden
address@hidden@keepnext@;The library package Characters has the following 
declaration:
address@hidden
address@hidden,address@hidden(package) Ada.Characters @key[is]
+  @key[pragma] Pure(Characters);
address@hidden(end) Ada.Characters;
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The library package
+Wide_Characters has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden,address@hidden(package) Ada.Wide_Characters 
@key[is]
+  @key[pragma] Pure(Wide_Characters);
address@hidden Ada.Wide_Characters;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The library package
+Wide_Wide_Characters has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden,address@hidden(package) Ada.Wide_Wide_Characters 
@key[is]
+  @key[pragma] Pure(Wide_Wide_Characters);
address@hidden Ada.Wide_Wide_Characters;]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0185-1]}
address@hidden,Text=[If an implementation chooses to provide
+implementation-defined operations on Wide_Character or Wide_String (such as
address@hidden,New=[],Old=[case mapping, classification, ]}collating and
+sorting, etc.) it should do so by
+providing child units of Wide_Characters. Similarly if it chooses to
+provide implementation-defined operations on Wide_Wide_Character or
+Wide_Wide_String it should do so by providing child units of
+Wide_Wide_Characters.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Implementation-defined operations on Wide_Character, Wide_String,
+Wide_Wide_Character, and Wide_Wide_String should be child units of
+Wide_Characters or Wide_Wide_Characters.]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00395-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The packages Wide_Characters and Wide_Wide_Characters are new.]}
address@hidden
+
+
address@hidden Package Characters.Handling}
address@hidden
address@hidden@keepnext@;The library package Characters.Handling has the 
following declaration:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00362-01],ARef=[AI95-00395-01]}
address@hidden,address@hidden Ada.Characters.Conversions;
+],address@hidden Ada.Characters.Handling @address@hidden,Child=[Handling]}
+  @key[pragma] @Chg{Version=[2],New=[Pure],Old=[Preelaborate]}(Handling);
+
address@hidden@RI{Character classification functions}
+
address@hidden,Kind=[Revised],ARef=[AI05-0185-1]}
+  @key[function] @AdaSubDefn{Is_Control}           (Item : @key[in] Character) 
@key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_Graphic}           (Item : @key[in] Character) 
@key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_Letter}            (Item : @key[in] Character) 
@key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_Lower}             (Item : @key[in] Character) 
@key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_Upper}             (Item : @key[in] Character) 
@key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_Basic}             (Item : @key[in] Character) 
@key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_Digit}             (Item : @key[in] Character) 
@key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_Decimal_Digit}     (Item : @key[in] Character) 
@key[return] Boolean
+                     @key[renames] Is_Digit;
+  @key[function] @AdaSubDefn{Is_Hexadecimal_Digit} (Item : @key[in] Character) 
@key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_Alphanumeric}      (Item : @key[in] Character) 
@key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_Special}           (Item : @key[in] Character) 
@key[return] Boolean;@Chg{Version=[3],New=[
+  @key[function] @AdaSubDefn{Is_Line_Terminator}   (Item : @key[in] Character) 
@key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_Mark}              (Item : @key[in] Character) 
@key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_Other_Format}      (Item : @key[in] Character) 
@key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_Punctuation_Connector} (Item : @key[in] 
Character) @key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_Space}             (Item : @key[in] Character) 
@key[return] Boolean;],Old=[]}
+
address@hidden@RI{Conversion functions for Character and String}
+
+  @key[function] @AdaSubDefn{To_Lower} (Item : @key[in] Character) 
@key[return] Character;
+  @key[function] @AdaSubDefn{To_Upper} (Item : @key[in] Character) 
@key[return] Character;
+  @key[function] @AdaSubDefn{To_Basic} (Item : @key[in] Character) 
@key[return] Character;
+
+  @key[function] @AdaSubDefn{To_Lower} (Item : @key[in] String) @key[return] 
String;
+  @key[function] @AdaSubDefn{To_Upper} (Item : @key[in] String) @key[return] 
String;
+  @key[function] @AdaSubDefn{To_Basic} (Item : @key[in] String) @key[return] 
String;
+
+
address@hidden@RI{Classifications of and conversions between Character and ISO 
646}
+
+  @key[subtype] @AdaSubtypeDefn{Name=[ISO_646],Of=[Character]} @key[is]
+    Character @key[range] Character'Val(0) .. Character'Val(127);
+
+  @key[function] @AdaSubDefn{Is_ISO_646} (Item : @key[in] Character) 
@key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_ISO_646} (Item : @key[in] String)    
@key[return] Boolean;
+
+  @key[function] @AdaSubDefn{To_ISO_646} (Item       : @key[in] Character;
+                       Substitute : @key[in] ISO_646 := ' ')
+    @key[return] ISO_646;
+
+  @key[function] @AdaSubDefn{To_ISO_646} (Item       : @key[in] String;
+                       Substitute : @key[in] ISO_646 := ' ')
+    @key[return] String;
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden@address@hidden,New=[ The functions Is_Character, Is_String, 
To_Character, To_String, To_Wide_Character,],Old=[Classifications of and 
conversions between Wide_Character and address@hidden,New=[
address@hidden and To_Wide_String are obsolescent; see @RefSecnum{Character and 
Wide_Character Conversion Functions}.}],Old=[]}
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@address@hidden<Paragraphs
 14 through 18 were deleted.>address@hidden
+message should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00395-01]}
address@hidden,Text=[  @key[function] @AdaSubDefn{Is_Character} (Item : 
@key[in] Wide_Character) @key[return] Boolean;
+  @key[function] @AdaSubDefn{Is_String}    (Item : @key[in] Wide_String)    
@key[return] Boolean;]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00395-01]}
address@hidden,Text=[  @key[function] @AdaSubDefn{To_Character} (Item       : 
@key[in] Wide_Character;
+                         Substitute : @key[in] Character := ' ')
+    @key[return] Character;]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00395-01]}
address@hidden,Text=[  @key[function] @AdaSubDefn{To_String}    (Item       : 
@key[in] Wide_String;
+                         Substitute : @key[in] Character := ' ')
+    @key[return] String;]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00395-01]}
address@hidden,Text=[  @key[function] @AdaSubDefn{To_Wide_Character} (Item : 
@key[in] Character) @key[return] Wide_Character;]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00395-01]}
address@hidden,Text=[  @key[function] @AdaSubDefn{To_Wide_String}    (Item : 
@key[in] String)    @key[return] Wide_String;]}
+
address@hidden Ada.Characters.Handling;
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Text=[The @nt{with_clause} for Ada.Characters.Conversions
+is needed for the definition of the obsolescent functions (see
address@hidden and Wide_Character Conversion Functions}). It would
+be odd to put this clause
+into @RefSecnum{Character and Wide_Character Conversion Functions}
+as it was not present in Ada 95,
+and @nt{with_clause}s are semantically neutral to clients anyway.]}
address@hidden
+
+In the description below for each function that returns a Boolean
+result, the effect is described in terms of the conditions under which
+the value True is returned. If these conditions are not met, then the
+function returns False.
+
+Each of the following classification functions has a formal Character
+parameter, Item, and returns a Boolean result.
address@hidden
address@hidden character], sec=[a category of Character]}Is_Control @\True if 
Item is a control character.
+A @i{control character} is a character whose position is
+in one of the ranges 0..31 or 127..159.
+
address@hidden character], sec=[a category of Character]}Is_Graphic @\True if 
Item is a graphic character. A @i[graphic character]
+is a character whose position is in one of the ranges
+32..126 or 160..255.
+
address@hidden, sec=[a category of Character]}Is_Letter @\True if Item is a 
letter.
+A @i[letter] is a character that is in one of the ranges
+'A'..'Z' or 'a'..'z', or whose position is in one of the ranges
+192..214, 216..246, or 248..255.
+
address@hidden letter], sec=[a category of Character]}Is_Lower @\True if Item 
is a lower-case letter.
+A @i[lower-case letter] is a character that is in
+the range 'a'..'z', or whose position is in one of the ranges
+223..246 or 248..255.
+
address@hidden letter], sec=[a category of address@hidden if Item is an 
upper-case letter.
+An @i[upper-case letter] is a character that is in the range
+'A'..'Z' or whose position is in one of the ranges
+192..214 or 216.. 222.
+
address@hidden letter], sec=[a category of Character]}Is_Basic @\True if Item 
is a basic letter.
+A @i[basic letter] is a character that is in one of the
+ranges 'A'..'Z' and 'a'..'z', or that is one of the
+following:
+'@latin1(198)', '@latin1(230)', '@latin1(208)', '@latin1(240)', 
'@latin1(222)', '@latin1(254)', or '@latin1(223)'.
+
address@hidden characters are at the positions
+198 and 230, 208 and 240, 222 and 254, and 223.]
+
address@hidden digit], sec=[a category of Character]}Is_Digit @\True if Item is 
a decimal digit.
+A @i[decimal digit] is a character in the range '0'..'9'.
+
+Is_Decimal_Digit @\A renaming of Is_Digit.
+
address@hidden digit], sec=[a category of Character]}Is_Hexadecimal_Digit 
@\True if Item is a hexadecimal digit.
+A @i[hexadecimal digit] is a character that is either a
+decimal digit or that is in one of the ranges 'A' .. 'F' or 'a' .. 'f'.
+
address@hidden character], sec=[a category of Character]}Is_Alphanumeric @\True 
if Item is an alphanumeric character.
+An @i[alphanumeric character] is a character that is either
+a letter or a decimal digit.
+
address@hidden graphic character], sec=[a category of Character]}Is_Special 
@\True if Item is a special graphic character.
+A @i[special graphic character] is a graphic character that is
+not alphanumeric.
+
address@hidden,Kind=[Added],ARef=[AI05-0185-1]}
address@hidden,address@hidden if Item is a character
+with position 10 .. 13 (Line_Feed, Line_Tabulation, Form_Feed, Carriage_Return)
+or 133 (Next_Line).]}
+
address@hidden,Kind=[Added],ARef=[AI05-0185-1]}
address@hidden,address@hidden True (no value of type Character
+has categories Mark, Non-Spacing or Mark, Spacing Combining).]}
+
address@hidden,Kind=[Added],ARef=[AI05-0185-1]}
address@hidden,address@hidden if Item is a character
+with position 173 (Soft_Hyphen).]}
+
address@hidden,Kind=[Added],ARef=[AI05-0185-1]}
address@hidden,address@hidden if Item is a
+character with position 95 ('_', known as Low_Line or Underscore).]}
+
address@hidden,Kind=[Added],ARef=[AI05-0185-1]}
address@hidden,address@hidden if Item is a character with
+position 32 (' ') or 160 (No_Break_Space).]}
address@hidden
+
+Each of the names
+To_Lower, To_Upper, and To_Basic refers to two
+functions: one that converts from Character to Character, and the
+other that converts from String to String. The result of each
+Character-to-Character function is described below, in terms of the
+conversion applied to Item, its formal Character parameter. The
+result of each  String-to-String conversion is obtained by applying
+to each element of the function's
+ String parameter the corresponding Character-to-Character conversion;
+the result is the null String if the value of the formal parameter
+is the null String.
+The lower bound of the result String is 1.
address@hidden
address@hidden the corresponding lower-case value for Item if
+Is_Upper(Item), and returns Item otherwise.
+
address@hidden the corresponding upper-case value for Item if
+Is_Lower(Item) and Item has an upper-case form, and returns Item otherwise.
+The lower case letters
+'@latin1(223)' and '@latin1(255)'
address@hidden are at positions 223 and 255}
+do not have upper case forms.
+
address@hidden the letter corresponding to Item
+but with no diacritical mark,
+if Item is a letter but not a basic letter;
+returns Item otherwise.
address@hidden
+
+The following set of functions test for membership in the ISO 646
+character range, or convert between ISO 646 and Character.
address@hidden
address@hidden function whose formal parameter, Item, is of type
+Character returns True if Item is in the subtype ISO_646.
+
address@hidden function whose formal parameter, Item, is of type
+String returns True if Is_ISO_646(Item(I)) is True for each I in
+Item'Range.
+
address@hidden function whose first formal parameter, Item, is of type
+Character returns Item if Is_ISO_646(Item), and returns the Substitute
+ISO_646 character otherwise.
+
address@hidden function whose first formal parameter, Item, is of type
+String returns the String whose Range is 1..Item'Length and each of
+whose elements is given by To_ISO_646 of the corresponding element in
+Item.
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@address@hidden<Paragraphs
 42
+through 49 were deleted.>address@hidden message should be deleted if the
+paragraphs are ever renumbered. This includes the following ImplAdv paragraph.}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,Text=[The following set of functions test
+Wide_Character values for membership in Character,
+or convert between corresponding characters of
+Wide_Character and Character.]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,address@hidden True if
+Wide_Character'Pos(Item) <= Character'Pos(Character'Last).]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,address@hidden True if Is_Character(Item(I))
+is True for each I in Item'Range.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,address@hidden the Character corresponding
+to Item if Is_Character(Item), and returns the Substitute Character 
otherwise.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,address@hidden the String whose range is
+1..Item'Length and each of whose elements is given by To_Character of the
+corresponding element in Item.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,address@hidden the Wide_Character X
+such that Character'Pos(Item) = Wide_Character'Pos(X).]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,address@hidden the Wide_String whose
+range is 1..Item'Length and each of whose elements is given by
+To_Wide_Character of the corresponding element in Item.]}
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00285-01]}
address@hidden,Text=[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
address@hidden(Character Types).]}
address@hidden @ChgImplAdvice here, because we'd have to insert and delete the
+item in the same version.}
address@hidden
+
address@hidden
+ A basic letter is a letter without a diacritical mark.
+
address@hidden@;Except for the hexadecimal digits, basic letters, and ISO_646
+characters, the categories identified in the classification functions
+form a strict hierarchy:
address@hidden
address@hidden@Comment{We use "Leading" below to make this list closely packed}
address@hidden, 8, 12, 16}
address@hidden@em Control characters
+
address@hidden@em Graphic characters
+
address@hidden@address@hidden Alphanumeric characters
+
address@hidden@address@hidden@em Letters
+
address@hidden@address@hidden@address@hidden Upper-case letters
+
address@hidden@address@hidden@address@hidden Lower-case letters
+
address@hidden@address@hidden@em Decimal digits
+
address@hidden@address@hidden Special graphic characters
address@hidden
+
address@hidden
+Thus each Character value is either a control character or
+a graphic character but not both; each graphic character is either
+an alphanumeric or special graphic but not both; each alphanumeric
+is either a letter or decimal digit but not both; each letter is
+either upper case or lower case but not address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0114-1]}
address@hidden,Text=[There are certain characters which are defined to be
+lower case letters by ISO 10646 and are therefore allowed in identifiers, but
+are not considered lower case letters by Ada.Characters.Handling.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is to maintain runtime compatibility with
+  the Ada 95 definitions of these functions. We don't list the exact characters
+  involved because they're likely to change in future character set standards;
+  the list for ISO 10646:2011 can be found in
+  @AILink{AI=[AI05-0114-1],Text=[AI05-0114-1]}.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[No version of Characters.Handling is intended
+  to do portable (Ada-version independent) manipulation of Ada identifiers.
+  The classification given by Wide_Characters.Handling will be correct for
+  the current implementation for Ada 2012 identifiers, but it might not be
+  correct for a different implementation or version of Ada.]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00362-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Characters.Handling is now Pure, so it can be used in pure units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0185-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  Added additional classification routines so that Characters.Handling has
+  all of the routines available in Wide_Characters.Handling. If
+  Characters.Handling is referenced in a @nt{use_clause}, and an
+  entity @i<E> with a @nt{defining_identifier} that is the same as one of
+  the new functions is
+  defined in a package that is also referenced in a @nt{use_clause}, the entity
+  @i<E> may no longer be use-visible, resulting in errors. This should be rare
+  and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
+  @ChgAdded{Version=[2],Text=[The conversion functions are made obsolescent;
+  a more complete set is available in Characters.Conversions @em
+  see @RefSecNum{The Package Characters.Conversions}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[2],Text=[We no longer talk about localized character
+  sets; these are a @Chg{Version=[3],New=[nonstandard],Old=[non-standard]} 
mode,
+  which is none of our business.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0114-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a note to clarify 
that
+  these functions don't have any relationship to the characters allowed in
+  identifiers.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden Package Characters.Latin_1}
address@hidden
+The package Characters.Latin_1 declares constants for
+characters in ISO 8859-1.
address@hidden
+The constants for the ISO 646 characters could have
+been declared as renamings of objects declared in package ASCII, as
+opposed to explicit constants. The main reason for explicit constants
+was for consistency of style with the upper-half constants, and to avoid
+emphasizing the package address@hidden
address@hidden
+
address@hidden
address@hidden@keepnext@;The library package Characters.Latin_1 has the 
following
+declaration:
address@hidden
address@hidden Ada.Characters.Latin_1 @address@hidden,Child=[Latin_1]}
+    @key[pragma] Pure(Latin_1);
+
address@hidden@RI{ Control characters:address@hidden character],
+sec=[a category of Character]}
+
+    @AdaObjDefn{NUL}                  : @key[constant] Character := 
Character'Val(0);
+    @AdaObjDefn{SOH}                  : @key[constant] Character := 
Character'Val(1);
+    @AdaObjDefn{STX}                  : @key[constant] Character := 
Character'Val(2);
+    @AdaObjDefn{ETX}                  : @key[constant] Character := 
Character'Val(3);
+    @AdaObjDefn{EOT}                  : @key[constant] Character := 
Character'Val(4);
+    @AdaObjDefn{ENQ}                  : @key[constant] Character := 
Character'Val(5);
+    @AdaObjDefn{ACK}                  : @key[constant] Character := 
Character'Val(6);
+    @AdaObjDefn{BEL}                  : @key[constant] Character := 
Character'Val(7);
+    @AdaObjDefn{BS}                   : @key[constant] Character := 
Character'Val(8);
+    @AdaObjDefn{HT}                   : @key[constant] Character := 
Character'Val(9);
+    @AdaObjDefn{LF}                   : @key[constant] Character := 
Character'Val(10);
+    @AdaObjDefn{VT}                   : @key[constant] Character := 
Character'Val(11);
+    @AdaObjDefn{FF}                   : @key[constant] Character := 
Character'Val(12);
+    @AdaObjDefn{CR}                   : @key[constant] Character := 
Character'Val(13);
+    @AdaObjDefn{SO}                   : @key[constant] Character := 
Character'Val(14);
+    @AdaObjDefn{SI}                   : @key[constant] Character := 
Character'Val(15);
+
+    @AdaObjDefn{DLE}                  : @key[constant] Character := 
Character'Val(16);
+    @AdaObjDefn{DC1}                  : @key[constant] Character := 
Character'Val(17);
+    @AdaObjDefn{DC2}                  : @key[constant] Character := 
Character'Val(18);
+    @AdaObjDefn{DC3}                  : @key[constant] Character := 
Character'Val(19);
+    @AdaObjDefn{DC4}                  : @key[constant] Character := 
Character'Val(20);
+    @AdaObjDefn{NAK}                  : @key[constant] Character := 
Character'Val(21);
+    @AdaObjDefn{SYN}                  : @key[constant] Character := 
Character'Val(22);
+    @AdaObjDefn{ETB}                  : @key[constant] Character := 
Character'Val(23);
+    @AdaObjDefn{CAN}                  : @key[constant] Character := 
Character'Val(24);
+    @AdaObjDefn{EM}                   : @key[constant] Character := 
Character'Val(25);
+    @AdaObjDefn{SUB}                  : @key[constant] Character := 
Character'Val(26);
+    @AdaObjDefn{ESC}                  : @key[constant] Character := 
Character'Val(27);
+    @AdaObjDefn{FS}                   : @key[constant] Character := 
Character'Val(28);
+    @AdaObjDefn{GS}                   : @key[constant] Character := 
Character'Val(29);
+    @AdaObjDefn{RS}                   : @key[constant] Character := 
Character'Val(30);
+    @AdaObjDefn{US}                   : @key[constant] Character := 
Character'Val(31);
+
address@hidden@RI{ ISO 646 graphic characters:}
+
+    @AdaObjDefn{Space}                : @key[constant] Character := ' ';  
address@hidden Character'Val(32)}
+    @AdaObjDefn{Exclamation}          : @key[constant] Character := '!';  
address@hidden Character'Val(33)}
+    @AdaObjDefn{Quotation}            : @key[constant] Character := '"';  
address@hidden Character'Val(34)}
+    @AdaObjDefn{Number_Sign}          : @key[constant] Character := '#';  
address@hidden Character'Val(35)}
+    @AdaObjDefn{Dollar_Sign}          : @key[constant] Character := '$';  
address@hidden Character'Val(36)}
+    @AdaObjDefn{Percent_Sign}         : @key[constant] Character := '%';  
address@hidden Character'Val(37)}
+    @AdaObjDefn{Ampersand}            : @key[constant] Character := '&';  
address@hidden Character'Val(38)}
+    @AdaObjDefn{Apostrophe}           : @key[constant] Character := ''';  
address@hidden Character'Val(39)}
+    @AdaObjDefn{Left_Parenthesis}     : @key[constant] Character := '(';  
address@hidden Character'Val(40)}
+    @AdaObjDefn{Right_Parenthesis}    : @key[constant] Character := ')';  
address@hidden Character'Val(41)}
+    @AdaObjDefn{Asterisk}             : @key[constant] Character := '*';  
address@hidden Character'Val(42)}
+    @AdaObjDefn{Plus_Sign}            : @key[constant] Character := '+';  
address@hidden Character'Val(43)}
+    @AdaObjDefn{Comma}                : @key[constant] Character := ',';  
address@hidden Character'Val(44)}
+    @AdaObjDefn{Hyphen}               : @key[constant] Character := '-';  
address@hidden Character'Val(45)}
+    @AdaObjDefn{Minus_Sign}           : Character @key[renames] Hyphen;
+    @AdaObjDefn{Full_Stop}            : @key[constant] Character := '.';  
address@hidden Character'Val(46)}
+    @AdaObjDefn{Solidus}              : @key[constant] Character := '/';  
address@hidden Character'Val(47)}
+
address@hidden    address@hidden Decimal digits '0' though '9' are at positions 
48 through 57}
+
+    @AdaObjDefn{Colon}                : @key[constant] Character := ':';  
address@hidden Character'Val(58)}
+    @AdaObjDefn{Semicolon}            : @key[constant] Character := ';';  
address@hidden Character'Val(59)}
+    @AdaObjDefn{Less_Than_Sign}       : @key[constant] Character := '<';  
address@hidden Character'Val(60)}
+    @AdaObjDefn{Equals_Sign}          : @key[constant] Character := '=';  
address@hidden Character'Val(61)}
+    @AdaObjDefn{Greater_Than_Sign}    : @key[constant] Character := '>';  
address@hidden Character'Val(62)}
+    @AdaObjDefn{Question}             : @key[constant] Character := '?';  
address@hidden Character'Val(63)}
+    @AdaObjDefn{Commercial_At}        : @key[constant] Character := '@@';  
address@hidden Character'Val(64)}
+
address@hidden    address@hidden Letters 'A' through 'Z' are at positions 65 
through 90}
+
+    @AdaObjDefn{Left_Square_Bracket}  : @key[constant] Character := '[';  
address@hidden Character'Val(91)}
+    @AdaObjDefn{Reverse_Solidus}      : @key[constant] Character := '\';  
address@hidden Character'Val(92)}
+    @AdaObjDefn{Right_Square_Bracket} : @key[constant] Character := ']';  
address@hidden Character'Val(93)}
+    @AdaObjDefn{Circumflex}           : @key[constant] Character := '^';  
address@hidden Character'Val(94)}
+    @AdaObjDefn{Low_Line}             : @key[constant] Character := '_';  
address@hidden Character'Val(95)}
+
+    @AdaObjDefn{Grave}                : @key[constant] Character := '`';  
address@hidden Character'Val(96)}
+    @AdaObjDefn{LC_A}                 : @key[constant] Character := 'a';  
address@hidden Character'Val(97)}
+    @AdaObjDefn{LC_B}                 : @key[constant] Character := 'b';  
address@hidden Character'Val(98)}
+    @AdaObjDefn{LC_C}                 : @key[constant] Character := 'c';  
address@hidden Character'Val(99)}
+    @AdaObjDefn{LC_D}                 : @key[constant] Character := 'd';  
address@hidden Character'Val(100)}
+    @AdaObjDefn{LC_E}                 : @key[constant] Character := 'e';  
address@hidden Character'Val(101)}
+    @AdaObjDefn{LC_F}                 : @key[constant] Character := 'f';  
address@hidden Character'Val(102)}
+    @AdaObjDefn{LC_G}                 : @key[constant] Character := 'g';  
address@hidden Character'Val(103)}
+    @AdaObjDefn{LC_H}                 : @key[constant] Character := 'h';  
address@hidden Character'Val(104)}
+    @AdaObjDefn{LC_I}                 : @key[constant] Character := 'i';  
address@hidden Character'Val(105)}
+    @AdaObjDefn{LC_J}                 : @key[constant] Character := 'j';  
address@hidden Character'Val(106)}
+    @AdaObjDefn{LC_K}                 : @key[constant] Character := 'k';  
address@hidden Character'Val(107)}
+    @AdaObjDefn{LC_L}                 : @key[constant] Character := 'l';  
address@hidden Character'Val(108)}
+    @AdaObjDefn{LC_M}                 : @key[constant] Character := 'm';  
address@hidden Character'Val(109)}
+    @AdaObjDefn{LC_N}                 : @key[constant] Character := 'n';  
address@hidden Character'Val(110)}
+    @AdaObjDefn{LC_O}                 : @key[constant] Character := 'o';  
address@hidden Character'Val(111)}
+
+    @AdaObjDefn{LC_P}                 : @key[constant] Character := 'p';  
address@hidden Character'Val(112)}
+    @AdaObjDefn{LC_Q}                 : @key[constant] Character := 'q';  
address@hidden Character'Val(113)}
+    @AdaObjDefn{LC_R}                 : @key[constant] Character := 'r';  
address@hidden Character'Val(114)}
+    @AdaObjDefn{LC_S}                 : @key[constant] Character := 's';  
address@hidden Character'Val(115)}
+    @AdaObjDefn{LC_T}                 : @key[constant] Character := 't';  
address@hidden Character'Val(116)}
+    @AdaObjDefn{LC_U}                 : @key[constant] Character := 'u';  
address@hidden Character'Val(117)}
+    @AdaObjDefn{LC_V}                 : @key[constant] Character := 'v';  
address@hidden Character'Val(118)}
+    @AdaObjDefn{LC_W}                 : @key[constant] Character := 'w';  
address@hidden Character'Val(119)}
+    @AdaObjDefn{LC_X}                 : @key[constant] Character := 'x';  
address@hidden Character'Val(120)}
+    @AdaObjDefn{LC_Y}                 : @key[constant] Character := 'y';  
address@hidden Character'Val(121)}
+    @AdaObjDefn{LC_Z}                 : @key[constant] Character := 'z';  
address@hidden Character'Val(122)}
+    @AdaObjDefn{Left_Curly_Bracket}   : @key[constant] Character := '{';  
address@hidden Character'Val(123)}
+    @AdaObjDefn{Vertical_Line}        : @key[constant] Character := '|';  
address@hidden Character'Val(124)}
+    @AdaObjDefn{Right_Curly_Bracket}  : @key[constant] Character := '}';  
address@hidden Character'Val(125)}
+    @AdaObjDefn{Tilde}                : @key[constant] Character := '~';  
address@hidden Character'Val(126)}
+    @AdaObjDefn{DEL}                  : @key[constant] Character := 
Character'Val(127);
+
+
address@hidden@RI{ ISO 6429 control characters:address@hidden character],
+sec=[a category of Character]}
+
+    @AdaObjDefn{IS4}                  : Character @key[renames] FS;
+    @AdaObjDefn{IS3}                  : Character @key[renames] GS;
+    @AdaObjDefn{IS2}                  : Character @key[renames] RS;
+    @AdaObjDefn{IS1}                  : Character @key[renames] US;
+
+    @AdaObjDefn{Reserved_128}         : @key[constant] Character := 
Character'Val(128);
+    @AdaObjDefn{Reserved_129}         : @key[constant] Character := 
Character'Val(129);
+    @AdaObjDefn{BPH}                  : @key[constant] Character := 
Character'Val(130);
+    @AdaObjDefn{NBH}                  : @key[constant] Character := 
Character'Val(131);
+    @AdaObjDefn{Reserved_132}         : @key[constant] Character := 
Character'Val(132);
+    @AdaObjDefn{NEL}                  : @key[constant] Character := 
Character'Val(133);
+    @AdaObjDefn{SSA}                  : @key[constant] Character := 
Character'Val(134);
+    @AdaObjDefn{ESA}                  : @key[constant] Character := 
Character'Val(135);
+    @AdaObjDefn{HTS}                  : @key[constant] Character := 
Character'Val(136);
+    @AdaObjDefn{HTJ}                  : @key[constant] Character := 
Character'Val(137);
+    @AdaObjDefn{VTS}                  : @key[constant] Character := 
Character'Val(138);
+    @AdaObjDefn{PLD}                  : @key[constant] Character := 
Character'Val(139);
+    @AdaObjDefn{PLU}                  : @key[constant] Character := 
Character'Val(140);
+    @AdaObjDefn{RI}                   : @key[constant] Character := 
Character'Val(141);
+    @AdaObjDefn{SS2}                  : @key[constant] Character := 
Character'Val(142);
+    @AdaObjDefn{SS3}                  : @key[constant] Character := 
Character'Val(143);
+
+    @AdaObjDefn{DCS}                  : @key[constant] Character := 
Character'Val(144);
+    @AdaObjDefn{PU1}                  : @key[constant] Character := 
Character'Val(145);
+    @AdaObjDefn{PU2}                  : @key[constant] Character := 
Character'Val(146);
+    @AdaObjDefn{STS}                  : @key[constant] Character := 
Character'Val(147);
+    @AdaObjDefn{CCH}                  : @key[constant] Character := 
Character'Val(148);
+    @AdaObjDefn{MW}                   : @key[constant] Character := 
Character'Val(149);
+    @AdaObjDefn{SPA}                  : @key[constant] Character := 
Character'Val(150);
+    @AdaObjDefn{EPA}                  : @key[constant] Character := 
Character'Val(151);
+
+    @AdaObjDefn{SOS}                  : @key[constant] Character := 
Character'Val(152);
+    @AdaObjDefn{Reserved_153}         : @key[constant] Character := 
Character'Val(153);
+    @AdaObjDefn{SCI}                  : @key[constant] Character := 
Character'Val(154);
+    @AdaObjDefn{CSI}                  : @key[constant] Character := 
Character'Val(155);
+    @AdaObjDefn{ST}                   : @key[constant] Character := 
Character'Val(156);
+    @AdaObjDefn{OSC}                  : @key[constant] Character := 
Character'Val(157);
+    @AdaObjDefn{PM}                   : @key[constant] Character := 
Character'Val(158);
+    @AdaObjDefn{APC}                  : @key[constant] Character := 
Character'Val(159);
+
address@hidden@RI{ Other graphic characters:}
+
address@hidden,Kind=[Revised],ARef=[AI05-0181-1]}
address@hidden Character positions 160 (16#A0#) .. 175 (16#AF#):}
+    @AdaObjDefn{No_Break_Space}             : @key[constant] Character := ' '; 
address@hidden'Val(160)}
+    @AdaObjDefn{NBSP}                       : Character @key[renames] 
No_Break_Space;
+    @AdaObjDefn{Inverted_Exclamation}       : @key[constant] Character := 
'@latin1(161)'; address@hidden'Val(161)}
+    @AdaObjDefn{Cent_Sign}                  : @key[constant] Character := 
'@latin1(162)'; address@hidden'Val(162)}
+    @AdaObjDefn{Pound_Sign}                 : @key[constant] Character := 
'@latin1(163)'; address@hidden'Val(163)}
+    @AdaObjDefn{Currency_Sign}              : @key[constant] Character := 
'@latin1(164)'; address@hidden'Val(164)}
+    @AdaObjDefn{Yen_Sign}                   : @key[constant] Character := 
'@latin1(165)'; address@hidden'Val(165)}
+    @AdaObjDefn{Broken_Bar}                 : @key[constant] Character := 
'@latin1(166)'; address@hidden'Val(166)}
+    @AdaObjDefn{Section_Sign}               : @key[constant] Character := 
'@latin1(167)'; address@hidden'Val(167)}
+    @AdaObjDefn{Diaeresis}                  : @key[constant] Character := 
'@latin1(168)'; address@hidden'Val(168)}
+    @AdaObjDefn{Copyright_Sign}             : @key[constant] Character := 
'@latin1(169)'; address@hidden'Val(169)}
+    @AdaObjDefn{Feminine_Ordinal_Indicator} : @key[constant] Character := 
'@latin1(170)'; address@hidden'Val(170)}
+    @AdaObjDefn{Left_Angle_Quotation}       : @key[constant] Character := 
'@latin1(171)'; address@hidden'Val(171)}
+    @AdaObjDefn{Not_Sign}                   : @key[constant] Character := 
'@latin1(172)'; address@hidden'Val(172)}
+    @AdaObjDefn{Soft_Hyphen}                : @key[constant] Character := 
@Chg{Version=[3],New=[Character'Val(173);],Old=['@latin1(173)'; 
address@hidden'Val(173)}]}
+    @AdaObjDefn{Registered_Trade_Mark_Sign} : @key[constant] Character := 
'@latin1(174)'; address@hidden'Val(174)}
+    @AdaObjDefn{Macron}                     : @key[constant] Character := 
'@latin1(175)'; address@hidden'Val(175)}
+
address@hidden Character positions 176 (16#B0#) .. 191 (16#BF#):}
+    @AdaObjDefn{Degree_Sign}                : @key[constant] Character := 
'@latin1(176)'; address@hidden'Val(176)}
+    @AdaObjDefn{Ring_Above}                 : Character @key[renames] 
Degree_Sign;
+    @AdaObjDefn{Plus_Minus_Sign}            : @key[constant] Character := 
'@latin1(177)'; address@hidden'Val(177)}
+    @AdaObjDefn{Superscript_Two}            : @key[constant] Character := 
'@latin1(178)'; address@hidden'Val(178)}
+    @AdaObjDefn{Superscript_Three}          : @key[constant] Character := 
'@latin1(179)'; address@hidden'Val(179)}
+    @AdaObjDefn{Acute}                      : @key[constant] Character := 
'@latin1(180)'; address@hidden'Val(180)}
+    @AdaObjDefn{Micro_Sign}                 : @key[constant] Character := 
'@latin1(181)'; address@hidden'Val(181)}
+    @AdaObjDefn{Pilcrow_Sign}               : @key[constant] Character := 
'@latin1(182)'; address@hidden'Val(182)}
+    @AdaObjDefn{Paragraph_Sign}             : Character @key[renames] 
Pilcrow_Sign;
+    @AdaObjDefn{Middle_Dot}                 : @key[constant] Character := 
'@latin1(183)'; address@hidden'Val(183)}
+    @AdaObjDefn{Cedilla}                    : @key[constant] Character := 
'@latin1(184)'; address@hidden'Val(184)}
+    @AdaObjDefn{Superscript_One}            : @key[constant] Character := 
'@latin1(185)'; address@hidden'Val(185)}
+    @AdaObjDefn{Masculine_Ordinal_Indicator}: @key[constant] Character := 
'@latin1(186)'; address@hidden'Val(186)}
+    @AdaObjDefn{Right_Angle_Quotation}      : @key[constant] Character := 
'@latin1(187)'; address@hidden'Val(187)}
+    @AdaObjDefn{Fraction_One_Quarter}       : @key[constant] Character := 
'@latin1(188)'; address@hidden'Val(188)}
+    @AdaObjDefn{Fraction_One_Half}          : @key[constant] Character := 
'@latin1(189)'; address@hidden'Val(189)}
+    @AdaObjDefn{Fraction_Three_Quarters}    : @key[constant] Character := 
'@latin1(190)'; address@hidden'Val(190)}
+    @AdaObjDefn{Inverted_Question}          : @key[constant] Character := 
'@latin1(191)'; address@hidden'Val(191)}
+
address@hidden Character positions 192 (16#C0#) .. 207 (16#CF#):}
+    @AdaObjDefn{UC_A_Grave}                 : @key[constant] Character := 
'@latin1(192)'; address@hidden'Val(192)}
+    @AdaObjDefn{UC_A_Acute}                 : @key[constant] Character := 
'@latin1(193)'; address@hidden'Val(193)}
+    @AdaObjDefn{UC_A_Circumflex}            : @key[constant] Character := 
'@latin1(194)'; address@hidden'Val(194)}
+    @AdaObjDefn{UC_A_Tilde}                 : @key[constant] Character := 
'@latin1(195)'; address@hidden'Val(195)}
+    @AdaObjDefn{UC_A_Diaeresis}             : @key[constant] Character := 
'@latin1(196)'; address@hidden'Val(196)}
+    @AdaObjDefn{UC_A_Ring}                  : @key[constant] Character := 
'@latin1(197)'; address@hidden'Val(197)}
+    @AdaObjDefn{UC_AE_Diphthong}            : @key[constant] Character := 
'@latin1(198)'; address@hidden'Val(198)}
+    @AdaObjDefn{UC_C_Cedilla}               : @key[constant] Character := 
'@latin1(199)'; address@hidden'Val(199)}
+    @AdaObjDefn{UC_E_Grave}                 : @key[constant] Character := 
'@latin1(200)'; address@hidden'Val(200)}
+    @AdaObjDefn{UC_E_Acute}                 : @key[constant] Character := 
'@latin1(201)'; address@hidden'Val(201)}
+    @AdaObjDefn{UC_E_Circumflex}            : @key[constant] Character := 
'@latin1(202)'; address@hidden'Val(202)}
+    @AdaObjDefn{UC_E_Diaeresis}             : @key[constant] Character := 
'@latin1(203)'; address@hidden'Val(203)}
+    @AdaObjDefn{UC_I_Grave}                 : @key[constant] Character := 
'@latin1(204)'; address@hidden'Val(204)}
+    @AdaObjDefn{UC_I_Acute}                 : @key[constant] Character := 
'@latin1(205)'; address@hidden'Val(205)}
+    @AdaObjDefn{UC_I_Circumflex}            : @key[constant] Character := 
'@latin1(206)'; address@hidden'Val(206)}
+    @AdaObjDefn{UC_I_Diaeresis}             : @key[constant] Character := 
'@latin1(207)'; address@hidden'Val(207)}
+
address@hidden Character positions 208 (16#D0#) .. 223 (16#DF#):}
+    @AdaObjDefn{UC_Icelandic_Eth}           : @key[constant] Character := 
'@latin1(208)'; address@hidden'Val(208)}
+    @AdaObjDefn{UC_N_Tilde}                 : @key[constant] Character := 
'@latin1(209)'; address@hidden'Val(209)}
+    @AdaObjDefn{UC_O_Grave}                 : @key[constant] Character := 
'@latin1(210)'; address@hidden'Val(210)}
+    @AdaObjDefn{UC_O_Acute}                 : @key[constant] Character := 
'@latin1(211)'; address@hidden'Val(211)}
+    @AdaObjDefn{UC_O_Circumflex}            : @key[constant] Character := 
'@latin1(212)'; address@hidden'Val(212)}
+    @AdaObjDefn{UC_O_Tilde}                 : @key[constant] Character := 
'@latin1(213)'; address@hidden'Val(213)}
+    @AdaObjDefn{UC_O_Diaeresis}             : @key[constant] Character := 
'@latin1(214)'; address@hidden'Val(214)}
+    @AdaObjDefn{Multiplication_Sign}        : @key[constant] Character := 
'@latin1(215)'; address@hidden'Val(215)}
+    @AdaObjDefn{UC_O_Oblique_Stroke}        : @key[constant] Character := 
'@latin1(216)'; address@hidden'Val(216)}
+    @AdaObjDefn{UC_U_Grave}                 : @key[constant] Character := 
'@latin1(217)'; address@hidden'Val(217)}
+    @AdaObjDefn{UC_U_Acute}                 : @key[constant] Character := 
'@latin1(218)'; address@hidden'Val(218)}
+    @AdaObjDefn{UC_U_Circumflex}            : @key[constant] Character := 
'@latin1(219)'; address@hidden'Val(219)}
+    @AdaObjDefn{UC_U_Diaeresis}             : @key[constant] Character := 
'@latin1(220)'; address@hidden'Val(220)}
+    @AdaObjDefn{UC_Y_Acute}                 : @key[constant] Character := 
'@latin1(221)'; address@hidden'Val(221)}
+    @AdaObjDefn{UC_Icelandic_Thorn}         : @key[constant] Character := 
'@latin1(222)'; address@hidden'Val(222)}
+    @AdaObjDefn{LC_German_Sharp_S}          : @key[constant] Character := 
'@latin1(223)'; address@hidden'Val(223)}
+
address@hidden Character positions 224 (16#E0#) .. 239 (16#EF#):}
+    @AdaObjDefn{LC_A_Grave}                 : @key[constant] Character := 
'@latin1(224)'; address@hidden'Val(224)}
+    @AdaObjDefn{LC_A_Acute}                 : @key[constant] Character := 
'@latin1(225)'; address@hidden'Val(225)}
+    @AdaObjDefn{LC_A_Circumflex}            : @key[constant] Character := 
'@latin1(226)'; address@hidden'Val(226)}
+    @AdaObjDefn{LC_A_Tilde}                 : @key[constant] Character := 
'@latin1(227)'; address@hidden'Val(227)}
+    @AdaObjDefn{LC_A_Diaeresis}             : @key[constant] Character := 
'@latin1(228)'; address@hidden'Val(228)}
+    @AdaObjDefn{LC_A_Ring}                  : @key[constant] Character := 
'@latin1(229)'; address@hidden'Val(229)}
+    @AdaObjDefn{LC_AE_Diphthong}            : @key[constant] Character := 
'@latin1(230)'; address@hidden'Val(230)}
+    @AdaObjDefn{LC_C_Cedilla}               : @key[constant] Character := 
'@latin1(231)'; address@hidden'Val(231)}
+    @AdaObjDefn{LC_E_Grave}                 : @key[constant] Character := 
'@latin1(232)'; address@hidden'Val(232)}
+    @AdaObjDefn{LC_E_Acute}                 : @key[constant] Character := 
'@latin1(233)'; address@hidden'Val(233)}
+    @AdaObjDefn{LC_E_Circumflex}            : @key[constant] Character := 
'@latin1(234)'; address@hidden'Val(234)}
+    @AdaObjDefn{LC_E_Diaeresis}             : @key[constant] Character := 
'@latin1(235)'; address@hidden'Val(235)}
+    @AdaObjDefn{LC_I_Grave}                 : @key[constant] Character := 
'@latin1(236)'; address@hidden'Val(236)}
+    @AdaObjDefn{LC_I_Acute}                 : @key[constant] Character := 
'@latin1(237)'; address@hidden'Val(237)}
+    @AdaObjDefn{LC_I_Circumflex}            : @key[constant] Character := 
'@latin1(238)'; address@hidden'Val(238)}
+    @AdaObjDefn{LC_I_Diaeresis}             : @key[constant] Character := 
'@latin1(239)'; address@hidden'Val(239)}
+
address@hidden Character positions 240 (16#F0#) .. 255 (16#FF#):}
+    @AdaObjDefn{LC_Icelandic_Eth}           : @key[constant] Character := 
'@latin1(240)'; address@hidden'Val(240)}
+    @AdaObjDefn{LC_N_Tilde}                 : @key[constant] Character := 
'@latin1(241)'; address@hidden'Val(241)}
+    @AdaObjDefn{LC_O_Grave}                 : @key[constant] Character := 
'@latin1(242)'; address@hidden'Val(242)}
+    @AdaObjDefn{LC_O_Acute}                 : @key[constant] Character := 
'@latin1(243)'; address@hidden'Val(243)}
+    @AdaObjDefn{LC_O_Circumflex}            : @key[constant] Character := 
'@latin1(244)'; address@hidden'Val(244)}
+    @AdaObjDefn{LC_O_Tilde}                 : @key[constant] Character := 
'@latin1(245)'; address@hidden'Val(245)}
+    @AdaObjDefn{LC_O_Diaeresis}             : @key[constant] Character := 
'@latin1(246)'; address@hidden'Val(246)}
+    @AdaObjDefn{Division_Sign}              : @key[constant] Character := 
'@latin1(247)'; address@hidden'Val(247)}
+    @AdaObjDefn{LC_O_Oblique_Stroke}        : @key[constant] Character := 
'@latin1(248)'; address@hidden'Val(248)}
+    @AdaObjDefn{LC_U_Grave}                 : @key[constant] Character := 
'@latin1(249)'; address@hidden'Val(249)}
+    @AdaObjDefn{LC_U_Acute}                 : @key[constant] Character := 
'@latin1(250)'; address@hidden'Val(250)}
+    @AdaObjDefn{LC_U_Circumflex}            : @key[constant] Character := 
'@latin1(251)'; address@hidden'Val(251)}
+    @AdaObjDefn{LC_U_Diaeresis}             : @key[constant] Character := 
'@latin1(252)'; address@hidden'Val(252)}
+    @AdaObjDefn{LC_Y_Acute}                 : @key[constant] Character := 
'@latin1(253)'; address@hidden'Val(253)}
+    @AdaObjDefn{LC_Icelandic_Thorn}         : @key[constant] Character := 
'@latin1(254)'; address@hidden'Val(254)}
+    @AdaObjDefn{LC_Y_Diaeresis}             : @key[constant] Character := 
'@latin1(255)'; address@hidden'Val(255)}
address@hidden Ada.Characters.Latin_1;
address@hidden
+
address@hidden
+
address@hidden
+An implementation may provide additional packages as children of
+Ada.Characters, to declare names for the symbols of the local character set
+or other character sets.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0181-1]}
address@hidden,address@hidden<Correction:> Soft_Hyphen is not a graphic
+character, and thus a character literal for it is illegal. So we have to use 
the
+position value. This makes no semantic change to users of the constant.]}
address@hidden
+
+
address@hidden@LabeledAddedSubClause{Version=[2],Name=[The Package 
Characters.Conversions]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The library package
+Characters.Conversions has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Characters.Conversions 
@address@hidden,Child=[Conversions]}
+   @key[pragma] Pure(Conversions);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Character} (Item : 
@key[in] Wide_Character)      @key[return] Boolean;
+   @key[function] @AdaSubDefn{Is_String}    (Item : @key[in] Wide_String)      
   @key[return] Boolean;
+   @key[function] @AdaSubDefn{Is_Character} (Item : @key[in] 
Wide_Wide_Character) @key[return] Boolean;
+   @key[function] @AdaSubDefn{Is_String}    (Item : @key[in] Wide_Wide_String) 
   @key[return] Boolean;
+   @key[function] @AdaSubDefn{Is_Wide_Character} (Item : @key[in] 
Wide_Wide_Character)
+      @key[return] Boolean;
+   @key[function] @AdaSubDefn{Is_Wide_String}    (Item : @key[in] 
Wide_Wide_String)
+      @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{To_Wide_Character} (Item : 
@key[in] Character) @key[return] Wide_Character;
+   @key[function] @AdaSubDefn{To_Wide_String}    (Item : @key[in] String)    
@key[return] Wide_String;
+   @key[function] @AdaSubDefn{To_Wide_Wide_Character} (Item : @key[in] 
Character)
+      @key[return] Wide_Wide_Character;
+   @key[function] @AdaSubDefn{To_Wide_Wide_String}    (Item : @key[in] String)
+      @key[return] Wide_Wide_String;
+   @key[function] @AdaSubDefn{To_Wide_Wide_Character} (Item : @key[in] 
Wide_Character)
+      @key[return] Wide_Wide_Character;
+   @key[function] @AdaSubDefn{To_Wide_Wide_String}    (Item : @key[in] 
Wide_String)
+      @key[return] Wide_Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{To_Character} (Item       : 
@key[in] Wide_Character;
+                         Substitute : @key[in] Character := ' ')
+      @key[return] Character;
+   @key[function] @AdaSubDefn{To_String}    (Item       : @key[in] Wide_String;
+                          Substitute : @key[in] Character := ' ')
+      @key[return] String;
+   @key[function] @AdaSubDefn{To_Character} (Item :       @key[in] 
Wide_Wide_Character;
+                          Substitute : @key[in] Character := ' ')
+      @key[return] Character;
+   @key[function] @AdaSubDefn{To_String}    (Item :       @key[in] 
Wide_Wide_String;
+                          Substitute : @key[in] Character := ' ')
+      @key[return] String;
+   @key[function] @AdaSubDefn{To_Wide_Character} (Item :       @key[in] 
Wide_Wide_Character;
+                               Substitute : @key[in] Wide_Character := ' ')
+      @key[return] Wide_Character;
+   @key[function] @AdaSubDefn{To_Wide_String}    (Item :       @key[in] 
Wide_Wide_String;
+                               Substitute : @key[in] Wide_Character := ' ')
+      @key[return] Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Characters.Conversions;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Text=[The functions in package Characters.Conversions
+test Wide_Wide_Character or Wide_Character values for membership in
+Wide_Character or Character, or convert between corresponding characters of
+Wide_Wide_Character, Wide_Character, and Character.]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Is_Character (Item : @key[in] Wide_Character) 
@key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns True if Wide_Character'Pos(Item) 
<= Character'Pos(Character'Last).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Is_Character (Item : @key[in] 
Wide_Wide_Character) @key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns True if 
Wide_Wide_Character'Pos(Item) <= Character'Pos(Character'Last).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Is_Wide_Character (Item : @key[in] 
Wide_Wide_Character) @key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns True if 
Wide_Wide_Character'Pos(Item) <=
+Wide_Character'Pos(Wide_Character'Last).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Is_String (Item : @key[in] Wide_String)      
@key[return] Boolean;
address@hidden Is_String (Item : @key[in] Wide_Wide_String) @key[return] 
Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns True if Is_Character(Item(I)) is 
True for each I in Item'Range.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Is_Wide_String (Item : @key[in] Wide_Wide_String) 
@key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns True if Is_Wide_Character(Item(I)) 
is True for each I in Item'Range.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden To_Character (Item :       @key[in] 
Wide_Character;
+                       Substitute : @key[in] Character := ' ') @key[return] 
Character;
address@hidden To_Character (Item :       @key[in] Wide_Wide_Character;
+                       Substitute : @key[in] Character := ' ') @key[return] 
Character;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns the Character corresponding to 
Item if Is_Character(Item), and returns
+the Substitute Character otherwise.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden To_Wide_Character (Item : @key[in] Character) 
@key[return] Wide_Character;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns the Wide_Character X such that 
Character'Pos(Item) = Wide_Character'Pos
+(X).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden To_Wide_Character (Item :       @key[in] 
Wide_Wide_Character;
+                            Substitute : @key[in] Wide_Character := ' ')
+   @key[return] Wide_Character;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns the Wide_Character corresponding 
to Item if Is_Wide_Character(Item),
+and returns the Substitute Wide_Character otherwise.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden To_Wide_Wide_Character (Item : @key[in] Character)
+   @key[return] Wide_Wide_Character;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns the Wide_Wide_Character X such 
that Character'Pos(Item) =
+Wide_Wide_Character'Pos (X).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden To_Wide_Wide_Character (Item : @key[in] 
Wide_Character)
+   @key[return] Wide_Wide_Character;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns the Wide_Wide_Character X such 
that Wide_Character'Pos(Item) =
+Wide_Wide_Character'Pos (X).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden To_String (Item :       @key[in] Wide_String;
+                    Substitute : @key[in] Character := ' ') @key[return] 
String;
address@hidden To_String (Item :       @key[in] Wide_Wide_String;
+                    Substitute : @key[in] Character := ' ') @key[return] 
String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns the String whose range is 
1..Item'Length and each of whose elements is
+given by To_Character of the corresponding element in Item.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden To_Wide_String (Item : @key[in] String) 
@key[return] Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns the Wide_String whose range is 
1..Item'Length and each of whose
+elements is given by To_Wide_Character of the corresponding element in Item.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden To_Wide_String (Item :       @key[in] 
Wide_Wide_String;
+                         Substitute : @key[in] Wide_Character := ' ')
+   @key[return] Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns the Wide_String whose range is 
1..Item'Length and each of whose
+elements is given by To_Wide_Character of the corresponding element in Item
+with the given Substitute Wide_Character.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden To_Wide_Wide_String (Item : @key[in] 
String) @key[return] Wide_Wide_String;
address@hidden To_Wide_Wide_String (Item : @key[in] Wide_String)
+   @key[return] Wide_Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Type=[Trailing],Text=[Returns the Wide_Wide_String whose range 
is 1..Item'Length and each of whose
+elements is given by To_Wide_Wide_Character of the corresponding element in
+Item.]}
+
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00395-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The package Characters.Conversions is new, replacing functions
+  previously found in Characters.Handling.]}
address@hidden
+
+
address@hidden@Comment{For ISO version of Ada 2012 Standard}
address@hidden,Name=[The Package Wide_Characters.Handling]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Text=[The package Wide_Characters.Handling provides
+operations for classifying Wide_Characters and case folding for 
Wide_Characters.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The library package
+Wide_Characters.Handling has the following declaration:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1],ARef=[AI05-0266-1]}
address@hidden,address@hidden Ada.Wide_Characters.Handling 
@address@hidden,Child=[Handling]}
+   @key[pragma] Pure(Handling);]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0266-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Character_Set_Version} 
@key[return] String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Control} (Item : 
Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Letter} (Item : 
Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Lower} (Item : 
Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Upper} (Item : 
Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Digit} (Item : 
Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Decimal_Digit} (Item : 
Wide_Character) @key[return] Boolean
+      @key[renames] Is_Digit;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Hexadecimal_Digit} (Item 
: Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Alphanumeric} (Item : 
Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Special} (Item : 
Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Line_Terminator} (Item : 
Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Mark} (Item : 
Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Other_Format} (Item : 
Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Punctuation_Connector} 
(Item : Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Space} (Item : 
Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Graphic} (Item : 
Wide_Character) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{To_Lower} (Item : 
Wide_Character) @key[return] Wide_Character;
+   @key[function] @AdaSubDefn{To_Upper} (Item : Wide_Character) @key[return] 
Wide_Character;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{To_Lower} (Item : 
Wide_String) @key[return] Wide_String;
+   @key[function] @AdaSubDefn{To_Upper} (Item : Wide_String) @key[return] 
Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Wide_Characters.Handling;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Text=[The subprograms defined in Wide_Characters.Handling are 
locale independent.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Character_Set_Version @key[return] 
String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0266-1]}
address@hidden,Type=[Trailing],Text=[Returns an implementation-defined
+identifier that identifies the version of the character set standard that is
+used for categorizing characters by the implementation.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Is_Control (Item : Wide_Character) 
@key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{other_control}; otherwise returns 
False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Is_Letter (Item : Wide_Character) 
@key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{letter_uppercase},
address@hidden, @ntf{letter_titlecase}, @ntf{letter_modifier},
address@hidden, or @ntf{number_letter}; otherwise returns False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],Keepnext=[T],address@hidden Is_Lower (Item : 
Wide_Character) @key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{letter_lowercase}; otherwise returns
+False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Is_Upper (Item : Wide_Character) 
@key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{letter_uppercase}; otherwise returns
+False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Is_Digit (Item : Wide_Character) 
@key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{number_decimal}; otherwise returns
+False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Is_Hexadecimal_Digit (Item : 
Wide_Character) @key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{number_decimal}, or is in the range
+'A' .. 'F' or 'a' .. 'f'; otherwise returns False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Is_Alphanumeric (Item : 
Wide_Character) @key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{letter_uppercase},
address@hidden, @ntf{letter_titlecase}, @ntf{letter_modifier},
address@hidden, @ntf{number_letter}, or @ntf{number_decimal}; otherwise
+returns False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Is_Special (Item : Wide_Character) 
@key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{graphic_character}, but not 
categorized as
address@hidden, @ntf{letter_lowercase}, @ntf{letter_titlecase},
address@hidden, @ntf{letter_other}, @ntf{number_letter}, or
address@hidden; otherwise returns False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Is_Line_Terminator (Item : 
Wide_Character) @key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{separator_line} or
address@hidden, or if Item is a conventional line terminator
+character (Line_Feed, Line_Tabulation, Form_Feed,
+Carriage_Return, Next_Line); otherwise returns False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Is_Mark (Item : Wide_Character) 
@key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{mark_non_spacing} or
address@hidden; otherwise returns False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Is_Other_Format (Item : 
Wide_Character) @key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{other_format}; otherwise returns 
False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Is_Punctuation_Connector (Item : 
Wide_Character) @key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{punctuation_connector}; otherwise
+returns False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Is_Space (Item : Wide_Character) 
@key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{separator_space}; otherwise returns
+False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Is_Graphic (Item : Wide_Character) 
@key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns True if the Wide_Character
+designated by Item is categorized as @ntf{graphic_character}; otherwise returns
+False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden To_Lower (Item : Wide_Character) 
@key[return] Wide_Character;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1],ARef=[AI05-0266-1],ARef=[AI05-0299-1]}
address@hidden,Type=[Trailing],Text=[Returns the Simple Lowercase Mapping
+as defined by documents referenced in the note in Clause 1 of ISO/IEC 
10646:2011
+of the Wide_Character designated by Item. If the Simple Lowercase Mapping does
+not exist for the Wide_Character designated by Item, then the value of Item is
+returned.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The case mappings come from Unicode as
+  ISO/IEC 10646:2011 does not include case mappings (but rather references
+  the Unicode ones as above).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden To_Lower (Item : Wide_String) 
@key[return] Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns the result of applying the
+To_Lower conversion to each Wide_Character element of the
+Wide_String designated by Item. The result is the null Wide_String if the value
+of the formal parameter is the null Wide_String. The lower bound of the result
+Wide_String is 1.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden To_Upper (Item : Wide_Character) 
@key[return] Wide_Character;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1],ARef=[AI05-0266-1],ARef=[AI05-0299-1]}
address@hidden,Type=[Trailing],Text=[Returns the Simple Uppercase Mapping
+as defined by documents referenced in the note in Clause 1 of ISO/IEC 
10646:2011
+of the Wide_Character designated by Item. If the Simple Uppercase
+Mapping does not exist for the Wide_Character designated by Item, then the 
value
+of Item is returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden To_Upper (Item : Wide_String) 
@key[return] Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Type=[Trailing],Text=[Returns the result of applying the
+To_Upper conversion to each Wide_Character element of the
+Wide_String designated by Item. The result is the null Wide_String if the value
+of the formal parameter is the null Wide_String. The lower bound of the result
+Wide_String is 1.]}
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0266-1]}
address@hidden,Text=[The string returned by Character_Set_Version should include
+either @ldquote@;10646:@rdquote or @ldquote@;address@hidden@;.]}
+
address@hidden,Kind=[Added],address@hidden,
+Text=[The string returned by Wide_Characters.Handling.Character_Set_Version
+should include either @ldquote@;10646:@rdquote or 
@ldquote@;address@hidden@;.]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=<The intent is that the returned string include the
+year for 10646 (as in "10646:2011"), and the version number for Unicode (as in
+"Unicode 6.0"). We don't try to specify that further so we don't need to decide
+how to represent Corrigenda for 10646, nor which of these is preferred.
+(Giving a Unicode version is more accurate, as the case folding and mapping
+rules always come from a Unicode version [10646 just tells one to look at
+Unicode to get those], and the character classifications ought to be the same
+for equivalent versions, but we don't want to talk about non-ISO standards
+in an ISO standard.)>}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0266-1]}
address@hidden,Text=[The results returned by these functions may depend
+on which particular version of the 10646 standard is supported by the
+implementation (see @RefSecNum{Character Set}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0286-1]}
address@hidden,Text=[The case insensitive equality comparison routines
+provided in @RefSec{String Comparison} are also available for wide strings
+(see @RefSecNum{Wide_String Handling}).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0185-1],ARef=[AI05-0266-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The package Wide_Characters.Handling is new.]}
address@hidden
+
+
address@hidden,Name=[The Package Wide_Wide_Characters.Handling]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0185-1]}
address@hidden,Text=[The package Wide_Wide_Characters.Handling
address@hidden,Child=[Handling]}has the same contents as
+Wide_Characters.Handling except that each occurrence of Wide_Character is
+replaced by Wide_Wide_Character, and each occurrence of Wide_String is replaced
+by Wide_Wide_String.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0185-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The package Wide_Wide_Characters.Handling is new.]}
address@hidden
+
+
+
diff --git a/packages/ada-ref-man/source_2012/pre_cmdln.mss 
b/packages/ada-ref-man/source_2012/pre_cmdln.mss
new file mode 100755
index 0000000..a44bb76
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pre_cmdln.mss
@@ -0,0 +1,128 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/pre_cmdln.mss,v $ }
address@hidden $Revision: 1.29 $ $Date: 2012/11/28 23:53:06 $ $Author: randy $ }
address@hidden(predefcmdln, Root="ada.mss")
+
address@hidden: 2012/11/28 23:53:06 $}
address@hidden Package Command_Line}
address@hidden
+The package Command_Line allows a program to obtain the values of its
+arguments and to set the exit status code to be returned on normal termination.
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[The meaning of Argument_Count,
+Argument, and address@hidden,New=[ for package Command_Line. The
+bounds of type Command_Line.Exit_Status],Old=[]}.]}
address@hidden
+
address@hidden
address@hidden@Keepnext@;The library package Ada.Command_Line has the following 
declaration:
address@hidden
address@hidden Ada.Command_Line @address@hidden,Child=[Command_Line]}
+  @key[pragma] Preelaborate(Command_Line);
+
+  @key[function] @AdaSubDefn{Argument_Count} @key[return] Natural;
+
+  @key[function] @AdaSubDefn{Argument} (Number : @key[in] Positive) 
@key[return] String;
+
+  @key[function] @AdaSubDefn{Command_Name} @key[return] String;
+
+  @key[type] @AdaTypeDefn{Exit_Status} @key[is] @RI{implementation-defined 
integer type};
+
+  @AdaObjDefn{Success} : @key[constant] Exit_Status;
+  @AdaObjDefn{Failure} : @key[constant] Exit_Status;
+
+  @key[procedure] @AdaSubDefn{Set_Exit_Status} (Code : @key[in] Exit_Status);
+
address@hidden
+  ... -- @RI{not specified by the language}
address@hidden Ada.Command_Line;
address@hidden line}
address@hidden
address@hidden
address@hidden@Keepnext
address@hidden Argument_Count @key[return] Natural;
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+If the external execution environment supports passing arguments to
+a program, then Argument_Count returns
+the number of arguments passed to the program
+invoking the function. address@hidden,New=[,],Old=[]}
+it returns 0.
+The meaning of @lquotes@;number of address@hidden@; is implementation defined.
+
address@hidden@Keepnext
address@hidden Argument (Number : @key[in] Positive) @key[return] String;
address@hidden
address@hidden@;If the external execution environment supports passing 
arguments to
+a program, then
+Argument returns an implementation-defined value corresponding to
+the argument at relative position Number.
address@hidden,Sec=(raised by failure of run-time check)}
+If Number is outside the range 1..Argument_Count, then
+Constraint_Error is propagated.
address@hidden
+If the external execution environment does not support
+passing arguments to a program, then Argument(N) for any N will
+raise Constraint_Error, since Argument_Count is address@hidden
+
address@hidden@Keepnext
address@hidden Command_Name @key[return] String;
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+If the external execution environment supports passing arguments to
+a program, then
+Command_Name returns an implementation-defined value corresponding to
+the name of the command invoking the program;
address@hidden,New=[,],Old=[]}
+Command_Name returns the null string.
+
address@hidden is missing; leading the following paragraph glued to 
"Command_Name"}
address@hidden@Keepnext
address@hidden,Kind=[Added]}
address@hidden@key[type] Exit_Status @key[is] @RI{implementation-defined 
integer type};],Old=[]}
address@hidden
address@hidden@;
+The type Exit_Status represents the range of exit
+status values supported by the external execution environment.
+The constants Success and Failure correspond to success and failure,
+respectively.
+
address@hidden@Keepnext
address@hidden Set_Exit_Status (Code : @key[in] Exit_Status);
address@hidden
+If the external execution environment supports returning an exit status
+from a program, then Set_Exit_Status sets Code as the status. Normal
+termination of a program returns as the exit status the value most
+recently set by Set_Exit_Status, or, if no such value has been set, then the
+value Success. If a program terminates abnormally, the status set by
+Set_Exit_Status is ignored, and an implementation-defined exit status value
+is set.
+
address@hidden incorrect index entry; presentation AI-00005}
address@hidden,address@hidden
+If the external execution environment does not support returning
+an exit value from a program, then Set_Exit_Status does nothing.
address@hidden
address@hidden
+
address@hidden
+An alternative declaration is allowed
+for package Command_Line if different functionality is appropriate
+for the external execution environment.
address@hidden
+
address@hidden
+Argument_Count, Argument, and Command_Name
+correspond to the C language's argc, argv[n] (for n>0) and argv[0],
+respectively.
address@hidden
+The correspondence of Argument_Count to argc is not direct @em
+argc would be one more than Argument_Count, since the argc count
+includes the command name, whereas Argument_Count does not.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden to Ada 83}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} is new in Ada 95.
address@hidden
\ No newline at end of file
diff --git a/packages/ada-ref-man/source_2012/pre_con2.mss 
b/packages/ada-ref-man/source_2012/pre_con2.mss
new file mode 100755
index 0000000..5261e0a
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pre_con2.mss
@@ -0,0 +1,5147 @@
address@hidden(precontainers-2, Root="ada.mss")
address@hidden $Source: e:\\cvsroot/ARM/Source/pre_con2.mss,v $ }
address@hidden $Revision: 1.29 $ $Date: 2015/04/03 04:12:42 $ $Author: randy $ }
+
address@hidden,Name=[The Generic Package Containers.Multiway_Trees]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Multiway_Trees provides private types Tree and Cursor, and a set of
+operations for each type. A multiway tree container is well-suited to represent
+nested structures.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Text=[This tree just provides a basic structure, and
+  make no promises about balancing or other automatic organization. In this
+  sense, it is different than the indexed (Map, Set) forms. Rather, it
+  provides a building block on which to construct more complex and more
+  specialized tree containers.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0078-1],ARef=[AI12-0159-1]}
address@hidden,Text=[A multiway tree container object manages a tree of
address@hidden,New=[],Old=[internal address@hidden<nodes>,
address@hidden,New=[consisting of a @i<root node>@Defn2{Term=[root],Sec=[of a 
address@hidden node],Sec=[of a tree]}
+and a set address@hidden node],Sec=[of a tree]}
address@hidden<internal nodes>;],Old=[]} each @Chg{Version=[4],New=[internal 
node],Old=[of
+which]} contains an element and pointers to the parent,
+first child, last child, next (successor) sibling, and previous (predecessor)
+sibling internal address@hidden,Sec=[of a tree]} A cursor designates a
+particular node within a tree (and by extension the element contained in that
+node, if any). A cursor keeps designating the same node (and element) as long 
as
+the node is part of the container, even if the node is moved within
+the container.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0269-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0078-1]}
address@hidden,Text=[A @i<subtree> is a particular node (which @i<roots the 
subtree>) and all of its child
+nodes (including all of the children of the child nodes, recursively).
address@hidden,Sec=[of a address@hidden the address@hidden,Sec=[node which 
roots]}
address@hidden,New=[The root node],Old=[There is
+a special node, the @i<root>, which]} is always present and has neither an
+associated element value nor any parent address@hidden,New=[; it has
+pointers to its first child and its last child, if any],Old=[]}. The root node
+provides a place to add nodes to an otherwise empty tree and
+represents the base of the
address@hidden,New=[],address@hidden,Sec=[of a address@hidden node],Sec=[of a 
tree]}]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0269-1]}
address@hidden,Text=[A node that has no children is called a
address@hidden<leaf node>address@hidden node],Sec=[of a tree]} The 
@i<ancestors> of
+a node are the node itself, its parent node, the parent of the parent node,
+and so on until a node with no parent is address@hidden,Sec=[of a tree node]}
+Similarly, the @i<descendants> of a node are the node itself, its child nodes,
+the children of each child node, and so address@hidden,Sec=[of a tree node]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0262-1],ARef=[AI05-0269-1]}
address@hidden,Text=[The nodes of a subtree can be visited in several
+different orders. For a @i<depth-first order>, after visiting a node, the nodes
+of its child list are each visited in depth-first order, with each child node
+visited in natural order (first child to last child)address@hidden order}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[For the depth-first order, when each child node 
is
+    visited, the child list of the child node is visited before the next 
sibling
+    of the child node is visited.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+package Containers.Multiway_Trees has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0212-1]}
address@hidden,address@hidden Ada.Iterator_Interfaces;
address@hidden
+   @key{type} Element_Type @key{is private};
+   @key{with function} "=" (Left, Right : Element_Type) @key{return} Boolean 
@key{is} <>;
address@hidden Ada.Containers.Multiway_Trees 
@address@hidden,Child=[Multiway_Trees]}
+   @key{pragma} Preelaborate(Multiway_Trees);
+   @key{pragma} Remote_Types(Multiway_Trees);]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Tree} @key{is tagged private}
+      @key{with} Constant_Indexing => Constant_Reference,
+           Variable_Indexing => Reference,
+           Default_Iterator  => Iterate,
+           Iterator_Element  => Element_Type;
+   @key{pragma} Preelaborable_Initialization(Tree);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Cursor} @key{is private};
+   @key{pragma} Preelaborable_Initialization(Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{Empty_Tree} : @key{constant} Tree;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{No_Element} : @key{constant} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Has_Element} (Position : 
Cursor) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{package} @AdaPackDefn{Tree_Iterator_Interfaces} 
@key{is new}
+      Ada.Iterator_Interfaces (Cursor, Has_Element);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Equal_Subtree} 
(Left_Position : Cursor;
+                           Right_Position: Cursor) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "=" (Left, Right : Tree) @key{return} 
Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Empty} (Container : Tree) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Node_Count} (Container : 
Tree) @key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Subtree_Node_Count} 
(Position : Cursor) @key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Depth} (Position : Cursor) 
@key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Root} (Position : Cursor) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Leaf} (Position : Cursor) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Root} (Container : Tree) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Clear} (Container : @key{in 
out} Tree);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Element} (Position : Cursor) 
@key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Replace_Element} (Container 
: @key{in out} Tree;
+                              Position  : @key{in}     Cursor;
+                              New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Query_Element}
+     (Position : @key{in} Cursor;
+      Process  : @key{not null access procedure} (Element : @key{in} 
Element_Type));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Update_Element}
+     (Container : @key{in out} Tree;
+      Position  : @key{in}     Cursor;
+      Process   : @key{not null access procedure}
+                      (Element : @key{in out} Element_Type));]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Constant_Reference_Type}
+         (Element : @key[not null access constant] Element_Type) @key[is 
private]
+      @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Reference_Type} (Element : 
@key[not null access] Element_Type) @key[is private]
+      @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Constant_Reference} 
(Container : @key[aliased in] Tree;
+                                Position  : @key[in] Cursor)
+      @key[return] Constant_Reference_Type;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Reference} (Container : 
@key[aliased in out] Tree;
+                       Position  : @key[in] Cursor)
+      @key[return] Reference_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Assign} (Target : @key{in 
out} Tree; Source : @key{in} Tree);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Copy} (Source : Tree) 
@key{return} Tree;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Move} (Target : @key{in 
out} Tree;
+                   Source : @key{in out} Tree);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_Leaf} (Container : 
@key{in out} Tree;
+                          Position  : @key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_Subtree} (Container 
: @key{in out} Tree;
+                             Position  : @key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Swap} (Container : @key{in 
out} Tree;
+                   I, J      : @key{in}     Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Find} (Container : Tree;
+                  Item      : Element_Type)
+      @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Find_In_Subtree} (Position : 
Cursor;
+                             Item     : Element_Type)
+      @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Ancestor_Find} (Position : 
Cursor;
+                           Item     : Element_Type)
+      @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Contains} (Container : Tree;
+                      Item      : Element_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Iterate}
+     (Container : @key{in} Tree;
+      Process   : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Iterate_Subtree}
+     (Position  : @key{in} Cursor;
+      Process   : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Iterate} (Container : 
@key{in} Tree)
+      @key{return} Tree_Iterator_Interfaces.Forward_Iterator'Class;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Iterate_Subtree} (Position : 
@key{in} Cursor)
+      @key{return} Tree_Iterator_Interfaces.Forward_Iterator'Class;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Child_Count} (Parent : 
Cursor) @key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Child_Depth} (Parent, Child 
: Cursor) @key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert_Child} (Container : 
@key{in out} Tree;
+                           Parent    : @key{in}     Cursor;
+                           Before    : @key{in}     Cursor;
+                           New_Item  : @key{in}     Element_Type;
+                           Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert_Child} (Container : 
@key{in out} Tree;
+                           Parent    : @key{in}     Cursor;
+                           Before    : @key{in}     Cursor;
+                           New_Item  : @key{in}     Element_Type;
+                           Position  :    @key{out} Cursor;
+                           Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert_Child} (Container : 
@key{in out} Tree;
+                           Parent    : @key{in}     Cursor;
+                           Before    : @key{in}     Cursor;
+                           Position  :    @key{out} Cursor;
+                           Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Prepend_Child} (Container : 
@key{in out} Tree;
+                            Parent    : @key{in}     Cursor;
+                            New_Item  : @key{in}     Element_Type;
+                            Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Append_Child} (Container : 
@key{in out} Tree;
+                           Parent    : @key{in}     Cursor;
+                           New_Item  : @key{in}     Element_Type;
+                           Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_Children} (Container 
: @key{in out} Tree;
+                              Parent    : @key{in}     Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Copy_Subtree} (Target   : 
@key{in out} Tree;
+                           Parent   : @key{in}     Cursor;
+                           Before   : @key{in}     Cursor;
+                           Source   : @key{in}     Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Splice_Subtree} (Target   : 
@key{in out} Tree;
+                             Parent   : @key{in}     Cursor;
+                             Before   : @key{in}     Cursor;
+                             Source   : @key{in out} Tree;
+                             Position : @key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Splice_Subtree} (Container: 
@key{in out} Tree;
+                             Parent   : @key{in}     Cursor;
+                             Before   : @key{in}     Cursor;
+                             Position : @key{in}     Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Splice_Children} (Target    
      : @key{in out} Tree;
+                              Target_Parent   : @key{in}     Cursor;
+                              Before          : @key{in}     Cursor;
+                              Source          : @key{in out} Tree;
+                              Source_Parent   : @key{in}     Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Splice_Children} (Container 
      : @key{in out} Tree;
+                              Target_Parent   : @key{in}     Cursor;
+                              Before          : @key{in}     Cursor;
+                              Source_Parent   : @key{in}     Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Parent} (Position : Cursor) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First_Child} (Parent : 
Cursor) @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First_Child_Element} (Parent 
: Cursor) @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Last_Child} (Parent : 
Cursor) @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Last_Child_Element} (Parent 
: Cursor) @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Next_Sibling} (Position : 
Cursor) @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Previous_Sibling} (Position 
: Cursor) @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Next_Sibling} (Position : 
@key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Previous_Sibling} (Position 
: @key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Iterate_Children}
+     (Parent  : @key{in} Cursor;
+      Process : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Reverse_Iterate_Children}
+     (Parent  : @key{in} Cursor;
+      Process : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Iterate_Children} (Container 
: @key[in] Tree; Parent : @key[in] Cursor)
+      @key[return] Tree_Iterator_Interfaces.Reversible_Iterator'Class;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   ... -- @Examcom[not specified by the language]
address@hidden Ada.Containers.Multiway_Trees;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[The actual function for the generic formal function "=" on 
Element_Type values
+is expected to define a reflexive and symmetric relationship and return the 
same
+result value each time it is called with a particular pair of values. If it
+behaves in some other manner, the functions Find, Reverse_Find, Equal_Subtree,
+and "=" on tree values return an unspecified value. The exact arguments and
+number of calls of this generic formal function by the functions Find,
+Reverse_Find, Equal_Subtree, and "=" on tree values are address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[The type Tree is used to represent trees. The
+type Tree needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
address@hidden,Text=[Empty_Tree represents the empty Tree object. It
+contains only the root node (Node_Count (Empty_Tree) returns 1). If an object 
of type
+Tree is not otherwise initialized, it is initialized to the same value as
+Empty_Tree.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[No_Element represents a cursor that designates no
+element. If an object of type Cursor is not otherwise initialized, it is
+initialized to the same value as No_Element.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[The predefined "=" operator for type Cursor returns
+True if both cursors are No_Element, or designate the same element in the same
+container.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[Execution of the default implementation of the
+Input, Output, Read, or Write attribute of type Cursor raises Program_Error.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1]}
address@hidden,Text=[Tree'Write for a Tree object @i<T> writes
+Node_Count(@i<T>) - 1 elements of the tree to the stream. It also may write
+additional information about the tree.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1]}
address@hidden,Text=[Tree'Read reads the representation of a tree
+from the stream, and assigns to @i<Item> a tree with the same elements and
+structure as was written by Tree'Write.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Streaming more elements than the container
+  holds is wrong. For implementation implications of this rule, see the 
Implementation Note in
+  @RefSecNum{The Generic Package Containers.Vectors}.]}
address@hidden
+
+
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,address@hidden operations of this generic package
+have access-to-subprogram parameters. To ensure such operations are
+well-defined, they guard against certain actions by the designated subprogram.
+In particular, some operations check for "tampering with cursors" of a 
container
+because they depend on the set of elements of the container remaining constant,
+and others check for "tampering with elements" of a container because they
+depend on elements of the container not being replaced.]]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Type=[Leading],address@hidden with cursors],Sec=[of a tree]}
+A subprogram is said to
address@hidden with cursors} of a tree object @i<T> if:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[it inserts or deletes elements of @i<T>, that is,
+  it calls the Clear, Delete_Leaf, Insert_Child, Delete_Children,
+  Delete_Subtree, or Copy_Subtree procedures
+  with @i<T> as a parameter; or]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Operations which are defined to be equivalent 
to
+    a call on one of these operations also are included. Similarly, operations
+    which call one of these as part of their definition are included.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Text=[it reorders the elements of @i<T>, that is, it
+  calls the Splice_Subtree or Splice_Children procedures with @i<T> as a
+  parameter; or]}
+
address@hidden,Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[it finalizes @i<T>; or]}
+
address@hidden,Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[it calls Assign with @i<T> as the Target 
parameter; or]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[We don't need to explicitly mention
+  @nt{assignment_statement}, because that finalizes the target object
+  as part of the operation, and finalization of an object is already defined
+  as tampering with cursors.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[it calls the Move procedure with @i<T> as a 
parameter.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Swap copies elements rather than reordering
+    them, so it doesn't tamper with cursors.]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Type=[Leading],address@hidden with elements],Sec=[of a tree]}
+A subprogram is said to
address@hidden with elements} of a tree object @i<T> if:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[it tampers with cursors of @i<T>; or]}
+
address@hidden,Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[it replaces one or more elements of @i<T>, that 
is, it calls the Replace_Element or Swap
+  procedures with @i<T> as a parameter.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Complete replacement of an element can cause 
its
+    memory to be deallocated while another operation is holding onto a 
reference
+    to it. That can't be allowed. However, a simple modification of (part of) 
an
+    element is not a problem, so Update_Element does not cause a problem.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[Assign is defined in terms of Clear and 
Replace_Element,
+  so we don't need to mention it explicitly. Similarly, we don't need to
+  explicitly mention @nt{assignment_statement}, because that finalizes the
+  target object as part of the operation, and finalization of an object is
+  already defined as tampering with the element.]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0265-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0110-1]}
address@hidden,address@hidden,Sec=[tampering with a tree]}
address@hidden,Sec=[prohibited for a tree]}
+When tampering with cursors is @i<prohibited> for a particular tree object
address@hidden<T>, Program_Error is propagated by a call of any 
language-defined subprogram
+that is defined to tamper with the cursors of @i<T>, leaving @i<T> unmodified.
+Similarly, when tampering with elements is @i<prohibited> for a particular tree
+object @i<T>, Program_Error is propagated by a call of any language-defined
+subprogram that is defined to tamper with the elements of @i<T> @Redundant[(or
+tamper with the cursors of @i<T>)], leaving @i<T>
address@hidden,New=[ These checks are made before any other
+defined behavior of the body of the language-defined subprogram.],Old=[]}]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Tampering with elements includes tampering with
+  cursors, so we mention it only from completeness in the second sentence.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Has_Element (Position : Cursor) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns True if Position designates
+an element, and returns False otherwise. @Redundant[In particular, Has_Element
+returns False if the cursor designates a root node or equals No_Element.]]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Text=[This function might not detect cursors that
+  designate deleted elements; such cursors are invalid (see below) and the
+  result of calling Has_Element with an invalid cursor is unspecified (but
+  not erroneous).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Equal_Subtree (Left_Position : 
Cursor;
+                        Right_Position: Cursor) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1],ARef=[AI05-0264-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Left_Position or 
Right_Position
+  equals No_Element, propagates Constraint_Error. If the number of child nodes
+  of the element designated by Left_Position is different from the number of
+  child nodes of the element designated by Right_Position, the function
+  returns False. If Left_Position designates a root node and Right_Position 
does
+  not, the function returns False. If Right_Position designates a root
+  node and Left_Position does not, the function returns False. Unless both
+  cursors designate a root node, the elements are compared using the generic
+  formal equality operator. If the result of the element comparison is False,
+  the function returns
+  False. Otherwise, it calls Equal_Subtree on a cursor designating each child
+  element of the element designated by Left_Position and a cursor designating
+  the corresponding child element of the element designated by Right_Position.
+  If any such call returns False, the function returns False; otherwise, it
+  returns True. Any exception raised during the evaluation of element equality
+  is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Left_Position and Right_Position do not need to
+    be from the same tree.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[This wording describes the canonical semantics.
+    However, the order and number of calls on the formal equality function
+    is unspecified for all of the operations that use it in this package, so an
+    implementation can call it as many or as few times as it needs to get the
+    correct answer. Similarly, a global rule (see the introduction of
+    @RefSecNum{Predefined Language Environment})
+    says that language-defined routines are not affected by overriding of other
+    language-defined routines. This means that no reasonable program can tell
+    how many times Equal_Subtree is called, and thus an implementation can call
+    it as many or as few times as it needs to get the correct answer.
+    Specifically, there is no requirement to call the formal equality or
+    Equal_Subtree additional times once the answer has been determined.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "=" (Left, Right : Tree) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Left and Right denote the same
+  tree object, then the function returns True. Otherwise, it calls 
Equal_Subtree
+  with cursors designating the root nodes of Left and Right; the result is
+  returned. Any exception raised during the evaluation of Equal_Subtree is
+  propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Similar considerations apply here as apply to
+    Equal_Subtree. The actual number of calls performed is unspecified.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Node_Count (Container : Tree) 
@key{return} Count_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Node_Count returns the number of
+  nodes in Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Since all tree objects have a root node, this
+    can never return a value of 0. Node_Count (Some_Tree) should always equal
+    Subtree_Node_Count (Root (Some_Tree)).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Subtree_Node_Count (Position : 
Cursor) @key{return} Count_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position is No_Element,
+  Subtree_Node_Count returns 0; otherwise, Subtree_Node_Count returns the 
number of
+  nodes in the subtree that is rooted by Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Is_Empty (Container : Tree) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Equivalent to Node_Count 
(Container) = 1.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[An empty tree contains just the root node.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Depth (Position : Cursor) 
@key{return} Count_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position equals No_Element,
+  Depth returns 0; otherwise, Depth returns the number of ancestor nodes of the
+  node designated by Position (including the node itself).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Depth (Root (Some_Tree)) = 1.]}
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Is_Root (Position : Cursor) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Is_Root returns True if the
+  Position designates the root node of some tree; and returns False 
otherwise.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Is_Leaf (Position : Cursor) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Is_Leaf returns True if Position
+  designates a node that does not have any child nodes; and returns False
+  otherwise.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Is_Leaf returns False if passed No_Element,
+    since No_Element does not designate a node. Is_Leaf can be passed a cursor
+    that designates the root node; Is_Leaf will return True if passed the root
+    node of an empty tree.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Root (Container : Tree) @key{return} 
Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Root returns a cursor that
+  designates the root node of Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[There is always a root node, even in an empty
+    container, so this function never returns No_Element.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Clear (Container : @key{in out} 
Tree);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Removes all the elements from
+  Container.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The root node is not removed; all trees have a
+    root node.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Element (Position : Cursor) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position equals No_Element,
+  then Constraint_Error is propagated; if Position designates the root node of 
a
+  tree, then Program_Error is propagated. Otherwise, Element returns the 
element
+  designated by Position.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The root node does not contain an element, so
+    that value cannot be read or written.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Replace_Element (Container : @key{in 
out} Tree;
+                           Position  : @key{in}     Cursor;
+                           New_Item  : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0264-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position equals No_Element,
+  then Constraint_Error is propagated; if Position does not designate an 
element
+  in Container (including if it designates the root node), then Program_Error 
is
+  propagated. Otherwise, Replace_Element assigns the value New_Item to the
+  element designated by Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Query_Element
+  (Position : @key{in} Cursor;
+   Process  : @key{not null access procedure} (Element : @key{in} 
Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0265-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position equals No_Element,
+  then Constraint_Error is propagated; if Position designates the root node of 
a
+  tree, then Program_Error is propagated. Otherwise, Query_Element calls
+  address@hidden with the element designated by Position as the argument.
+  Tampering with the elements of the tree that contains the element designated
+  by Position is prohibited during the execution of the call on
+  address@hidden Any exception raised by address@hidden is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Update_Element
+  (Container : @key{in out} Tree;
+   Position  : @key{in}     Cursor;
+   Process   : @key{not null access procedure}
+                   (Element : @key{in out} Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0264-1],ARef=[AI05-0265-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position equals No_Element,
+  then Constraint_Error is propagated; if Position does not designate an 
element
+  in Container (including if it designates the root node), then Program_Error 
is
+  propagated. Otherwise, Update_Element calls address@hidden with the element
+  designated by Position as the argument. Tampering with the elements of
+  Container is prohibited during the execution of the call on address@hidden
+  Any exception raised by address@hidden is propagated.]}
+
address@hidden,Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If Element_Type is unconstrained and definite,
+  then the actual Element parameter of address@hidden shall be
+  unconstrained.]}
+
+  @begin{Ramification}
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[This means that the elements cannot be directly
+    allocated from the heap; it must be possible to change the discriminants of
+    the element in place.]}
+  @end{Ramification}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Constant_Reference_Type
+      (Element : @key[not null access constant] Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Reference_Type (Element : @key[not null access] 
Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[The types Constant_Reference_Type
+  and Reference_Type need address@hidden<needs 
finalization>,Sec=<language-defined type>}]}
+
address@hidden,Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The default initialization of an object of type
+  Constant_Reference_Type or Reference_Type propagates Program_Error.]}
+
+  @begin{Reason}
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[It is expected that Reference_Type (and
+    Constant_Reference_Type) will be a controlled type, for which finalization
+    will have some action to terminate the tampering check for the associated
+    container. If the object is created by default, however, there is no
+    associated container. Since this is useless, and supporting this case would
+    take extra work, we define it to raise an exception.]}
+  @end{Reason}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Constant_Reference (Container : 
@key[aliased in] Tree;
+                             Position  : @key[in] Cursor)
+   @key[return] Constant_Reference_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[This function (combined with the
+  Constant_Indexing and Implicit_Dereference aspects) provides a convenient way
+  to gain read access to an individual element of a tree given a
+  cursor.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1],ARef=[AI05-0265-1]}
+  @ChgAdded{Version=[3],Text=[If Position equals No_Element, then
+  Constraint_Error is propagated; if Position does not designate an element in
+  Container, then Program_Error is propagated. Otherwise, Constant_Reference
+  returns an object whose discriminant is an access value that designates the
+  element designated by Position. Tampering with the elements of Container
+  is prohibited while the object returned by Constant_Reference exists
+  and has not been finalized.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reference (Container : @key[aliased 
in out] Tree;
+                    Position  : @key[in] Cursor)
+   @key[return] Reference_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[This function (combined with the
+  Variable_Indexing and Implicit_Dereference aspects) provides a convenient way
+  to gain read and write access to an individual element of a tree
+  given a cursor.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1],ARef=[AI05-0265-1]}
+  @ChgAdded{Version=[3],Text=[If Position equals No_Element, then
+  Constraint_Error is propagated; if Position does not designate an element in
+  Container, then Program_Error is propagated. Otherwise, Reference returns an
+  object whose discriminant is an access value that designates the element
+  designated by Position. Tampering with the elements
+  of Container is prohibited while the object returned by Reference exists
+  and has not been finalized.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Assign (Target : @key{in out} Tree; 
Source : @key{in} Tree);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Target denotes the same object
+  as Source, the operation has no effect. Otherwise, the elements of Source are
+  copied to Target as for an @nt{assignment_statement} assigning Source to
+  Target.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Each element in Target has a
+    parent element that corresponds to the parent element of the Source 
element,
+    and has child elements that correspond to the child elements of the Source
+    element.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[3],Text=[This routine exists for compatibility with the
+  bounded tree container. For an unbounded tree, @exam{Assign(A, B)} and
+  @exam{A := B} behave identically. For a bounded tree, := will raise an
+  exception if the container capacities are different, while Assign will
+  not raise an exception if there is enough room in the target.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Copy (Source : Tree) @key{return} 
Tree;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Returns a tree with the same
+  structure as Source and whose elements are initialized from the corresponding
+  elements of Source.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Move (Target : @key{in out} Tree;
+                Source : @key{in out} Tree);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Target denotes the same object
+  as Source, then the operation has no effect. Otherwise, Move first calls 
Clear
+  (Target). Then, the nodes other than the root node in Source are moved to
+  Target (in the same positions). After Move completes, Node_Count (Target) is
+  the number of nodes originally in Source, and Node_Count (Source) is 1.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete_Leaf (Container : @key{in 
out} Tree;
+                       Position  : @key{in out} Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position equals No_Element,
+  then Constraint_Error is propagated; if Position does not designate an 
element
+  in Container (including if it designates the root node), then Program_Error 
is
+  propagated. If the element designated by position has any child elements, 
then
+  Constraint_Error is propagated. Otherwise, Delete_Leaf removes (from 
Container)
+  the element designated by Position. Finally, Position is set to No_Element.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The check on Position
+    checks that the cursor does not belong to some other Container. This check
+    implies that a reference to the container is included in the cursor value.
+    This wording is not meant to require detection of dangling cursors; such
+    cursors are defined to be invalid, which means that execution is erroneous,
+    and any result is allowed (including not raising an exception).]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The root node cannot be deleted.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete_Subtree (Container : @key{in 
out} Tree;
+                          Position  : @key{in out} Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0264-1],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position equals No_Element,
+  then Constraint_Error is propagated. If Position does not designate an 
element
+  in Container (including if it designates the root node), then Program_Error 
is
+  propagated. Otherwise, Delete_Subtree removes (from Container) the subtree
+  designated by Position (that is, all descendants of the node designated
+  by Position including the node itself), and Position is set to No_Element.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The root node cannot be deleted. To delete the
+    entire contents of the tree, call Clear(Container).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Swap (Container : @key{in out} Tree;
+                I, J      : @key{in}     Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If either I or J equals
+  No_Element, then Constraint_Error is propagated. If either I or J do not
+  designate an element in Container (including if either designates the root
+  node), then Program_Error is propagated. Otherwise, Swap exchanges the values
+  of the elements designated by I and J.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[After a call to Swap, I designates the element
+    value previously designated by J, and J designates the element value
+    previously designated by I. The position of the elements do not change; for
+    instance, the parent node and the first child node of I are unchanged by 
the
+    operation.]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The root nodes do not contain element values, 
so
+    they cannot be swapped.]}
address@hidden
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The implementation is not required to actually
+    copy the elements if it can do the swap some other way. But it is allowed 
to
+    copy the elements if needed.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Find (Container : Tree;
+               Item      : Element_Type)
+   @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Find searches the elements of
+  Container for an element equal to Item (using the generic formal equality
+  operator). The search starts at the root node. The search traverses the tree
+  in a depth-first order. If no equal element is found, then Find returns
+  No_Element. Otherwise, it returns a cursor designating the first equal 
element
+  encountered.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Find_In_Subtree (Position : Cursor;
+                          Item     : Element_Type)
+   @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position equals No_Element,
+  then Constraint_Error is propagated. Find_In_Subtree searches
+  the subtree rooted by Position for an element equal to Item (using the
+  generic formal equality operator). The search starts at the element 
designated
+  by Position. The search traverses the subtree in a depth-first
+  order. If no equal element is found, then Find returns No_Element. Otherwise,
+  it returns a cursor designating the first equal element encountered.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Find_In_Subtree does not check any siblings of
+    the element designated by Position. The root node does not contain an
+    element, and therefore it can never be returned, but it can be explicitly
+    passed to Position.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Ancestor_Find (Position : Cursor;
+                        Item     : Element_Type)
+   @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position equals No_Element,
+  then Constraint_Error is propagated. Otherwise, Ancestor_Find searches
+  for an element equal to Item (using the generic formal equality operator). 
The
+  search starts at the node designated by Position, and checks each ancestor
+  proceeding toward the root of the subtree. If no equal element is found, then
+  Ancestor_Find returns No_Element. Otherwise, it returns a cursor designating
+  the first equal element encountered.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Text=[No_Element is returned if Position is the root
+  node.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Contains (Container : Tree;
+                   Item      : Element_Type) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Equivalent to Find (Container, 
Item) /= No_Element.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Iterate
+  (Container : @key{in} Tree;
+   Process   : @key{not null access procedure} (Position : @key{in} Cursor));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0265-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0069-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Iterate calls address@hidden
+  with a cursor that designates each element in Container, starting
+  @Chg{Version=[4],New=[from],Old=[with]} the
+  root node and proceeding in a depth-first order. Tampering with the cursors
+  of Container is prohibited during the execution of a call on address@hidden
+  Any exception raised by address@hidden is propagated.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Process is not called with the root node, which
+    does not have an associated element.]}
address@hidden
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The purpose of the tamper with cursors check is
+    to prevent erroneous execution from the Position parameter of
+    address@hidden becoming invalid. This check takes place when the
+    operations that tamper with the cursors of the container are called. The
+    check cannot be made later (say in the body of Iterate), because that could
+    cause the Position cursor to be invalid and potentially cause execution to
+    become erroneous @em defeating the purpose of the check.]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[See Iterate for vectors
+    (@RefSecNum{The Generic Package Containers.Vectors}) for a suggested
+    implementation of the check.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Iterate_Subtree
+  (Position  : @key{in} Cursor;
+   Process   : @key{not null access procedure} (Position : @key{in} Cursor));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0265-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0069-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position equals No_Element,
+  then Constraint_Error is propagated. Otherwise, Iterate_Subtree calls
+  address@hidden
+  with a cursor that designates each element in the subtree rooted by the node
+  designated by Position, starting
+  @Chg{Version=[4],New=[from],Old=[with]} the node designated by Position and
+  proceeding in a depth-first order.
+  Tampering with the cursors of the tree that contains the element
+  designated by Position
+  is prohibited during the execution of a call on address@hidden
+  Any exception raised by address@hidden is propagated.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Position can be passed a cursor designating the
+    root node; in that case, Process is not called with the root node, which
+    does not have an associated element.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Iterate (Container : @key{in} Tree)
+   @key{return} Tree_Iterator_Interfaces.Forward_Iterator'Class;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1],ARef=[AI05-0265-1],ARef=[AI05-0269-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0069-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Iterate returns an iterator 
object
+  (see @RefSecNum{User-Defined Iterator Types}) that will
+  generate a value for a loop parameter (see @RefSecNum{Generalized Loop 
Iteration})
+  designating each @Chg{Version=[4],New=[element],Old=[node]} in Container, 
starting
+  @Chg{Version=[4],New=[from],Old=[with]} the root node and proceeding in a 
depth-first order.
+  Tampering with the cursors of Container is prohibited while the iterator
+  object exists (in particular, in the
+  @nt{sequence_of_statements} of the @nt{loop_statement} whose
+  @nt{iterator_specification} denotes this object). The iterator object needs
+  finalization.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[Exits are allowed from the loops
+  created using the iterator objects. In particular, to stop the iteration at a
+  particular cursor, just add]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden when] Cur = Stop;]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[in the body of the loop (assuming
+  that @exam{Cur} is the loop parameter and @exam{Stop} is the cursor that you
+  want to stop at).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Iterate_Subtree (Position : @key{in} 
Cursor)
+   @key{return} Tree_Iterator_Interfaces.Forward_Iterator'Class;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1],ARef=[AI05-0265-1],ARef=[AI05-0269-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0069-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position equals No_Element,
+  then Constraint_Error is propagated. Otherwise, Iterate_Subtree returns an
+  iterator object (see @RefSecNum{User-Defined Iterator Types}) that will
+  generate a value for a loop parameter (see @RefSecNum{Generalized Loop 
Iteration})
+  designating each element in the subtree rooted by the node designated by 
Position,
+  starting @Chg{Version=[4],New=[from],Old=[with]} the
+  node designated by Position and proceeding in a depth-first
+  order. If Position equals No_Element, then Constraint_Error is propagated.
+  Tampering with the cursors of the container that contains the node
+  designated by Position is prohibited while the iterator object exists
+  (in particular, in the
+  @nt{sequence_of_statements} of the @nt{loop_statement} whose
+  @nt{iterator_specification} denotes this object). The iterator object
+  needs finalization.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Child_Count (Parent : Cursor) 
@key{return} Count_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Child_Count returns the number of
+  child nodes of the node designated by Parent.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Child_Depth (Parent, Child : Cursor) 
@key{return} Count_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Child or Parent is equal to
+  No_Element, then Constraint_Error is propagated. Otherwise, Child_Depth
+  returns the number of ancestor nodes of Child (including Child itself), up to
+  but not including Parent; Program_Error is propagated if Parent
+  is not an ancestor of Child.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Program_Error is propagated if Parent and Child
+    are nodes in different containers.]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Child_Depth (Root (Some_Tree), Child) + 1 =
+    Depth (Child) as the root is not counted.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert_Child (Container : @key{in 
out} Tree;
+                        Parent    : @key{in}     Cursor;
+                        Before    : @key{in}     Cursor;
+                        New_Item  : @key{in}     Element_Type;
+                        Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Parent equals No_Element, then
+  Constraint_Error is propagated. If Parent does not designate a node in
+  Container, then Program_Error is propagated. If Before is not equal to
+  No_Element, and does not designate a node in Container, then Program_Error is
+  propagated. If Before is not equal to No_Element, and
+  Parent does not designate the parent node of the node designated by Before,
+  then Constraint_Error is propagated.
+  Otherwise, Insert_Child allocates Count nodes containing copies of New_Item
+  and inserts them as children of Parent. If Parent already has child nodes, 
then
+  the new nodes are inserted prior to the node designated by Before, or, if
+  Before equals No_Element, the new nodes are inserted after the last existing
+  child node of Parent. Any exception raised during allocation of internal
+  storage is propagated, and Container is not modified.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert_Child (Container : @key{in 
out} Tree;
+                        Parent    : @key{in}     Cursor;
+                        Before    : @key{in}     Cursor;
+                        New_Item  : @key{in}     Element_Type;
+                        Position  :    @key{out} Cursor;
+                        Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1],ARef=[AI05-0257-1],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Parent equals No_Element, then
+  Constraint_Error is propagated. If Parent does not designate a node in
+  Container, then Program_Error is propagated. If Before is not equal to
+  No_Element, and does not designate a node in Container, then Program_Error is
+  propagated. If Before is not equal to No_Element, and
+  Parent does not designate the parent node of the node designated by Before,
+  then Constraint_Error is propagated.
+  Otherwise, Insert_Child allocates Count nodes containing copies of New_Item
+  and inserts them as children of Parent. If Parent already has child nodes, 
then
+  the new nodes are inserted prior to the node designated by Before, or, if
+  Before equals No_Element, the new nodes are inserted after the last existing
+  child node of Parent. Position designates the first newly-inserted node, or 
if
+  Count equals 0, then Position is assigned the value of Before. Any exception
+  raised during allocation of internal storage is propagated, and Container is
+  not modified.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert_Child (Container : @key{in 
out} Tree;
+                        Parent    : @key{in}     Cursor;
+                        Before    : @key{in}     Cursor;
+                        Position  :    @key{out} Cursor;
+                        Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0257-1],ARef=[AI05-0262-1],ARef=[AI05-0264-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Parent equals No_Element, then
+  Constraint_Error is propagated. If Parent does not designate a node in
+  Container, then Program_Error is propagated. If Before is not equal to
+  No_Element, and does not designate a node in Container, then Program_Error is
+  propagated. If Before is not equal to No_Element, and
+  Parent does not designate the parent node of the node designated by Before,
+  then Constraint_Error is propagated.
+  Otherwise, Insert_Child allocates Count nodes, the elements contained in the
+  new nodes are initialized by default (see @RefSecNum{Object Declarations}),
+  and the new nodes are inserted as children of Parent. If Parent already has
+  child nodes, then the new nodes are inserted prior to the node designated by
+  Before, or, if Before equals No_Element, the new nodes are inserted after the
+  last existing child node of Parent. Position designates the first
+  newly-inserted node, or if Count equals 0, then Position is assigned the 
value
+  of Before. Any exception raised during allocation of internal storage is
+  propagated, and Container is not modified.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Prepend_Child (Container : @key{in 
out} Tree;
+                         Parent    : @key{in}     Cursor;
+                         New_Item  : @key{in}     Element_Type;
+                         Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Equivalent to Insert_Child
+  (Container, Parent, First_Child (Container, Parent), New_Item, Count).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Append_Child (Container : @key{in 
out} Tree;
+                        Parent    : @key{in}     Cursor;
+                        New_Item  : @key{in}     Element_Type;
+                        Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Equivalent to Insert_Child
+  (Container, Parent, No_Element, New_Item, Count).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete_Children (Container : @key{in 
out} Tree;
+                           Parent    : @key{in}     Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Parent equals No_Element, then
+  Constraint_Error is propagated. If Parent does not designate a node in
+  Container, Program_Error is propagated. Otherwise, Delete_Children removes
+  (from Container) all of the descendants of Parent other than Parent itself.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[This routine deletes all of the child subtrees
+    of Parent at once. Use Delete_Subtree to delete an individual subtree.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Copy_Subtree (Target   : @key{in 
out} Tree;
+                        Parent   : @key{in}     Cursor;
+                        Before   : @key{in}     Cursor;
+                        Source   : @key{in}     Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Parent equals No_Element, then
+  Constraint_Error is propagated. If Parent does not designate a node in 
Target,
+  then Program_Error is propagated. If Before is not equal to No_Element, and
+  does not designate a node in Target, then Program_Error is propagated. If
+  Before is not equal to No_Element, and
+  Parent does not designate the parent node of the node designated by Before,
+  then Constraint_Error is propagated. If Source designates a root node,
+  then Constraint_Error is propagated. If Source is equal to No_Element, then
+  the operation has no effect. Otherwise, the subtree rooted by Source (which
+  can be from any tree; it does not have to be a subtree of Target) is copied
+  (new nodes are allocated to create a new subtree with the same structure as
+  the Source subtree, with each element initialized from the corresponding
+  element of the Source subtree) and inserted into Target as a child of Parent.
+  If Parent already has child nodes, then the new nodes are inserted prior to 
the
+  node designated by Before, or, if Before equals No_Element, the new nodes are
+  inserted after the last existing child node of Parent. The parent of the 
newly
+  created subtree is set to Parent, and the overall count of Target is
+  incremented by Subtree_Node_Count (Source). Any exception raised during 
allocation
+  of internal storage is propagated, and Container is not modified.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[We only need one routine here, as the source
+    object is not modified, so we can use the same routine for both copying
+    within and between containers.]}
address@hidden
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[We do not allow copying a subtree that includes
+    a root node, as that would require inserting a node with no value in the
+    middle of the target tree. To copy an entire tree to another tree object,
+    use Copy.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Splice_Subtree (Target   : @key{in 
out} Tree;
+                          Parent   : @key{in}     Cursor;
+                          Before   : @key{in}     Cursor;
+                          Source   : @key{in out} Tree;
+                          Position : @key{in out} Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Parent equals No_Element, then
+  Constraint_Error is propagated. If Parent does not designate a node in 
Target,
+  then Program_Error is propagated. If Before is not equal to No_Element, and
+  does not designate a node in Target, then Program_Error is propagated. If
+  Before is not equal to No_Element, and
+  Parent does not designate the parent node of the node designated by Before,
+  then Constraint_Error is propagated. If Position equals No_Element,
+  Constraint_Error is propagated. If Position does not designate a node in
+  Source or designates a root node, then Program_Error is propagated. If Source
+  denotes the same object as Target, then:
+  if Position equals Before there is no effect; if Position designates an
+  ancestor of Parent (including Parent itself), Constraint_Error is propagated;
+  otherwise, the subtree rooted by the element designated by Position is
+  moved to be a child of Parent. If Parent already has child nodes, then the
+  moved nodes are inserted prior to the node designated by Before, or, if 
Before
+  equals No_Element, the moved nodes are inserted after the last existing child
+  node of Parent. In each of these cases, Position and the count of Target are
+  unchanged, and the parent of the element designated by Position is set to
+  Parent.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[We can't allow moving the subtree of Position 
to
+    a proper descendant node of the subtree, as the descendant node will be 
part of the
+    subtree being moved. The result would be a circularly linked tree, or one
+    with inaccessible nodes. Thus we have to check Position against Parent, 
even
+    though such a check is @i<O>(Depth(Source)).]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Text=[Otherwise (if Source does not denote the same
+  object as Target), the subtree designated by Position is removed from Source
+  and moved to Target. The subtree is inserted as a child of Parent. If Parent
+  already has child nodes, then the moved nodes are inserted prior to the node
+  designated by Before, or, if Before equals No_Element, the moved nodes are
+  inserted after the last existing child node of Parent. In each of these 
cases,
+  the count of Target is incremented by Subtree_Node_Count (Position), and the
+  count of Source is decremented by Subtree_Node_Count (Position), Position is
+  updated to represent an element in Target.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[If Source is the same as Target, and Position =
+    Before, or Next_Sibling(Position) = Before, Splice_Subtree has no effect, 
as
+    the subtree does not have to move to meet the postcondition.]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[We do not allow splicing a subtree that 
includes
+    a root node, as that would require inserting a node with no value in the
+    middle of the target tree. Splice the children of the root node instead.]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[For this reason there is no operation to splice
+    an entire tree, as that would necessarily involve splicing a root node.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Splice_Subtree (Container: @key{in 
out} Tree;
+                          Parent   : @key{in}     Cursor;
+                          Before   : @key{in}     Cursor;
+                          Position : @key{in}     Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Parent equals No_Element, then
+  Constraint_Error is propagated. If Parent does not designate a node in
+  Container, then Program_Error is propagated. If Before is not equal to
+  No_Element, and does not designate a node in Container, then Program_Error is
+  propagated. If Before is not equal to No_Element, and
+  Parent does not designate the parent node of the node designated by Before,
+  then Constraint_Error is propagated. If Position
+  equals No_Element, Constraint_Error is propagated. If Position does not
+  designate a node in Container or designates a root node, then Program_Error 
is
+  propagated. If Position equals Before, there is no effect. If Position
+  designates an ancestor of Parent (including Parent itself), Constraint_Error 
is
+  propagated. Otherwise, the subtree rooted by the element designated by
+  Position is moved to be a child of Parent. If Parent already has child nodes,
+  then the moved nodes are inserted prior to the node designated by Before, or,
+  if Before equals No_Element, the moved nodes are inserted after the last
+  existing child node of Parent. The parent of the element designated by
+  Position is set to Parent.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[We can't allow moving the subtree of Position 
to
+    a proper descendant node of the subtree, as the descendant node will be 
part of the
+    subtree being moved.]}
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Splice_Children (Target          : 
@key{in out} Tree;
+                           Target_Parent   : @key{in}     Cursor;
+                           Before          : @key{in}     Cursor;
+                           Source          : @key{in out} Tree;
+                           Source_Parent   : @key{in}     Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Target_Parent equals
+  No_Element, then Constraint_Error is propagated. If Target_Parent does not
+  designate a node in Target, then Program_Error is propagated. If Before is 
not
+  equal to No_Element, and does not designate an element in Target, then
+  Program_Error is propagated. If Source_Parent equals No_Element, then
+  Constraint_Error is propagated. If Source_Parent does not designate a node in
+  Source, then Program_Error is propagated. If Before is not equal to
+  No_Element, and Target_Parent does not designate the parent node of the
+  node designated by Before, then Constraint_Error is propagated.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[If Source denotes the same object 
as Target, then:]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[if Target_Parent equals Source_Parent there is
+    no effect; else]}
+
+    
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0269-1]}
+    @ChgAdded{Version=[3],Text=[if Source_Parent is an ancestor of
+    Target_Parent other than Target_Parent itself, then Constraint_Error is 
propagated; else]}
+
+    
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1],ARef=[AI05-0269-1]}
+    @ChgAdded{Version=[3],Text=[the child elements (and the further 
descendants) of
+    Source_Parent are moved to be child elements of Target_Parent. If
+    Target_Parent already has child elements, then the moved elements are
+    inserted prior to the node designated by Before, or, if Before equals
+    No_Element, the moved elements are inserted after the last existing child
+    node of Target_Parent. The parent of each moved child element is set to
+    Target_Parent.]}
address@hidden
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[We can't allow moving the children of
+    Source_Parent to a proper descendant node, as the descendant node will be
+    part of one of the subtrees being moved.]}
address@hidden
+
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],Text=[Otherwise (if Source does not denote the same
+  object as Target), the child elements (and the further descendants) of 
Source_Parent
+  are removed from Source and moved to Target. The child elements are inserted
+  as children of Target_Parent. If Target_Parent already has child elements, 
then
+  the moved elements are inserted prior to the node designated by Before, or, 
if
+  Before equals No_Element, the moved elements are inserted after the last
+  existing child node of Target_Parent. In each of these cases, the overall
+  count of Target is incremented by Subtree_Node_Count (Source_Parent)-1, and
+  the overall count of Source is decremented by Subtree_Node_Count
+  (Source_Parent)-1.]}
+
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The node designated by Source_Parent is not
+    moved, thus we never need to update Source_Parent.]}
+
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[Move (Target, Source) could be written
+    Splice_Children (Target, Target.Root, No_Element, Source, Source.Root);]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Splice_Children (Container       : 
@key{in out} Tree;
+                           Target_Parent   : @key{in}     Cursor;
+                           Before          : @key{in}     Cursor;
+                           Source_Parent   : @key{in}     Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1],ARef=[AI05-0264-1],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Target_Parent equals
+  No_Element, then Constraint_Error is propagated. If Target_Parent does not
+  designate a node in Container, then Program_Error is propagated. If Before is
+  not equal to No_Element, and does not designate an element in Container, then
+  Program_Error is propagated. If Source_Parent equals No_Element, then
+  Constraint_Error is propagated. If Source_Parent does not designate a node in
+  Container, then Program_Error is propagated. If Before is not equal to
+  No_Element, and Target_Parent does not designate the parent node of the
+  node designated by Before, then Constraint_Error is propagated.
+  If Target_Parent equals Source_Parent there is
+  no effect. If Source_Parent is an ancestor of Target_Parent other than
+  Target_Parent itself, then
+  Constraint_Error is propagated. Otherwise, the child elements (and the 
further
+  descendants) of Source_Parent are moved to be child elements of 
Target_Parent.
+  If Target_Parent already has child elements, then the moved elements are
+  inserted prior to the node designated by Before, or, if Before equals
+  No_Element, the moved elements are inserted after the last existing child 
node
+  of Target_Parent. The parent of each moved child element is set to
+  Target_Parent.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Parent (Position : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position is equal to 
No_Element
+  or designates a root node, No_Element is returned. Otherwise, a cursor
+  designating the parent node of the node designated by Position is returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First_Child (Parent : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Parent is equal to No_Element,
+  then Constraint_Error is propagated. Otherwise, First_Child returns a cursor
+  designating the first child node of the node designated by Parent; if there 
is
+  no such node, No_Element is returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First_Child_Element (Parent : 
Cursor) @key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Equivalent to Element 
(First_Child (Parent)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Last_Child (Parent : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Parent is equal to No_Element,
+  then Constraint_Error is propagated. Otherwise, Last_Child returns a cursor
+  designating the last child node of the node designated by Parent; if there is
+  no such node, No_Element is returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Last_Child_Element (Parent : Cursor) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Equivalent to Element 
(Last_Child (Parent)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Next_Sibling (Position : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position equals No_Element or
+  designates the last child node of its parent, then Next_Sibling returns the
+  value No_Element. Otherwise, it returns a cursor that designates the 
successor
+  (with the same parent) of the node designated by Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Previous_Sibling (Position : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[If Position equals No_Element or
+  designates the first child node of its parent, then Previous_Sibling returns
+  the value No_Element. Otherwise, it returns a cursor that designates the
+  predecessor (with the same parent) of the node designated by Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Next_Sibling (Position : @key{in 
out} Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Equivalent to Position := 
Next_Sibling (Position);]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Previous_Sibling (Position : @key{in 
out} Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[Equivalent to Position := 
Previous_Sibling (Position);]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Iterate_Children
+  (Parent  : @key{in} Cursor;
+   Process : @key{not null access procedure} (Position : @key{in} Cursor));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
address@hidden,Type=[Trailing],Text=[If Parent equals No_Element, then
+Constraint_Error is propagated.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Iterate_Children calls address@hidden with a
+cursor that designates each child node of Parent, starting with the first child
+node and moving the cursor as per the Next_Sibling function.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0265-1]}
address@hidden,Text=[Tampering with the cursors of the tree containing
+Parent is prohibited during the execution of a call on address@hidden
+Any exception raised by address@hidden is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reverse_Iterate_Children
+  (Parent  : @key{in} Cursor;
+   Process : @key{not null access procedure} (Position : @key{in} Cursor));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
address@hidden,Type=[Trailing],Text=[If Parent equals No_Element, then
+Constraint_Error is propagated.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Reverse_Iterate_Children calls address@hidden
+with a cursor that designates each child node of Parent, starting with the last
+child node and moving the cursor as per the Previous_Sibling function.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0265-1]}
address@hidden,Text=[Tampering with the cursors of the tree containing
+Parent is prohibited during the execution of a call on address@hidden
+Any exception raised by address@hidden is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Iterate_Children (Container : 
@key[in] Tree; Parent : @key[in] Cursor)
+   @key[return] Tree_Iterator_Interfaces.Reversible_Iterator'Class;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1],ARef=[AI05-0265-1]}
address@hidden,Type=[Trailing],Text=[Iterate_Children returns a
+reversible iterator object
+(see @RefSecNum{User-Defined Iterator Types}) that will generate
+a value for a loop parameter (see @RefSecNum{Generalized Loop Iteration})
+designating each child node of Parent. If Parent equals No_Element, then
+Constraint_Error is propagated. If Parent does not designate a node in
+Container, then Program_Error is propagated. Otherwise, when used as a forward
+iterator, the nodes are designated starting with the first child node and 
moving
+the cursor as per the function Next_Sibling; when used as a reverse iterator,
+the nodes are designated starting with the last child node and moving the 
cursor
+as per the function Previous_Sibling. Tampering with the cursors of Container 
is
+prohibited while the iterator object exists (in particular, in the
address@hidden of the @nt{loop_statement} whose
address@hidden denotes this object). The iterator object needs
+finalization.]}
+
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error for the actual function associated with a generic formal
+subprogram, when called as part of an operation of this package, to tamper with
+elements of any Tree parameter of the operation. Either Program_Error is 
raised,
+or the operation works as defined on the value of the Tree either prior to, or
+subsequent to, some or all of the modifications to the Tree.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to call any subprogram declared in the visible part of
+Containers.Multiway_Trees when the associated container has been finalized. If
+the operation takes Container as an @key[in out] parameter, then it raises
+Constraint_Error or Program_Error. Otherwise, the operation either proceeds as
+it would for an empty container, or it raises Constraint_Error or 
Program_Error.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[A Cursor
+value is @i<invalid> if any of the following have occurred since
+it was created:@Defn2{Term=[invalid cursor],Sec=[of a tree]}
address@hidden,Sec=[invalid]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The tree that contains the element it designates has
+been finalized;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The tree that contains the element it designates has
+been used as the Source or Target of a call to Move;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The tree that contains the element it designates has
+been used as the Target of a call to Assign or the target of an
address@hidden;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The element it designates has been removed from the
+tree that previously contained the element.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We talk about which tree the element was removed
+  from in order to handle splicing nodes from one tree to another. The node
+  still exists, but any cursors that designate it in the original tree are now
+  invalid. This bullet covers removals caused by calls to Clear, Delete_Leaf,
+  Delete_Subtree, Delete_Children, Splice_Children, and Splice_Subtree.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The result of "=" or Has_Element is unspecified if
+it is called with an invalid cursor address@hidden Execution is
+erroneous if any other subprogram declared in Containers.Multiway_Trees is
+called with an invalid cursor parameter.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The list above is intended to be exhaustive. In
+  other cases, a cursor value continues to designate its original element (or
+  the root node). For instance, cursor values survive the insertion and 
deletion
+  of other nodes.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[While it is possible to check for these cases, in
+  many cases the overhead necessary to make the check is substantial in time or
+  space. Implementations are encouraged to check for as many of these cases as
+  possible and raise Program_Error if detected.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[Execution is erroneous if the tree associated with
+the result of a call to Reference or Constant_Reference is finalized before the
+result object returned by the call to Reference or Constant_Reference is
+finalized.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Each object of Reference_Type and
+  Constant_Reference_Type probably contains some reference to the originating
+  container. If that container is prematurely finalized (which is only possible
+  via Unchecked_Deallocation, as accessibility checks prevent passing a
+  container to Reference that will not live as long as the result), the
+  finalization of the object of Reference_Type will try to access a nonexistent
+  object. This is a normal case of a dangling pointer created by
+  Unchecked_Deallocation; we have to explicitly mention it here as the pointer
+  in question is not visible in the specification of the type. (This is the 
same
+  reason we have to say this for invalid cursors.)]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[No storage associated with a multiway tree object
+shall be lost upon assignment or scope exit.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0262-1]}
address@hidden,Text=[The execution of an @nt{assignment_statement} for
+a tree shall have the effect of copying the elements from the source tree
+object to the target tree object and changing the node count of the target
+object to that of the source object.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0298-1]}
+  @ChgAdded{Version=[3],Text=[An assignment of a Tree is a 
@lquotes@;address@hidden
+  copy; that is the elements are copied as well the data structures.
+  We say @lquotes@;effect address@hidden in order to allow the implementation 
to
+  avoid copying elements immediately if it wishes. For instance, an
+  implementation that avoided copying until one of the containers is modified
+  would be allowed. (Note that this implementation would
+  require care, see @RefSecNum{The Generic Package Containers.Vectors} for 
more.)]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[Containers.Multiway_Trees should be implemented
+similarly to a multiway tree. In particular, if @i{N} is the overall number of 
nodes
+for a particular tree, then the worst-case time complexity of Element, Parent,
+First_Child, Last_Child, Next_Sibling, Previous_Sibling,
+Insert_Child with Count=1, and Delete should be @i{O}(log @i{N}).]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The worst-case time complexity of the Element, Parent,
+First_Child, Last_Child, Next_Sibling, Previous_Sibling,
+Insert_Child with Count=1, and Delete
+operations of Containers.Multiway_Trees should be @i{O}(log @i<N>).]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We do not mean to overly constrain implementation
+  strategies here. However, it is important for portability that the 
performance
+  of large containers has roughly the same factors on different 
implementations.
+  If a program is moved to an implementation that takes @i{O}(@i<N>) time to 
access
+  elements, that program could be unusable when the trees are large. We allow
+  @i{O}(log @i<N>) access because the proportionality constant and caching 
effects are
+  likely to be larger than the log factor, and we don't want to discourage
+  innovative implementations.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[Move should not copy elements, and should minimize
+copying of internal data structures.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Containers.Multiway_Trees.Move should not copy elements, and should
+minimize copying of internal data structures.]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Usually that can be accomplished simply by
+  moving the pointer(s) to the internal data structures from the Source
+  container to the Target container.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[If an exception is propagated from a tree
+operation, no storage should be lost, nor any elements removed from a tree
+unless specified by the operation.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If an exception is propagated from a tree
+operation, no storage should be lost, nor any elements removed from a tree
+unless specified by the operation.]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is important so that programs can recover
+  from errors. But we don't want to require heroic efforts, so we just require
+  documentation of cases where this can't be accomplished.]}
address@hidden
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0257-1],ARef=[AI05-0265-1],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The generic package Containers.Multiway_Trees is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0069-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Fixed the function Iterate
+  so it is clear that the root node is never visited.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0078-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> The definition of 
@i<node> is
+  clarified so that it it doesn't appear to say all nodes have an element.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0110-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that tampering 
checks
+  precede all other checks made by a subprogram (but come after those 
associated
+  with the call).]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Indefinite_Vectors]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The language-defined generic package
+Containers.Indefinite_Vectors provides a private type Vector and a set of
+operations. It provides the same operations as the package Containers.Vectors
+(see @RefSecNum{The Generic Package Containers.Vectors}), with the difference 
that
+the generic formal Element_Type is indefinite.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
address@hidden,Type=[Leading],Text=[The declaration
+of the generic library package
address@hidden,Child=[Indefinite_Vectors]}
+has the same contents @Chg{Version=[3],New=[and semantics ],Old=[]}as
+Containers.Vectors except:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The generic formal Element_Type is indefinite.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],Type=[Leading],Text=[The procedures with
+the profiles:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Keepnext=[F],Type=[Leading],address@hidden Insert 
(Container : @key{in out} Vector;
+                  Before    : @key{in}     Extended_Index;
+                  Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Keepnext=[T],Type=[Leading],address@hidden Insert 
(Container : @key{in out} Vector;
+                  Before    : @key{in}     Cursor;
+                  Position  :    @key{out} Cursor;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[are omitted.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[These procedures are omitted because there is no
+  way to create a default-initialized object of an indefinite type. Note that
+  Insert_Space can be used instead of this routine in most cases. Omitting
+  the routine completely allows any problems to be diagnosed by
+  the compiler when converting from a definite to indefinite vector.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The actual Element parameter of access subprogram Process
+of Update_Element may be constrained even if Element_Type is unconstrained.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0035-1]}
address@hidden,Text=[The operations "&", Append, Insert, Prepend,
+Replace_Element, and To_Vector that have a formal parameter of type
+Element_Type perform indefinite insertion (see @RefSecNum{Containers}).]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The generic package Containers.Indefinite_Vectors is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0035-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Defined some routines to @ldquote@;perform indefinite address@hidden
+  This could mean that some calls to those routines would now raise
+  Program_Error where they previously worked. However, this is extremely
+  unlikely, as it would require that the package was not implemented in Ada
+  (an Ada @nt{allocator} would raise Program_Error in these circumstances), and
+  that a program inserted a more nested tagged type (or access discriminant)
+  into a container, and then used that object before its type or discriminant
+  went out of scope. All known implementations are implemented in Ada, so we
+  believe there is no practical incompatibility. As such, we
+  mention this only for completeness.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package 
Containers.Indefinite_Doubly_Linked_Lists]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The language-defined generic package 
Containers.Indefinite_Doubly_Linked_Lists
+provides private types List and Cursor, and a set of operations for each
+type. It provides the same operations as the package
+Containers.Doubly_Linked_Lists
+(see @RefSecNum{The Generic Package Containers.Doubly_Linked_Lists}),
+with the difference that the generic formal Element_Type is indefinite.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
address@hidden,Type=[Leading],Text=[The declaration of
+the generic library package
address@hidden@address@hidden@address@hidden,Child=[Indefinite_Doubly_Linked_Lists]}
+has the same contents @Chg{Version=[3],New=[and semantics ],Old=[]}as
address@hidden@address@hidden except:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The generic formal Element_Type is indefinite.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],Type=[Leading],Text=[The procedure with
+the profile:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Keepnext=[T],Type=[Leading],address@hidden Insert 
(Container : @key{in out} List;
+                  Before    : @key{in}     Cursor;
+                  Position  :    @key{out} Cursor;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[is omitted.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This procedure is omitted because there is no way
+  to create a default-initialized object of an indefinite type. We considered
+  having this routine insert an empty element similar to the empty elements of
+  a vector, but rejected this possibility because the semantics are fairly
+  complex and very different from the existing definite container. That would
+  make it more error-prone to convert a container from a definite type to an
+  indefinite type; by omitting the routine completely, any problems will be
+  diagnosed by the compiler.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The actual Element parameter of access subprogram Process
+of Update_Element may be constrained even if Element_Type is unconstrained.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0035-1]}
address@hidden,Text=[The operations Append, Insert, Prepend, and
+Replace_Element that have a formal parameter of type Element_Type perform
+indefinite insertion (see @RefSecNum{Containers}).]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden to Ada 95}
+The generic package Containers.Indefinite_Doubly_Linked_Lists is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0035-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Defined some routines to @ldquote@;perform indefinite address@hidden
+  This could mean that some calls to those routines would now raise
+  Program_Error where they previously worked. However, this is extremely
+  unlikely; see @Inconsistent2012Title in
+  @RefSecNum{The Generic Package Containers.Indefinite_Vectors} for details.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Indefinite_Hashed_Maps]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The language-defined generic package 
Containers.Indefinite_Hashed_Maps provides
+a map with the same operations as the package Containers.Hashed_Maps
+(see @RefSecNum{The Generic Package Containers.Hashed_Maps}),
+with the difference that the generic formal types Key_Type and Element_Type are
+indefinite.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
address@hidden,Type=[Leading],Text=[The declaration of
+the generic library package
address@hidden,Child=[Indefinite_Hashed_Maps]}
+has the same contents @Chg{Version=[3],New=[and semantics ],Old=[]}as
+Containers.Hashed_Maps except:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The generic formal Key_Type is indefinite.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The generic formal Element_Type is indefinite.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],Type=[Leading],Text=[The procedure with
+the profile:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Keepnext=[T],Type=[Leading],address@hidden Insert 
(Container : @key{in out} Map;
+                  Key       : @key{in}     Key_Type;
+                  Position  :    @key{out} Cursor;
+                  Inserted  :    @key{out} Boolean);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[is omitted.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This procedure is omitted because there is no way
+  to create a default-initialized object of an indefinite type. We considered
+  having this routine insert an empty element similar to the empty elements of
+  a vector, but rejected this possibility because the semantics are fairly
+  complex and very different from the existing case. That would make it more
+  error-prone to convert a container from a definite type to an indefinite
+  type; by omitting the routine completely, any problems will be diagnosed by
+  the compiler.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The actual Element parameter of access subprogram Process
+of Update_Element may be constrained even if Element_Type is unconstrained.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0035-1]}
address@hidden,Text=[The operations Include, Insert, Replace, and
+Replace_Element that have a formal parameter of type Element_Type perform
+indefinite insertion (see @RefSecNum{Containers}).]}
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[Some of the named operations also have a formal
+  of the indefinite formal type Key_Type and perform indefinite insertion using
+  that value, but it is sufficient to mention the formal of type Element_Type
+  to cover those.]}
address@hidden
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden to Ada 95}
+The generic package Containers.Indefinite_Hashed_Maps is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0035-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Defined some routines to @ldquote@;perform indefinite address@hidden
+  This could mean that some calls to those routines would now raise
+  Program_Error where they previously worked. However, this is extremely
+  unlikely; see @Inconsistent2012Title in
+  @RefSecNum{The Generic Package Containers.Indefinite_Vectors} for details.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Indefinite_Ordered_Maps]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The language-defined generic package 
Containers.Indefinite_Ordered_Maps
+provides a map with the same operations as the package Containers.Ordered_Maps
+(see @RefSecNum{The Generic Package Containers.Ordered_Maps}), with the 
difference that
+the generic formal types Key_Type and Element_Type are indefinite.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
address@hidden,Type=[Leading],Text=[The declaration of
+the generic library package
address@hidden,Child=[Indefinite_Ordered_Maps]}
+has the same contents @Chg{Version=[3],New=[and semantics ],Old=[]}as
+Containers.Ordered_Maps except:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The generic formal Key_Type is indefinite.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The generic formal Element_Type is indefinite.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],Type=[Leading],Text=[The procedure with
+the profile:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Keepnext=[T],Type=[Leading],address@hidden Insert 
(Container : @key{in out} Map;
+                  Key       : @key{in}     Key_Type;
+                  Position  :    @key{out} Cursor;
+                  Inserted  :    @key{out} Boolean);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[is omitted.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This procedure is omitted because there is no way
+  to create a default-initialized object of an indefinite type. We considered
+  having this routine insert an empty element similar to the empty elements of
+  a vector, but rejected this possibility because the semantics are fairly
+  complex and very different from the existing case. That would make it more
+  error-prone to convert a container from a definite type to an indefinite
+  type; by omitting the routine completely, any problems will be diagnosed by
+  the compiler.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The actual Element parameter of access subprogram Process
+of Update_Element may be constrained even if Element_Type is unconstrained.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0035-1]}
address@hidden,Text=[The operations Include, Insert, Replace, and
+Replace_Element that have a formal parameter of type Element_Type perform
+indefinite insertion (see @RefSecNum{Containers}).]}
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[Some of the named operations also have a formal
+  of the indefinite formal type Key_Type and perform indefinite insertion using
+  that value, but it is sufficient to mention the formal of type Element_Type
+  to cover those.]}
address@hidden
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden to Ada 95}
+The generic package Containers.Indefinite_Ordered_Maps is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0035-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Defined some routines to @ldquote@;perform indefinite address@hidden
+  This could mean that some calls to those routines would now raise
+  Program_Error where they previously worked. However, this is extremely
+  unlikely; see @Inconsistent2012Title in
+  @RefSecNum{The Generic Package Containers.Indefinite_Vectors} for details.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Indefinite_Hashed_Sets]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The language-defined generic package
+Containers.Indefinite_Hashed_Sets provides a set with the same operations as
+the package Containers.Hashed_Sets
+(see @RefSecNum{The Generic Package Containers.Hashed_Sets}), with the 
difference
+that the generic formal type Element_Type is indefinite.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
address@hidden,Type=[Leading],Text=[The declaration
+of the generic library package
address@hidden,Child=[Indefinite_Hashed_Sets]}
+has the same contents @Chg{Version=[3],New=[and semantics ],Old=[]}as
+Containers.Hashed_Sets except:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The generic formal Element_Type is indefinite.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The actual Element parameter of access subprogram Process
+of address@hidden@!Preserving_Key may be constrained even if Element_Type is
+unconstrained.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0035-1]}
address@hidden,Text=[The operations Include, Insert, Replace,
+Replace_Element, and To_Set that have a formal parameter of type Element_Type
+perform indefinite insertion (see @RefSecNum{Containers}).]}
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This includes the procedure Replace declared in
+  the nested generic package Generic_Keys, as well as the routines declared
+  directly in the Containers.Indefinite_Hashed_Sets package.]}
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden to Ada 95}
+The generic package Containers.Indefinite_Hashed_Sets is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0035-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Defined some routines to @ldquote@;perform indefinite address@hidden
+  This could mean that some calls to those routines would now raise
+  Program_Error where they previously worked. However, this is extremely
+  unlikely; see @Inconsistent2012Title in
+  @RefSecNum{The Generic Package Containers.Indefinite_Vectors} for details.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Indefinite_Ordered_Sets]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The language-defined generic package
+Containers.Indefinite_Ordered_Sets provides a set with the same operations as
+the package Containers.Ordered_Sets
+(see @RefSecNum{The Generic Package Containers.Ordered_Sets}), with the 
difference
+that the generic formal type Element_Type is indefinite.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
address@hidden,Type=[Leading],Text=[The declaration
+of the generic library package
address@hidden,Child=[Indefinite_Ordered_Sets]}
+has the same contents @Chg{Version=[3],New=[and semantics ],Old=[]}as
+Containers.Ordered_Sets except:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The generic formal Element_Type is indefinite.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The actual Element parameter of access subprogram Process
+of address@hidden@!Preserving_Key may be constrained even if Element_Type is
+unconstrained.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0035-1]}
address@hidden,Text=[The operations Include, Insert, Replace,
+Replace_Element, and To_Set that have a formal parameter of type Element_Type
+perform indefinite insertion (see @RefSecNum{Containers}).]}
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This includes the procedure Replace declared in
+  the nested generic package Generic_Keys, as well as the routines declared
+  directly in the Containers.Indefinite_Ordered_Sets package.]}
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden to Ada 95}
+The generic package Containers.Indefinite_Ordered_Sets is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0035-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Defined some routines to @ldquote@;perform indefinite address@hidden
+  This could mean that some calls to those routines would now raise
+  Program_Error where they previously worked. However, this is extremely
+  unlikely; see @Inconsistent2012Title in
+  @RefSecNum{The Generic Package Containers.Indefinite_Vectors} for details.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Indefinite_Multiway_Trees]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Indefinite_Multiway_Trees
+provides a multiway tree with the same operations as the package
+Containers.Multiway_Trees (see @RefSecNum{The Generic Package 
Containers.Multiway_Trees}),
+with the difference that the generic formal Element_Type is indefinite.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Type=[Leading],Text=[The declaration
+of the generic library package
address@hidden,Child=[Indefinite_Multiway_Trees]}
+has the same contents and semantics as
+Containers.Multiway_Trees except:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The generic formal Element_Type is indefinite.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Keepnext=[T],Type=[Leading],Text=[The procedure with
+the profile:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Keepnext=[T],Type=[Leading],address@hidden 
Insert_Child (Container : @key{in out} Tree;
+                        Parent    : @key{in}     Cursor;
+                        Before    : @key{in}     Cursor;
+                        Position  :    @key{out} Cursor;
+                        Count     : @key{in}     Count_Type := 1);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[is omitted.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This procedure is omitted because there is no way to 
create a
+default-initialized object of an indefinite type. We considered having this
+routine insert an empty element similar to the empty elements of a vector, but
+rejected this possibility because the semantics are fairly complex and very
+different from the existing case. That would make it more error-prone to 
convert
+a container from a definite type to an indefinite type; by omitting the routine
+completely, any problems will be diagnosed by the compiler.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The actual Element parameter of access subprogram
+Process of Update_Element may be constrained even if Element_Type is
+unconstrained.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0035-1]}
address@hidden,Text=[The operations Append_Child, Insert_Child,
+Prepend_Child, and Replace_Element that have a formal parameter of type
+Element_Type perform indefinite insertion (see @RefSecNum{Containers}).]}
+
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The generic package Containers.Indefinite_Multiway_Trees is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0035-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Defined some routines to @ldquote@;perform indefinite address@hidden
+  This could mean that some calls to those routines would now raise
+  Program_Error where they previously worked. However, this is extremely
+  unlikely; see @Inconsistent2012Title in
+  @RefSecNum{The Generic Package Containers.Indefinite_Vectors} for details.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Indefinite_Holders]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Indefinite_Holders provides a private type Holder and a set of
+operations for that type. A holder container holds a single element of an
+indefinite type.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,Text=[A holder container allows the declaration of an
+object that can be used like an uninitialized variable or component of an
+indefinite type.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,Text=[A holder container may be @i{empty}.
+An empty holder does not contain an address@hidden holder}]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+package Containers.Indefinite_Holders has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal],Aref=[AI05-0069-1],Aref=[AI05-0084-1]}
address@hidden,address@hidden
+   @key[type] Element_Type (<>) @key[is private];
+   @key[with function] "=" (Left, Right : Element_Type) @key[return] Boolean 
@key[is] <>;
address@hidden Ada.Containers.Indefinite_Holders 
@address@hidden,Child=[Indefinite_Holders]}
+   @key[pragma] Preelaborate(Indefinite_Holders);
+   @key[pragma] Remote_Types(Indefinite_Holders);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Holder} @key[is tagged private];
+   @key[pragma] Preelaborable_Initialization (Holder);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{Empty_Holder} : @key[constant] Holder;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] "=" (Left, Right : Holder) @key[return] 
Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{To_Holder} (New_Item : 
Element_Type) @key[return] Holder;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Is_Empty} (Container : 
Holder) @key[return] Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Clear} (Container : @key[in 
out] Holder);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Element} (Container : 
Holder) @key[return] Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Replace_Element} (Container 
: @key[in out] Holder;
+                              New_Item  : @key[in]     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Query_Element}
+  (Container : @key[in] Holder;
+   Process   : @key[not null access procedure] (Element : @key[in] 
Element_Type));]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1],ARef=[AI05-0248-1]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Update_Element}
+  (Container : @key[in out] Holder;
+   Process   : @key[not null access procedure] (Element : @key[in out] 
Element_Type));]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Constant_Reference_Type}
+      (Element : @key[not null access constant] Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Reference_Type} (Element : 
@key[not null access] Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Constant_Reference} 
(Container : @key[aliased in] Holder)
+   @key[return] Constant_Reference_Type;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Reference} (Container : 
@key[aliased in out] Holder)
+   @key[return] Reference_Type;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Assign} (Target : @key[in 
out] Holder; Source : @key[in] Holder);]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Copy} (Source : Holder) 
@key[return] Holder;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Move} (Target : @key[in 
out] Holder; Source : @key[in out] Holder);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ... -- @Examcom[not specified by the language]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Indefinite_Holders;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,Text=[The actual function for the generic formal
+function "=" on Element_Type values is expected to define a reflexive and
+symmetric relationship and return the same result value each time it is called
+with a particular pair of values. If it behaves in some other manner, the
+function "=" on holder values returns an unspecified value. The exact arguments
+and number of calls of this generic formal function by the function "=" on
+holder values are unspecified.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If the actual function for "=" is not symmetric
+  and consistent, the result returned by any of the functions defined to use
+  "=" cannot be predicted. The implementation is not required to protect
+  against "=" raising an exception, or returning random results, or any other
+  "bad" behavior. And it can call "=" in whatever manner makes sense. But
+  note that only the results of the function "=" is unspecified; other
+  subprograms are not allowed to break if "=" is bad.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,Text=[The type Holder is used to represent holder
+containers. The type Holder needs address@hidden<needs finalization>,
+Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,Text=[Empty_Holder represents an empty holder object. If
+an object of type Holder is not otherwise initialized, it is initialized to the
+same value as Empty_Holder.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1],ARef=[AI05-0262-1]}
address@hidden,address@hidden operations of this generic package
+have access-to-subprogram parameters. To ensure such operations are
+well-defined, they guard against certain actions by the designated subprogram.
+In particular, some operations check for @ldquote@;tampering with
+the address@hidden of a container because they depend on the element of the
+container not being replaced.]]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1],ARef=[AI05-0262-1]}
address@hidden,Type=[Leading],address@hidden with elements],Sec=[of a holder]}
+A subprogram is said to @i{tamper with the element} of a holder object @i<H> 
if:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[It clears the element contained by @i<H>, that is,
+it calls the Clear procedure with @i<H> as a parameter;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[It replaces the element contained by @i<H>, that is,
+it calls the Replace_Element procedure with @i<H> as a parameter;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[It calls the Move procedure with @i<H> as a parameter;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[It finalizes @i<H>.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Complete replacement of an element can cause its
+  memory to be deallocated while another operation is holding onto a reference
+  to it. That can't be allowed. However, a simple modification of (part of) an
+  element is not a problem, so Update_Element does not cause a problem.]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0265-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0110-1]}
address@hidden,address@hidden,Sec=[tampering with a holder]}
address@hidden,Sec=[prohibited for a holder]}
+When tampering with the element is @i<prohibited> for a particular holder 
object
address@hidden<H>, Program_Error is propagated by a call of any 
language-defined subprogram
+that is defined to tamper with the element of @i<H>, leaving @i<H>
address@hidden,New=[ These checks are made before any other
+defined behavior of the body of the language-defined subprogram.],Old=[]}]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "=" (Left, Right : Holder) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,Type=[Trailing],Text=[If Left and Right denote the same
+holder object, then the function returns True. Otherwise, it compares the
+element contained in Left to the element contained in Right using the
+generic formal equality operator, returning the result of that operation. Any
+exception raised during the evaluation of element equality is propagated.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This wording describes the canonical semantics.
+  However, the order and number of calls on the formal equality @key[function]
+  is unspecified, so an implementation need not call the equality function
+  if the correct answer can be determined without doing so.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden To_Holder (New_Item : Element_Type) 
@key[return] Holder;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0035-1]}
address@hidden,Type=[Trailing],Text=[Returns a nonempty holder
+containing an element initialized to address@hidden,New=[
+To_Holder performs indefinite insertion (see 
@RefSecNum{Containers}).],Old=[]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Is_Empty (Container : Holder) 
@key[return] Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,Type=[Trailing],Text=[Returns True if Container is
+empty, and False if it contains an element.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Clear (Container : @key[in out] 
Holder);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,Type=[Trailing],Text=[Removes the element from Container.
+Container is empty after a successful Clear operation.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Element (Container : Holder) 
@key[return] Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,Type=[Trailing],Text=[If Container is empty,
+Constraint_Error is propagated. Otherwise, returns the element stored in
+Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Replace_Element (Container : @key[in 
out] Holder;
+                           New_Item  : @key[in]     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0035-1]}
address@hidden,Type=[Trailing],Text=[Replace_Element assigns the value
+New_Item into Container, replacing any preexisting content of
address@hidden,New=[; Replace_Element performs indefinite insertion
+(see @RefSecNum{Containers})],Old=[]}.
+Container is not empty after a successful call to Replace_Element.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Query_Element
+  (Container : @key[in] Holder;
+   Process   : @key[not null access procedure] (Element : @key[in] 
Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1],ARef=[AI05-0262-1],ARef=[AI05-0265-1]}
address@hidden,Type=[Trailing],Text=[If Container is empty,
+Constraint_Error is propagated. Otherwise, Query_Element calls
address@hidden with the contained element as the argument.
+Tampering with the element
+of Container is prohibited during the execution of the call on
address@hidden Any exception raised by address@hidden is propagated.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[3],Text=[The @ldquote@;tamper with the address@hidden
+  check is intended to prevent the Element parameter of Process from being
+  replaced or deleted outside of Process. The check prevents data loss (if
+  Element_Type is passed by copy) or erroneous execution (if Element_Type is an
+  unconstrained type).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1],ARef=[AI05-0248-1]}
address@hidden,KeepNext=[T],address@hidden Update_Element
+  (Container : @key[in out] Holder;
+   Process   : @key[not null access procedure] (Element : @key[in out] 
Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1],ARef=[AI05-0262-1],ARef=[AI05-0265-1]}
address@hidden,Type=[Trailing],Text=[If Container is empty,
+Constraint_Error is propagated. Otherwise, Update_Element calls
address@hidden with the contained element as the argument.
+Tampering with the element
+of Container is prohibited during the execution of the call on address@hidden
+Any exception raised by address@hidden is propagated.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The Element parameter of address@hidden may be
+  constrained even if Element_Type is unconstrained.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,address@hidden Constant_Reference_Type
+      (Element : @key[not null access constant] Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,KeepNext=[T],address@hidden Reference_Type (Element : @key[not 
null access] Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[The types Constant_Reference_Type and 
Reference_Type
+need address@hidden<needs finalization>,Sec=<language-defined type>}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[The default initialization of an object of type
+Constant_Reference_Type or Reference_Type propagates Program_Error.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[It is expected that Reference_Type (and
+  Constant_Reference_Type) will be a controlled type, for which finalization
+  will have some action to terminate the tampering check for the associated
+  container. If the object is created by default, however, there is no
+  associated container. Since this is useless, and supporting this case would
+  take extra work, we define it to raise an exception.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,KeepNext=[T],address@hidden Constant_Reference (Container : 
@key[aliased in] Holder)
+   @key[return] Constant_Reference_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Implicit_Dereference aspect) provides a convenient way to gain read access to
+the contained element of a holder container.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1],ARef=[AI05-0262-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Container is empty, Constraint_Error is
+propagated. Otherwise, Constant_Reference returns an object whose discriminant
+is an access value that designates the contained element. Tampering with the
+elements of Container is prohibited while the object returned by
+Constant_Reference exists and has not been finalized.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,KeepNext=[T],address@hidden Reference (Container : @key[aliased 
in out] Holder)
+   @key[return] Reference_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Implicit_Dereference aspects) provides a convenient way to gain read and write
+access to the contained element of a holder container.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1],ARef=[AI05-0262-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Container is empty, Constraint_Error is
+propagated. Otherwise, Reference returns an object whose discriminant is an
+access value that designates the contained element. Tampering with the
+elements of Container is prohibited while the object returned by
+Reference exists and has not been finalized.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Assign (Target : @key[in out] 
Holder; Source : @key[in] Holder);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Type=[Trailing],Text=[If Target denotes the same object as
+Source, the operation has no effect. If Source is empty, Clear (Target) is
+called. Otherwise, Replace_Element (Target, Element (Source)) is called.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[3],Text=[This routine exists for compatibility with the
+  other containers. For a holder, @exam{Assign(A, B)} and
+  @exam{A := B} behave effectively the same. (Assign Clears the Target, while
+  := finalizes the Target, but these should have similar effects.)]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Copy (Source : Holder) @key[return] 
Holder;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Type=[Trailing],Text=[If Source is empty, returns an empty
+holder container; otherwise, returns To_Holder (Element (Source)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Move (Target : @key[in out] Holder; 
Source : @key[in out] Holder);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1],ARef=[AI05-0248-1]}
address@hidden,Type=[Trailing],Text=[If Target denotes the same object
+as Source, then the operation has no effect. Otherwise, the element contained
+by Source (if any) is removed from Source and inserted into Target, replacing
+any preexisting content. Source is empty after a successful call to Move.]}
+
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0022-1],ARef=[AI05-0069-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error for the actual function associated with a
+generic formal subprogram, when called as part of an operation of
+this package, to tamper with the element of any Holder parameter of the
+operation. Either Program_Error is raised, or the operation works as
+defined on the value of the Holder either prior to, or subsequent to,
+some or all of the modifications to the Holder.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0027-1],ARef=[AI05-0069-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to call any subprogram declared in the visible part
+of Containers.Indefinite_Holders when the associated container has been
+finalized. If the operation takes Container as an @key[in out] parameter,
+then it raises Constraint_Error or Program_Error. Otherwise, the operation
+either proceeds as it would for an empty container, or it raises
+Constraint_Error or Program_Error.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Text=[Execution is erroneous if the holder container
+associated with the result of a call to Reference or Constant_Reference is
+finalized before the result object returned by the call to Reference or
+Constant_Reference is address@hidden(erroneous execution),Sec=(cause)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],Text=[Each object of Reference_Type and
+  Constant_Reference_Type probably contains some reference to the originating
+  container. If that container is prematurely finalized (which is only possible
+  via Unchecked_Deallocation, as accessibility checks prevent passing a
+  container to Reference that will not live as long as the result), the
+  finalization of the object of Reference_Type will try to access a nonexistent
+  object. This is a normal case of a dangling pointer created by
+  Unchecked_Deallocation; we have to explicitly mention it here as the pointer
+  in question is not visible in the specification of the type. (This is the 
same
+  reason we have to say this for invalid cursors.)]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1]}
address@hidden,Text=[No storage associated with a holder object shall be
+lost upon assignment or scope exit.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1],ARef=[AI05-0269-1]}
address@hidden,Text=[The execution of an @nt{assignment_statement}
+for a holder container shall have the effect of copying the element (if any)
+from the source holder object to the target holder object.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0298-1]}
+  @ChgAdded{Version=[3],Text=[An assignment of a holder container is a
+  @ldquote@;address@hidden copy; that is the element is copied as well as any
+  data structures. We say @ldquote@;effect address@hidden in order to allow the
+  implementation to avoid copying the element immediately if it wishes. For
+  instance, an implementation that avoided copying until one of the containers
+  is modified would be allowed. (Note that this implementation would
+  require care, see @RefSecNum{The Generic Package Containers.Vectors} for 
more.)]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1],ARef=[AI05-0269-1]}
address@hidden,Text=[Move should not copy the element, and should minimize
+copying of internal data structures.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Containers.Indefinite_Holders.Move should not copy the element, and 
should
+minimize copying of internal data structures.]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Usually that can be accomplished simply by moving
+  the pointer(s) to the internal data structures from the Source holder to the
+  Target holder.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0069-1],ARef=[AI05-0269-1]}
address@hidden,Text=[If an exception is propagated from a holder
+operation, no storage should be lost, nor should the element be removed from a
+holder container unless specified by the operation.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[If an exception is propagated from a holder
+operation, no storage should be lost, nor should the element be removed from a
+holder container unless specified by the operation.]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is important so that programs can recover
+  from errors. But we don't want to require heroic efforts, so we just require
+  documentation of cases where this can't be accomplished.]}
address@hidden
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0069-1],ARef=[AI05-0084-1],ARef=[AI05-0265-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005} The generic package
+  Containers.Indefinite_Holders is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0035-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Defined some routines to @ldquote@;perform indefinite address@hidden
+  This could mean that some calls to those routines would now raise
+  Program_Error where they previously worked. However, this is extremely
+  unlikely; see @Inconsistent2012Title in
+  @RefSecNum{The Generic Package Containers.Indefinite_Vectors} for details.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0110-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that tampering 
checks
+  precede all other checks made by a subprogram (but come after those 
associated
+  with the call).]}
address@hidden
+
address@hidden,Name=[The Generic Package Containers.Bounded_Vectors]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Bounded_Vectors provides a private type Vector and a set of
+operations. It provides the same operations as the package Containers.Vectors
+(see @RefSecNum{The Generic Package Containers.Vectors}), with the difference 
that the
+maximum storage is bounded.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Type=[Leading],Text=[The declaration of the generic
+library package Containers.Bounded_Vectors has the same contents and semantics
+as Containers.Vectors except:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The @nt{pragma} Preelaborate is replaced with 
@nt{pragma} Pure.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The type Vector is declared with a
+    discriminant that specifies the capacity:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key{type} Vector (Capacity : Count_Type) 
@key[is tagged private];]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The type Vector needs finalization if and only if
+    type Element_Type needs finalization.]}
+
+  @begin{ImplNote}
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+    @ChgAdded{Version=[3],Text=[The type Vector cannot depend on package
+    Ada.Finalization unless the element type depends on that package.
+    The objects returned from the Iterator and Reference functions probably do
+    depend on package Ada.Finalization. Restricted environments may need to
+    avoid use of those functions and their associated types.]}
+  @end{ImplNote}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[In function Copy, if the Capacity parameter is
+    equal to or greater than the length of Source, the vector capacity exactly 
equals
+    the value of the Capacity parameter.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The description of 
Reserve_Capacity
+  is replaced with:]}
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],NoPrefix=[T],Text=[If the specified Capacity is 
larger
+    than the capacity of Container, then Reserve_Capacity propagates 
Capacity_Error.
+    Otherwise, the operation has no effect.]}
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0160-1],ARef=[AI05-0265-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to assign from a bounded vector object while tampering
+with elements @Redundant[or cursors] of that object is prohibited. Either
+Program_Error is raised by the assignment, execution proceeds with the target
+object prohibiting tampering with elements @Redundant[or cursors], or execution
+proceeds normally.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Tampering with elements includes tampering
+  with cursors, so we only really need to talk about tampering with elements
+  here; we mention cursors for clarity.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0265-1]}
address@hidden,Text=[When a bounded vector object @i<V> is
+finalized, if tampering with cursors is prohibited for @i<V> other than due
+to an assignment from another vector, then execution is erroneous.
address@hidden(erroneous execution),Sec=(cause)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is a tampering event, but since the
+  implementation is not allowed to use Ada.Finalization, it is not possible in 
a
+  pure Ada implementation to detect this error. (There is no Finalize routine
+  that will be called that could make the check.) Since the check probably
+  cannot be made, the bad effects that could occur (such as an iterator going
+  into an infinite loop or accessing a nonexistent element) cannot be prevented
+  and we have to allow anything. We do allow re-assigning an object that only
+  prohibits tampering because it was copied from another object as that cannot
+  cause any negative effects.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0264-1]}
address@hidden,Type=[Leading],Text=[For each instance of
+Containers.Vectors and each instance of Containers.Bounded_Vectors,
+if the two instances meet the following conditions,
+then the output generated by
+the Vector'Output or Vector'Write subprograms of either instance
+shall be readable by the Vector'Input
+or Vector'Read of the other instance, respectively:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Text=[the Element_Type parameters of the two instances
+    are statically matching subtypes of the same type; and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],Text=[the output generated by Element_Type'Output or
+    Element_Type'Write is readable by Element_Type'Input or Element_Type'Read,
+    respectively (where Element_Type denotes the type of the two actual
+    Element_Type parameters); and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],Text=[the preceding two conditions also hold for the
+    Index_Type parameters of the instances.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[Bounded vector objects should be implemented without
+implicit pointers or dynamic allocation.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Bounded vector objects should be implemented without
+implicit pointers or dynamic allocation.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[The implementation advice for procedure Move to
+minimize copying does not apply.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The implementation advice for procedure Move to
+minimize copying does not apply to bounded vectors.]}]}
+
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0160-1],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005} The generic package
+  Containers.Bounded_Vectors is new.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package 
Containers.Bounded_Doubly_Linked_Lists]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Bounded_Doubly_Linked_Lists provides a private type List
+and a set of operations. It provides the same operations as the
+package Containers.Doubly_Linked_Lists
+(see @RefSecNum{The Generic Package Containers.Doubly_Linked_Lists}), with the
+difference that the maximum storage is bounded.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Type=[Leading],Text=[The declaration of the generic
+library package Containers.Bounded_Doubly_Linked_Lists has the same contents 
and semantics
+as Containers.Doubly_Linked_Lists except:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The @nt{pragma} Preelaborate is replaced with 
@nt{pragma} Pure.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The type List is declared with a
+    discriminant that specifies the capacity (maximum number of elements)
+    as follows:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key{type} List (Capacity : Count_Type) 
@key[is tagged private];]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The type List needs finalization if and only if
+    type Element_Type needs finalization.]}
+
+  @begin{ImplNote}
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+    @ChgAdded{Version=[3],Text=[The type List cannot depend on package
+    Ada.Finalization unless the element type depends on that package.
+    The objects returned from the Iterator and Reference functions probably do
+    depend on package Ada.Finalization. Restricted environments may need to
+    avoid use of those functions and their associated types.]}
+  @end{ImplNote}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The allocation of internal storage includes a
+    check that the capacity is not exceeded, and Capacity_Error is raised
+    if this check fails.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[In procedure Assign, if Source length is greater
+    than Target capacity, then Capacity_Error is propagated.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The function Copy is replaced 
with:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key[function] @AdaSubDefn{Copy} (Source : 
List; Capacity : Count_Type := 0)
+     @key[return] List;]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Noprefix=[T],Text=[If Capacity is 0, then the list 
capacity is the length of
+    Source; if Capacity is equal to or greater than the length of Source,
+    the list capacity equals the value of the Capacity parameter;
+    otherwise, the operation propagates Capacity_Error.]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[In the three-parameter procedure Splice whose
+    Source has type List, if the sum of the length of Target and the length
+    of Source is greater than the capacity of Target, then Splice propagates
+    Capacity_Error.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[In the four-parameter procedure Splice, if
+    the length of Target equals the capacity of Target, then Splice
+    propagates Capacity_Error.]}
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0160-1],ARef=[AI05-0265-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to assign from a bounded list object while tampering
+with elements @Redundant[or cursors] of that object is prohibited. Either
+Program_Error is raised by the assignment, execution proceeds with the target
+object prohibiting tampering with elements @Redundant[or cursors], or execution
+proceeds normally.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Tampering with elements includes tampering
+  with cursors, so we only really need to talk about tampering with elements
+  here; we mention cursors for clarity.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0265-1]}
address@hidden,Text=[When a bounded list object @i<L> is
+finalized, if tampering with cursors is prohibited for @i<L> other than due
+to an assignment from another list, then execution is erroneous.
address@hidden(erroneous execution),Sec=(cause)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is a tampering event, but since the
+  implementation is not allowed to use Ada.Finalization, it is not possible in 
a
+  pure Ada implementation to detect this error. (There is no Finalize routine
+  that will be called that could make the check.) Since the check probably
+  cannot be made, the bad effects that could occur (such as an iterator going
+  into an infinite loop or accessing a nonexistent element) cannot be prevented
+  and we have to allow anything. We do allow re-assigning an object that only
+  prohibits tampering because it was copied from another object as that cannot
+  cause any negative effects.]}
address@hidden
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0264-1]}
address@hidden,Type=[Leading],Text=[For each instance of
+Containers.Doubly_Linked_Lists and each instance of
+Containers.Bounded_Doubly_Linked_Lists,
+if the two instances meet the following conditions,
+then the output generated by
+the List'Output or List'Write subprograms of either instance
+shall be readable by the List'Input
+or List'Read of the other instance, respectively:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Text=[the Element_Type parameters of the two instances
+    are statically matching subtypes of the same type; and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],Text=[the output generated by Element_Type'Output or
+    Element_Type'Write is readable by Element_Type'Input or Element_Type'Read,
+    respectively (where Element_Type denotes the type of the two actual
+    Element_Type parameters).]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[Bounded list objects should be implemented without
+implicit pointers or dynamic allocation.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Bounded list objects should be implemented without
+implicit pointers or dynamic allocation.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[The implementation advice for procedure Move to
+minimize copying does not apply.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The implementation advice for procedure Move to
+minimize copying does not apply to bounded lists.]}]}
+
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0160-1],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005} The generic package
+  Containers.Bounded_Doubly_Linked_Lists is new.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Bounded_Hashed_Maps]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Bounded_Hashed_Maps provides a private type Map
+and a set of operations. It provides the same operations as the
+package Containers.Hashed_Maps
+(see @RefSecNum{The Generic Package Containers.Hashed_Maps}), with the
+difference that the maximum storage is bounded.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Type=[Leading],Text=[The declaration of the generic
+library package Containers.Bounded_Hashed_Maps has the same contents and 
semantics
+as Containers.Hashed_Maps except:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The @nt{pragma} Preelaborate is replaced with 
@nt{pragma} Pure.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The type Map is declared with
+    discriminants that specify both the capacity (number of elements) and
+    modulus (number of distinct hash values) of the hash table as follows:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key[type] Map (Capacity : Count_Type;
+            Modulus  : Hash_Type) @key[is tagged private];]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The type Map needs finalization if and only if 
type
+      Key_Type or type Element_Type needs finalization.]}
+
+  @begin{ImplNote}
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+    @ChgAdded{Version=[3],Text=[The type Map cannot depend on package
+    Ada.Finalization unless the element or key type depends on that package.
+    The objects returned from the Iterator and Reference functions probably do
+    depend on package Ada.Finalization. Restricted environments may need to
+    avoid use of those functions and their associated types.]}
+  @end{ImplNote}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The description of 
Reserve_Capacity
+  is replaced with:]}
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],NoPrefix=[T],Text=[If the specified Capacity is 
larger
+    than the capacity of Container, then Reserve_Capacity propagates 
Capacity_Error.
+    Otherwise, the operation has no effect.]}
address@hidden
+
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[An additional operation is added 
immediately following Reserve_Capacity:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key[function] @AdaSubDefn{Default_Modulus} 
(Capacity : Count_Type) @key[return] Hash_Type;]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Noprefix=[T],Text=[Default_Modulus returns an
+    implementation-defined value for the number of distinct hash values to be
+    used for the given capacity (maximum number of elements).]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The function Copy is replaced 
with:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key[function] @AdaSubDefn{Copy} (Source   
: Map;
+                 Capacity : Count_Type := 0;
+                 Modulus  : Hash_Type := 0) @key[return] Map;]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0264-1]}
+  @ChgAdded{Version=[3],Noprefix=[T],Text=[Returns a map with key/element 
pairs initialized from the values
+    in Source. If Capacity is 0, then the map capacity is the
+    length of Source; if Capacity is equal to or greater than
+    the length of Source, the map capacity is the value of the Capacity
+    parameter; otherwise, the operation propagates Capacity_Error.  If
+    the Modulus argument is 0, then the map modulus is the value
+    returned by a call to Default_Modulus with the map capacity as its
+    argument; otherwise, the map modulus is the value of the Modulus 
parameter.]}
address@hidden
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0160-1],ARef=[AI05-0265-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to assign from a bounded map object while tampering
+with elements @Redundant[or cursors] of that object is prohibited. Either
+Program_Error is raised by the assignment, execution proceeds with the target
+object prohibiting tampering with elements @Redundant[or cursors], or execution
+proceeds normally.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Tampering with elements includes tampering
+  with cursors, so we only really need to talk about tampering with elements
+  here; we mention cursors for clarity.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0265-1]}
address@hidden,Text=[When a bounded map object @i<M> is
+finalized, if tampering with cursors is prohibited for @i<M> other than due
+to an assignment from another map, then execution is erroneous.
address@hidden(erroneous execution),Sec=(cause)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is a tampering event, but since the
+  implementation is not allowed to use Ada.Finalization, it is not possible in 
a
+  pure Ada implementation to detect this error. (There is no Finalize routine
+  that will be called that could make the check.) Since the check probably
+  cannot be made, the bad effects that could occur (such as an iterator going
+  into an infinite loop or accessing a nonexistent element) cannot be prevented
+  and we have to allow anything. We do allow re-assigning an object that only
+  prohibits tampering because it was copied from another object as that cannot
+  cause any negative effects.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0264-1]}
address@hidden,Type=[Leading],Text=[For each instance of
+Containers.Hashed_Maps and each instance of Containers.Bounded_Hashed_Maps,
+if the two instances meet the following conditions,
+then the output generated by
+the Map'Output or Map'Write subprograms of either instance
+shall be readable by the Map'Input
+or Map'Read of the other instance, respectively:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Text=[the Element_Type parameters of the two instances
+    are statically matching subtypes of the same type; and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],Text=[the output generated by Element_Type'Output or
+    Element_Type'Write is readable by Element_Type'Input or Element_Type'Read,
+    respectively (where Element_Type denotes the type of the two actual
+    Element_Type parameters); and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],Text=[the preceding two conditions also hold for the
+    Key_Type parameters of the instances.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0269-1]}
address@hidden,Text=[Bounded hashed map objects should be implemented without
+implicit pointers or dynamic allocation.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Bounded hashed map objects should be implemented without
+implicit pointers or dynamic allocation.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[The implementation advice for procedure Move to
+minimize copying does not apply.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The implementation advice for procedure Move to
+minimize copying does not apply to bounded hashed maps.]}]}
+
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0160-1],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005} The generic package
+  Containers.Bounded_Hashed_Maps is new.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Bounded_Ordered_Maps]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Bounded_Ordered_Maps provides a private type Map
+and a set of operations. It provides the same operations as the
+package Containers.Ordered_Maps
+(see @RefSecNum{The Generic Package Containers.Ordered_Maps}), with the
+difference that the maximum storage is bounded.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Type=[Leading],Text=[The declaration of the generic
+library package Containers.Bounded_Ordered_Maps has the same contents and 
semantics
+as Containers.Ordered_Maps except:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The @nt{pragma} Preelaborate is replaced with 
@nt{pragma} Pure.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The type Map is declared with a
+    discriminant that specifies the capacity (maximum number of elements)
+    as follows:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key[type] Map (Capacity : Count_Type) 
@key[is tagged private];]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The type Map needs finalization if and only if
+     type Key_Type or type Element_Type needs finalization.]}
+
+  @begin{ImplNote}
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+    @ChgAdded{Version=[3],Text=[The type Map cannot depend on package
+    Ada.Finalization unless the element type depends on that package.
+    The objects returned from the Iterator and Reference functions probably do
+    depend on package Ada.Finalization. Restricted environments may need to
+    avoid use of those functions and their associated types.]}
+  @end{ImplNote}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The allocation of a new node includes a check 
that
+    the capacity is not exceeded, and Capacity_Error is raised if this check
+    fails.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[In procedure Assign, if Source length is greater
+    than Target capacity, then Capacity_Error is propagated.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The function Copy is replaced 
with:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key[function] @AdaSubDefn{Copy} (Source   
: Map;
+                 Capacity : Count_Type := 0) @key[return] Map;]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Noprefix=[T],Text=[Returns a map with key/element pairs
+    initialized from the values in Source. If Capacity is 0, then the map
+    capacity is the length of Source; if Capacity is equal to or greater than
+    the length of Source, the map capacity is the specified value; otherwise, 
the
+    operation propagates Capacity_Error.]}
address@hidden
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0160-1],ARef=[AI05-0265-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to assign from a bounded map object while tampering
+with elements @Redundant[or cursors] of that object is prohibited. Either
+Program_Error is raised by the assignment, execution proceeds with the target
+object prohibiting tampering with elements @Redundant[or cursors], or execution
+proceeds normally.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Tampering with elements includes tampering
+  with cursors, so we only really need to talk about tampering with elements
+  here; we mention cursors for clarity.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0265-1]}
address@hidden,Text=[When a bounded map object @i<M> is
+finalized, if tampering with cursors is prohibited for @i<M> other than due
+to an assignment from another map, then execution is erroneous.
address@hidden(erroneous execution),Sec=(cause)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is a tampering event, but since the
+  implementation is not allowed to use Ada.Finalization, it is not possible in 
a
+  pure Ada implementation to detect this error. (There is no Finalize routine
+  that will be called that could make the check.) Since the check probably
+  cannot be made, the bad effects that could occur (such as an iterator going
+  into an infinite loop or accessing a nonexistent element) cannot be prevented
+  and we have to allow anything. We do allow re-assigning an object that only
+  prohibits tampering because it was copied from another object as that cannot
+  cause any negative effects.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0264-1]}
address@hidden,Type=[Leading],Text=[For each instance of
+Containers.Ordered_Maps and each instance of Containers.Bounded_Ordered_Maps,
+if the two instances meet the following conditions,
+then the output generated by
+the Map'Output or Map'Write subprograms of either instance
+shall be readable by the Map'Input
+or Map'Read of the other instance, respectively:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Text=[the Element_Type parameters of the two instances
+    are statically matching subtypes of the same type; and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],Text=[the output generated by Element_Type'Output or
+    Element_Type'Write is readable by Element_Type'Input or Element_Type'Read,
+    respectively (where Element_Type denotes the type of the two actual
+    Element_Type parameters); and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],Text=[the preceding two conditions also hold for the
+    Key_Type parameters of the instances.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0269-1]}
address@hidden,Text=[Bounded ordered map objects should be implemented
+without implicit pointers or dynamic allocation.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Bounded ordered map objects should be implemented without
+implicit pointers or dynamic allocation.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[The implementation advice for procedure Move to
+minimize copying does not apply.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The implementation advice for procedure Move to
+minimize copying does not apply to bounded ordered maps.]}]}
+
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0160-1],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005} The generic package
+  Containers.Bounded_Ordered_Maps is new.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Bounded_Hashed_Sets]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Bounded_Hashed_Sets provides a private type Set
+and a set of operations. It provides the same operations as the
+package Containers.Hashed_Sets
+(see @RefSecNum{The Generic Package Containers.Hashed_Sets}), with the
+difference that the maximum storage is bounded.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Type=[Leading],Text=[The declaration of the generic
+library package Containers.Bounded_Hashed_Sets has the same contents and 
semantics
+as Containers.Hashed_Sets except:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The @nt{pragma} Preelaborate is replaced with 
@nt{pragma} Pure.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The type Set is declared with
+    discriminants that specify both the capacity (number of elements) and
+    modulus (number of distinct hash values) of the hash table as follows:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key[type] Set (Capacity : Count_Type;
+            Modulus  : Hash_Type) @key[is tagged private];]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The type Set needs finalization if and only if
+    type Element_Type needs finalization.]}
+
+  @begin{ImplNote}
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+    @ChgAdded{Version=[3],Text=[The type Set cannot depend on package
+    Ada.Finalization unless the element or key type depends on that package.
+    The objects returned from the Iterator and Reference functions probably do
+    depend on package Ada.Finalization. Restricted environments may need to
+    avoid use of those functions and their associated types.]}
+  @end{ImplNote}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The description of 
Reserve_Capacity
+  is replaced with:]}
address@hidden
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],NoPrefix=[T],Text=[If the specified Capacity is 
larger
+    than the capacity of Container, then Reserve_Capacity propagates 
Capacity_Error.
+    Otherwise, the operation has no effect.]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[An additional operation is added 
immediately following Reserve_Capacity:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key[function] @AdaSubDefn{Default_Modulus} 
(Capacity : Count_Type) @key[return] Hash_Type;]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Noprefix=[T],Text=[Default_Modulus returns an
+    implementation-defined value for the number of distinct hash values to be
+    used for the given capacity (maximum number of elements).]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The function Copy is replaced 
with:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key[function] @AdaSubDefn{Copy} (Source   
: Set;
+                 Capacity : Count_Type := 0;
+                 Modulus  : Hash_Type := 0) @key[return] Set;]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0264-1]}
+  @ChgAdded{Version=[3],Noprefix=[T],Text=[Returns a set whose elements are
+    initialized from the values in Source. If Capacity is 0, then the set
+    capacity is the length of Source; if Capacity is equal to or greater than
+    the length of Source, the set capacity is the value of the Capacity 
parameter;
+    otherwise, the operation propagates Capacity_Error. If the Modulus 
argument is
+    0, then the set modulus is the value returned by a call to Default_Modulus
+    with the set capacity as its argument; otherwise, the set modulus is the
+    value of the Modulus parameter.]}
address@hidden
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0160-1],ARef=[AI05-0265-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to assign from a bounded set object while tampering
+with elements @Redundant[or cursors] of that object is prohibited. Either
+Program_Error is raised by the assignment, execution proceeds with the target
+object prohibiting tampering with elements @Redundant[or cursors], or execution
+proceeds normally.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Tampering with elements includes tampering
+  with cursors, so we only really need to talk about tampering with elements
+  here; we mention cursors for clarity.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0265-1]}
address@hidden,Text=[When a bounded set object @i<S> is
+finalized, if tampering with cursors is prohibited for @i<S> other than due
+to an assignment from another set, then execution is erroneous.
address@hidden(erroneous execution),Sec=(cause)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is a tampering event, but since the
+  implementation is not allowed to use Ada.Finalization, it is not possible in 
a
+  pure Ada implementation to detect this error. (There is no Finalize routine
+  that will be called that could make the check.) Since the check probably
+  cannot be made, the bad effects that could occur (such as an iterator going
+  into an infinite loop or accessing a nonexistent element) cannot be prevented
+  and we have to allow anything. We do allow re-assigning an object that only
+  prohibits tampering because it was copied from another object as that cannot
+  cause any negative effects.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0264-1]}
address@hidden,Type=[Leading],Text=[For each instance of
+Containers.Hashed_Sets and each instance of Containers.Bounded_Hashed_Sets,
+if the two instances meet the following conditions,
+then the output generated by
+the Set'Output or Set'Write subprograms of either instance
+shall be readable by the Set'Input
+or Set'Read of the other instance, respectively:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Text=[the Element_Type parameters of the two instances
+    are statically matching subtypes of the same type; and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],Text=[the output generated by Element_Type'Output or
+    Element_Type'Write is readable by Element_Type'Input or Element_Type'Read,
+    respectively (where Element_Type denotes the type of the two actual
+    Element_Type parameters).]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0269-1]}
address@hidden,Text=[Bounded hashed set objects should be implemented
+without implicit pointers or dynamic allocation.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Bounded hashed set objects should be implemented without
+implicit pointers or dynamic allocation.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[The implementation advice for procedure Move to
+minimize copying does not apply.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The implementation advice for procedure Move to
+minimize copying does not apply to bounded hashed sets.]}]}
+
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0160-1],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005} The generic package
+  Containers.Bounded_Hashed_Sets is new.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Bounded_Ordered_Sets]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Bounded_Ordered_Sets provides a private type Set
+and a set of operations. It provides the same operations as the
+package Containers.Ordered_Sets
+(see @RefSecNum{The Generic Package Containers.Ordered_Sets}), with the
+difference that the maximum storage is bounded.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Type=[Leading],Text=[The declaration of the generic
+library package Containers.Bounded_Ordered_Sets has the same contents and 
semantics
+as Containers.Ordered_Sets except:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The @nt{pragma} Preelaborate is replaced with 
@nt{pragma} Pure.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The type Set is declared with a
+    discriminant that specifies the capacity (maximum number of elements)
+    as follows:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key{type} Set (Capacity : Count_Type) 
@key[is tagged private];]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The type Set needs finalization if and only if
+    type Element_Type needs finalization.]}
+
+  @begin{ImplNote}
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+    @ChgAdded{Version=[3],Text=[The type Set cannot depend on package
+    Ada.Finalization unless the element type depends on that package. The
+    objects returned from the Iterator and Reference functions probably do
+    depend on package Ada.Finalization. Restricted environments may need to
+    avoid use of those functions and their associated types.]}
+  @end{ImplNote}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[If Insert (or Include) adds an element, a check 
is
+    made that the capacity is not exceeded, and Capacity_Error is raised
+    if this check fails.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[In procedure Assign, if Source length is greater
+    than Target capacity, then Capacity_Error is propagated.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The function Copy is replaced 
with:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key[function] @AdaSubDefn{Copy} (Source   
: Set;
+                 Capacity : Count_Type := 0) @key[return] Set;]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Noprefix=[T],Text=[Returns a set whose elements
+    are initialized from the values in Source. If Capacity is 0, then the set
+    capacity is the length of Source; if Capacity is equal to or greater than
+    the length of Source, the set capacity is the specified value; otherwise, 
the
+    operation propagates Capacity_Error.]}
address@hidden
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0160-1],ARef=[AI05-0265-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to assign from a bounded set object while tampering
+with elements @Redundant[or cursors] of that object is prohibited. Either
+Program_Error is raised by the assignment, execution proceeds with the target
+object prohibiting tampering with elements @Redundant[or cursors], or execution
+proceeds normally.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Tampering with elements includes tampering
+  with cursors, so we only really need to talk about tampering with elements
+  here; we mention cursors for clarity.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0265-1]}
address@hidden,Text=[When a bounded set object @i<S> is
+finalized, if tampering with cursors is prohibited for @i<S> other than due
+to an assignment from another set, then execution is erroneous.
address@hidden(erroneous execution),Sec=(cause)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is a tampering event, but since the
+  implementation is not allowed to use Ada.Finalization, it is not possible in 
a
+  pure Ada implementation to detect this error. (There is no Finalize routine
+  that will be called that could make the check.) Since the check probably
+  cannot be made, the bad effects that could occur (such as an iterator going
+  into an infinite loop or accessing a nonexistent element) cannot be prevented
+  and we have to allow anything. We do allow re-assigning an object that only
+  prohibits tampering because it was copied from another object as that cannot
+  cause any negative effects.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0264-1]}
address@hidden,Type=[Leading],Text=[For each instance of
+Containers.Ordered_Sets and each instance of Containers.Bounded_Ordered_Sets,
+if the two instances meet the following conditions,
+then the output generated by
+the Set'Output or Set'Write subprograms of either instance
+shall be readable by the Set'Input
+or Set'Read of the other instance, respectively:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Text=[the Element_Type parameters of the two instances
+    are statically matching subtypes of the same type; and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],Text=[the output generated by Element_Type'Output or
+    Element_Type'Write is readable by Element_Type'Input or Element_Type'Read,
+    respectively (where Element_Type denotes the type of the two actual
+    Element_Type parameters).]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0269-1]}
address@hidden,Text=[Bounded ordered set objects should be implemented
+without implicit pointers or dynamic allocation.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Bounded ordered set objects should be implemented without
+implicit pointers or dynamic allocation.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1]}
address@hidden,Text=[The implementation advice for procedure Move to
+minimize copying does not apply.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The implementation advice for procedure Move to
+minimize copying does not apply to bounded ordered sets.]}]}
+
address@hidden
+
address@hidden
+  
@ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0160-1],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005} The generic package
+  Containers.Bounded_Ordered_Sets is new.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Bounded_Multiway_Trees]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Bounded_Multiway_Trees provides a private type Tree and a set of
+operations. It provides the same operations as the package
+Containers.Multiway_Trees (see
address@hidden Generic Package Containers.Multiway_Trees}), with the difference
+that the maximum storage is bounded.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Type=[Leading],Text=[The declaration of the generic
+library package Containers.Bounded_Multiway_Trees has the same contents and
+semantics as Containers.Multiway_Trees except:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The @nt{pragma} Preelaborate is replaced with 
@nt{pragma} Pure.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[The type Tree is declared with a
+    discriminant that specifies the capacity (maximum number of elements)
+    as follows:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Noprefix=[T],Text=[  @key{type} Tree (Capacity : Count_Type) 
@key[is tagged private];]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The type Tree needs finalization if and only if
+    type Element_Type needs finalization.]}
+
+  @begin{ImplNote}
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+    @ChgAdded{Version=[3],Text=[The type Tree cannot depend on package
+    Ada.Finalization unless the element type depends on that package. The
+    objects returned from the Iterator and Reference functions probably do
+    depend on package Ada.Finalization. Restricted environments may need to
+    avoid use of those functions and their associated types.]}
+  @end{ImplNote}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The allocation of internal storage includes a
+    check that the capacity is not exceeded, and Capacity_Error is raised if
+    this check fails.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[In procedure Assign, if Source length is greater
+    than Target capacity, then Capacity_Error is propagated.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[Function Copy is declared as 
follows:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0056-1]}
address@hidden,Noprefix=[T],Text=[  @key{function} Copy (Source : Tree; 
Capacity : Count_Type := 0)
+     @key{return} @Chg{Version=[4],New=[Tree],Old=[List]};]}
address@hidden
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Noprefix=[T],Text=[If Capacity is 0, then the tree
+    capacity is the count of Source; if Capacity is equal to or greater than
+    Source.Count, the tree capacity equals the value of the Capacity parameter;
+    otherwise, the operation propagates Capacity_Error.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Text=[In the five-parameter procedure Splice_Subtree, 
if
+    Source is not the same object as Target, and if the sum of Target.Count and
+    Subtree_Node_Count (Position) is greater than Target.Capacity, then
+    Splice_Subtree propagates Capacity_Error.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Text=[In the five-parameter procedure Splice_Children,
+    if Source is not the same object as Target, and if the sum of Target.Count
+    and Subtree_Node_Count (Source_Parent)-1 is greater than Target.Capacity,
+    then Splice_Children propagates Capacity_Error.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0160-1],ARef=[AI05-0265-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to assign from a bounded tree object while tampering
+with elements @Redundant[or cursors] of that object is prohibited. Either
+Program_Error is raised by the assignment, execution proceeds with the target
+object prohibiting tampering with elements @Redundant[or cursors], or execution
+proceeds normally.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Tampering with elements includes tampering
+  with cursors, so we only really need to talk about tampering with elements
+  here; we mention cursors for clarity.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0265-1]}
address@hidden,Text=[When a bounded tree object @i<T> is
+finalized, if tampering with cursors is prohibited for @i<T> other than due
+to an assignment from another tree, then execution is erroneous.
address@hidden(erroneous execution),Sec=(cause)}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is a tampering event, but since the
+  implementation is not allowed to use Ada.Finalization, it is not possible in 
a
+  pure Ada implementation to detect this error. (There is no Finalize routine
+  that will be called that could make the check.) Since the check probably
+  cannot be made, the bad effects that could occur (such as an iterator going
+  into an infinite loop or accessing a nonexistent element) cannot be prevented
+  and we have to allow anything. We do allow re-assigning an object that only
+  prohibits tampering because it was copied from another object as that cannot
+  cause any negative effects.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0264-1]}
address@hidden,Type=[Leading],Text=[For each instance of
+Containers.Multiway_Trees and each instance of 
Containers.Bounded_Multiway_Trees,
+if the two instances meet the following conditions,
+then the output generated by
+the Tree'Output or Tree'Write subprograms of either instance
+shall be readable by the Tree'Input
+or Tree'Read of the other instance, respectively:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],Text=[the Element_Type parameters of the two instances
+    are statically matching subtypes of the same type; and]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],Text=[the output generated by Element_Type'Output or
+    Element_Type'Write is readable by Element_Type'Input or Element_Type'Read,
+    respectively (where Element_Type denotes the type of the two actual
+    Element_Type parameters).]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[Bounded tree objects should be implemented without
+implicit pointers or dynamic allocation.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Bounded tree objects should be implemented without
+implicit pointers or dynamic allocation.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0136-1]}
address@hidden,Text=[The implementation advice for procedure Move to
+minimize copying does not apply.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The implementation advice for procedure Move to
+minimize copying does not apply to bounded trees.]}]}
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0136-1],ARef=[AI05-0184-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The generic package Containers.Bounded_Multiway_Trees is new.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,Name=[Array Sorting]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0001-1]}
address@hidden,Text=[The language-defined generic procedures
address@hidden@address@hidden,New=[,],Old=[ and]}
address@hidden@address@hidden@Chg{Version=[3],New=[, and
address@hidden,Old=[]}
+provide sorting on arbitrary array types.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+procedure Containers.Generic_Array_Sort has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key{type} Index_Type @key{is} (<>);
+   @key{type} Element_Type @key{is private};
+   @key{type} Array_Type @key{is array} (Index_Type @key{range} <>) @key{of} 
Element_Type;
+   @key{with function} "<" (Left, Right : Element_Type)
+      @key{return} Boolean @key{is} <>;
address@hidden Ada.Containers.Generic_Array_Sort (Container : @key{in out} 
Array_Type);@SubChildUnit{Parent=[Ada.Containers],Child=[Generic_Array_Sort]}
address@hidden Pure(Ada.Containers.Generic_Array_Sort);]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Reorders the elements of Container such that the elements 
are
+sorted smallest first as determined by the generic formal "<" operator
+provided. Any exception raised during evaluation of "<" is propagated.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0044-1],ARef=[AI05-0262-1]}
address@hidden,Text=[The actual function for the generic formal function
+"<" of Generic_Array_Sort is expected to return the same value each time it is
+called with a particular pair of element values. It should define a strict
address@hidden,New=[weak ],Old=[]}ordering address@hidden,
+New=[ (see @RefSecNum{Containers})],Old=[, that is, be irreflexive, asymmetric,
+and transitive]}; it
+should not modify Container. If the actual for "<" behaves in some other
+manner, the behavior of the instance of Generic_Array_Sort is unspecified.
address@hidden,New=[The number of],Old=[How many]}
+times Generic_Array_Sort calls "<" is address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This implies swapping the elements, usually
+  including an intermediate copy. This of course means that the elements will 
be
+  copied. Since the elements are nonlimited, this usually will not be a 
problem.
+  Note that there is Implementation Advice below that the implementation should
+  use a sort that minimizes copying of elements.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The sort is not required to be stable (and the 
fast
+  algorithm required will not be stable). If a stable sort is needed, the user
+  can include the original location of the element as an extra "sort key". We
+  considered requiring the implementation to do that, but it is mostly extra
+  overhead -- usually there is something already in the element that provides 
the
+  needed stability.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+procedure address@hidden@address@hidden has the following
+declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key{type} Index_Type @key{is} (<>);
+   @key{type} Element_Type @key{is private};
+   @key{type} Array_Type @key{is array} (Index_Type) @key{of} Element_Type;
+   @key{with function} "<" (Left, Right : Element_Type)
+      @key{return} Boolean @key{is} <>;
address@hidden address@hidden,Child=[Generic_Constrained_Array_Sort]}
+      (Container : @key{in out} Array_Type);
address@hidden Pure(Ada.Containers.Generic_Constrained_Array_Sort);]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Reorders the elements of Container such that the
+elements are sorted smallest first as determined by the generic formal "<"
+operator provided. Any exception raised during evaluation of "<" is
+propagated.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0044-1],ARef=[AI05-0262-1]}
address@hidden,Text=[The actual function for the generic formal function
+"<" of Generic_Constrained_Array_Sort is expected to return the same value each
+time it is called with a particular pair of element values. It should define a
+strict @Chg{Version=[3],New=[weak ],Old=[]}ordering address@hidden,
+New=[ (see @RefSecNum{Containers})],Old=[, that is, be irreflexive, asymmetric,
+and transitive]}; it should not modify Container. If the actual for "<" 
behaves in
+some other manner, the behavior of the instance of
+Generic_Constrained_Array_Sort is unspecified. @Chg{Version=[3],New=[The number
+of],Old=[How many]} times Generic_Constrained_Array_Sort calls "<" is
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+procedure address@hidden@!Sort has the following declaration:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0056-1]}
address@hidden,address@hidden
+   @key{type} Index_Type @key{is} (<>);
+   @key{with function} Before (Left, Right : Index_Type) @key{return} Boolean;
+   @key{with procedure} Swap (Left, Right : @Chg{Version=[4],address@hidden 
],Old=[]}Index_Type);
address@hidden address@hidden,Child=[Generic_Sort]}
+      (First, Last : Index_Type'Base);
address@hidden Pure(Ada.Containers.Generic_Sort);]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0248-1]}
address@hidden,Text=[Reorders the elements of an indexable structure,
+over the range First .. Last, such that the elements are sorted in the ordering
+determined by the generic formal function Before; Before should return True if
+Left is to be sorted before Right. The generic formal Before
+compares the elements having the given indices, and the generic formal Swap
+exchanges the values of the indicated elements. Any exception raised during
+evaluation of Before or Swap is propagated.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The actual function for the generic formal function Before 
of
+Generic_Sort is expected to return the same value each time it is
+called with index values that identify a particular pair of element values.
+It should define a strict weak ordering relationship (see 
@RefSecNum{Containers});
+it should not modify the elements. The actual function for the generic formal
+Swap should exchange the values of the indicated elements. If the actual for
+either Before or Swap behaves in some other manner, the behavior of
+Generic_Sort is unspecified. The number of times the Generic_Sort calls Before
+or Swap is address@hidden
+
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[
+The worst-case time complexity of a call on an instance of
+Containers.Generic_Array_Sort or
+Containers.Generic_Constrained_Array_Sort should be @i{O}(@i<N>**2) or better,
+and the average time complexity should be better
+than @i{O}(@i<N>**2), where @i<N> is the length of the Container parameter.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Containers.Generic_Array_Sort and 
Containers.Generic_Constrained_Array_Sort
+should have an average time complexity better than @i{O}(@i{N}**2) and worst 
case no
+worse than @i{O}(@i{N}**2).]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[In other words, we're requiring the use of
+  a sorting algorithm better than @i{O}(@i<N>**2), such as Quicksort. No bubble
+  sorts allowed!]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[
+Containers.Generic_Array_Sort and Containers.Generic_Constrained_Array_Sort
+should minimize copying of elements.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Containers.Generic_Array_Sort and 
Containers.Generic_Constrained_Array_Sort
+should minimize copying of elements.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We do not mean @lquotes@;absolutely 
address@hidden@;
+  here; we're not intending to require a single copy for each element. Rather,
+  we want to suggest that the sorting algorithm chosen is one that does not
+  copy items unnecessarily. Bubble sort would not meet this advice, for
+  instance.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0248-1]}
address@hidden,Text=[
+The worst-case time complexity of a call on an instance of
+Containers.Generic_Sort should be @i{O}(@i<N>**2) or better,
+and the average time complexity should be better
+than @i{O}(@i<N>**2), where @i<N> is the difference between the Last and First
+parameters plus 1.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Containers.Generic_Sort
+should have an average time complexity better than @i{O}(@i{N}**2) and worst 
case no
+worse than @i{O}(@i{N}**2).]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0248-1]}
address@hidden,Text=[Containers.Generic_Sort
+should minimize calls to the generic formal Swap.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Containers.Generic_Sort should minimize calls to the generic formal 
Swap.]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The generic procedures Containers.Generic_Array_Sort and
+  Containers.Generic_Constrained_Array_Sort are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0248-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005} The generic
+  procedure Containers.Generic_Sort is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0044-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Redefined "<" actuals
+  to require a strict weak ordering; the old definition allowed
+  indeterminant comparisons that would not have worked in a sort.]}
address@hidden
+
+
+
address@hidden,Name=[The Generic Package 
Containers.Synchronized_Queue_Interfaces]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Synchronized_Queue_Interfaces provides interface type Queue, and a
+set of operations for that type. Interface Queue specifies a first-in, 
first-out
+queue.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+package Containers.Synchronized_Queue_Interfaces has the following 
declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key[type] Element_Type @key[is private];
address@hidden Ada.Containers.Synchronized_Queue_Interfaces 
@address@hidden,Child=[Synchronized_Queue_Interfaces]}
+   @key[pragma] Pure(Synchronized_Queue_Interfaces);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Queue} @key[is synchronized 
interface];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Enqueue}
+     (Container : @key[in out] Queue;
+      New_Item  : @key[in]     Element_Type) @key[is abstract]
+       @key[with] Synchronization => By_Entry;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Dequeue}
+     (Container : @key[in out] Queue;
+      Element   :    @key[out] Element_Type) @key[is abstract]
+       @key[with] Synchronization => By_Entry;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Current_Use} (Container : 
Queue) @key[return] Count_Type @key[is abstract];
+   @key[function] @AdaSubDefn{Peak_Use} (Container : Queue) @key[return] 
Count_Type @key[is abstract];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Synchronized_Queue_Interfaces;]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Enqueue
+  (Container : @key[in out] Queue;
+   New_Item  : @key[in]     Element_Type) @key[is abstract];]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1],ARef=[AI05-0262-1],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[A queue type that implements this
+interface is allowed to have a bounded 
@i<capacity>@Defn2{Term=[capacity],Sec=[of a queue]}.
+If the queue object has a bounded
+capacity, and the number of existing elements equals the capacity, then Enqueue
+blocks until storage becomes available; otherwise, Enqueue does not block. In 
any
+case, it then copies New_Item onto the queue.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Dequeue
+  (Container : @key[in out] Queue;
+   Element   :    @key[out] Element_Type) @key[is abstract];]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1],ARef=[AI05-0251-1]}
address@hidden,Type=[Trailing],Text=[If the queue is empty, then Dequeue
+blocks until an item becomes available. In any case, it then assigns the
+element at the head of the queue to Element, and removes it from the queue.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Current_Use (Container : Queue) 
@key[return] Count_Type @key[is abstract];]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Type=[Trailing],Text=[Returns the number of elements
+currently in the queue.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Peak_Use (Container : Queue) 
@key[return] Count_Type @key[is abstract];]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Type=[Trailing],Text=[Returns the maximum number of
+elements that have been in the queue at any one time.]}
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0251-1]}
address@hidden,Text=[Unlike other language-defined containers, there are
+no queues whose element types are indefinite. Elements of an indefinite type 
can
+be handled by defining the element of the queue to be a holder container (see
address@hidden Generic Package Containers.Indefinite_Holders}) of the indefinite
+type, or to be an explicit access type that designates the indefinite type.]}
+
+  @begin{Reason}
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[There are no indefinite queues, as a useful
+  definition for Dequeue is not possible. Dequeue cannot be a function, as Ada
+  does not have entries that are functions (thus conditional and timed calls
+  would not be possible). Moreover, protected functions do not allow modifying
+  the queue object (thus it doesn't work even if we decided we didn't care 
about
+  conditional and timed calls). If Dequeue is an entry, then the dequeued 
object
+  would have to be an @key[out] parameter and that would require the queue 
client to
+  guess the tag and constraints of the value that will be dequeued (otherwise
+  Constraint_Error would be raised), and that is rarely going to be possible.]}
+  @end{Reason}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0159-1],ARef=[AI05-0251-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005} The generic
+  package Containers.Synchronized_Queue_Interfaces is new.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package 
Containers.Unbounded_Synchronized_Queues]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Unbounded_Synchronized_Queues provides type Queue, which implements
+the interface type Containers.Synchronized_Queue_Interfaces.Queue.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden System;
address@hidden Ada.Containers.Synchronized_Queue_Interfaces;
address@hidden
+   @key[with package] Queue_Interfaces @key[is new] 
Ada.Containers.Synchronized_Queue_Interfaces (<>);
+   Default_Ceiling : System.Any_Priority := System.Priority'Last;
address@hidden Ada.Containers.Unbounded_Synchronized_Queues 
@address@hidden,Child=[Unbounded_Synchronized_Queues]}
+   @key[pragma] Preelaborate(Unbounded_Synchronized_Queues);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[package] Implementation @key[is]
+      ... -- @Examcom[not specified by the language]
+   @key[end] Implementation;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[protected type] @AdaTypeDefn{Queue}
+        (Ceiling : System.Any_Priority := Default_Ceiling)
+           @key[with] Priority => Ceiling @key[is]
+        @key[new] Queue_Interfaces.Queue @key[with]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key[overriding]
+      @key[entry] @AdaSubDefn{Enqueue} (New_Item : @key[in] 
Queue_Interfaces.Element_Type);
+      @key[overriding]
+      @key[entry] @AdaSubDefn{Dequeue} (Element : @key[out] 
Queue_Interfaces.Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key[overriding]
+      @key[function] @AdaSubDefn{Current_Use} @key[return] Count_Type;
+      @key[overriding]
+      @key[function] @AdaSubDefn{Peak_Use} @key[return] Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[private]
+      ... -- @Examcom[not specified by the language]
+   @key[end] Queue;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ... -- @Examcom[not specified by the language]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Unbounded_Synchronized_Queues;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Text=[The type Queue is used to represent task-safe
+queues.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Text=[The capacity for instances of type Queue is
+unbounded.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Enqueue never blocks; if more storage is needed
+  for a new element, it is allocated dynamically. We don't need to explicitly
+  specify that Queue needs finalization, because it is visibly protected.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Nested package Implementation can be used to
+  declare the types needed to implement the protected type Queue. This
+  nested package is necessary as types cannot be declared in the private
+  part of a protected type, and the types have to be declared within the
+  generic unit in order to depend on the types imported with package
+  Queue_Interfaces. Clients should never depend on the contents of
+  nested package Implementation.]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0159-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005} The generic
+  package Containers.Unbounded_Synchronized_Queues is new.]}
address@hidden
+
+
+
address@hidden,Name=[The Generic Package 
Containers.Bounded_Synchronized_Queues]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Bounded_Synchronized_Queues provides type Queue, which implements
+the interface type Containers.Synchronized_Queue_Interfaces.Queue.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden System;
address@hidden Ada.Containers.Synchronized_Queue_Interfaces;
address@hidden
+   @key[with package] Queue_Interfaces @key[is new] 
Ada.Containers.Synchronized_Queue_Interfaces (<>);
+   Default_Capacity : Count_Type;
+   Default_Ceiling  : System.Any_Priority := System.Priority'Last;
address@hidden Ada.Containers.Bounded_Synchronized_Queues 
@address@hidden,Child=[Bounded_Synchronized_Queues]}
+   @key[pragma] Preelaborate(Bounded_Synchronized_Queues);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[package] Implementation @key[is]
+      ... -- @Examcom[not specified by the language]
+   @key[end] Implementation;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[protected type] @AdaTypeDefn{Queue}
+        (Capacity : Count_Type := Default_Capacity;
+         Ceiling  : System.Any_Priority := Default_Ceiling)
+           @key[with] Priority => Ceiling @key[is]
+        @key[new] Queue_Interfaces.Queue @key[with]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key[overriding]
+      @key[entry] @AdaSubDefn{Enqueue} (New_Item : @key[in] 
Queue_Interfaces.Element_Type);
+      @key[overriding]
+      @key[entry] @AdaSubDefn{Dequeue} (Element : @key[out] 
Queue_Interfaces.Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key[overriding]
+      @key[function] @AdaSubDefn{Current_Use} @key[return] Count_Type;
+      @key[overriding]
+      @key[function] @AdaSubDefn{Peak_Use} @key[return] Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[private]
+      ... -- @Examcom[not specified by the language]
+   @key[end] Queue;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ... -- @Examcom[not specified by the language]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Bounded_Synchronized_Queues;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Keepnext=[T],Type=[Leading],Text=[The semantics are the
+same as for Unbounded_Synchronized_Queues, except:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The capacity for instances of type Queue is
+  bounded and specified by the discriminant Capacity.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Since this type has a bounded capacity, Enqueue
+  might block if the queue is full.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Text=[Bounded queue objects should be implemented without
+implicit pointers or dynamic allocation.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Bounded queue objects should be implemented without
+implicit pointers or dynamic allocation.]}]}
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0159-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005} The generic
+  package Containers.Bounded_Synchronized_Queues is new.]}
address@hidden
+
+
+
address@hidden,Name=[The Generic Package Containers.Unbounded_Priority_Queues]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Unbounded_Priority_Queues provides type Queue, which implements
+the interface type Containers.Synchronized_Queue_Interfaces.Queue.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden System;
address@hidden Ada.Containers.Synchronized_Queue_Interfaces;
address@hidden
+   @key[with package] Queue_Interfaces @key[is new] 
Ada.Containers.Synchronized_Queue_Interfaces (<>);
+   @key[type] Queue_Priority @key[is private];
+   @key[with] @key[function] Get_Priority
+     (Element : Queue_Interfaces.Element_Type) @key[return] Queue_Priority 
@key[is] <>;
+   @key[with] @key[function] Before
+     (Left, Right : Queue_Priority) @key[return] Boolean @key[is] <>;
+   Default_Ceiling : System.Any_Priority := System.Priority'Last;
address@hidden Ada.Containers.Unbounded_Priority_Queues 
@address@hidden,Child=[Unbounded_Priority_Queues]}
+   @key[pragma] Preelaborate(Unbounded_Priority_Queues);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[package] Implementation @key[is]
+      ... -- @Examcom[not specified by the language]
+   @key[end] Implementation;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[protected type] @AdaTypeDefn{Queue}
+        (Ceiling : System.Any_Priority := Default_Ceiling)
+           @key[with] Priority => Ceiling @key[is]
+        @key[new] Queue_Interfaces.Queue @key[with]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key[overriding]
+      @key[entry] @AdaSubDefn{Enqueue} (New_Item : @key[in] 
Queue_Interfaces.Element_Type);
+      @key[overriding]
+      @key[entry] @AdaSubDefn{Dequeue} (Element : @key[out] 
Queue_Interfaces.Element_Type);]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1],ARef=[AI05-0251-1]}
address@hidden,Text=[      @key[not overriding]
+      @key[procedure] @AdaSubDefn{Dequeue_Only_High_Priority}
+        (At_Least : @key[in]     Queue_Priority;
+         Element  : @key[in out] Queue_Interfaces.Element_Type;
+         Success  :    @key[out] Boolean);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key[overriding]
+      @key[function] @AdaSubDefn{Current_Use} @key[return] Count_Type;
+      @key[overriding]
+      @key[function] @AdaSubDefn{Peak_Use} @key[return] Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[private]
+      ... -- @Examcom[not specified by the language]
+   @key[end] Queue;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ... -- @Examcom[not specified by the language]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Unbounded_Priority_Queues;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Text=[The type Queue is used to represent task-safe
+priority queues.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Text=[The capacity for instances of type Queue is
+unbounded.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Text=[Two elements @i<E1> and @i<E2> are equivalent if
+Before(Get_Priority(@i<E1>), Get_Priority(@i<E2>)) and
+Before(Get_Priority(@i<E2>), Get_Priority(@i<E1>)) both return False.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1],ARef=[AI05-0248-1]}
address@hidden,Text=[The actual functions for Get_Priority and Before are
+expected to return the same value each time they are called with the same
+actuals, and should not modify their actuals. Before should define a strict 
weak
+ordering relationship (see @RefSecNum{Containers}). If the actual
+functions behave in some other manner, the behavior of 
Unbounded_Priority_Queues
+is unspecified.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Text=[Enqueue inserts an item according to the order
+specified by the Before function on the result of Get_Priority on the elements;
+Before should return True if Left is to be inserted before Right.
+If the queue already contains elements equivalent to New_Item, then it is
+inserted after the existing equivalent elements.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Enqueue never blocks; if more storage is needed
+  for a new element, it is allocated dynamically. We don't need to explicitly
+  specify that Queue needs finalization, because it is visibly protected.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1],ARef=[AI05-0251-1],ARef=[AI05-0262-1]}
address@hidden,Text=[For a call on Dequeue_Only_High_Priority, if the
+head of the nonempty queue is @i<E>, and the function Before(At_Least,
+Get_Priority(@i<E>)) returns False, then @i<E> is assigned to
+Element and then removed from the queue, and Success is set to True;
+otherwise, Success is set to False and Element is unchanged.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0251-1]}
+  @ChgAdded{Version=[3],Text=[Unlike Dequeue, Dequeue_Only_High_Priority is not
+  blocking; it always returns immediately.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0251-1]}
+  @ChgAdded{Version=[3],Text=[The use of Before is "backwards" so that it acts
+  like ">=" (it is defined similarly to ">"); thus we dequeue only when it is
+  False.]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0159-1],ARef=[AI05-0251-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005} The generic
+  package Containers.Unbounded_Priority_Queues is new.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Bounded_Priority_Queues]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Text=[The language-defined generic package
+Containers.Bounded_Priority_Queues provides type Queue, which implements
+the interface type Containers.Synchronized_Queue_Interfaces.Queue.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden System;
address@hidden Ada.Containers.Synchronized_Queue_Interfaces;
address@hidden
+   @key[with package] Queue_Interfaces @key[is new] 
Ada.Containers.Synchronized_Queue_Interfaces (<>);
+   @key[type] Queue_Priority @key[is private];
+   @key[with function] Get_Priority
+     (Element : Queue_Interfaces.Element_Type) @key[return] Queue_Priority 
@key[is] <>;
+   @key[with function] Before
+     (Left, Right : Queue_Priority) @key[return] Boolean @key[is] <>;
+   Default_Capacity : Count_Type;
+   Default_Ceiling  : System.Any_Priority := System.Priority'Last;
address@hidden Ada.Containers.Bounded_Priority_Queues 
@address@hidden,Child=[Bounded_Priority_Queues]}
+   @key[pragma] Preelaborate(Bounded_Priority_Queues);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[package] Implementation @key[is]
+      ... -- @Examcom[not specified by the language]
+   @key[end] Implementation;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[protected type] @AdaTypeDefn{Queue}
+        (Capacity : Count_Type := Default_Capacity;
+         Ceiling  : System.Any_Priority := Default_Ceiling)
+           @key[with] Priority => Ceiling @key[is]
+      @key[new] Queue_Interfaces.Queue @key[with]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key[overriding]
+      @key[entry] @AdaSubDefn{Enqueue} (New_Item : @key[in] 
Queue_Interfaces.Element_Type);
+      @key[overriding]
+      @key[entry] @AdaSubDefn{Dequeue} (Element : @key[out] 
Queue_Interfaces.Element_Type);]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1],ARef=[AI05-0251-1]}
address@hidden,Text=[      @key[not overriding]
+      @key[procedure] @AdaSubDefn{Dequeue_Only_High_Priority}
+        (At_Least : @key[in]     Queue_Priority;
+         Element  : @key[in out] Queue_Interfaces.Element_Type;
+         Success  :    @key[out] Boolean);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key[overriding]
+      @key[function] @AdaSubDefn{Current_Use} @key[return] Count_Type;
+      @key[overriding]
+      @key[function] @AdaSubDefn{Peak_Use} @key[return] Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[private]
+      ... -- @Examcom[not specified by the language]
+   @key[end] Queue;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ... -- @Examcom[not specified by the language]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Bounded_Priority_Queues;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Keepnext=[T],Type=[Leading],Text=[The semantics are the
+same as for Unbounded_Priority_Queues, except:]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The capacity for instances of type Queue is
+  bounded and specified by the discriminant Capacity.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Since this type has a bounded capacity, Enqueue
+  might block if the queue is full.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0159-1]}
address@hidden,Text=[Bounded priority queue objects should be implemented 
without
+implicit pointers or dynamic allocation.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Bounded priority queue objects should be implemented without
+implicit pointers or dynamic allocation.]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0159-1],ARef=[AI05-0251-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005} The generic
+  package Containers.Bounded_Priority_Queues is new.]}
address@hidden
+
+
address@hidden,Name=[Example of Container Use]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Text=[The following example is an implementation of
+Dijkstra's shortest path algorithm in a directed graph with positive distances.
+The graph is represented by a map from nodes to sets of edges.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Vectors;
address@hidden Ada.Containers.Doubly_Linked_Lists;
address@hidden Ada.Containers;
address@hidden
+   @key[type] Node @key[is range] <>;
address@hidden Shortest_Paths @key[is]
+   @key[type] Distance @key[is new] Float @key[range] 0.0 .. Float'Last;
+   @key[type] Edge @key[is record]
+      To, From : Node;
+      Length   : Distance;
+   @key[end record];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[package] Node_Maps @key[is new] Vectors (Node, 
Node);
+   -- @Examcom{The algorithm builds a map to indicate the node used to reach a 
given}
+   -- @Examcom{node in the shortest distance.}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[package] Adjacency_Lists @key[is new] 
Doubly_Linked_Lists (Edge);
+   @key[use] Adjacency_Lists;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[package] Graphs @key[is new] Vectors (Node, 
Adjacency_Lists.List);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[package] Paths @key[is new] Doubly_Linked_Lists 
(Node);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] Shortest_Path
+     (G : Graphs.Vector; Source : Node; Target : Node) @key[return] Paths.List
+      @key[with] Pre => G (Source) /= Adjacency_Lists.Empty_List;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Shortest_Paths;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden body] Shortest_Paths @key[is]
+   @key[function] Shortest_Path
+     (G : Graphs.Vector; Source : Node; Target : Node) @key[return] Paths.List
+   @key[is]
+      @key[use] Adjacency_Lists, Node_Maps, Paths, Graphs;
+      Reached  : @key[array] (Node) @key[of] Boolean := (@key[others] => 
False);
+      -- @ExamCom{The set of nodes whose shortest distance to the source is 
known.}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0299-1]}
address@hidden,Text=[      Reached_From : @key[array] (Node) @key[of] Node;
+      So_Far   : @key[array] (Node) @key[of] Distance := (@key[others] => 
Distance'Last);
+      The_Path : Paths.List := Paths.Empty_List;
+      Nearest_Distance : Distance;
+      Next     : Node;
+   @key[begin]
+      So_Far(Source)  := 0.0;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key[while not] Reached(Target) @key[loop]
+         Nearest_Distance := Distance'Last;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[         -- @Examcom{Find closest node not reached yet, by 
iterating over all nodes.}
+         -- @Examcom{A more efficient algorithm uses a priority queue for this 
step.}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[         Next := Source;
+         @key[for] N @key[in] Node'First .. Node'Last @key[loop]
+            @key[if not] Reached(N)
+              @key[and then] So_Far(N) < Nearest_Distance @key[then]
+                 Next := N;
+                 Nearest_Distance := So_Far(N);
+            @key[end if];
+         @key[end loop];]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0299-1]}
address@hidden,Text=[         @key[if] Nearest_Distance = Distance'Last 
@key[then]
+            -- @Examcom{No next node found, graph is not connected}
+            @key[return] Paths.Empty_List;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[         @key[else]
+            Reached(Next) := True;
+         @key[end if];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[         -- @ExamCom{Update minimum distance to newly 
reachable nodes.}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0299-1]}
address@hidden,Text=[         @key[for] E @key[of] G (Next) @key[loop]
+            @key[if not] Reached(E.To) @key[then]
+               Nearest_Distance := E.Length + So_Far(Next);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[               @key[if] Nearest_Distance < So_Far(E.To) 
@key[then]
+                  Reached_From(E.To) := Next;
+                  So_Far(E.To) := Nearest_Distance;
+               @key[end if];
+            @key[end if];
+         @key[end loop];
+      @key[end loop];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      -- @ExamCom{Rebuild path from target to source.}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key[declare]
+         N : Node := Target;
+      @key[begin]
+         @key[while] N /= Source @key[loop]
+            N := Reached_From(N);
+            Prepend (The_Path, N);
+         @key[end loop];
+      @key[end];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key[return] The_Path;
+   @key[end];
address@hidden Shortest_Paths;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Type=[Leading],Text=[Note that the effect of the
+Constant_Indexing aspect (on type Vector) and the Implicit_Dereference aspect
+(on type Reference_Type) is that]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[G (Next)]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Type=[Leading],Text=[is a convenient short hand for]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[G.Constant_Reference (Next)address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[Similarly, the effect of the 
loop:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden E @key[of] G (Next) @key[loop]
+   @key[if not] Reached(E.To) @key[then]
+      ...
+   @key[end if];
address@hidden loop];]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[is the same as:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0080-1]}
address@hidden,address@hidden C @key[in] G (Next).Iterate @key[loop]
+   @key[declare]
+      E : Edge @key[renames] G (Next)(C)@Chg{Version=[4],New=[],address@hidden;
+   @key[begin]
+      @key[if not] Reached(E.To) @key[then]
+         ...
+      @key[end if];
+   @key[end];
address@hidden loop];]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0212-1]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[which is the same as:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0080-1]}
address@hidden,address@hidden
+   L : Adjacency_Lists.List @key[renames] G (Next);
+   C : Adjacency_Lists.Cursor := L.First;
address@hidden
+   @key[while] Has_Element (C) @key[loop]
+      @key[declare]
+         E : Edge @key[renames] L(C)@Chg{Version=[4],New=[],address@hidden;
+      @key[begin]
+         @key[if not] Reached(E.To) @key[then]
+            ...
+         @key[end if];
+      @key[end];
+      C := L.Next (C);
+   @key[end loop];
address@hidden;]}
+
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],Text=[This example of container use is new.]}
address@hidden
+
+
+
diff --git a/packages/ada-ref-man/source_2012/pre_containers.mss 
b/packages/ada-ref-man/source_2012/pre_containers.mss
new file mode 100755
index 0000000..1035c15
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pre_containers.mss
@@ -0,0 +1,9389 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/pre_containers.mss,v $ }
address@hidden $Revision: 1.99 $ $Date: 2015/04/03 04:12:43 $ $Author: randy $ }
address@hidden(precontainers, Root="ada.mss")
+
address@hidden: 2015/04/03 04:12:43 $}
+
address@hidden
address@hidden,Name=[Containers]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[This clause presents the specifications of the package
+Containers and several child packages, which provide facilities for storing
+collections of elements.]}
+
address@hidden,Kind=[Added],Term=<Container>,
+Text=<@ChgAdded{Version=[3],Text=[A container is an object that contain other
+objects all of the same type, which could be class-wide.
+Several predefined container types are provided by the children
+of package Ada.Containers (see @RefSecNum{The Package Containers}).]}>}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[A variety of sequence and associative containers are
+provided. Each container includes a @i{cursor} type. A cursor is a reference
+to an element within a container. Many operations on cursors are common to
+all of the containers. A cursor referencing
+an element in a container is considered to be overlapping
+with the container object address@hidden,Sec=[for a container]}
address@hidden,Sec=[cursor]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The last sentence is intended to clarify that
+  operations that just use a cursor are on the same footing as operations that
+  use a container in terms of the reentrancy rules of Annex A.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Within this clause we provide Implementation Advice
+for the desired average or worst case time complexity of certain operations
+on a container. This advice is expressed using the Landau symbol @i{O}(X).
+Presuming f is some function of a length parameter N and t(N) is the time the
+operation takes (on average or worst case, as specified) for the length N, a
+complexity of @i{O}(f(N)) means that there exists a finite A such that for any 
N,
+t(N)/f(N) < A. @Defn{Landau symbol @i{O}(X)address@hidden@i{O}(f(N))}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Of course, an implementation can do better than a
+  specified @i{O}(f(N)): for example, @i{O}(1) meets the requirements for
+  @i{O}(log N).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This concept seems to have
+  as many names as there are authors. We used @lquotes@;Landau address@hidden
+  because that's what our reference does. But we'd also seen this referred as
+  big-O address@hidden notation} (sometimes written as @i<big-oh>), and
+  as Bachmann notation. Whatever the name, it always has the above 
definition.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If the advice suggests that the complexity should be
+less than @i{O}(f(N)), then for any arbitrarily small positive real D, there
+should exist a positive integer M such that for all N > M,
+t(N)/f(N) < D.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0044-1]}
address@hidden,Text=[When a formal function is used to provide an
+ordering for a container, it is generally required to define
+a strict weak ordering. A function "<" defines
+a @i<strict weak ordering>@Defn{strict weak ordering} if it is irreflexive,
+asymmetric, transitive, and in addition, if @i<x> < @i<y> for any values
address@hidden<x> and @i<y>, then for all other
+values @i<z>, (@i<x> < @i<z>) or (@i<z> < @i<y>).]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+provides a number of useful containers
+for Ada. Only the most useful containers are provided. Ones that are relatively
+easy to code, redundant, or rarely used are omitted from this set, even if they
+are generally included in containers libraries.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The containers packages are modeled on the Standard 
Template Library (STL), an
+algorithms and data structure library popularized by Alexander Stepanov, and
+included in the C++ standard library. The structure and terminology differ from
+the STL where that better maps to common Ada usage. For instance, what the STL
+calls @lquotes@;address@hidden@; are
+called @lquotes@;address@hidden@; here.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[The following major nonlimited
+containers are provided:]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[(Expandable) Vectors of any nonlimited type;]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Doubly-linked Lists of any nonlimited type;]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Hashed Maps keyed by any nonlimited hashable 
type,
+  and containing any nonlimited type;]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Ordered Maps keyed by any nonlimited ordered 
type,
+  and containing any nonlimited type;]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[2],Text=[Hashed Sets of any nonlimited hashable 
type;@Chg{Version=[3],New=[],Old=[ and]}]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[2],Text=[Ordered Sets of any nonlimited ordered 
address@hidden,New=[;],Old=[.]}]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0136-1]}
+  @ChgAdded{Version=[3],Text=[Multiway Trees of any nonlimited type;]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0069-1]}
+  @ChgAdded{Version=[3],Text=[Holders of any (indefinite) nonlimited type;]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0159-1]}
+  @ChgAdded{Version=[3],Text=[Synchronized queues of any definite nonlimited 
type; and]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0159-1]}
+  @ChgAdded{Version=[3],Text=[Priority queues of any definite nonlimited 
type.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0001-1]}
address@hidden,Text=[Separate versions for definite and indefinite
+element types are provided, as those for definite types can be implemented more
address@hidden,New=[ Similarly, a separate bounded version is
+provided in order to give more predictable memory usage.],Old=[]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Each container includes a cursor, which is a
+reference to an element within a container. Cursors generally remain valid as
+long as the container exists and the element referenced is not deleted. Many
+operations on cursors are common to all of the containers. This makes it
+possible to write generic algorithms that work on any kind of container.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The containers packages are structured so that
+additional packages can be added in the future. Indeed, we hope that these
+packages provide the basis for a more extensive secondary standard for
+containers.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If containers with similar functionality (but
+different performance characteristics) are provided (by the implementation or
+by a secondary standard), we suggest that a prefix be used to identify the
+class of the functionality: "Ada.Containers.Bounded_Sets" (for a set with a
+maximum number of elements); "Ada.Containers.Protected_Maps" (for a map which
+can be accessed by multiple tasks at one time);
+"Ada.Containers.Persistent_Vectors" (for a persistent vector which continues to
+exist between executions of a program) and so on.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[Note that the language already
+includes several requirements that are important to the use of containers.
+These include:]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Library packages must be
+  reentrant @en multiple tasks can use the packages as long as they operate on
+  separate containers. Thus, it is only necessary for a user to protect a
+  container if a single container needs to be used by multiple tasks.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Language-defined types must stream "properly".
+  That means that the stream attributes can be used to implement persistence
+  of containers when necessary, and containers can be passed between
+  partitions of a program.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Equality of language-defined types must compose
+  @lquotes@;address@hidden@;. This means that the version of "=" directly
+  used by users is the same one that will be used in generics and in predefined
+  equality operators of types with components of the containers and/or cursors.
+  This prevents the abstraction from breaking unexpectedly.]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0048-1]}
+  @ChgAdded{Version=[3],Text=[Redispatching is not allowed (unless it is
+  required). That means that overriding a container operation will not change
+  the behavior of any other predefined container operation. This provides
+  a stable base for extensions.]}
address@hidden
+
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If a container's element type is controlled, the
+point at which the element is finalized will depend on the implementation of
+the container. We do not specify precisely where this will happen (it will
+happen no later than the finalization of the container, of course) in order to
+give implementation's flexibility to cache, block, or split the nodes of the
+container. In particular, Delete does not necessarily finalize the element; the
+implementation may (or may not) hold the space for reuse.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This is not likely to be a hardship, as the element
+type has to be nonlimited. Types used to manage scarce resources generally
+need to be limited. Otherwise, the amount of resources needed is hard to
+control, as the language allows a lot of variation in the number or order of
+adjusts/finalizations. For common uses of nonlimited controlled types such as
+managing storage, the types already have to manage arbitrary copies.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The use of controlled types also brings up the
+possibility of failure of finalization (and thus deallocation) of an element.
+This is a @ldquote@;serious address@hidden@;, as AI95-179 puts it, so we don't 
try
+to specify what happens in that case. The implementation should propagate
+the exception.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[It is expected that exceptions propagated from
+these operations do not
+damage containers. That is, if Storage_Error is propagated because of an
+allocation failure, or Constraint_Error is propagated by the assignment of
+elements, the container can continue to be used without further exceptions.
+The intent is that it should be possible to recover from errors without
+losing data. We don't try to state this formally in most cases, because it is
+hard to define precisely what is and is not allowed behavior.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[When this clause says that the behavior of
+something is address@hidden, we
+really mean that any result of executing Ada code short of erroneous
+execution is allowed. We do not mean that memory not belonging to the
+parameters of the operation can be trashed. When we mean to allow erroneous
+behavior, we specifically say that execution is erroneous. All this means
+if the containers are written in Ada is that checks should not be suppressed
+or removed assuming some behavior of other code, and that the implementation
+should take care to avoid creating internal dangling accesses by assuming
+behavior from generic formals that can't be guaranteed. We don't
+try to say this normatively because it would be fairly complex, and
+implementers are unlikely to increase their support costs by fielding
+implementations that are unstable if given buggy hash functions, et al.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI12-0035-1]}
address@hidden,Text=[Certain subprograms declared within instances of
+some of the generic packages presented in this clause are said to @i<perform
+indefinite insertion>. These subprograms are those corresponding (in the sense
+of the copying described in subclause @RefSecNum{Generic Instantiation}) to
+subprograms that have formal parameters of a generic formal indefinite type and
+that are identified as performing indefinite insertion in the subclause 
defining
+the generic address@hidden indefinite insertion}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0035-1]}
address@hidden,Type=[Leading],Text=[If a subprogram performs indefinite
+insertion, then certain run-time checks are performed as part of a call to the
+subprogram; if any of these checks fail, then the resulting exception is
+propagated to the caller and the container is not modified by the call. These
+checks are performed for each parameter corresponding (in the sense of the
+copying described in @RefSecNum{Generic Instantiation}) to a parameter in the
+corresponding generic whose type is a generic formal indefinite type. The 
checks
+performed for a given parameter are those checks explicitly specified in
+subclause @RefSecNum{Allocators} that would be performed as part of the
+evaluation of an initialized allocator whose access type is declared 
immediately
+within the instance, where:]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[the value of the @nt{qualified_expression} is
+  that of the parameter; and]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[the designated subtype of the access type is the
+  subtype of the parameter; and]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[finalization of the collection of the access type
+  has started if and only if the finalization of the instance has started.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[The phrase "explicitly specified" means those
+  checks for which subclause @RefSecNum{Allocators} includes the phrase "<some
+  exception> is raised if ...". It does not refer, for example, to any checks
+  performed as part of any subtype conversion. In particular, this wording
+  includes the checks described in subclause @RefSecNum{Allocators} to be
+  performed in the case of a class-wide designated type, and of a designated
+  subtype that has access discriminant parts. These checks are needed to 
prevent
+  containers from outliving their contained (Element_Type or Key_Type) 
values.]}
address@hidden
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[These rules have a dual purpose. Mainly, we are
+  @i{requiring} checks needed to prevent dangling references. As a side 
effect, we
+  are also @i{allowing} checks needed to permit an implementation of a 
container
+  generic to make use of access types in a straightforward way. As an example 
of
+  the second purpose, suppose that an implementation does declare such an 
access
+  type and suppose further that the finalization of the collection of the
+  access type has started. These rules allow Program_Error to be propagated
+  in this case (as specified in @RefSecNum{Allocators}); this is necessary to
+  allow an all-Ada implementation of these packages.]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  This @Chg{Version=[3],New=[subclause],Old=[clause]} is new. It just
+  provides an introduction to the following subclauses.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0044-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a definition of
+  strict weak ordering.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0035-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Added a definition of
+  @ldquote@;performs indefinite address@hidden This is used in
+  other subclauses and any resulting inconsistencies are documented
+  there.]}
address@hidden
+
+
address@hidden,Name=[The Package Containers]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The package Containers is the root of
+the containers subsystem.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library package
+Containers has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers @address@hidden,Child=[Containers]}
+   @key{pragma} Pure(Containers);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Hash_Type} @key{is mod} 
@i<implementation-defined>;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Count_Type} @key{is range} 0 .. 
@i<implementation-defined>;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Text=[   @AdaExcDefn{Capacity_Error} : @key[exception];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Hash_Type represents the range of the result of a
+hash function. Count_Type represents the (potential or actual) number of
+elements of a container.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The value of Containers.Hash_Type'Modulus. The value of
+Containers.Count_Type'Last.]}]}
+
address@hidden,Kind=[Added],ARef=[AI05-0262-1]}
address@hidden,Text=[Capacity_Error is raised when the capacity of a
+container is exceeded.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Hash_Type'Modulus should be at least 2**32.
+Count_Type'Last should be at least address@hidden@;1.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Containers.Hash_Type'Modulus should be at least 2**32.
+Containers.Count_Type'Last should be at least address@hidden@;1.]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This is not a requirement so that these types
+can be declared
+properly on machines with native sizes that are not 32 bits. For instance, a
+24-bit target could use 2**24 for Hash_Type'Modulus.]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The package Containers is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}Exception Capacity_Error
+  is added to Containers. If Containers is referenced in a @nt{use_clause},
+  and an entity with the name Capacity_Error is defined in a package that is
+  also referenced in a @nt{use_clause}, the entity Capacity_Error may no
+  longer be use-visible, resulting in errors. This should be rare and is
+  easily fixed if it does occur.]}
address@hidden
+
+
+
address@hidden,Name=[The Generic Package Containers.Vectors]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The language-defined generic package
+Containers.Vectors provides private types Vector and Cursor, and a set of
+operations for each type. A vector container allows insertion and deletion at
+any position, but it is specifically optimized for insertion and deletion at
+the high end (the end with the higher index) of the container. A vector
+container also provides random access to its address@hidden container}
address@hidden,Sec=[vector]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden, Sec=(of a vector container)}
address@hidden, Sec=(of a vector)}
+A vector container behaves conceptually as an array that expands as necessary
+as items are inserted. The @i{length} of a vector is the number of elements 
that
+the vector contains. The @i{capacity} of a vector is the maximum number of
+elements that can be inserted into the vector prior to it being automatically
+expanded.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Elements in a vector container can be referred to by
+an index value of a generic formal type. The first element of a vector always
+has its index value equal to the lower bound of the formal type.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden element], Sec=(of a vector)}
+A vector container may contain @i{empty elements}. Empty elements do not have a
+specified value.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[
+Vectors are not intended to be sparse (that is, there are elements at all
+defined positions). Users are expected to use other containers (like a Map)
+when they need sparse structures (there is a Note to this effect at the
+end of this subclause).]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[
+The internal array is a conceptual model of a vector. There is no requirement
+for an implementation to be a single contiguous array.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+package Containers.Vectors has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0084-1],ARef=[AI05-0212-1]}
address@hidden,address@hidden,address@hidden Ada.Iterator_Interfaces;
+],address@hidden
+   @key{type} Index_Type @key{is range} <>;
+   @key{type} Element_Type @key{is private};
+   @key{with function} "=" (Left, Right : Element_Type)
+      @key{return} Boolean @key{is} <>;
address@hidden Ada.Containers.Vectors @address@hidden,Child=[Vectors]}
+   @key{pragma} Preelaborate(Vectors);@Chg{Version=[3],New=[
+   @key{pragma} Remote_Types(Vectors);],Old=[]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{subtype} 
@AdaSubtypeDefn{Name=[Extended_Index],Of=[Index_Type'Base]} @key{is}
+      Index_Type'Base @key{range}
+         Index_Type'First-1 ..
+         Index_Type'Min (Index_Type'Base'Last - 1, Index_Type'Last) + 1;
+   @AdaObjDefn{No_Index} : @key{constant} Extended_Index := 
Extended_Index'First;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Vector} @key{is tagged 
address@hidden,New=[
+      @key[with] Constant_Indexing => Constant_Reference,
+           Variable_Indexing => Reference,
+           Default_Iterator  => Iterate,
+           Iterator_Element  => Element_Type],Old=[]};
+   @key{pragma} Preelaborable_Initialization(Vector);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Cursor} @key{is private};
+   @key{pragma} Preelaborable_Initialization(Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{Empty_Vector} : @key{constant} Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{No_Element} : @key{constant} Cursor;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Has_Element} (Position : 
Cursor) @key{return} Boolean;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[package] @AdaPackDefn{Vector_Iterator_Interfaces} 
@key[is new]
+       Ada.Iterator_Interfaces (Cursor, Has_Element);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "=" (Left, Right : Vector) @key{return} 
Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{To_Vector} (Length : 
Count_Type) @key{return} Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{To_Vector}
+     (New_Item : Element_Type;
+      Length   : Count_Type) @key{return} Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "&" (Left, Right : Vector) @key{return} 
Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "&" (Left  : Vector;
+                 Right : Element_Type) @key{return} Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "&" (Left  : Element_Type;
+                 Right : Vector) @key{return} Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "&" (Left, Right  : Element_Type) 
@key{return} Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Capacity} (Container : 
Vector) @key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Reserve_Capacity} 
(Container : @key{in out} Vector;
+                               Capacity  : @key{in}     Count_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Length} (Container : Vector) 
@key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Set_Length} (Container : 
@key{in out} Vector;
+                         Length    : @key{in}     Count_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Empty} (Container : 
Vector) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Clear} (Container : @key{in 
out} Vector);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{To_Cursor} (Container : 
Vector;
+                       Index     : Extended_Index) @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{To_Index} (Position  : 
Cursor) @key{return} Extended_Index;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Element} (Container : Vector;
+                     Index     : Index_Type)
+      @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Element} (Position : Cursor) 
@key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Replace_Element} (Container 
: @key{in out} Vector;
+                              Index     : @key{in}     Index_Type;
+                              New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Replace_Element} (Container 
: @key{in out} Vector;
+                              Position  : @key{in}     Cursor;
+                              New_item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Query_Element}
+     (Container : @key{in} Vector;
+      Index     : @key{in} Index_Type;
+      Process   : @key{not null access procedure} (Element : @key{in} 
Element_Type));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Query_Element}
+     (Position : @key{in} Cursor;
+      Process  : @key{not null access procedure} (Element : @key{in} 
Element_Type));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Update_Element}
+     (Container : @key{in out} Vector;
+      Index     : @key{in}     Index_Type;
+      Process   : @key{not null access procedure}
+                      (Element : @key{in out} Element_Type));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Update_Element}
+     (Container : @key{in out} Vector;
+      Position  : @key{in}     Cursor;
+      Process   : @key{not null access procedure}
+                      (Element : @key{in out} Element_Type));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] Constant_Reference_Type
+         (Element : @key[not null access constant] Element_Type) @key[is 
private]
+      @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Reference_Type} (Element : 
@key[not null access] Element_Type) @key[is private]
+      @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Constant_Reference} 
(Container : @key[aliased in] Vector;
+                                Index     : @key[in] Index_Type)
+      @key[return] Constant_Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Reference} (Container : 
@key[aliased in out] Vector;
+                       Index     : @key[in] Index_Type)
+      @key[return] Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Constant_Reference} 
(Container : @key[aliased in] Vector;
+                                Position  : @key[in] Cursor)
+      @key[return] Constant_Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Reference} (Container : 
@key[aliased in out] Vector;
+                       Position  : @key[in] Cursor)
+      @key[return] Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Assign} (Target : @key{in 
out} Vector; Source : @key{in} Vector);]}
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Copy} (Source : Vector; 
Capacity : Count_Type := 0)
+      @key[return] Vector;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Move} (Target : @key{in 
out} Vector;
+                   Source : @key{in out} Vector);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Vector;
+                     Before    : @key{in}     Extended_Index;
+                     New_Item  : @key{in}     Vector);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Vector;
+                     Before    : @key{in}     Cursor;
+                     New_Item  : @key{in}     Vector);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Vector;
+                     Before    : @key{in}     Cursor;
+                     New_Item  : @key{in}     Vector;
+                     Position  :    @key{out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Vector;
+                     Before    : @key{in}     Extended_Index;
+                     New_Item  : @key{in}     Element_Type;
+                     Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Vector;
+                     Before    : @key{in}     Cursor;
+                     New_Item  : @key{in}     Element_Type;
+                     Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Vector;
+                     Before    : @key{in}     Cursor;
+                     New_Item  : @key{in}     Element_Type;
+                     Position  :    @key{out} Cursor;
+                     Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Vector;
+                     Before    : @key{in}     Extended_Index;
+                     Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Vector;
+                     Before    : @key{in}     Cursor;
+                     Position  :    @key{out} Cursor;
+                     Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Prepend} (Container : 
@key{in out} Vector;
+                      New_Item  : @key{in}     Vector);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Prepend} (Container : 
@key{in out} Vector;
+                      New_Item  : @key{in}     Element_Type;
+                      Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Append} (Container : 
@key{in out} Vector;
+                     New_Item  : @key{in}     Vector);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Append} (Container : 
@key{in out} Vector;
+                     New_Item  : @key{in}     Element_Type;
+                     Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert_Space} (Container : 
@key{in out} Vector;
+                           Before    : @key{in}     Extended_Index;
+                           Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert_Space} (Container : 
@key{in out} Vector;
+                           Before    : @key{in}     Cursor;
+                           Position  :    @key{out} Cursor;
+                           Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete} (Container : 
@key{in out} Vector;
+                     Index     : @key{in}     Extended_Index;
+                     Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete} (Container : 
@key{in out} Vector;
+                     Position  : @key{in out} Cursor;
+                     Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_First} (Container : 
@key{in out} Vector;
+                           Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_Last} (Container : 
@key{in out} Vector;
+                          Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Reverse_Elements} 
(Container : @key{in out} Vector);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Swap} (Container : @key{in 
out} Vector;
+                   I, J      : @key{in}     Index_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Swap} (Container : @key{in 
out} Vector;
+                   I, J      : @key{in}     Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First_Index} (Container : 
Vector) @key{return} Index_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First} (Container : Vector) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First_Element} (Container : 
Vector)
+      @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Last_Index} (Container : 
Vector) @key{return} Extended_Index;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Last} (Container : Vector) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Last_Element} (Container : 
Vector)
+      @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Next} (Position : Cursor) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Next} (Position : @key{in 
out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Previous} (Position : 
Cursor) @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Previous} (Position : 
@key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Find_Index} (Container : 
Vector;
+                        Item      : Element_Type;
+                        Index     : Index_Type := Index_Type'First)
+      @key{return} Extended_Index;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Find} (Container : Vector;
+                  Item      : Element_Type;
+                  Position  : Cursor := No_Element)
+      @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Reverse_Find_Index} 
(Container : Vector;
+                                Item      : Element_Type;
+                                Index     : Index_Type := Index_Type'Last)
+      @key{return} Extended_Index;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Reverse_Find} (Container : 
Vector;
+                          Item      : Element_Type;
+                          Position  : Cursor := No_Element)
+      @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Contains} (Container : 
Vector;
+                      Item      : Element_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Deleted],ARef=[AI05-0212-1]}
address@hidden,address@hidden,New=[],Old=[   @key{function} 
@AdaSubDefn{Has_Element} (Position : Cursor) @key{return} Boolean;]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure}  @AdaSubDefn{Iterate}
+     (Container : @key{in} Vector;
+      Process   : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Reverse_Iterate}
+     (Container : @key{in} Vector;
+      Process   : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] Iterate (Container : @key[in] Vector)
+      @key[return] Vector_Iterator_Interfaces.Reversible_Iterator'Class;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] Iterate (Container : @key[in] Vector; 
Start : @key[in] Cursor)
+      @key[return] Vector_Iterator_Interfaces.Reversible_Iterator'Class;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{generic}
+      @key{with function} "<" (Left, Right : Element_Type)
+         @key{return} Boolean is <>;
+   @key{package} @AdaPackDefn{Generic_Sorting} @key{is}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{function} @AdaSubDefn{Is_Sorted} (Container : 
Vector) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{procedure} @AdaSubDefn{Sort} (Container : 
@key{in out} Vector);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{procedure} @AdaSubDefn{Merge} (Target  : 
@key{in out} Vector;
+                       Source  : @key{in out} Vector);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{end} Generic_Sorting;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ... -- @RI[not specified by the language]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Vectors;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The actual function for the generic formal function
+"=" on Element_Type values is expected to define a reflexive and symmetric
+relationship and return the same result value each time it is called with a
+particular pair of values. If it behaves in some other manner, the functions
+defined to use it return an unspecified value. The exact arguments and number
+of calls of this generic formal function by the functions defined to use it are
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The @lquotes@;functions defined to use 
address@hidden
+  are Find, Find_Index, Reverse_Find, Reverse_Find_Index, and
+  "=" for Vectors. This list is a bit too long to give explicitly.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If the actual function for "=" is not symmetric
+  and consistent, the result returned by any of the functions defined to use
+  "=" cannot be predicted. The implementation is not required to protect
+  against "=" raising an exception, or returning random results, or any
+  other @lquotes@;address@hidden behavior. And it can call "=" in whatever
+  manner makes sense. But note that only the results of the functions defined
+  to use "=" are unspecified; other subprograms are not allowed to break if
+  "=" is bad.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The type Vector is used to represent vectors.
+The type Vector needs address@hidden<needs finalization>,
+Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Empty_Vector represents the empty vector object. It
+has a length of 0. If an object of type Vector is not otherwise initialized, it
+is initialized to the same value as Empty_Vector.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[No_Element represents a cursor that designates no
+element. If an object of type Cursor is not otherwise initialized, it is
+initialized to the same value as No_Element.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The predefined "=" operator for type Cursor returns
+True if both cursors are No_Element, or designate the same element in the same
+container.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Execution of the default implementation of the
+Input, Output, Read, or Write attribute of type Cursor raises Program_Error.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[A cursor will probably be implemented in terms
+  of one or more access values, and the effects of streaming access values is
+  unspecified. Rather than letting the user stream junk by accident, we mandate
+  that streaming of cursors raise Program_Error by default. The attributes
+  can always be specified if there is a need to support streaming.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0262-1]}
address@hidden,Text=[Vector'Write for a Vector object @i<V> writes
+Length(@i<V>) elements of the vector to the stream. It also may write
+additional information about the vector.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0262-1]}
address@hidden,Text=[Vector'Read reads the representation of a vector
+from the stream, and assigns to @i<Item> a vector with the same length and
+elements as was written by Vector'Write.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The Standard requires streaming of all
+  language-defined nonlimited types (including containers) to "work" (see
+  @RefSecNum{Stream-Oriented Attributes}). In addition, we do not want all
+  of the elements that make up the
+  capacity of the vector streamed, as those beyond the length of the container
+  have undefined contents (and might cause bad things when read back in).
+  This will require a custom stream attribute
+  implementation; the language-defined default implementation will not work
+  (even for a bounded form, as that would most likely stream the entire
+  capacity of the vector). There is a separate requirement that the unbounded
+  and Bounded form use the same streaming representation for the same element
+  type, see @RefSecNum{The Generic Package Containers.Bounded_Vectors}.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[No_Index represents a position that does not
+correspond to any element. The subtype Extended_Index includes the indices
+covered by Index_Type plus the value No_Index and, if it exists, the successor
+to the Index_Type'Last.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We require the existence of Index_Type'First @en 
1,
+  so that No_Index and Last_Index of an empty vector is well-defined. We don't
+  require the existence of Index_Type'Last + 1, as it is only used as the
+  position of insertions (and needs to be allowed only when inserting an empty
+  vector).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Text=[If an operation attempts to modify the vector such
+that the position of the last element would be greater than Index_Type'Last,
+then the operation propagates Constraint_Error.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We don't want to require an implementation to
+  go to heroic efforts to handle index values larger than the base type of
+  the index subtype.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden operations of this generic package
+have access-to-subprogram parameters. To ensure such operations are
+well-defined, they guard against certain actions by the designated
+subprogram. In particular, some operations check for @lquotes@;tampering with
address@hidden of a container because they depend on the set of elements of
+the container remaining constant, and others check for @lquotes@;tampering with
address@hidden of a container because they depend on elements of the
+container not being replaced.]]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],address@hidden with cursors],Sec=[of a vector]}
+A subprogram is said to
address@hidden with cursors} of a vector object @i<V> if:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it inserts or deletes elements of @i<V>, that is,
+it calls the Insert, Insert_Space, Clear, Delete, or Set_Length procedures with
address@hidden<V> as a parameter; or]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Operations which are defined to be equivalent to
+  a call on one of these operations also are included. Similarly, operations
+  which call one of these as part of their definition are included.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it finalizes @i<V>; or]}
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Text=[it calls the Assign procedure with @i<V> as the Target 
parameter;
+or]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[We don't need to explicitly mention
+  @nt{assignment_statement}, because that finalizes the target object
+  as part of the operation, and finalization of an object is already defined
+  as tampering with cursors.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it calls the Move procedure with @i<V> as
+a parameter.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Swap, Sort, and Merge copy elements rather
+  than reordering them, so they don't tamper with cursors.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],address@hidden with elements],Sec=[of a vector]}
+A subprogram is said to @i{tamper with elements} of a vector object @i<V> if:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it tampers with cursors of @i<V>; or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it replaces one or more elements of @i<V>, that is,
+it calls the Replace_Element, Reverse_Elements, or Swap procedures or the Sort
+or Merge procedures of an instance of Generic_Sorting with @i<V> as a
+parameter.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Complete replacement of an element can cause its
+  memory to be deallocated while another operation is holding onto a reference
+  to it. That can't be allowed. However, a simple modification of (part of) an
+  element is not a problem, so Update_Element does not cause a problem.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0265-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0110-1]}
address@hidden,address@hidden,Sec=[tampering with a vector]}
address@hidden,Sec=[prohibited for a vector]}
+When tampering with cursors is @i<prohibited> for a particular vector object
address@hidden<V>, Program_Error is propagated by a call of any 
language-defined subprogram
+that is defined to tamper with the cursors of @i<V>, leaving @i<V> unmodified.
+Similarly, when tampering with elements is @i<prohibited> for a particular 
vector
+object @i<V>, Program_Error is propagated by a call of any language-defined
+subprogram that is defined to tamper with the elements of @i<V> @Redundant[(or
+tamper with the cursors of @i<V>)], leaving @i<V>
address@hidden,New=[ These checks are made before any other
+defined behavior of the body of the language-defined subprogram.],Old=[]}]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Tampering with elements includes tampering with
+  cursors, so we mention it only from completeness in the second sentence.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Has_Element (Position : Cursor) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[Returns True if Position designates
+an element, and returns False otherwise.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],Text=[This function might not detect cursors that
+  designate deleted elements; such cursors are invalid (see below) and the
+  result of calling Has_Element with an invalid cursor is unspecified (but
+  not erroneous).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "=" (Left, Right : Vector) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Left and Right denote the same
+vector object, then the function returns True. If Left and Right have different
+lengths, then the function returns False.
+Otherwise, it compares each element in Left to
+the corresponding element in Right using the generic formal equality operator.
+If any such comparison returns False, the function returns False;
address@hidden,New=[,],Old=[]} it
+returns True. Any exception raised during
+evaluation of element equality is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This wording describes the canonical semantics.
+However, the order and number of calls on the formal equality function is
+unspecified for all of the operations that use it in this package, so an
+implementation can call it as many or as few times as it needs to get the
+correct answer. Specifically, there is no requirement to call the formal
+equality additional times once the answer has been determined.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden To_Vector (Length : Count_Type) 
@key{return} Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a vector with a length of
+Length, filled with empty elements.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden To_Vector
+  (New_Item : Element_Type;
+   Length   : Count_Type) @key{return} Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a vector with a length of
+Length, filled with elements initialized to the value New_Item.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "&" (Left, Right : Vector) 
@key{return} Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a vector comprising the
+elements of Left followed by the elements of Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "&" (Left  : Vector;
+              Right : Element_Type) @key{return} Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a vector comprising the
+elements of Left followed by the element Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "&" (Left  : Element_Type;
+              Right : Vector) @key{return} Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a vector comprising the
+element Left followed by the elements of Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "&" (Left, Right  : Element_Type) 
@key{return} Vector;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a vector comprising the
+element Left followed by the element Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Capacity (Container : Vector) 
@key{return} Count_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns the capacity of Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reserve_Capacity (Container : 
@key{in out} Vector;
+                            Capacity  : @key{in}     Count_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0001-1],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],address@hidden,New=[If the
+capacity of Container is already greater than or equal to Capacity, then
+Reserve_Capacity has no effect. Otherwise, ],Old=[]}Reserve_Capacity allocates
address@hidden,New=[additional storage as necessary to
+ensure],Old=[new internal data structures such]} that the length of the
+resulting vector can become at least the value Capacity without requiring an 
additional call to
+Reserve_Capacity, and is large enough to hold the current length of Container.
+Reserve_Capacity address@hidden,New=[, as necessary, moves],Old=[ copies the]}
+elements into the new @Chg{Version=[3],New=[storage],Old=[data structures]} and
+deallocates @Chg{Version=[3],New=[any storage no longer needed],Old=[the old
+data structures]}. Any exception raised during allocation is
+propagated and Container is not modified.]}
+
address@hidden
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Expanding the internal array can be done by
+  allocating a new, longer array, copying the elements, and deallocating the
+  original array. This may raise Storage_Error, or cause an exception from a
+  controlled subprogram. We require that a failed Reserve_Capacity does not
+  lose any elements if an exception occurs, but we do not require a specific
+  order of evaluations or copying.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This routine is used to preallocate the internal
+  array to the specified capacity such that future Inserts do not require
+  memory allocation overhead. Therefore, the implementation should allocate the
+  needed memory to make that true at this point, even though the visible
+  semantics could be preserved by waiting until the memory is needed. This
+  doesn't apply to the indefinite element container, because elements will have
+  to be allocated individually.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The implementation does not have to contract the
+  internal array if the capacity is reduced, as any capacity greater than or
+  equal to the specified capacity is allowed.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Length (Container : Vector) 
@key{return} Count_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns the number of elements in 
Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Set_Length (Container : @key{in out} 
Vector;
+                      Length    : @key{in}     Count_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Length is larger than the
+capacity of Container, Set_Length calls Reserve_Capacity (Container, Length),
+then sets the length of the Container to Length. If Length is greater than the
+original length of Container, empty elements are added to Container;
address@hidden,New=[,],Old=[]}
+elements are removed from Container.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[No elements are moved by this operation; any new
+  empty elements are added at the end. This follows from the rules that a
+  cursor continues to designate the same element unless the routine is
+  defined to make the cursor ambiguous or invalid; this operation does not do
+  that.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Is_Empty (Container : Vector) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Length (Container) = 0.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Clear (Container : @key{in out} 
Vector);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Removes all the elements from
+Container. The capacity of Container does not change.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden To_Cursor (Container : Vector;
+                    Index     : Extended_Index) @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Index is not in the range
+First_Index (Container) .. Last_Index (Container), then No_Element is returned.
+Otherwise, a cursor designating the element at position Index in Container is
+returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden To_Index (Position  : Cursor) 
@key{return} Extended_Index;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position is No_Element, No_Index
+is returned. Otherwise, the index (within its containing vector) of the element
+designated by Position is returned.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This implies that the index is determinable from
+  a bare cursor alone. The basic model is that a vector cursor is implemented
+  as a record containing an access to the vector container and an index value.
+  This does constrain implementations, but it also allows all of the cursor
+  operations to be defined in terms of the corresponding index operation (which
+  should be primary for a vector).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Element (Container : Vector;
+                  Index     : Index_Type)
+   @key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Index is not in the range
+First_Index (Container) .. Last_Index (Container), then Constraint_Error is
+propagated. Otherwise, Element returns the element at position Index.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Element (Position  : Cursor) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Constraint_Error is propagated. Otherwise, Element returns the element
+designated by Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Replace_Element (Container : @key{in 
out} Vector;
+                           Index     : @key{in}     Index_Type;
+                           New_Item  : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Index is not in the range
+First_Index (Container) .. Last_Index (Container), then Constraint_Error is
+propagated. address@hidden,New=[,],Old=[]}
+Replace_Element assigns the value New_Item to the element at
+position Index. Any exception raised during the assignment is propagated. The
+element at position Index is not an empty element after successful call to
+Replace_Element.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Replace_Element (Container : @key{in 
out} Vector;
+                           Position  : @key{in}     Cursor;
+                           New_Item  : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element,
+then Constraint_Error is propagated; if Position does not designate an element
+in Container, then Program_Error is propagated.
address@hidden,New=[,],Old=[]} Replace_Element
+assigns New_Item to the element designated by Position. Any exception raised
+during the assignment is propagated. The element at Position is not an empty
+element after successful call to Replace_Element.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[2],address@hidden,New=[,],Old=[ and]}
+  address@hidden,New=[, and Reference],Old=[]} are the only
+  ways that an element can change from empty to nonempty. Also see the note
+  following Update_Element.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Query_Element
+  (Container : @key{in} Vector;
+   Index     : @key{in} Index_Type;
+   Process   : @key{not null access} @key{procedure} (Element : @key{in} 
Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0265-1]}
address@hidden,Type=[Trailing],Text=[If Index is not in the range
+First_Index (Container) .. Last_Index (Container), then Constraint_Error is
+propagated. Otherwise, Query_Element calls address@hidden with the element at
+position Index as the argument.
address@hidden,New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the elements of address@hidden,New=[ is prohibited during the
+execution of the call on address@hidden,Old=[]}. Any exception raised by
address@hidden is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[The @lquotes@;tamper with the address@hidden@;
+  check is intended to prevent the Element parameter of Process from being
+  @Chg{Version=[3],New=[replaced],Old=[modified]} or deleted
+  outside of Process. The check prevents data loss (if Element_Type is passed 
by
+  copy) or erroneous execution (if Element_Type is an unconstrained type in an
+  indefinite container).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Query_Element
+  (Position : @key{in} Cursor;
+   Process  : @key{not null access} @key{procedure} (Element : @key{in} 
Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0021-1],ARef=[AI05-0265-1]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Constraint_Error is propagated. Otherwise, Query_Element calls
address@hidden with the element designated by Position as the argument.
address@hidden,New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the elements of @Chg{Version=[3],New=[the vector that contains the
+element designated by Position is prohibited during the
+execution of the call on address@hidden,Old=[Container]}. Any
+exception raised by address@hidden is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Update_Element
+  (Container : @key{in out} Vector;
+   Index     : @key{in}     Index_Type;
+   Process   : @key{not null access} @key{procedure} (Element : @key{in out} 
Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0265-1]}
address@hidden,Text=[If Index is not in the range
+First_Index (Container) .. Last_Index (Container), then Constraint_Error is
+propagated. Otherwise, Update_Element calls address@hidden with the element
+at position Index as the argument.
address@hidden,New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the elements of address@hidden,New=[ is prohibited during the
+execution of the call on address@hidden,Old=[]}. Any exception raised by
address@hidden is propagated.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If Element_Type is unconstrained and definite, then
+the actual Element parameter of address@hidden shall be unconstrained.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This means that the elements cannot be directly
+  allocated from the heap; it must be possible to change the discriminants of
+  the element in place.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[The element at position Index is
+not an empty element after successful completion of this operation.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Since reading an empty element is a bounded
+  error, attempting to use this procedure to replace empty elements may fail.
+  Use Replace_Element to do that reliably.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Update_Element
+  (Container : @key{in out} Vector;
+   Position  : @key{in}     Cursor;
+   Process   : @key{not null access} @key{procedure} (Element : @key{in out} 
Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Position equals No_Element, then
+Constraint_Error is propagated; if Position does not designate an element in
+Container, then Program_Error is propagated.
address@hidden,New=[,],Old=[]} Update_Element calls
address@hidden with the element designated by Position as the argument.
address@hidden,New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the elements of address@hidden,New=[ is prohibited during the
+execution of the call on address@hidden,Old=[]}. Any exception raised by
address@hidden is propagated.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If Element_Type is unconstrained and definite, then
+the actual Element parameter of address@hidden shall be unconstrained.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[The element designated by Position
+is not an empty element after successful completion of this operation.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden Constant_Reference_Type
+      (Element : @key[not null access constant] Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Reference_Type (Element : @key[not 
null access] Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[The types Constant_Reference_Type
+and Reference_Type need address@hidden<needs finalization>,
+Sec=<language-defined type>}]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The default initialization of an object of type
+Constant_Reference_Type or Reference_Type propagates Program_Error.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[It is expected that Reference_Type (and
+  Constant_Reference_Type) will be a controlled type, for which finalization
+  will have some action to terminate the tampering check for the associated
+  container. If the object is created by default, however, there is no
+  associated container. Since this is useless, and supporting this case would
+  take extra work, we define it to raise an exception.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Constant_Reference (Container : 
@key[aliased in] Vector;
+                             Index     : @key[in] Index_Type)
+   @key[return] Constant_Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Constant_Indexing and Implicit_Dereference aspects) provides a convenient way 
to
+gain read access to an individual element of a vector given an
+index value.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Index is not in the range First_Index (Container)
+.. Last_Index (Container), then Constraint_Error is propagated. Otherwise,
+Constant_Reference returns an object whose discriminant is an access value that
+designates the element at position Index. Tampering with the elements of
+Container is prohibited while the object returned by Constant_Reference exists
+and has not been finalized.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Reference (Container : @key[aliased 
in out] Vector;
+                    Index     : @key[in] Index_Type)
+   @key[return] Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Variable_Indexing and Implicit_Dereference aspects) provides a convenient way 
to
+gain read and write access to an individual element of a vector given
+an index value.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Index is not in the range First_Index (Container)
+.. Last_Index (Container), then Constraint_Error is propagated. Otherwise,
+Reference returns an object whose discriminant is an access value that
+designates the element at position Index. Tampering with the elements of
+Container is prohibited while the object returned by Reference exists and has
+not been finalized.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The element at position Index is not an empty
+element after successful completion of this operation.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Constant_Reference (Container : 
@key[aliased in] Vector;
+                             Position  : @key[in] Cursor)
+   @key[return] Constant_Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Constant_Indexing and Implicit_Dereference aspects) provides a convenient way 
to
+gain read access to an individual element of a vector given a cursor.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Position equals No_Element, then Constraint_Error
+is propagated; if Position does not designate an element in Container, then
+Program_Error is propagated. Otherwise, Constant_Reference returns an object
+whose discriminant is an access value that designates the element designated by
+Position. Tampering with the elements of Container is prohibited while the
+object returned by Constant_Reference exists and has not been finalized.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Reference (Container : @key[aliased 
in out] Vector;
+                    Position  : @key[in] Cursor)
+   @key[return] Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Variable_Indexing and Implicit_Dereference aspects) provides a convenient way 
to
+gain read and write access to an individual element of a vector given
+a cursor.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Position equals No_Element, then Constraint_Error
+is propagated; if Position does not designate an element in Container, then
+Program_Error is propagated. Otherwise, Reference returns an object whose
+discriminant is an access value that designates the element designated by
+Position. Tampering with the elements of Container is prohibited while the
+object returned by Reference exists and has not been finalized.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The element designated by Position is not an empty
+element after successful completion of this operation.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Assign (Target : @key{in out} 
Vector; Source : @key{in} Vector);]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1]}
address@hidden,Type=[Trailing],Text=[If Target denotes the same object as
+Source, the operation has no effect. If the length of Source is greater than 
the
+capacity of Target, Reserve_Capacity (Target, Length (Source)) is called.
+The elements of Source are then copied to Target as for an
address@hidden assigning Source to Target (this includes
+setting the length of Target to be that of Source).]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[3],Text=[This routine exists for compatibility with the
+  bounded vector container. For an unbounded vector, @exam{Assign(A, B)} and
+  @exam{A := B} behave identically. For a bounded vector, := will raise an
+  exception if the container capacities are different, while Assign will
+  not raise an exception if there is enough room in the target.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Copy (Source : Vector; Capacity : 
Count_Type := 0)
+   @key[return] Vector;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Type=[Trailing],Text=[Returns a vector whose elements are
+initialized from the corresponding elements of Source. If Capacity is 0, then
+the vector capacity is the length of Source; if Capacity is equal to or greater
+than the length of Source, the vector capacity is at least the specified value.
+Otherwise, the operation propagates Capacity_Error.]}
+
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Move (Target : @key{in out} Vector;
+                Source : @key{in out} Vector);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0001-1],ARef=[AI05-0248-1]}
address@hidden,Type=[Trailing],Text=[If Target denotes the same object
+as Source, then @Chg{Version=[3],New=[the operation],Old=[Move]}
+has no effect. Otherwise, Move first calls
address@hidden,New=[Reserve_Capacity (Target, Length (Source))
+and then ],Old=[]}Clear (Target);
+then, each element from Source is removed from Source and inserted into Target
+in the original order. The length of Source is 0 after a successful call to
+Move.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The idea is that the internal array is removed
+  from Source and moved to Target. (See the @ImplAdviceName for Move). If
+  Capacity (Target) /= 0, the previous internal array may need to be
+  deallocated. We don't mention this explicitly, because it is covered by the
+  "no memory loss" @ImplReqName@;.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} 
Vector;
+                  Before    : @key{in}     Extended_Index;
+                  New_Item  : @key{in}     Vector);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[If Before is not in the range First_Index
+(Container) .. Last_Index (Container) + 1, then Constraint_Error is propagated.
+If Length(New_Item) is 0, then Insert does nothing. Otherwise, it computes the
+new length @i<NL> as the sum of the current length and Length (New_Item); if
+the value of Last appropriate for length @i<NL> would be greater than
+Index_Type'address@hidden,New=[,],Old=[]} then
+Constraint_Error is propagated.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[If the current vector capacity is
+less than @i<NL>, Reserve_Capacity (Container, @i<NL>) is called to
+increase the vector capacity. Then Insert slides the elements in the range
+Before .. Last_Index (Container) up by Length(New_Item) positions, and then
+copies the elements of New_Item to the positions starting at Before. Any
+exception raised during the copying is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Moving the elements does not necessarily involve
+  copying. Similarly, since Reserve_Capacity does not require the copying of
+  elements, it does not need to be explicitly called (the implementation can
+  combine the operations if it wishes to).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} 
Vector;
+                  Before    : @key{in}     Cursor;
+                  New_Item  : @key{in}     Vector);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Before is not No_Element, and
+does not designate an element in Container, then Program_Error is propagated.
+Otherwise, if
+Length(New_Item) is 0, then Insert does nothing. If Before is No_Element, then
+the call is equivalent to Insert (Container, Last_Index (Container) + 1,
+New_Item); address@hidden,New=[,],Old=[]}
+the call is equivalent to Insert (Container, To_Index
+(Before), New_Item);]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The check on Before checks that the cursor does
+  not belong to some other Container. This check implies that a reference to
+  the container is included in the cursor value. This wording is not meant to
+  require detection of dangling cursors; such cursors are defined to be
+  invalid, which means that execution is erroneous, and any result is allowed
+  (including not raising an exception).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} 
Vector;
+                  Before    : @key{in}     Cursor;
+                  New_Item  : @key{in}     Vector;
+                  Position  :    @key{out} Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Before is not No_Element, and
+does not designate an element in Container, then Program_Error is propagated.
+If Before
+equals No_Element, then let @i<T> be Last_Index (Container) + 1; otherwise, let
address@hidden<T> be To_Index (Before). Insert (Container, @i<T>, New_Item) is 
called, and
+then Position is set to To_Cursor (Container, @i<T>).]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The messy wording is needed because Before is
+  invalidated by Insert, and we don't want Position to be invalid after this
+  call. An implementation probably only needs to copy Before to Position.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} 
Vector;
+                  Before    : @key{in}     Extended_Index;
+                  New_Item  : @key{in}     Element_Type;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Insert (Container, Before, 
To_Vector (New_Item, Count));]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} 
Vector;
+                  Before    : @key{in}     Cursor;
+                  New_Item  : @key{in}     Element_Type;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Insert (Container, Before, 
To_Vector (New_Item, Count));]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} 
Vector;
+                  Before    : @key{in}     Cursor;
+                  New_Item  : @key{in}     Element_Type;
+                  Position  :    @key{out} Cursor;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Insert (Container, Before, 
To_Vector (New_Item, Count), Position);]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0257-1]}
+  @ChgAdded{Version=[3],Text=[If Count equals 0, Position will designate the
+  element designated by Before, rather than a newly inserted element. 
Otherwise,
+  Position will designate the first newly inserted element.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} 
Vector;
+                  Before    : @key{in}     Extended_Index;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[If Before is not in the range
+First_Index (Container) .. Last_Index (Container) + 1, then Constraint_Error is
+propagated. If Count is 0, then Insert does nothing. Otherwise, it
+computes the new length @i<NL> as the sum of the current length and Count; if
+the value of Last appropriate for length @i<NL> would be greater than
+Index_Type'address@hidden,New=[,],Old=[]} then
+Constraint_Error is propagated.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[If the current vector capacity is
+less than @i<NL>, Reserve_Capacity (Container, @i<NL>) is called to
+increase the vector capacity. Then Insert slides the elements in the
+range Before .. Last_Index (Container) up by Count positions, and then inserts
+elements that are initialized by default (see @RefSecNum{Object Declarations})
+in the positions starting at Before.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} 
Vector;
+                  Before    : @key{in}     Cursor;
+                  Position  :    @key{out} Cursor;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Before is not No_Element, and
+does not designate an element in Container, then Program_Error is propagated.
+If Before
+equals No_Element, then let @i<T> be Last_Index (Container) + 1; otherwise, let
address@hidden<T> be To_Index (Before). Insert (Container, @i<T>, Count) is 
called,
+and then Position is set to To_Cursor (Container, @i<T>).]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This routine exists mainly to ease conversion
+  between Vector and List containers. Unlike Insert_Space, this routine
+  default initializes the elements it inserts, which can be more expensive
+  for some element types.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0080-1]}
address@hidden,KeepNext=[T],address@hidden Prepend (Container : @key{in out} 
Vector;
+                   New_Item  : @key{in}     address@hidden,New=[],Old=[;
+                   Count     : @key{in}     Count_Type := 1]});]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Insert (Container, 
First_Index (Container), New_Item).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Prepend (Container : @key{in out} 
Vector;
+                   New_Item  : @key{in}     Element_Type;
+                   Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Insert (Container, 
First_Index (Container), New_Item, Count).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Append (Container : @key{in out} 
Vector;
+                  New_Item  : @key{in}     Vector);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Insert (Container, 
Last_Index (Container) + 1, New_Item).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Append (Container : @key{in out} 
Vector;
+                  New_Item  : @key{in}     Element_Type;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Insert (Container, 
Last_Index (Container) + 1, New_Item, Count).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert_Space (Container : @key{in 
out} Vector;
+                        Before    : @key{in}     Extended_Index;
+                        Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[If Before is not in the range
+First_Index (Container) .. Last_Index (Container) + 1, then Constraint_Error is
+propagated. If Count is 0, then Insert_Space does nothing. Otherwise, it
+computes the new length @i<NL> as the sum of the current length and Count; if
+the value of Last appropriate for length @i<NL> would be greater than
+Index_Type'address@hidden,New=[,],Old=[]} then
+Constraint_Error is propagated.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[If the current vector capacity is
+less than @i<NL>, Reserve_Capacity (Container, @i<NL>) is called to
+increase the vector capacity. Then Insert_Space slides the elements in the
+range Before .. Last_Index (Container) up by Count positions, and then inserts
+empty elements in the positions starting at Before.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert_Space (Container : @key{in 
out} Vector;
+                        Before    : @key{in}     Cursor;
+                        Position  :    @key{out} Cursor;
+                        Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Before is not No_Element, and
+does not designate an element in Container, then Program_Error is propagated.
+If Before
+equals No_Element, then let @i<T> be Last_Index (Container) + 1; otherwise, let
address@hidden<T> be To_Index (Before). Insert_Space (Container, @i<T>, Count) 
is called,
+and then Position is set to To_Cursor (Container, @i<T>).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete (Container : @key{in out} 
Vector;
+                  Index     : @key{in}     Extended_Index;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Index is not in the range
+First_Index (Container) .. Last_Index (Container) + 1, then Constraint_Error is
+propagated. If Count is 0, Delete has no effect.
address@hidden,New=[,],Old=[]} Delete slides the
+elements (if any) starting at position Index + Count down to Index. Any
+exception raised during element assignment is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If Index + Count >= Last_Index(Container), this
+  effectively truncates the vector (setting Last_Index to Index @en 1 and
+  consequently sets Length to Index @en Index_Type'First).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete (Container : @key{in out} 
Vector;
+                  Position  : @key{in out} Cursor;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Constraint_Error is propagated. If Position does not designate an element in
+Container, then Program_Error is propagated. Otherwise, Delete (Container,
+To_Index (Position), Count) is called, and then Position is set to 
No_Element.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete_First (Container : @key{in 
out} Vector;
+                        Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Delete (Container, 
First_Index (Container), Count).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete_Last (Container : @key{in 
out} Vector;
+                       Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If
+Length (Container) <= address@hidden,New=[,],Old=[]} then
+Delete_Last is equivalent to Clear (Container).
address@hidden,New=[,],Old=[]} it is equivalent to
+Delete (Container, Index_Type'Val(Index_Type'Pos(Last_Index (Container)) @en
+Count + 1), Count).]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reverse_Elements (Container : 
@key{in out} @Chg{Version=[3],New=[Vector],Old=[List]});]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Reorders the elements of Container
+in reverse order.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This can copy the elements of the vector @em
+  all cursors referencing the vector are ambiguous afterwards and may
+  designate different elements afterwards.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Swap (Container : @key{in out} 
Vector;
+                I, J      : @key{in}     Index_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If either I or J is not in the range
+First_Index (Container) .. Last_Index (Container), then Constraint_Error is
+propagated. Otherwise, Swap exchanges the values of the elements at positions I
+and J.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The implementation is not required to actually
+  copy the elements if it can do the swap some other way. But it is allowed
+  to copy the elements if needed.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Swap (Container : @key{in out} 
Vector;
+                I, J      : @key{in}     Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If either I or J is No_Element,
+then Constraint_Error is propagated. If either I or J do not designate an
+element in Container, then Program_Error is propagated. Otherwise, Swap
+exchanges the values of the elements designated by I and J.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[After a call to Swap, I designates the element
+  value previously designated by J, and J designates the element value
+  previously designated by I. The cursors do not become ambiguous from this
+  operation.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The implementation is not required to actually
+  copy the elements if it can do the swap some other way. But it is allowed
+  to copy the elements if needed.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First_Index (Container : Vector) 
@key{return} Index_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns the value Index_Type'First.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We'd rather call this @lquotes@;address@hidden@;,
+  but then calling most routines in here with First (Some_Vect) would be
+  ambiguous.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First (Container : Vector) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Container is empty, First
+returns No_Element. Otherwise, it returns a cursor that designates the first
+element in Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First_Element (Container : Vector) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Element (Container, 
First_Index (Container)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Last_Index (Container : Vector) 
@key{return} Extended_Index;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Container is empty, Last_Index
+returns No_Index. Otherwise, it returns the position of the last element in
+Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Last (Container : Vector) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Container is empty, Last returns
+No_Element. Otherwise, it returns a cursor that designates the last element in
+Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Last_Element (Container : Vector) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Element (Container,
+Last_Index (Container)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Next (Position : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element or
+designates the last element of the container, then Next returns the value
+No_Element. Otherwise, it returns a cursor that designates the element with 
index
+To_Index (Position) + 1 in the same vector as Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Next (Position : @key{in out} 
Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Position := Next 
(Position).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Previous (Position : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element or
+designates the first element of the container, then Previous returns the value
+No_Element. Otherwise, it returns a cursor that designates the element with 
index
+To_Index (Position) @en 1 in the same vector as Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Previous (Position : @key{in out} 
Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Position := Previous 
(Position).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Find_Index (Container : Vector;
+                     Item      : Element_Type;
+                     Index     : Index_Type := Index_Type'First)
+   @key{return} Extended_Index;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Searches the elements of Container
+for an element equal to Item (using the generic formal equality
+operator). The search starts at position Index and proceeds towards Last_Index
+(Container). If no equal element is found, then Find_Index returns No_Index.
+Otherwise, it returns the index of the first equal element encountered.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Find (Container : Vector;
+               Item      : Element_Type;
+               Position  : Cursor := No_Element)
+   @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Position is not No_Element, and
+does not designate an element in Container, then Program_Error is propagated.
address@hidden,New=[,],Old=[]}
+Find searches the elements of Container for an element equal to Item
+(using the generic formal equality operator). The search starts at
+the first element if Position equals No_Element, and at the element designated 
by
+Position otherwise. It proceeds towards the last element of Container. If no
+equal element is found, then Find returns No_Element. Otherwise, it returns a
+cursor designating the first equal element encountered.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reverse_Find_Index (Container : 
Vector;
+                             Item      : Element_Type;
+                             Index     : Index_Type := Index_Type'Last)
+   @key{return} Extended_Index;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Searches the elements of Container
+for an element equal to Item (using the generic formal equality
+operator). The search starts at position Index or, if Index is greater than
+Last_Index (Container), at position Last_Index (Container). It proceeds towards
+First_Index (Container). If no equal element is found, then Reverse_Find_Index
+returns No_Index. Otherwise, it returns the index of the first equal element
+encountered.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reverse_Find (Container : Vector;
+                       Item      : Element_Type;
+                       Position  : Cursor := No_Element)
+   @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Position is not No_Element, and
+does not designate an element in Container, then Program_Error is propagated.
address@hidden,New=[,],Old=[]}
+Reverse_Find searches the elements of Container for an element equal
+to Item (using the generic formal equality operator). The search
+starts at the last element if Position equals No_Element, and at the element
+designated by Position otherwise. It proceeds towards the first element of
+Container. If no equal element is found, then Reverse_Find returns No_Element.
+Otherwise, it returns a cursor designating the first equal element
+encountered.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Contains (Container : Vector;
+                   Item      : Element_Type) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Has_Element (Find 
(Container, Item)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,KeepNext=[T],address@hidden,New=[],address@hidden Has_Element 
(Position : Cursor) @key{return} Boolean;]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],address@hidden,New=[],Old=[Returns True if 
Position designates
+an element, and returns False otherwise.]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[2],address@hidden,New=[],Old=[This function may not 
detect cursors that
+  designate deleted elements; such cursors are invalid (see below) and the
+  result of calling Has_Element with an invalid cursor is unspecified (but
+  not erroneous).]}]}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraphs 225 and 226
+were moved above.>address@hidden message should be
+deleted if the paragraphs are ever renumbered.}
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Iterate
+  (Container : @key{in} Vector;
+   Process   : @key{not null access} @key{procedure} (Position : @key{in} 
Cursor));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0265-1]}
address@hidden,Type=[Trailing],Text=[Invokes address@hidden with a
+cursor that designates each element in Container, in index order.
address@hidden,New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the cursors of address@hidden,New=[ is prohibited during the
+execution of a call on address@hidden,Old=[]}. Any exception raised by
address@hidden is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The purpose of the @lquotes@;tamper with the
+  address@hidden@; check is
+  to prevent erroneous execution from the Position parameter of address@hidden
+  becoming invalid. This check takes place when the operations that tamper with
+  the cursors of the container are called. The check cannot be made later (say
+  in the body of Iterate), because that could cause the Position cursor to be
+  invalid and potentially cause execution to become erroneous -- defeating the
+  purpose of the check.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[ There is no check needed if an attempt is made
+  to insert or delete nothing (that is, Count = 0 or Length(Item) = 0).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The check is easy to implement: each container
+  needs a counter. The counter is incremented when Iterate is called, and
+  decremented when Iterate completes. If the counter is nonzero when an
+  operation that inserts or deletes is called, Finalize is called, or one of
+  the other operations in the list occurs, Program_Error is raised.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reverse_Iterate
+  (Container : @key{in} Vector;
+   Process   : @key{not null access} @key{procedure} (Position : @key{in} 
Cursor));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[Iterates over the elements in
+Container as per @Chg{Version=[3],New=[procedure ],Old=[]}Iterate,
+except that elements are traversed in reverse index order.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Iterate (Container : @key[in] Vector)
+   @key[return] Vector_Iterator_Interfaces.Reversible_Iterator'Class;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[Iterate returns a reversible
+iterator object (see @RefSecNum{User-Defined Iterator Types}) that
+will generate a value for a loop parameter (see
address@hidden Loop Iteration}) designating
+each node in Container, starting with the first node and moving the cursor as
+per the Next function when used as a forward iterator, and starting with the
+last node and moving the cursor as per the Previous function when used as a
+reverse iterator. Tampering with the cursors of Container is prohibited while
+the iterator object exists (in particular, in
+the @nt{sequence_of_statements} of the @nt{loop_statement} whose
address@hidden denotes this object). The iterator object needs
+finalization.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Iterate (Container : @key[in] 
Vector; Start : @key[in] Cursor)
+   @key[return] Vector_Iterator_Interfaces.Reversible_Iterator'Class;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0262-1],ARef=[AI05-0265-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[If Start is not No_Element and does
+not designate an item in Container, then Program_Error is propagated. If Start
+is No_Element, then Constraint_Error is propagated. Otherwise, Iterate
+returns a reversible iterator object
+(see @RefSecNum{User-Defined Iterator Types}) that will generate
+a value for a loop parameter (see @RefSecNum{Generalized Loop Iteration})
+designating each node in Container, starting with the node
+designated by Start and moving the cursor as per the Next function when used as
+a forward iterator, or moving the cursor as per the Previous function when used
+as a reverse iterator. Tampering with the cursors of Container is prohibited
+while the iterator object exists (in particular, in the
address@hidden of the @nt{loop_statement} whose
address@hidden denotes this object). The iterator object needs
+finalization.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[Exits are allowed from the loops
+  created using the iterator objects. In particular, to stop the iteration at a
+  particular cursor, just add]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden when] Cur = Stop;]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[in the body of the loop (assuming
+  that @exam{Cur} is the loop parameter and @exam{Stop} is the cursor that you
+  want to stop at).]}
address@hidden
+
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0044-1],ARef=[AI05-0262-1]}
address@hidden,Text=[The actual function for the generic formal function
+"<" of Generic_Sorting is expected to return the same value each time it is
+called with a particular pair of element values. It should define a strict
address@hidden,New=[weak ],Old=[]}ordering address@hidden,
+New=[ (see @RefSecNum{Containers})],Old=[, that is, be irreflexive, asymmetric,
+and transitive]};
+it should not modify Container. If the actual for "<" behaves in some other
+manner, the behavior of the subprograms of Generic_Sorting are unspecified.
address@hidden,New=[The number of],Old=[How many]} times the subprograms of
+Generic_Sorting call "<" is address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Is_Sorted (Container : Vector) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns True if the elements are
+sorted smallest first as determined by the
+generic formal "<" operator; otherwise, Is_Sorted returns False.
+Any exception raised during evaluation of "<" is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Sort (Container : @key{in out} 
Vector);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Reorders the elements of Container
+such that the elements are
+sorted smallest first as determined by the generic formal "<" operator
+provided. Any exception raised during evaluation of "<" is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This implies swapping the elements, usually
+  including an intermediate copy. This means that the elements will usually be
+  copied. (As with Swap, if the implementation can do this some other way, it
+  is allowed to.) Since the elements are nonlimited, this usually will not be
+  a problem. Note that there is @ImplAdviceName below that the implementation
+  should use a sort that minimizes copying of elements.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The sort is not required to be stable (and the
+  fast algorithm required will not be stable). If a stable sort is needed, the
+  user can include the original location of the element as an extra "sort key".
+  We considered requiring the implementation to do that, but it is mostly extra
+  overhead -- usually there is something already in the element that provides
+  the needed stability.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Merge (Target  : @key{in out} Vector;
+                 Source  : @key{in out} Vector);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0021-1]}
address@hidden,Type=[Trailing],address@hidden,New=[If Source is
+empty, then Merge does nothing. If Source and Target are the same nonempty
+container object, then Program_Error is propagated. Otherwise, ],Old=[]}Merge
+removes elements from Source and inserts them into Target; afterwards, Target
+contains the union of the elements that were initially in Source and Target;
+Source is left empty. If Target and Source are initially sorted smallest first,
+then Target is ordered smallest first as determined by the generic formal "<"
+operator; otherwise, the order of elements in Target is unspecified. Any
+exception raised during evaluation of "<" is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[It is a bounded error if either of the vectors is
+  unsorted, see below. The bounded error can be recovered by sorting Target
+  after the merge call, or the vectors can be pretested with Is_Sorted.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The Merge operation will usually require copying
+  almost all of the elements. One implementation strategy would be to
+  extend Target to the appropriate length, then copying elements from the back
+  of the vectors working towards the front. An alternative approach would be
+  to allocate a new internal data array of the appropriate length, copy the
+  elements into it in an appropriate order, and then replacing the data array
+  in Target with the temporary.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0212-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+Reading the value of an empty element by calling
+Element, Query_Element, Update_Element,@Chg{Version=[3],New=[
+Constant_Reference, Reference,],Old=[]} Swap, Is_Sorted, Sort, Merge,
+"=", Find, or Reverse_Find is a bounded error. The implementation may treat
+the element as having any normal value (see @RefSecNum{Data Validity}) of the
+element type, or raise Constraint_Error or Program_Error before modifying
+the vector.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[For instance, a default initialized element could
+  be returned. Or some previous value of an element. But returning random junk
+  is not allowed if the type has default initial value(s).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Assignment and streaming of empty elements are
+  @b<not> bounded errors. This is consistent with regular composite types, for
+  which assignment and streaming of uninitialized components do not cause a
+  bounded error, but reading the uninitialized component does cause a bounded
+  error.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[There are other operations which are defined in
+  terms of the operations listed above.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+Calling Merge in an instance of Generic_Sorting
+with either Source or Target not ordered smallest first using the provided
+generic formal "<" operator is a bounded error. Either Program_Error is raised
+after Target is updated as described for Merge, or the operation works as
+defined.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0022-1],ARef=[AI05-0248-1]}
address@hidden,Text=[It is a bounded error for the actual function
+associated with a generic formal subprogram, when called as part of an
+operation of this package, to tamper with elements of any Vector parameter of
+the operation. Either Program_Error is raised, or the operation works as
+defined on the value of the Vector either prior to, or subsequent to, some or
+all of the modifications to the Vector.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0027-1]}
address@hidden,Text=[It is a bounded error to call any subprogram
+declared in the visible part of Containers.Vectors
+when the associated container has been finalized. If the operation takes
+Container as an @key[in out] parameter, then it raises Constraint_Error or
+Program_Error. Otherwise, the operation either proceeds as it would
+for an empty container, or it raises Constraint_Error or Program_Error.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],Text=[
address@hidden cursor],Sec=[of a vector]}
address@hidden,Sec=[ambiguous]}
+A Cursor value is @i{ambiguous} if any of the following have occurred since it
+was created:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Insert, Insert_Space, or Delete has been called on
+the vector that contains the element the cursor designates with an index value
+(or a cursor designating an element at such an index value) less than or equal
+to the index value of the element designated by the cursor; or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The vector that contains the element it designates
+has been passed to the Sort or Merge procedures of an instance of
+Generic_Sorting, or to the Reverse_Elements procedure.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to call any subprogram other than "="
+or Has_Element declared in Containers.Vectors with an ambiguous (but not
+invalid, see below) cursor parameter. Possible results are:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The cursor may be treated as if it were No_Element;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The cursor may designate some element in the vector
+(but not necessarily the element that it originally designated);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Constraint_Error may be raised; or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Program_Error may be raised.]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Cursors are made ambiguous if an Insert or Delete
+  occurs that moves the elements in the internal array including the designated
+  ones. After such an operation, the cursor probably still designates an
+  element (although it might not after a deletion), but it is a @i<different>
+  element. That violates the definition of cursor @em it designates a 
particular
+  element.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[For "=" or Has_Element, the cursor works normally
+  (it would not be No_Element). We don't want to trigger an exception simply
+  for comparing a bad cursor.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[While it is possible to check for these cases
+  or ensure that cursors survive such operations, in many cases the overhead
+  necessary to make the check (or ensure cursors continue to designate the
+  same element) is substantial in time or space.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],Text=[
+A Cursor value is @i{invalid} if any of the following have occurred since it
+was created:@Defn2{Term=[invalid cursor],Sec=[of a vector]}
address@hidden,Sec=[invalid]}]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The vector that contains the element it designates
+has been finalized;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0160-1]}
address@hidden,Text=[The vector that contains the element it designates
+has been used as the Target of a call to Assign, or as the target of an
address@hidden;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden vector that contains the element it
+designates has been used as the Source or Target of a call to Move;] or]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],Text=[Move has been reworded in terms of Assign and
+  Clear, which are covered by other bullets, so this text is redundant.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0160-1],ARef=[AI05-0262-1]}
address@hidden,Text=[The element it designates has been
address@hidden,New=[ or removed from the vector that previously
+contained the element],Old=[]}.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0160-1]}
+  @ChgAdded{Version=[3],Text=[An element can be removed via calls to 
Set_Length,
+  Clear, and Merge; and indirectly via calls to Assign and Move.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The result of "=" or Has_Element is unspecified if
+it is called with an invalid cursor address@hidden Execution
+is erroneous if any other subprogram declared in Containers.Vectors is called
+with an invalid cursor address@hidden(erroneous execution),
+Sec=(cause)}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The list above (combined with the bounded error
+  cases) is intended to be exhaustive. In other cases, a cursor value continues
+  to designate its original element. For instance, cursor values survive the
+  appending of new elements.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[Execution is erroneous if the vector associated with the 
result of a call to
+Reference or Constant_Reference is finalized before the result object returned
+by the call to Reference or Constant_Reference is finalized.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Each object of Reference_Type and
+  Constant_Reference_Type probably contains some reference to the originating
+  container. If that container is prematurely finalized (which is only possible
+  via Unchecked_Deallocation, as accessibility checks prevent passing a
+  container to Reference that will not live as long as the result), the
+  finalization of the object of Reference_Type will try to access a nonexistent
+  object. This is a normal case of a dangling pointer created by
+  Unchecked_Deallocation; we have to explicitly mention it here as the pointer
+  in question is not visible in the specification of the type. (This is the 
same
+  reason we have to say this for invalid cursors.)]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[No storage associated with a vector object shall be
+lost upon assignment or scope exit.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden,Text=[The execution of an @nt{assignment_statement} for
+a vector shall have the effect of copying the elements from the source vector
+object to the target vector address@hidden,New=[ and changing the length
+of the target object to that of the source object],Old=[]}.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0298-1]}
+  @ChgAdded{Version=[2],Text=[An assignment of a Vector is a 
@lquotes@;address@hidden
+  copy; that is the elements are copied as well as the data structures.
+  We say @lquotes@;effect address@hidden in order to allow the implementation 
to
+  avoid copying elements immediately if it wishes. For instance, an
+  implementation that avoided copying until one of the containers is modified
+  would be address@hidden,New=[ (Note that such an implementation
+  would be require care, as Query_Element and Constant_Reference both could be
+  used to access an element which later needs to be reallocated while
+  the parameter or reference still exists, potentially leaving the
+  parameter or reference pointing at the wrong element.)],Old=[]}]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Containers.Vectors should be implemented similarly
+to an array. In particular, if the length of a vector is @i{N}, then]}
+
address@hidden
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[the worst-case time complexity of Element should
+  be @i{O}(log @i{N});]}
+  @ChgImplAdvice{Version=[2],Kind=[AddedNormal],address@hidden,
+  Text=[The worst-case time complexity of Element
+  for Containers.Vector should be @i{O}(log @i{N}).]}]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[the worst-case time complexity of Append with
+  Count=1 when @i{N} is less than the capacity of the vector should be
+  @i{O}(log @i{N}); and]}
+  @ChgImplAdvice{Version=[2],Kind=[AddedNormal],address@hidden,
+  Text=[The worst-case time complexity of Append with Count = 1 when
+  @i{N} is less than the capacity for Containers.Vector should be @i{O}(log 
@i{N}).]}]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[the worst-case time complexity of Prepend with
+  Count=1 and Delete_First with Count=1 should be @i{O}(@i{N} log @i{N}).]}
+  @ChgImplAdvice{Version=[2],Kind=[AddedNormal],address@hidden,
+  Text=[The worst-case time complexity of Prepend with Count = 1 and
+  Delete_First with Count=1 for Containers.Vectors should be @i{O}(@i{N} log 
@i{N}).]}]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We do not mean to overly constrain implementation
+  strategies here. However, it is important for portability that the
+  performance of large containers has roughly the same factors on different
+  implementations. If a program is moved to an implementation that takes
+  @i{O}(@i{N}) time to access elements, that program could be unusable when the
+  vectors are large. We allow @i{O}(log @i{N}) access because the 
proportionality
+  constant and caching effects are likely to be larger than the log factor, and
+  we don't want to discourage innovative implementations.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The worst-case time complexity of a call on procedure
+Sort of an instance of Containers.Vectors.Generic_Sorting should be 
@i{O}(@i{N}**2), and the
+average time complexity should be better than @i{O}(@i{N}**2).]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The worst-case time complexity of a call on procedure Sort of an
+instance of Containers.Vectors.Generic_Sorting should be @i{O}(@i{N}**2), and 
the
+average time complexity should be better than @i{O}(@i{N}**2).]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[In other words, we're requiring the use of a
+  better than @i{O}(@i{N}**2) sorting algorithm, such as Quicksort. No bubble 
sorts
+  allowed!]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Containers.Vectors.Generic_Sorting.Sort and
+Containers.Vectors.Generic_Sorting.Merge should minimize
+copying of elements.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Containers.Vectors.Generic_Sorting.Sort and
+Containers.Vectors.Generic_Sorting.Merge should minimize copying of 
elements.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We do not mean @lquotes@;absolutely 
address@hidden
+  here; we're not intending to require a single copy for each element.
+  Rather, we want to suggest that the sorting algorithm chosen is one that
+  does not copy items unnecessarily. Bubble sort would not meet this advice,
+  for instance.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Move should not copy elements, and should minimize
+copying of internal data structures.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Containers.Vectors.Move should not copy elements, and should minimize
+copying of internal data structures.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Usually that can be accomplished simply by
+  moving the pointer(s) to the internal data structures from the Source vector
+  to the Target vector.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[If an exception is propagated from a vector
+operation, no storage should be lost, nor any elements removed from a vector
+unless specified by the operation.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If an exception is propagated from a vector
+operation, no storage should be lost, nor any elements removed from a vector
+unless specified by the operation.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is important so that programs can recover
+  from errors. But we don't want to require heroic efforts, so we just require
+  documentation of cases where this can't be accomplished.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[All elements of a vector occupy locations in the
+internal array. If a sparse container is required, a Hashed_Map should be used
+rather than a vector.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If Index_Type'Base'First = Index_Type'First an
+instance of Ada.Containers.Vectors will raise Constraint_Error. A value
+below Index_Type'First is required so that an empty vector has a meaningful
+value of Last_Index.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This property is the main reason why only integer
+  types (as opposed to any discrete type) are allowed as the index type of a
+  vector. An enumeration or modular type would require a subtype in order to
+  meet this requirement.]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The package Containers.Vectors is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}Subprograms Assign and 
Copy
+  are added to Containers.Vectors. If an instance of Containers.Vectors
+  is referenced in a @nt{use_clause}, and an entity @i<E> with the same
+  @nt{defining_identifier} as a new entity in Containers.Vectors is
+  defined in a package that is also referenced in a @nt{use_clause}, the
+  entity @i<E> may no longer be use-visible, resulting in errors. This should
+  be rare and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Added iterator, reference, and indexing support to make vector containers 
more
+  convenient to use.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],Text=[Generalized the definition
+  of Reserve_Capacity and Move. Specified which elements are read/written
+  by stream attributes.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0022-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a @BoundedName
+  to cover tampering by generic actual subprograms.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0027-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a @BoundedName
+  to cover access to finalized vector containers.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0044-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Redefined "<" actuals
+  to require a strict weak ordering; the old definition allowed
+  indeterminant comparisons that would not have worked in a container.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0084-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a pragma
+  Remote_Types so that containers can be used in distributed programs.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0160-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Revised the definition
+  of invalid cursors to cover missing (and new) cases.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0265-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Defined when a container
+  prohibits tampering in order to more clearly define where the check is
+  made and the exception raised.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0110-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that tampering 
checks
+  precede all other checks made by a subprogram (but come after those 
associated
+  with the call).]}
address@hidden
+
+
address@hidden,
+Name=[The Generic Package Containers.Doubly_Linked_Lists]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The language-defined generic package
+Containers.Doubly_Linked_Lists provides private types List and Cursor, and a
+set of operations for each type. A list container is optimized for insertion
+and deletion at any position. @Defn{list address@hidden,Sec=[list]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden,Sec=[of a list]}A
+doubly-linked list container object manages a linked list of internal
address@hidden, each of which contains an element and pointers to the
+next (successor) and previous (predecessor) internal nodes. A cursor
+designates a particular node within a list (and by extension the element
+contained in that node). A cursor keeps designating the same node (and element)
+as long as the node is part of the container, even if the node is moved in the
+container.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The @i{length} of a list is the number of elements
+it address@hidden,Sec=(of a list container)}]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+package Containers.Doubly_Linked_Lists has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0084-1],ARef=[AI05-0212-1]}
address@hidden,address@hidden,address@hidden Ada.Iterator_Interfaces;
+],address@hidden
+   @key{type} Element_Type @key{is private};
+   @key{with function} "=" (Left, Right : Element_Type)
+      @key{return} Boolean @key{is} <>;
address@hidden Ada.Containers.Doubly_Linked_Lists 
@address@hidden,address@hidden@!Lists]}
+   @key{pragma} Preelaborate(Doubly_Linked_Lists);@Chg{Version=[3],New=[
+   @key{pragma} Remote_Types(Doubly_Linked_Lists);],Old=[]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{List} @key{is tagged 
address@hidden,New=[
+      @key[with] Constant_Indexing => Constant_Reference,
+           Variable_Indexing => Reference,
+           Default_Iterator  => Iterate,
+           Iterator_Element  => Element_Type],Old=[]};
+   @key{pragma} Preelaborable_Initialization(List);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Cursor} @key{is private};
+   @key{pragma} Preelaborable_Initialization(Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{Empty_List} : @key{constant} List;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{No_Element} : @key{constant} Cursor;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Has_Element} (Position : 
Cursor) @key{return} Boolean;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[package] @AdaPackDefn{List_Iterator_Interfaces} 
@key[is new]
+       Ada.Iterator_Interfaces (Cursor, Has_Element);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "=" (Left, Right : List) @key{return} 
Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Length} (Container : List) 
@key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Empty} (Container : List) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Clear} (Container : @key{in 
out} List);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Element} (Position : Cursor)
+      @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Replace_Element} (Container 
: @key{in out} List;
+                              Position  : @key{in}     Cursor;
+                              New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Query_Element}
+     (Position : @key{in} Cursor;
+      Process  : @key{not null access procedure} (Element : @key{in} 
Element_Type));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Update_Element}
+     (Container : @key{in out} List;
+      Position  : @key{in}     Cursor;
+      Process   : @key{not null access procedure}
+                      (Element : @key{in out} Element_Type));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] Constant_Reference_Type
+         (Element : @key[not null access constant] Element_Type) @key[is 
private]
+      @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Reference_Type} (Element : 
@key[not null access] Element_Type) @key[is private]
+      @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Constant_Reference} 
(Container : @key[aliased in] List;
+                                Position  : @key[in] Cursor)
+      @key[return] Constant_Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Reference} (Container : 
@key[aliased in out] List;
+                       Position  : @key[in] Cursor)
+      @key[return] Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Assign} (Target : @key{in 
out} List; Source : @key{in} List);]}
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Copy} (Source : List) 
@key[return] List;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Move} (Target : @key{in 
out} List;
+                   Source : @key{in out} List);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} List;
+                     Before    : @key{in}     Cursor;
+                     New_Item  : @key{in}     Element_Type;
+                     Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} List;
+                     Before    : @key{in}     Cursor;
+                     New_Item  : @key{in}     Element_Type;
+                     Position  :    @key{out} Cursor;
+                     Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} List;
+                     Before    : @key{in}     Cursor;
+                     Position  :    @key{out} Cursor;
+                     Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Prepend} (Container : 
@key{in out} List;
+                      New_Item  : @key{in}     Element_Type;
+                      Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Append} (Container : 
@key{in out} List;
+                     New_Item  : @key{in}     Element_Type;
+                     Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete} (Container : 
@key{in out} List;
+                     Position  : @key{in out} Cursor;
+                     Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_First} (Container : 
@key{in out} List;
+                           Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_Last} (Container : 
@key{in out} List;
+                          Count     : @key{in}     Count_Type := 1);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Reverse_Elements} 
(Container : @key{in out} List);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Swap} (Container : @key{in 
out} List;
+                   I, J      : @key{in}     Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Swap_Links} (Container : 
@key{in out} List;
+                         I, J      : @key{in}     Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Splice} (Target   : @key{in 
out} List;
+                     Before   : @key{in}     Cursor;
+                     Source   : @key{in out} List);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Splice} (Target   : @key{in 
out} List;
+                     Before   : @key{in}     Cursor;
+                     Source   : @key{in out} List;
+                     Position : @key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Splice} (Container: @key{in 
out} List;
+                     Before   : @key{in}     Cursor;
+                     Position : @key{in}     Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First} (Container : List) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First_Element} (Container : 
List)
+      @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Last} (Container : List) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Last_Element} (Container : 
List)
+      @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Next} (Position : Cursor) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Previous} (Position : 
Cursor) @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Next} (Position : @key{in 
out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Previous} (Position : 
@key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Find} (Container : List;
+                  Item      : Element_Type;
+                  Position  : Cursor := No_Element)
+      @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Reverse_Find} (Container : 
List;
+                          Item      : Element_Type;
+                          Position  : Cursor := No_Element)
+      @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Contains} (Container : List;
+                      Item      : Element_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Deleted],ARef=[AI05-0212-1]}
address@hidden,address@hidden,New=[],Old=[   @key{function} 
@AdaSubDefn{Has_Element} (Position : Cursor) @key{return} Boolean;]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Iterate}
+     (Container : @key{in} List;
+      Process   : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Reverse_Iterate}
+     (Container : @key{in} List;
+      Process   : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] Iterate (Container : @key[in] List)
+      @key[return] List_Iterator_Interfaces.Reversible_Iterator'Class;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] Iterate (Container : @key[in] List; 
Start : @key[in] Cursor)
+      @key[return] List_Iterator_Interfaces.Reversible_Iterator'Class;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{generic}
+      @key{with function} "<" (Left, Right : Element_Type)
+         @key{return} Boolean is <>;
+   @key{package} @AdaPackDefn{Generic_Sorting} @key{is}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{function} @AdaSubDefn{Is_Sorted} (Container : 
List) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{procedure} @AdaSubDefn{Sort} (Container : 
@key{in out} List);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{procedure} @AdaSubDefn{Merge} (Target  : 
@key{in out} List;
+                       Source  : @key{in out} List);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{end} Generic_Sorting;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ... -- @RI[not specified by the language]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Doubly_Linked_Lists;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The actual function for the generic formal function
+"=" on Element_Type values is expected to define a reflexive and symmetric
+relationship and return the same result value each time it is called with a
+particular pair of values. If it behaves in some other manner, the functions
+Find, Reverse_Find, and "=" on list values return an unspecified value. The
+exact arguments and number of calls of this generic formal function by the
+functions Find, Reverse_Find, and "=" on list values are
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If the actual function for "=" is not symmetric
+  and consistent, the result returned by the listed functions cannot be 
predicted.
+  The implementation is not required to protect
+  against "=" raising an exception, or returning random results, or any
+  other @lquotes@;address@hidden behavior. And it can call "=" in whatever
+  manner makes sense. But note that only the results of Find, Reverse_Find, and
+  List "=" are unspecified; other subprograms are not allowed to break if "="
+  is bad (they aren't expected to use "=").]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The type List is used to represent lists. The type
+List needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Empty_List represents the empty List object. It has
+a length of 0. If an object of type List is not otherwise initialized, it is
+initialized to the same value as Empty_List.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[No_Element represents a cursor that designates no
+element. If an object of type Cursor is not otherwise initialized, it is
+initialized to the same value as No_Element.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The predefined "=" operator for type Cursor returns
+True if both cursors are No_Element, or designate the same element in the same
+container.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Execution of the default implementation of the
+Input, Output, Read, or Write attribute of type Cursor raises Program_Error.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[A cursor will probably be implemented in terms
+  of one or more access values, and the effects of streaming access values is
+  unspecified. Rather than letting the user stream junk by accident, we mandate
+  that streaming of cursors raise Program_Error by default. The attributes
+  can always be specified if there is a need to support streaming.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0262-1]}
address@hidden,Text=[List'Write for a List object @i<L> writes
+Length(@i<L>) elements of the list to the stream. It also may write
+additional information about the list.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0262-1]}
address@hidden,Text=[List'Read reads the representation of a list
+from the stream, and assigns to @i<Item> a list with the same length and
+elements as was written by List'Write.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Streaming more elements than the container
+  length is wrong. For implementation implications of this rule, see the 
Implementation Note in
+  @RefSecNum{The Generic Package Containers.Vectors}.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden operations of this generic package
+have access-to-subprogram parameters. To ensure such operations are
+well-defined, they guard against certain actions by the designated
+subprogram. In particular, some operations check for @lquotes@;tampering with
address@hidden of a container because they depend on the set of elements of
+the container remaining constant, and others check for @lquotes@;tampering with
address@hidden of a container because they depend on elements of the
+container not being replaced.]]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],address@hidden with cursors],Sec=[of a list]}
+A subprogram is said to @i{tamper with cursors} of a list object
address@hidden<L> if:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it inserts or deletes elements of @i<L>, that is,
+it calls the Insert, Clear, Delete, or Delete_Last procedures with @i<L> as a
+parameter; or]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Operations which are defined to be equivalent to
+  a call on one of these operations also are included. Similarly, operations
+  which call one of these as part of their definition are included.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it reorders the elements of @i<L>, that is, it
+calls the Splice, Swap_Links, or Reverse_Elements procedures or the Sort or
+Merge procedures of an instance of Generic_Sorting with @i<L> as a parameter; 
or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it finalizes @i<L>; or]}
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Text=[it calls the Assign procedure with @i<L> as the
+Target parameter; or]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[We don't need to explicitly mention
+  @nt{assignment_statement}, because that finalizes the target object
+  as part of the operation, and finalization of an object is already defined
+  as tampering with cursors.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it calls the Move procedure with @i<L> as a
+parameter.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Swap copies elements rather than reordering them,
+  so it doesn't tamper with cursors.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],address@hidden with elements],Sec=[of a list]}
+A subprogram is said to @i{tamper with elements} of a list
+object @i<L> if:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it tampers with cursors of @i<L>; or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it replaces one or more elements of @i<L>, that is,
+it calls the Replace_Element or Swap procedures with @i<L> as
+a parameter.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Complete replacement of an element can cause
+  its memory to be deallocated while another operation is holding onto a
+  reference to it. That can't be allowed. However, a simple modification of
+  (part of) an element is not a problem, so Update_Element does not cause a
+  problem.]}
address@hidden
+
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0265-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0110-1]}
address@hidden,address@hidden,Sec=[tampering with a list]}
address@hidden,Sec=[prohibited for a list]}
+When tampering with cursors is @i<prohibited> for a particular list object
address@hidden<L>, Program_Error is propagated by a call of any 
language-defined subprogram
+that is defined to tamper with the cursors of @i<L>, leaving @i<L> unmodified.
+Similarly, when tampering with elements is @i<prohibited> for a particular list
+object @i<L>, Program_Error is propagated by a call of any language-defined
+subprogram that is defined to tamper with the elements of @i<L> @Redundant[(or
+tamper with the cursors of @i<L>)], leaving @i<L>
address@hidden,New=[ These checks are made before any other
+defined behavior of the body of the language-defined subprogram.],Old=[]}]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Tampering with elements includes tampering with
+  cursors, so we mention it only from completeness in the second sentence.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Has_Element (Position : Cursor) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[Returns True if Position designates
+an element, and returns False otherwise.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],Text=[This function might not detect cursors that
+  designate deleted elements; such cursors are invalid (see below) and the
+  result of calling Has_Element with an invalid cursor is unspecified (but
+  not erroneous).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "=" (Left, Right : List) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Left and Right denote the same
+list object, then the function returns True. If Left and Right have different
+lengths, then the function returns False.
+Otherwise, it compares each element in Left to
+the corresponding element in Right using the generic formal equality operator.
+If any such comparison returns False, the function returns False;
address@hidden,New=[,],Old=[]} it
+returns True. Any exception raised during
+evaluation of element equality is propagated.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This wording describes the canonical semantics.
+However, the order and number of calls on the formal equality function is
+unspecified for all of the operations that use it in this package, so an
+implementation can call it as many or as few times as it needs to get the
+correct answer. Specifically, there is no requirement to call the formal
+equality additional times once the answer has been determined.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Length (Container : List) 
@key{return} Count_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns the number of elements in
+Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Is_Empty (Container : List) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Length (Container) = 0.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Clear (Container : @key{in out} 
List);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Removes all the elements from Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Element (Position : Cursor) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Constraint_Error is propagated. Otherwise, Element returns the element
+designated by Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Replace_Element (Container : @key{in 
out} List;
+                           Position  : @b{in}     Cursor;
+                           New_Item  : @b{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element,
+then Constraint_Error is propagated; if Position does not designate an element
+in Container, then Program_Error is propagated.
address@hidden,New=[,],Old=[]} Replace_Element
+assigns the value New_Item to the element designated by Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Query_Element
+  (Position : @key{in} Cursor;
+   Process  : @key{not null access procedure} (Element : @key{in} 
Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0021-1],ARef=[AI05-0265-1]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Constraint_Error is propagated. Otherwise, Query_Element calls
address@hidden with the element designated by Position as the argument.
address@hidden,New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the elements of @Chg{Version=[3],New=[the list that contains the
+element designated by Position is prohibited during the
+execution of the call on address@hidden,Old=[Container]}. Any exception raised 
by
address@hidden is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Update_Element
+  (Container : @key{in out} List;
+   Position  : @key{in}     Cursor;
+   Process   : @key{not null access procedure} (Element : @key{in out} 
Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Position equals No_Element, then
+Constraint_Error is propagated; if Position does not designate an element in
+Container, then Program_Error is propagated.
address@hidden,New=[,],Old=[]} Update_Element calls
address@hidden with the element designated by Position as the
+argument. @Chg{Version=[3],New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the elements of address@hidden,New=[ is prohibited during the
+execution of the call on address@hidden,Old=[]}. Any exception raised by
address@hidden is propagated.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[If Element_Type is unconstrained
+and definite, then the actual Element parameter of address@hidden shall be
+unconstrained.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This means that the elements cannot be directly
+  allocated from the heap; it must be possible to change the discriminants of
+  the element in place.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden Constant_Reference_Type
+      (Element : @key[not null access constant] Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Reference_Type (Element : @key[not 
null access] Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[The types Constant_Reference_Type
+and Reference_Type need address@hidden<needs finalization>,
+Sec=<language-defined type>}]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The default initialization of an object of type
+Constant_Reference_Type or Reference_Type propagates Program_Error.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[It is expected that Reference_Type (and
+  Constant_Reference_Type) will be a controlled type, for which finalization
+  will have some action to terminate the tampering check for the associated
+  container. If the object is created by default, however, there is no
+  associated container. Since this is useless, and supporting this case would
+  take extra work, we define it to raise an exception.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Constant_Reference (Container : 
@key[aliased in] List;
+                             Position  : @key[in] Cursor)
+   @key[return] Constant_Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Constant_Indexing and Implicit_Dereference aspects) provides a convenient way 
to
+gain read access to an individual element of a list given a
+cursor.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Position equals No_Element, then Constraint_Error
+is propagated; if Position does not designate an element in Container, then
+Program_Error is propagated. Otherwise, Constant_Reference returns an object
+whose discriminant is an access value that designates the element designated by
+Position. Tampering with the elements of Container is prohibited while the
+object returned by Constant_Reference exists and has not been finalized.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Reference (Container : @key[aliased 
in out] List;
+                    Position  : @key[in] Cursor)
+   @key[return] Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Variable_Indexing and Implicit_Dereference aspects) provides a convenient way 
to
+gain read and write access to an individual element of a list given
+a cursor.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Position equals No_Element, then Constraint_Error
+is propagated; if Position does not designate an element in Container, then
+Program_Error is propagated. Otherwise, Reference returns an object whose
+discriminant is an access value that designates the element designated by
+Position. Tampering with the elements of Container is prohibited while the
+object returned by Reference exists and has not been finalized.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Assign (Target : @key{in out} List; 
Source : @key{in} List);]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0248-1]}
address@hidden,Type=[Trailing],Text=[If Target denotes the same object as
+Source, the operation has no effect. Otherwise, the elements of Source are
+copied to Target as for an @nt{assignment_statement} assigning Source to
+Target.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[3],Text=[This routine exists for compatibility with the
+  bounded list container. For an unbounded list, @exam{Assign(A, B)} and
+  @exam{A := B} behave identically. For a bounded list, := will raise an
+  exception if the container capacities are different, while Assign will
+  not raise an exception if there is enough room in the target.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Copy (Source : List) @key[return] 
List;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Type=[Trailing],Text=[Returns a list whose elements match
+the elements of Source.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Move (Target : @key{in out} List;
+                Source : @key{in out} List);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0001-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1]}
address@hidden,Type=[Trailing],Text=[If Target denotes the same object
+as Source, then @Chg{Version=[3],New=[the operation],Old=[Move]}
+has no effect. Otherwise, @Chg{Version=[3],New=[the operation is equivalent
+to Assign (Target, Source) followed by Clear (Source)],Old=[Move first calls 
Clear
+(Target). Then, the nodes in Source are moved to Target (in the original 
order).
+The length of Target is set to the length of Source, and the length of Source 
is
+set to 0]}.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} 
List;
+                  Before    : @key{in}     Cursor;
+                  New_Item  : @key{in}     Element_Type;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Before is not No_Element, and
+does not designate an element in Container, then Program_Error is propagated.
+Otherwise,
+Insert inserts Count copies of New_Item prior to the element designated by
+Before. If Before equals No_Element, the new elements are inserted after the
+last node (if any). Any exception raised during allocation of internal storage
+is propagated, and Container is not modified.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The check on Before checks that the cursor does
+  not belong to some other Container. This check implies that a reference to
+  the container is included in the cursor value. This wording is not meant to
+  require detection of dangling cursors; such cursors are defined to be
+  invalid, which means that execution is erroneous, and any result is allowed
+  (including not raising an exception).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} 
List;
+                  Before    : @key{in}     Cursor;
+                  New_Item  : @key{in}     Element_Type;
+                  Position  :    @key{out} Cursor;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0257-1]}
address@hidden,Type=[Trailing],Text=[If Before is not No_Element, and
+does not designate an element in Container, then Program_Error is
+propagated. Otherwise,
+Insert allocates Count copies of New_Item, and inserts them prior to the
+element designated by Before. If Before equals No_Element, the new elements are
+inserted after the last element (if any). Position designates the first
+newly-inserted address@hidden,New=[, or if Count equals 0,
+then Position is assigned the value of Before],Old=[]}. Any exception raised
+during allocation of internal
+storage is propagated, and Container is not modified.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} 
List;
+                  Before    : @key{in}     Cursor;
+                  Position  :    @key{out} Cursor;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0257-1]}
address@hidden,Type=[Trailing],Text=[If Before is not No_Element, and
+does not designate an element in Container, then Program_Error is
+propagated. Otherwise,
+Insert inserts Count new elements prior to the element designated by Before. If
+Before equals No_Element, the new elements are inserted after the last node (if
+any). The new elements are initialized by default (see
address@hidden Declarations}). @Chg{Version=[3],New=[Position designates the
+first newly-inserted element, or if Count equals 0,
+then Position is assigned the value of Before],Old=[]}. Any exception raised
+during allocation of internal storage is propagated, and Container is not
+modified.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Prepend (Container : @key{in out} 
List;
+                   New_Item  : @key{in}     Element_Type;
+                   Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Insert (Container,
+First (Container), New_Item, Count).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Append (Container : @key{in out} 
List;
+                  New_Item  : @key{in}     Element_Type;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Insert (Container,
+No_Element, New_Item, Count).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete (Container : @key{in out} 
List;
+                  Position  : @key{in out} Cursor;
+                  Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Constraint_Error is propagated. If Position does not designate an element in
+Container, then Program_Error is propagated.
address@hidden,New=[,],Old=[]} Delete removes (from
+Container) Count elements starting at the element designated by Position (or
+all of the elements starting at Position if there are fewer than Count elements
+starting at Position). Finally, Position is set to No_Element.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete_First (Container : @key{in 
out} List;
+                        Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0021-1]}
address@hidden,Type=[Trailing],address@hidden,New=[If Length
+(Container) <= Count, then Delete_First is equivalent to Clear (Container).
+Otherwise, it removes the first Count nodes from Container],Old=[Equivelent to
+Delete (Container, First (Container), Count)]}.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete_Last (Container : @key{in 
out} List;
+                       Count     : @key{in}     Count_Type := 1);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If
+Length (Container) <= address@hidden,New=[,],Old=[]} then
+Delete_Last is equivalent to Clear (Container).
address@hidden,New=[,],Old=[]} it removes the last
+Count nodes from Container.]}
+
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reverse_Elements (Container : 
@key{in out} List);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Reorders the elements of Container
+in reverse order.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Unlike the similar routine for a vector,
+  elements should not be copied; rather, the nodes should be exchanged. Cursors
+  are expected to reference the same elements afterwards.]}
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Swap (Container : @key{in out} List;
+                I, J      : @key{in}     Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If either I or J is No_Element,
+then Constraint_Error is propagated. If either I or J do not designate an
+element in Container, then Program_Error is propagated. Otherwise, Swap
+exchanges the values of the elements designated by I and J.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[After a call to Swap, I designates the element
+  value previously designated by J, and J designates the element value
+  previously designated by I. The cursors do not become ambiguous from
+  this operation.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The implementation is not required to actually
+  copy the elements if it can do the swap some other way. But it is allowed
+  to copy the elements if needed.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Swap_Links (Container : @key{in out} 
List;
+                      I, J      : @key{in}     Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If either I or J is No_Element,
+then Constraint_Error is propagated. If either I or J do not designate an
+element in Container, then Program_Error is propagated. Otherwise, Swap_Links
+exchanges the nodes designated by I and J.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Unlike Swap, this exchanges the nodes, not the
+  elements. No copying is performed. I and J designate the same elements after
+  this call as they did before it. This operation can provide better 
performance
+  than Swap if the element size is large.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Splice (Target   : @key{in out} List;
+                  Before   : @key{in}     Cursor;
+                  Source   : @key{in out} List);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Before is not No_Element, and
+does not designate an element in Target, then Program_Error is propagated.
+Otherwise, if
+Source denotes the same object as Target, the operation has no effect.
+Otherwise, Splice reorders elements such that they are removed from Source and
+moved to Target, immediately prior to Before. If Before equals No_Element, the
+nodes of Source are spliced after the last node of Target. The length of Target
+is incremented by the number of nodes in Source, and the length of Source is
+set to 0.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Splice (Target   : @key{in out} List;
+                  Before   : @key{in}     Cursor;
+                  Source   : @key{in out} List;
+                  Position : @key{in out} Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Position is
address@hidden,New=[,],Old=[]} then
+Constraint_Error is propagated. If Before does not equal No_Element, and does
+not designate an element in Target, then Program_Error is propagated. If
+Position does not equal No_Element, and does not designate a node in Source,
+then Program_Error is propagated. If Source denotes the same object as Target,
+then there is no effect if Position equals Before, else the element
+designated by Position is moved immediately prior to Before, or, if Before
+equals No_Element, after the last element.
+In both cases, Position and the length of Target are unchanged.
address@hidden,New=[,],Old=[]} the element
+designated by Position is removed from Source and moved to Target, immediately
+prior to Before, or, if Before equals No_Element, after the last element of
+Target. The length of Target is incremented, the length of Source is
+decremented, and Position is updated to represent an element in Target.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If Source is the same as Target, and
+  Position = Before, or Next(Position) = Before, Splice has no effect, as
+  the element does not have to move to meet the postcondition.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Splice (Container: @key{in out} List;
+                  Before   : @key{in}     Cursor;
+                  Position : @key{in}     Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Position is
address@hidden,New=[,],Old=[]} then
+Constraint_Error is propagated. If Before does not equal No_Element, and does
+not designate an element in Container, then Program_Error is propagated. If
+Position does not equal No_Element, and does not designate a node in Container,
+then Program_Error is propagated. If Position equals Before there is no effect.
+Otherwise, the element designated by Position is moved immediately prior to
+Before, or, if Before equals No_Element, after the last element. The length of
+Container is unchanged.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First (Container : List) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Container is empty, First
+returns the value No_Element.
address@hidden,New=[,],Old=[]}
+it returns a cursor that designates the first node in Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First_Element (Container : List) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Element (First 
(Container)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Last (Container : List) @key{return} 
Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Container is empty, Last returns
+the value No_Element. address@hidden,New=[,],Old=[]}
+it returns a cursor that designates the last node in Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Last_Element (Container : List) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Element (Last (Container)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Next (Position : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element or
+designates the last element of the container, then Next returns the value
+No_Element. Otherwise, it returns a cursor that designates the successor of the
+element designated by Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Previous (Position : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element or
+designates the first element of the container, then Previous returns the value
+No_Element. Otherwise, it returns a cursor that designates the predecessor of
+the element designated by Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Next (Position : @key{in out} 
Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Position := Next 
(Position).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Previous (Position : @key{in out} 
Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Position := Previous 
(Position).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Find (Container : List;
+               Item      : Element_Type;
+               Position  : Cursor := No_Element)
+  @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position is not No_Element, and
+does not designate an element in Container, then Program_Error is propagated.
+Find searches the elements of Container for an element equal to Item (using
+the generic formal equality operator). The search starts at the
+element designated by Position, or at the first element if Position equals
+No_Element. It proceeds towards Last (Container). If no equal element is found,
+then Find returns No_Element. Otherwise, it returns a cursor designating the
+first equal element encountered.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reverse_Find (Container : List;
+                       Item      : Element_Type;
+                       Position  : Cursor := No_Element)
+   @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position is not No_Element, and
+does not designate an element in Container, then Program_Error is propagated.
+Find searches the elements of Container for an element equal to Item (using
+the generic formal equality operator). The search starts at the
+element designated by Position, or at the last element if Position equals
+No_Element. It proceeds towards First (Container). If no equal element is
+found, then Reverse_Find returns No_Element. Otherwise, it returns a cursor
+designating the first equal element encountered.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Contains (Container : List;
+                   Item      : Element_Type) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Find (Container, Item) /= 
No_Element.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,KeepNext=[T],address@hidden,New=[],address@hidden Has_Element 
(Position : Cursor) @key{return} Boolean;]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],address@hidden,New=[],Old=[Returns True if 
Position designates
+an element, and returns False otherwise.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[2],address@hidden,New=[],Old=[This function may not 
detect cursors that
+  designate deleted elements; such cursors are invalid (see below) and the
+  result of calling Has_Element with an invalid cursor is unspecified (but
+  not erroneous).]}]}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraphs 139 and 140
+were moved above.>address@hidden message should be
+deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Iterate
+  (Container : @key{in} List;
+   Process   : @key{not null access procedure} (Position : @key{in} Cursor));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0265-1]}
address@hidden,Type=[Trailing],Text=[Iterate calls address@hidden
+with a cursor that designates each node in Container, starting with the first
+node and moving the cursor as per the Next function.
address@hidden,New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the cursors of address@hidden,New=[ is prohibited during the
+execution of a call on address@hidden,Old=[]}. Any exception raised by
address@hidden is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The purpose of the tamper with cursors check is
+  to prevent erroneous execution from the Position parameter of address@hidden
+  becoming invalid. This check takes place when the operations that tamper with
+  the cursors of the container are called. The check cannot be made later (say
+  in the body of Iterate), because that could cause the Position cursor to be
+  invalid and potentially cause execution to become erroneous -- defeating the
+  purpose of the check.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[See Iterate for vectors
+  (@RefSecNum{The Generic Package Containers.Vectors}) for a suggested
+  implementation of the check.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reverse_Iterate
+  (Container : @key{in} List;
+   Process   : @key{not null access procedure} (Position : @key{in} Cursor));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[Iterates over the nodes in
+Container as per @Chg{Version=[3],New=[procedure ],Old=[]}Iterate,
+except that elements are traversed in reverse order,
+starting with the last node and moving the cursor as per the Previous
+function.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Iterate (Container : @key[in] List)
+   @key[return] List_Iterator_Interfaces.Reversible_Iterator'Class;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[Iterate returns a reversible
+iterator object (see @RefSecNum{User-Defined Iterator Types}) that
+will generate a value for a loop parameter (see
address@hidden Loop Iteration}) designating
+each node in Container, starting with the first node and moving the cursor as
+per the Next function when used as a forward iterator, and starting with the
+last node and moving the cursor as per the Previous function when used as a
+reverse iterator. Tampering with the cursors of Container is prohibited while
+the iterator object exists (in particular, in
+the @nt{sequence_of_statements} of the @nt{loop_statement} whose
address@hidden denotes this object). The iterator object needs
+finalization.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Iterate (Container : @key[in] List; 
Start : @key[in] Cursor)
+   @key[return] List_Iterator_Interfaces.Reversible_Iterator'Class;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0262-1],ARef=[AI05-0265-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[If Start is not No_Element and does
+not designate an item in Container, then Program_Error is propagated. If Start
+is No_Element, then Constraint_Error is propagated. Otherwise, Iterate
+returns a reversible iterator object
+(see @RefSecNum{User-Defined Iterator Types}) that
+will generate a value for a loop parameter (see
address@hidden Loop Iteration}) designating
+each node in Container, starting with the node designated
+by Start and moving the cursor as per the Next function when used as a forward
+iterator, or moving the cursor as per the Previous function when used as a
+reverse iterator. Tampering with the cursors of Container is prohibited while
+the iterator object exists (in particular, in
+the @nt{sequence_of_statements} of the @nt{loop_statement} whose
address@hidden denotes this object). The iterator object needs
+finalization.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[Exits are allowed from the loops
+  created using the iterator objects. In particular, to stop the iteration at a
+  particular cursor, just add]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden when] Cur = Stop;]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[in the body of the loop (assuming
+  that @exam{Cur} is the loop parameter and @exam{Stop} is the cursor that you
+  want to stop at).]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0044-1],ARef=[AI05-0262-1]}
address@hidden,Text=[The actual function for the generic formal function
+"<" of Generic_Sorting is expected to return the same value each time it is
+called with a particular pair of element values. It should define a strict
address@hidden,New=[weak ],Old=[]}ordering address@hidden,
+New=[ (see @RefSecNum{Containers})],Old=[, that is, be irreflexive, asymmetric,
+and transitive]}; it
+should not modify Container. If the actual for "<" behaves in some other
+manner, the behavior of the subprograms of Generic_Sorting are unspecified.
address@hidden,New=[The number of],Old=[How many]} times the subprograms of
+Generic_Sorting call "<" is address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Is_Sorted (Container : List) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns True if the elements are
+sorted smallest first as determined by the generic formal "<" operator;
+otherwise, Is_Sorted returns False. Any exception raised during evaluation of
+"<" is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Sort (Container : @key{in out} 
List);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Reorders the nodes of Container
+such that the elements are sorted smallest first as determined by the generic
+formal "<" operator provided. The sort is stable. Any exception raised during
+evaluation of "<" is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Unlike array sorts, we do require stable sorts
+  here. That's because algorithms in the merge sort family (as described by
+  Knuth) can be both fast and stable. Such sorts use the extra memory as
+  offered by the links to provide better performance.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Note that list sorts never copy elements; it is
+  the nodes, not the elements, that are reordered.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Merge (Target  : @key{in out} List;
+                 Source  : @key{in out} List);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0021-1]}
address@hidden,Type=[Trailing],address@hidden,New=[If Source is
+empty, then Merge does nothing. If Source and Target are the same nonempty
+container object, then Program_Error is propagated. Otherwise, ],Old=[]}Merge
+removes elements from Source
+and inserts them into Target; afterwards,
+Target contains the union of the elements that were initially
+in Source and Target; Source is left empty.
+If Target and Source are initially sorted smallest first, then Target is
+ordered smallest first as determined by the generic formal "<" operator;
+otherwise, the order of elements in Target is unspecified.
+Any exception raised during evaluation of "<" is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[It is a bounded error if either of the lists is
+  unsorted, see below. The bounded error can be recovered by sorting Target
+  after the merge call, or the lists can be pretested with Is_Sorted.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+Calling Merge in an instance of Generic_Sorting
+with either Source or Target not ordered smallest first using the provided
+generic formal "<" operator is a bounded error. Either Program_Error is raised
+after Target is updated as described for Merge, or the operation works as
+defined.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0022-1],ARef=[AI05-0248-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error for the actual function
+associated with a generic formal subprogram, when called as part of an
+operation of this package, to tamper with elements of any List parameter of
+the operation. Either Program_Error is raised, or the operation works as
+defined on the value of the List either prior to, or subsequent to, some or
+all of the modifications to the List.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0027-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to call any subprogram
+declared in the visible part of Containers.Doubly_Linked_Lists
+when the associated container has been finalized. If the operation takes
+Container as an @key[in out] parameter, then it raises Constraint_Error or
+Program_Error. Otherwise, the operation either proceeds as it would
+for an empty container, or it raises Constraint_Error or Program_Error.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],Text=[A Cursor value is
address@hidden<invalid> if any of the following have occurred since it
+was created:@Defn2{Term=[invalid cursor],Sec=[of a list container]}
address@hidden,Sec=[invalid]}]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The list that contains the element it designates
+has been finalized;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0160-1]}
address@hidden,Text=[The list that contains the element it designates
+has been used as the Target of a call to Assign, or as the target of an
address@hidden;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden list that contains the element it
+designates has been used as the Source or Target of a call to Move;] or]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],Text=[Move has been reworded in terms of Assign and
+  Clear, which are covered by other bullets, so this text is redundant.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0160-1],ARef=[AI05-0262-1]}
address@hidden,Text=[The element it designates has been
address@hidden,New=[removed from the list that previously contained the
+element],Old=[deleted]}.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0160-1]}
+  @ChgAdded{Version=[3],Text=[The cursor modified by the four parameter Splice
+  is not invalid, even though the element it designates has been removed from
+  the source list, because that cursor has been modified to designate that
+  element in the target list @en the cursor no longer designates an element
+  in the source list.]}
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0160-1]}
+  @ChgAdded{Version=[3],Text=[This can happen directly via calls to Delete,
+  Delete_Last, Clear, Splice with a Source parameter, and Merge; and indirectly
+  via calls to Delete_First, Assign, and Move.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The result of "=" or Has_Element is unspecified
+if it is called with an invalid
+cursor parameter. Execution is erroneous if any other subprogram declared in
+Containers.Doubly_Linked_Lists is called with an invalid cursor parameter.
address@hidden@PDefn2{Term=(erroneous execution),Sec=(cause)}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The list above is intended to be exhaustive. In
+  other cases, a cursor value continues to designate its original element. For
+  instance, cursor values survive the insertion and deletion of other nodes.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[While it is possible to check for these cases, in
+  many cases the overhead necessary to make the check is substantial in time or
+  space. Implementations are encouraged to check for as many of these cases as
+  possible and raise Program_Error if detected.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[Execution is erroneous if the list associated with
+the result of a call to Reference or Constant_Reference is finalized before the
+result object returned by the call to Reference or Constant_Reference is
+finalized.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Each object of Reference_Type and
+  Constant_Reference_Type probably contains some reference to the originating
+  container. If that container is prematurely finalized (which is only possible
+  via Unchecked_Deallocation, as accessibility checks prevent passing a
+  container to Reference that will not live as long as the result), the
+  finalization of the object of Reference_Type will try to access a nonexistent
+  object. This is a normal case of a dangling pointer created by
+  Unchecked_Deallocation; we have to explicitly mention it here as the pointer
+  in question is not visible in the specification of the type. (This is the 
same
+  reason we have to say this for invalid cursors.)]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[No storage associated with a doubly-linked List
+object shall be lost upon assignment or scope exit.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden,Text=[The execution of an @nt{assignment_statement} for
+a list shall have the effect of copying the elements from the source list
+object to the target list address@hidden,New=[ and changing the length
+of the target object to that of the source object],Old=[]}.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0298-1]}
+  @ChgAdded{Version=[2],Text=[An assignment of a List is a 
@lquotes@;address@hidden
+  copy; that is the elements are copied as well as the data structures.
+  We say @lquotes@;effect address@hidden in order to allow the implementation 
to
+  avoid copying elements immediately if it wishes. For instance, an
+  implementation that avoided copying until one of the containers is modified
+  would be address@hidden,New=[ (Note that this implementation would
+  require care, see @RefSecNum{The Generic Package Containers.Vectors} for 
more.)],Old=[]}]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Containers.Doubly_Linked_Lists should be
+implemented similarly to a linked list. In particular, if @i<N> is the length
+of a list, then the worst-case time complexity of Element, Insert with Count=1,
+and Delete with Count=1 should be @i{O}(log @i<N>).]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The worst-case time complexity of Element, Insert with Count=1, and
+Delete with Count=1 for Containers.Doubly_Linked_Lists should be
address@hidden(log @i<N>).]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We do not mean to overly constrain implementation
+  strategies here. However, it is important for portability that the
+  performance of large containers has roughly the same factors on different
+  implementations. If a program is moved to an implementation that takes
+  @i{O}(@i<N>) time to access elements, that program could be unusable when the
+  lists are large. We allow @i{O}(log @i<N>) access because the proportionality
+  constant and caching effects are likely to be larger than the log factor, and
+  we don't want to discourage innovative implementations.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The worst-case time complexity of a call on
+procedure Sort of an
+instance of Containers.Doubly_Linked_Lists.Generic_Sorting should be
address@hidden(@i<N>**2), and the average time complexity should be better than 
@i{O}(@i<N>**2).]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[A call on procedure Sort of an
+instance of Containers.Doubly_Linked_Lists.Generic_Sorting
+should have an average time complexity better than @i{O}(@i{N}**2) and
+worst case no worse than @i{O}(@i{N}**2).]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[In other words, we're requiring the use of a
+  better than @i{O}(@i{N}**2) sorting algorithm, such as Quicksort. No bubble 
sorts
+  allowed!]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Move should not copy elements, and should minimize
+copying of internal data structures.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Containers.Doubly_Linked_Lists.Move should not copy elements, and should
+minimize copying of internal data structures.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Usually that can be accomplished simply by
+  moving the pointer(s) to the internal data structures from the Source
+  container to the Target container.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[If an exception is propagated from a list
+operation, no storage should be lost, nor any elements removed from a list
+unless specified by the operation.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If an exception is propagated from a list
+operation, no storage should be lost, nor any elements removed from a list
+unless specified by the operation.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is important so that programs can recover
+  from errors. But we don't want to require heroic efforts, so we just require
+  documentation of cases where this can't be accomplished.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Sorting a list never copies elements, and is a
+stable sort (equal elements remain in the original order). This is different
+than sorting an array or vector, which may need to copy elements, and is
+probably not a stable sort.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The generic package Containers.Doubly_Linked_Lists is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0248-1],ARef=[AI05-0257-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  The Insert versions that return a Position parameter are now defined to
+  return Position = Before if Count = 0. This was unspecified for Ada 2005;
+  so this will only be inconsistent if an implementation did something else and
+  a program depended on that something else @em this should be very rare.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}Subprograms Assign and 
Copy
+  are added to Containers.Doubly_Linked_Lists. If an instance of 
Containers.Doubly_Linked_Lists
+  is referenced in a @nt{use_clause}, and an entity @i<E> with the same
+  @nt{defining_identifier} as a new entity in Containers.Doubly_Linked_Lists is
+  defined in a package that is also referenced in a @nt{use_clause}, the
+  entity @i<E> may no longer be use-visible, resulting in errors. This should
+  be rare and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Added iterator, reference, and indexing support to make list containers more
+  convenient to use.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],Text=[Generalized the definition
+  of Move. Specified which elements are read/written by stream attributes.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0022-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a @BoundedName
+  to cover tampering by generic actual subprograms.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0027-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a @BoundedName
+  to cover access to finalized list containers.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0044-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Redefined "<" actuals
+  to require a strict weak ordering; the old definition allowed
+  indeterminant comparisons that would not have worked in a container.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0084-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a pragma
+  Remote_Types so that containers can be used in distributed programs.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0160-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Revised the definition
+  of invalid cursors to cover missing (and new) cases.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0257-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added missing wording to 
describe
+  the Position after Inserting 0 elements.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0265-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Defined when a container
+  prohibits tampering in order to more clearly define where the check is
+  made and the exception raised.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0110-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that tampering 
checks
+  precede all other checks made by a subprogram (but come after those 
associated
+  with the call).]}
address@hidden
+
address@hidden,Name=[Maps]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The language-defined generic packages
+Containers.Hashed_Maps and Containers.Ordered_Maps provide private types Map
+and Cursor, and a set of operations for each type. A map container allows an
+arbitrary type to be used as a key to find the element associated with that
+key. A hashed map uses a hash function to organize the keys, while an ordered
+map orders the keys per a specified relation.
address@hidden address@hidden,Sec=[map]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[section]}
+describes the declarations that are
+common to both kinds of maps. See @RefSecNum{The Generic Package 
Containers.Hashed_Maps}
+for a description of the semantics specific to
+Containers.Hashed_Maps and @RefSecNum{The Generic Package 
Containers.Ordered_Maps} for
+a description of the semantics specific to Containers.Ordered_Maps.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The actual function for the generic formal function
+"=" on Element_Type values is expected to define a reflexive and symmetric
+relationship and return the same result value each time it is called with a
+particular pair of values. If it behaves in some other manner, the function
+"=" on map values returns an unspecified value. The
+exact arguments and number of calls of this generic formal function by the
+function "=" on map values are address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If the actual function for "=" is not symmetric
+  and consistent, the result returned by "=" for Map objects cannot be 
predicted.
+  The implementation is not required to protect
+  against "=" raising an exception, or returning random results, or any
+  other @lquotes@;address@hidden behavior. And it can call "=" in whatever
+  manner makes sense. But note that only the result of "=" for Map objects
+  is unspecified; other subprograms are not allowed to break if "="
+  is bad (they aren't expected to use "=").]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The type Map is used to represent maps. The type
+Map needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden,Sec=[of a map]}A map contains
+pairs of keys and elements, called @i{nodes}. Map cursors designate nodes, but
+also can be thought of as designating an element (the element contained in the
+node) for consistency with the other containers. There exists an equivalence
+relation on keys, whose definition is different for hashed maps and ordered
+maps. A map never contains two or more nodes with equivalent keys. The
address@hidden of a map is the number of nodes it
address@hidden,Sec=[of a map]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden node],Sec=[of a map]}
address@hidden node],Sec=[of a map]}
address@hidden node],Sec=[of a map]}Each nonempty map has two
+particular nodes called the @i{first node} and the @i{last node} (which may be
+the same). Each node except for the last node has a @i{successor node}. If
+there are no other intervening operations, starting with the first node and
+repeatedly going to the successor node will visit each node in the map exactly
+once until the last node is reached. The exact definition of these terms is
+different for hashed maps and ordered maps.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden operations of these generic packages
+have access-to-subprogram parameters. To ensure such operations are
+well-defined, they guard against certain actions by the designated
+subprogram. In particular, some operations check for @lquotes@;tampering with
address@hidden of a container because they depend on the set of elements of
+the container remaining constant, and others check for @lquotes@;tampering with
address@hidden of a container because they depend on elements of the
+container not being replaced.]]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],Text=[
address@hidden with cursors],Sec=[of a map]}
+A subprogram is said to @i{tamper with cursors} of a map object @i<M>
+if:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it inserts or deletes elements of @i<M>, that is,
+it calls the Insert, Include, Clear, Delete, or Exclude procedures with @i<M>
+as a parameter; or]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Operations which are defined to be equivalent to
+  a call on one of these operations also are included. Similarly, operations
+  which call one of these as part of their definition are included.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it finalizes @i<M>; or]}
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Text=[it calls the Assign procedure with @i<M> as the Target 
parameter; or]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We don't need to explicitly mention
+  @nt{assignment_statement}, because that finalizes the target object
+  as part of the operation, and finalization of an object is already defined
+  as tampering with cursors.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it calls the Move procedure with @i<M> as a
+parameter; or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it calls one of the operations defined to tamper
+with the cursors of @i<M>.]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Replace only modifies a key and element rather
+  than rehashing, so it does not tamper with cursors.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],Text=[
address@hidden with elements],Sec=[of a map]}
+A subprogram is said to @i{tamper with elements} of a map object @i<M> if:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it tampers with cursors of @i<M>; or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it replaces one or more elements of @i<M>, that is,
+it calls the Replace or Replace_Element procedures with @i<M>
+as a parameter.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Complete replacement of an element can cause its
+  memory to be deallocated while another operation is holding onto a reference
+  to it. That can't be allowed. However, a simple modification of (part of) an
+  element is not a problem, so Update_Element does not cause a problem.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0265-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0110-1]}
address@hidden,address@hidden,Sec=[tampering with a map]}
address@hidden,Sec=[prohibited for a map]}
+When tampering with cursors is @i<prohibited> for a particular map object
address@hidden<M>, Program_Error is propagated by a call of any 
language-defined subprogram
+that is defined to tamper with the cursors of @i<M>, leaving @i<M> unmodified.
+Similarly, when tampering with elements is @i<prohibited> for a particular map
+object @i<M>, Program_Error is propagated by a call of any language-defined
+subprogram that is defined to tamper with the elements of @i<M> @Redundant[(or
+tamper with the cursors of @i<M>)], leaving @i<M>
address@hidden,New=[ These checks are made before any other
+defined behavior of the body of the language-defined subprogram.],Old=[]}]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Tampering with elements includes tampering with
+  cursors, so we mention it only from completeness in the second sentence.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Empty_Map represents the empty Map object. It has a
+length of 0. If an object of type Map is not otherwise initialized, it is
+initialized to the same value as Empty_Map.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[No_Element represents a cursor that designates no
+node. If an object of type Cursor is not otherwise initialized, it is
+initialized to the same value as No_Element.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The predefined "=" operator for type Cursor returns
+True if both cursors are No_Element, or designate the same element in the same
+container.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Execution of the default implementation of the
+Input, Output, Read, or Write attribute of type Cursor raises Program_Error.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[A cursor will probably be implemented in terms
+  of one or more access values, and the effects of streaming access values is
+  unspecified. Rather than letting the user stream junk by accident, we mandate
+  that streaming of cursors raise Program_Error by default. The attributes
+  can always be specified if there is a need to support streaming.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0262-1]}
address@hidden,Text=[Map'Write for a Map object @i<M> writes
+Length(@i<M>) elements of the map to the stream. It also may write
+additional information about the map.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0262-1]}
address@hidden,Text=[Map'Read reads the representation of a map
+from the stream, and assigns to @i<Item> a map with the same length and
+elements as was written by Map'Write.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Streaming more elements than the container
+  length is wrong. For implementation implications of this rule, see the 
Implementation Note in
+  @RefSecNum{The Generic Package Containers.Vectors}.]}
address@hidden
+
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Has_Element (Position : Cursor) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[Returns True if Position designates
+an element, and returns False otherwise.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],Text=[This function might not detect cursors that
+  designate deleted elements; such cursors are invalid (see below) and the
+  result of calling Has_Element with an invalid cursor is unspecified (but
+  not erroneous).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "=" (Left, Right : Map) @key{return} 
Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],Text=[If Left and Right denote the same
+map object, then the function returns True. If Left and Right have different
+lengths, then the function returns False. Otherwise, for each key @i<K> in
+Left, the function returns False if:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[a key equivalent to @i<K> is not present
+in Right; or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[the element associated with @i<K>
+in Left is not equal to the element associated with @i<K> in Right (using the
+generic formal equality operator for elements).]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[If the function has not returned a
+result after checking all of the keys, it returns True. Any exception raised
+during evaluation of key equivalence or element equality is propagated.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This wording describes the canonical semantics.
+However, the order and number of calls on the formal equality function is
+unspecified for all of the operations that use it in this package, so an
+implementation can call it as many or as few times as it needs to get the
+correct answer. Specifically, there is no requirement to call the formal
+equality additional times once the answer has been determined.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Length (Container : Map) 
@key{return} Count_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns the number of nodes in Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Is_Empty (Container : Map) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Length (Container) = 0.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Clear (Container : @key{in out} 
Map);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Removes all the nodes from Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Key (Position : Cursor) @key{return} 
Key_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Constraint_Error is propagated. Otherwise, Key returns the key component of the
+node designated by Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Element (Position : Cursor) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Constraint_Error is propagated. Otherwise, Element returns the element
+component of the node designated by Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Replace_Element (Container : @key{in 
out} Map;
+                           Position  : @key{in}     Cursor;
+                           New_Item  : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element,
+then Constraint_Error is propagated; if Position does not designate an element
+in Container, then Program_Error is propagated.
address@hidden,New=[,],Old=[]} Replace_Element
+assigns New_Item to the element of the node designated by Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Query_Element
+  (Position : @key{in} Cursor;
+   Process  : @key{not null access procedure} (Key     : @key{in} Key_Type;
+                                         Element : @key{in} Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0021-1],ARef=[AI05-0265-1]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Constraint_Error is propagated. Otherwise, Query_Element calls
address@hidden with the key and element from the node designated by Position
+as the arguments.
address@hidden,New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the elements of @Chg{Version=[3],New=[the map that contains the
+element designated by Position is prohibited during the
+execution of the call on address@hidden,Old=[Container]}. Any exception raised 
by
address@hidden is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Update_Element
+  (Container : @key{in out} Map;
+   Position  : @key{in}     Cursor;
+   Process   : @key{not null access procedure} (Key     : @key{in}     
Key_Type;
+                                          Element : @key{in out} 
Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Position equals No_Element, then
+Constraint_Error is propagated; if Position does not designate an element in
+Container, then Program_Error is propagated.
address@hidden,New=[,],Old=[]} Update_Element calls
address@hidden with the key and element from the node designated by Position
+as the arguments. @Chg{Version=[3],New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the elements of address@hidden,New=[ is prohibited during the
+execution of the call on address@hidden,Old=[]}. Any exception raised by
address@hidden is propagated.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Type=[Trailing],Text=[If Element_Type is
+unconstrained and definite, then the actual Element parameter of address@hidden
+shall be unconstrained.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This means that the elements cannot be directly
+  allocated from the heap; it must be possible to change the discriminants
+  of the element in place.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden Constant_Reference_Type
+      (Element : @key[not null access constant] Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Reference_Type (Element : @key[not 
null access] Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[The types Constant_Reference_Type
+and Reference_Type need address@hidden<needs finalization>,
+Sec=<language-defined type>}]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The default initialization of an object of type
+Constant_Reference_Type or Reference_Type propagates Program_Error.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[It is expected that Reference_Type (and
+  Constant_Reference_Type) will be a controlled type, for which finalization
+  will have some action to terminate the tampering check for the associated
+  container. If the object is created by default, however, there is no
+  associated container. Since this is useless, and supporting this case would
+  take extra work, we define it to raise an exception.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Constant_Reference (Container : 
@key[aliased in] Map;
+                             Position  : @key[in] Cursor)
+   @key[return] Constant_Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Constant_Indexing and Implicit_Dereference aspects) provides a convenient way 
to
+gain read access to an individual element of a map given a cursor.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Position equals No_Element, then Constraint_Error
+is propagated; if Position does not designate an element in Container, then
+Program_Error is propagated. Otherwise, Constant_Reference returns an object
+whose discriminant is an access value that designates the element designated by
+Position. Tampering with the elements of Container is prohibited while the
+object returned by Constant_Reference exists and has not been finalized.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Reference (Container : @key[aliased 
in out] Map;
+                    Position  : @key[in] Cursor)
+   @key[return] Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Variable_Indexing and Implicit_Dereference aspects) provides a convenient way 
to
+gain read and write access to an individual element of a map given
+a cursor.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Position equals No_Element, then Constraint_Error
+is propagated; if Position does not designate an element in Container, then
+Program_Error is propagated. Otherwise, Reference returns an object whose
+discriminant is an access value that designates the element designated by
+Position. Tampering with the elements of Container is prohibited while the
+object returned by Reference exists and has not been finalized.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Constant_Reference (Container : 
@key[aliased in] Map;
+                             Key       : @key[in] Key_Type)
+   @key[return] Constant_Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Constant_Indexing and Implicit_Dereference aspects) provides a convenient way 
to
+gain read access to an individual element of a map given a key value.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Equivalent to
+Constant_Reference (Container, Find (Container, Key)).]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Reference (Container : @key[aliased 
in out] Map;
+                    Key       : @key[in] Key_Type)
+   @key[return] Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Variable_Indexing and Implicit_Dereference aspects) provides a convenient way 
to
+gain read and write access to an individual element of a map given
+a key value.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Equivalent to Reference (Container, Find (Container, 
Key)).]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Assign (Target : @key{in out} Map; 
Source : @key{in} Map);]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0248-1]}
address@hidden,Type=[Trailing],Text=[If Target denotes the same object as
+Source, the operation has no effect. Otherwise, the key/element pairs of Source
+are copied to Target as for an @nt{assignment_statement} assigning Source to
+Target.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[3],Text=[This routine exists for compatibility with the
+  bounded map containers. For an unbounded map, @exam{Assign(A, B)} and
+  @exam{A := B} behave identically. For a bounded map, := will raise an
+  exception if the container capacities are different, while Assign will
+  not raise an exception if there is enough room in the target.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Move (Target : @key{in out} Map;
+                Source : @key{in out} Map);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0001-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1]}
address@hidden,Type=[Trailing],Text=[If Target denotes the same object
+as Source, then @Chg{Version=[3],New=[the operation],Old=[Move]}
+has no effect. Otherwise, @Chg{Version=[3],New=[the operation is equivalent
+to Assign (Target, Source) followed by Clear (Source)],Old=[Move first calls
+Clear (Target). Then, each node from Source is removed from Source and inserted
+into Target. The length of Source is 0 after a successful call to Move]}.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} Map;
+                  Key       : @key{in}     Key_Type;
+                  New_Item  : @key{in}     Element_Type;
+                  Position  :    @key{out} Cursor;
+                  Inserted  :    @key{out} Boolean);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Insert checks if a node with a key
+equivalent to Key is already present in Container. If a match is found,
+Inserted is set to False and Position designates the element with the matching
+key. Otherwise, Insert allocates a new node, initializes it to Key and
+New_Item, and adds it to Container; Inserted is set to True and Position
+designates the newly-inserted node. Any exception raised during allocation is
+propagated and Container is not modified.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} Map;
+                  Key       : @key{in}     Key_Type;
+                  Position  :    @key{out} Cursor;
+                  Inserted  :    @key{out} Boolean);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Insert inserts Key into Container
+as per the five-parameter Insert, with the difference that an element
+initialized by default (see @RefSecNum{Object Declarations}) is inserted.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} Map;
+                  Key       : @key{in}     Key_Type;
+                  New_Item  : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Insert inserts Key and New_Item
+into Container as per the five-parameter Insert, with the difference that if a
+node with a key equivalent to Key is already in the map, then Constraint_Error
+is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[This is equivalent to:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+  Inserted : Boolean; C : Cursor;
address@hidden
+  Insert (Container, Key, New_Item, C, Inserted);
+  @key{if not} Inserted @key{then}
+     @key{raise} Constraint_Error;
+  @key{end if};
address@hidden;]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[but doesn't require the hassle of
+  @key{out} parameters.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Include (Container : @key{in out} 
Map;
+                   Key       : @key{in}     Key_Type;
+                   New_Item  : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Include inserts Key and New_Item
+into Container as per the five-parameter Insert, with the difference that if a
+node with a key equivalent to Key is already in the map, then this operation
+assigns Key and New_Item to the matching node. Any exception raised during
+assignment is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[This is equivalent to:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+  C : Cursor := Find (Container, Key);
address@hidden
+  @key{if} C = No_Element @key{then}
+     Insert (Container, Key, New_Item);
+  @key{else}
+     Replace (Container, Key, New_Item);
+  @key{end if};
address@hidden;]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[but this avoids doing the search twice.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Replace (Container : @key{in out} 
Map;
+                   Key       : @key{in}     Key_Type;
+                   New_Item  : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Replace checks if a node with a key
+equivalent to Key is present in Container. If a match is found, Replace assigns
+Key and New_Item to the matching node; otherwise, Constraint_Error is
+propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We update the key as well as the
+  element, as the key might include additional information that does not
+  participate in equivalence. If only the element needs to be updated, use
+  Replace_Element (Find (Container, Key), New_Element).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Exclude (Container : @key{in out} 
Map;
+                   Key       : @key{in}     Key_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Exclude checks if a node with a key
+equivalent to Key is present in Container. If a match is found, Exclude removes
+the node from the map.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Exclude should work on an empty map; nothing
+  happens in that case.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete (Container : @key{in out} Map;
+                  Key       : @key{in}     Key_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Delete checks if a node with a key
+equivalent to Key is present in Container. If a match is found, Delete removes
+the node from the map; otherwise, Constraint_Error is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete (Container : @key{in out} Map;
+                  Position  : @key{in out} Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Constraint_Error is propagated. If Position does not designate an element in
+Container, then Program_Error is propagated. Otherwise, Delete removes the node
+designated by Position from the map. Position is set to No_Element on return.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The check on Position checks that the cursor does
+  not belong to some other map. This check implies that a reference to the map
+  is included in the cursor value. This wording is not meant to require
+  detection of dangling cursors; such cursors are defined to be invalid, which
+  means that execution is erroneous, and any result is allowed (including not
+  raising an exception).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First (Container : Map) @key{return} 
Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Length (Container) = 0, then
+First returns No_Element. Otherwise, First returns a cursor that designates the
+first node in Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Next (Position  : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a cursor that designates
+the successor of the node designated by Position. If Position designates the
+last node, then No_Element is returned. If Position equals No_Element, then
+No_Element is returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Next (Position  : @key{in out} 
Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Position := Next 
(Position).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Find (Container : Map;
+               Key       : Key_Type) @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Length (Container) equals 0,
+then Find returns No_Element. Otherwise, Find checks if a node with a key
+equivalent to Key is present in Container. If a match is found, a cursor
+designating the matching node is returned; otherwise, No_Element is returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Element (Container : Map;
+                  Key       : Key_Type) @key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Element (Find (Container, 
Key)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Contains (Container : Map;
+                   Key       : Key_Type) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Find (Container, Key) /= 
No_Element.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,KeepNext=[T],address@hidden,New=[],address@hidden Has_Element 
(Position : Cursor) @key{return} Boolean;]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],address@hidden,New=[],Old=[Returns True if 
Position designates
+an element, and returns False otherwise.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[2],address@hidden,New=[],Old=[This function may not 
detect cursors that
+  designate deleted elements; such cursors are invalid (see below) and the
+  result of calling Has_Element with an invalid cursor is unspecified (but
+  not erroneous).]}]}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraphs 72 and 73
+were moved above.>address@hidden message should be
+deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Iterate
+  (Container : @key{in} Map;
+   Process   : @key{not null access procedure} (Position : @key{in} Cursor));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0265-1]}
address@hidden,Type=[Trailing],Text=[Iterate calls address@hidden
+with a cursor that designates each node in Container, starting with the first
+node and moving the cursor according to the successor relation.
address@hidden,New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the cursors of address@hidden,New=[ is prohibited during the
+execution of a call on address@hidden,Old=[]}. Any exception raised by
address@hidden is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The @lquotes@;tamper with address@hidden@;
+  check takes place when the operations that insert or delete elements, and
+  so on, are called.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[See Iterate for vectors
+  (@RefSecNum{The Generic Package Containers.Vectors}) for a suggested
+  implementation of the check.]}
address@hidden
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0022-1],ARef=[AI05-0248-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error for the actual function
+associated with a generic formal subprogram, when called as part of an
+operation of a map package, to tamper with elements of any map parameter of
+the operation. Either Program_Error is raised, or the operation works as
+defined on the value of the map either prior to, or subsequent to, some or
+all of the modifications to the map.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0027-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to call any subprogram
+declared in the visible part of a map package
+when the associated container has been finalized. If the operation takes
+Container as an @key[in out] parameter, then it raises Constraint_Error or
+Program_Error. Otherwise, the operation either proceeds as it would
+for an empty container, or it raises Constraint_Error or Program_Error.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],Text=[
+A Cursor value is @i{invalid} if any of the following have occurred since it 
was
+created:@Defn2{Term=[invalid cursor],Sec=[of a map]}
address@hidden,Sec=[invalid]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The map that contains the node it designates has
+been finalized;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0160-1]}
address@hidden,Text=[The map that contains the node it designates has
+been used as the Target of a call to Assign, or as the target of an
address@hidden;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The map that contains the node it designates has
+been used as the Source or Target of a call to Move; or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0160-1],ARef=[AI05-0262-1]}
address@hidden,Text=[The node it designates has been
address@hidden,New=[removed],Old=[deleted]} from the address@hidden,New=[
+that previously contained the node],Old=[]}.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0160-1]}
+  @ChgAdded{Version=[3],Text=[This can happen directly via calls to Clear,
+  Exclude, and Delete.]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The result of "=" or Has_Element is unspecified if
+these functions are called with an invalid cursor address@hidden
+Execution is erroneous if any other subprogram declared in
+Containers.Hashed_Maps or Containers.Ordered_Maps is called with an invalid
+cursor address@hidden(erroneous execution),Sec=(cause)}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The list above is intended to be exhaustive. In
+  other cases, a cursor value continues to designate its original element. For
+  instance, cursor values survive the insertion and deletion of other nodes.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[While it is possible to check for these cases, in
+  many cases the overhead necessary to make the check is substantial in time or
+  space. Implementations are encouraged to check for as many of these cases as
+  possible and raise Program_Error if detected.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[Execution is erroneous if the map associated with
+the result of a call to Reference or Constant_Reference is finalized before the
+result object returned by the call to Reference or Constant_Reference is
+finalized.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Each object of Reference_Type and
+  Constant_Reference_Type probably contains some reference to the originating
+  container. If that container is prematurely finalized (which is only possible
+  via Unchecked_Deallocation, as accessibility checks prevent passing a
+  container to Reference that will not live as long as the result), the
+  finalization of the object of Reference_Type will try to access a nonexistent
+  object. This is a normal case of a dangling pointer created by
+  Unchecked_Deallocation; we have to explicitly mention it here as the pointer
+  in question is not visible in the specification of the type. (This is the 
same
+  reason we have to say this for invalid cursors.)]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[No storage associated with a Map object shall be
+lost upon assignment or scope exit.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden,Text=[The execution of an @nt{assignment_statement} for
+a map shall have the effect of copying the elements from the source map
+object to the target map address@hidden,New=[ and changing the length
+of the target object to that of the source object],Old=[]}.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0298-1]}
+  @ChgAdded{Version=[2],Text=[An assignment of a Map is a 
@lquotes@;address@hidden
+  copy; that is the elements are copied as well as the data structures.
+  We say @lquotes@;effect address@hidden in order to allow the implementation 
to
+  avoid copying elements immediately if it wishes. For instance, an
+  implementation that avoided copying until one of the containers is modified
+  would be address@hidden,New=[ (Note that this implementation would
+  require care, see @RefSecNum{The Generic Package Containers.Vectors} for 
more.)],Old=[]}]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Move should not copy elements, and should minimize
+copying of internal data structures.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Move for a map should not copy elements, and should
+minimize copying of internal data structures.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Usually that can be accomplished simply by
+  moving the pointer(s) to the internal data structures from the Source
+  container to the Target container.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[If an exception is propagated from a map
+operation, no storage should be lost, nor any elements removed from a map
+unless specified by the operation.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If an exception is propagated from a map
+operation, no storage should be lost, nor any elements removed from a map
+unless specified by the operation.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is important so that programs can recover
+  from errors. But we don't want to require heroic efforts, so we just require
+  documentation of cases where this can't be accomplished.]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],Text=[This description of maps is new; the
+  extensions are documented with the specific packages.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Added reference support to make map containers more
+  convenient to use.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],Text=[Added procedure Assign;
+  the extension and incompatibility is documented with the specific packages.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],Text=[Generalized the definition
+  of Move. Specified which elements are read/written by stream attributes.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0022-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a @BoundedName
+  to cover tampering by generic actual subprograms.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0027-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a @BoundedName
+  to cover access to finalized map containers.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0160-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Revised the definition
+  of invalid cursors to cover missing (and new) cases.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0265-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Defined when a container
+  prohibits tampering in order to more clearly define where the check is
+  made and the exception raised.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0110-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that tampering 
checks
+  precede all other checks made by a subprogram (but come after those 
associated
+  with the call).]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Hashed_Maps]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+package Containers.Hashed_Maps has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0084-1],ARef=[AI05-0212-1]}
address@hidden,address@hidden,address@hidden Ada.Iterator_Interfaces;
+],address@hidden
+   @key{type} Key_Type @key{is private};
+   @key{type} Element_Type @key{is private};
+   @key{with function} Hash (Key : Key_Type) @key{return} Hash_Type;
+   @key{with function} Equivalent_Keys (Left, Right : Key_Type)
+      @key{return} Boolean;
+   @key{with function} "=" (Left, Right : Element_Type)
+      @key{return} Boolean @Chg{Version=[3],address@hidden<is>],Old=[is]} <>;
address@hidden Ada.Containers.Hashed_Maps @address@hidden,Child=[Hashed_Maps]}
+   @key{pragma} Preelaborate(Hashed_Maps);@Chg{Version=[3],New=[
+   @key{pragma} Remote_Types(Hashed_Maps);],Old=[]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Map} @key{is tagged 
address@hidden,New=[
+      @key[with] Constant_Indexing => Constant_Reference,
+           Variable_Indexing => Reference,
+           Default_Iterator  => Iterate,
+           Iterator_Element  => Element_Type],Old=[]};
+   @key{pragma} Preelaborable_Initialization(Map);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Cursor} @key{is private};
+   @key{pragma} Preelaborable_Initialization(Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{Empty_Map} : @key{constant} Map;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{No_Element} : @key{constant} Cursor;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Has_Element} (Position : 
Cursor) @key{return} Boolean;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[package] @AdaPackDefn{Map_Iterator_Interfaces} 
@key[is new]
+       Ada.Iterator_Interfaces (Cursor, Has_Element);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "=" (Left, Right : Map) @key{return} 
Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Capacity} (Container : Map) 
@key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Reserve_Capacity} 
(Container : @key{in out} Map;
+                               Capacity  : @key{in}     Count_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Length} (Container : Map) 
@key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Empty} (Container : Map) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Clear} (Container : @key{in 
out} Map);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Key} (Position : Cursor) 
@key{return} Key_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Element} (Position : Cursor) 
@key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Replace_Element} (Container 
: @key{in out} Map;
+                              Position  : @key{in}     Cursor;
+                              New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Query_Element}
+     (Position : @key{in} Cursor;
+      Process  : @key{not null access procedure} (Key     : @key{in} Key_Type;
+                                            Element : @key{in} 
Element_Type));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Update_Element}
+     (Container : @key{in out} Map;
+      Position  : @key{in}     Cursor;
+      Process   : @key{not null access procedure}
+                      (Key     : @key{in}     Key_Type;
+                       Element : @key{in out} Element_Type));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] Constant_Reference_Type
+         (Element : @key[not null access constant] Element_Type) @key[is 
private]
+      @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Reference_Type} (Element : 
@key[not null access] Element_Type) @key[is private]
+      @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Constant_Reference} 
(Container : @key[aliased in] Map;
+                                Position  : @key[in] Cursor)
+      @key[return] Constant_Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Reference} (Container : 
@key[aliased in out] Map;
+                       Position  : @key[in] Cursor)
+      @key[return] Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Constant_Reference} 
(Container : @key[aliased in] Map;
+                                Key       : @key[in] Key_Type)
+      @key[return] Constant_Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Reference} (Container : 
@key[aliased in out] Map;
+                       Key       : @key[in] Key_Type)
+      @key[return] Reference_Type;]}
+
address@hidden,Kind=[Added],Aref=[AI05-0001-1]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Assign} (Target : @key[in 
out] Map; Source : @key[in] Map);]}
+
address@hidden,Kind=[Added],Aref=[AI05-0001-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Copy} (Source : Map; 
Capacity : Count_Type := 0) @key[return] Map;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Move} (Target : @key{in 
out} Map;
+                   Source : @key{in out} Map);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Map;
+                     Key       : @key{in}     Key_Type;
+                     New_Item  : @key{in}     Element_Type;
+                     Position  :    @key{out} Cursor;
+                     Inserted  :    @key{out} Boolean);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Map;
+                     Key       : @key{in}     Key_Type;
+                     Position  :    @key{out} Cursor;
+                     Inserted  :    @key{out} Boolean);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Map;
+                     Key       : @key{in}     Key_Type;
+                     New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Include} (Container : 
@key{in out} Map;
+                      Key       : @key{in}     Key_Type;
+                      New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Replace} (Container : 
@key{in out} Map;
+                      Key       : @key{in}     Key_Type;
+                      New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Exclude} (Container : 
@key{in out} Map;
+                      Key       : @key{in}     Key_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete} (Container : 
@key{in out} Map;
+                     Key       : @key{in}     Key_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete} (Container : 
@key{in out} Map;
+                     Position  : @key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First} (Container : Map)
+      @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Next} (Position  : Cursor) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Next} (Position  : @key{in 
out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Find} (Container : Map;
+                  Key       : Key_Type)
+      @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Element} (Container : Map;
+                     Key       : Key_Type)
+      @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Contains} (Container : Map;
+                      Key       : Key_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Deleted],ARef=[AI05-0212-1]}
address@hidden,address@hidden,New=[],Old=[   @key{function} 
@AdaSubDefn{Has_Element} (Position : Cursor) @key{return} Boolean;]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Equivalent_Keys} (Left, 
Right : Cursor)
+      @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Equivalent_Keys} (Left  : 
Cursor;
+                             Right : Key_Type)
+      @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Equivalent_Keys} (Left  : 
Key_Type;
+                             Right : Cursor)
+      @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Iterate}
+     (Container : @key{in} Map;
+      Process   : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] Iterate (Container : @key[in] Map)
+      @key[return] Map_Iterator_Interfaces.Forward_Iterator'Class;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ... -- @RI[not specified by the language]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Hashed_Maps;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[An object of type Map contains an expandable hash
+table, which is used to provide direct access to nodes. The @i<capacity> of an
+object of type Map is the maximum number of nodes that can be inserted into the
+hash table prior to it being automatically
address@hidden,Sec=[of a hashed map]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The expected implementation for a Map uses a
+  hash table which is grown when it is too small, with linked lists hanging off
+  of each bucket. Note that in that implementation a cursor needs a back
+  pointer to the Map object to implement iteration; that could either be in the
+  nodes, or in the cursor object. To provide an average @i{O}(1) access time,
+  capacity would typically equal the number of buckets in such an
+  implementation, so that the average bucket linked list length would be no
+  more than 1.0.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[There is no defined relationship between elements
+  in a hashed map. Typically, iteration will return elements in the order that
+  they are hashed in.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden key},Sec={of a hashed map}}
+Two keys @i<K1> and @i<K2> are defined to be @i<equivalent> if
+Equivalent_Keys (@i<K1>, @i<K2>) returns True.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The actual function for the generic formal function
+Hash is expected to return the same value each time it is called with a
+particular key value. For any two equivalent key values, the actual for Hash is
+expected to return the same value. If the actual for Hash behaves in some other
+manner, the behavior of this package is unspecified. Which subprograms of this
+package call Hash, and how many times they call it, is
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The implementation is not required to protect
+  against Hash raising an exception, or returning random numbers, or any other
+  @lquotes@;address@hidden behavior. It's not practical to do so, and a broken
+  Hash function makes the container unusable.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The implementation can call Hash whenever it is
+  needed; we don't want to specify how often that happens. The result must
+  remain the same (this is logically a pure function), or the behavior is
+  unspecified.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The actual function for the generic formal function
+Equivalent_Keys on Key_Type values is expected to return the same value each
+time it is called with a particular pair of key values. It should define an
+equivalence relationship, that is, be reflexive, symmetric, and transitive. If
+the actual for Equivalent_Keys behaves in some other manner, the behavior of
+this package is unspecified. Which subprograms of this package call
+Equivalent_Keys, and how many times they call it, is
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[As with Hash, the implementation is not required
+  to protect against Equivalent_Keys raising an exception or returning random
+  results. Similarly, the implementation can call this operation whenever it is
+  needed. The result must remain the same (this is a logically pure function),
+  or the behavior is unspecified.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[If the value of a key stored in a node of a map is
+changed other than by an operation in this package such that at least one of
+Hash or Equivalent_Keys give different results, the behavior of this package is
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The implementation is not required to protect
+  against changes to key values other than via the operations declared in the
+  Hashed_Maps package.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[To see how this could happen,
+  imagine an instance of Hashed_Maps where the key type is an
+  access-to-variable type and Hash returns a value derived from the components
+  of the designated object. Then, any operation that has a key value could
+  modify those components and change the hash value:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Key (Map).Some_Component := New_Value;]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is really a design error on the part of the
+  user of the map; it shouldn't be possible to modify keys stored in a map. But
+  we can't prevent this error anymore than we can prevent someone passing as
+  Hash a random number generator.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden node],Sec=[of a hashed map]}
address@hidden node],Sec=[of a hashed map]}
address@hidden node],Sec=[of a hashed map]}Which nodes are the first node and 
the last node of a map, and which node is the
+successor of a given node, are unspecified, other than the general semantics
+described in @address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Typically the first node will be the first node
+  in the first bucket, the last node will be the last node in the last bucket,
+  and the successor will be obtained by following the collision list, and going
+  to the next bucket at the end of each bucket.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Capacity (Container : Map) 
@key{return} Count_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns the capacity of Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reserve_Capacity (Container : 
@key{in out} Map;
+                            Capacity  : @key{in}     Count_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Reserve_Capacity allocates a new hash table such
+that the length of the resulting map can become at least the value Capacity
+without requiring an additional call to Reserve_Capacity, and is large enough
+to hold the current length of Container. Reserve_Capacity then rehashes the
+nodes in Container onto the new hash table. It replaces the old hash table with
+the new hash table, and then deallocates the old hash table. Any exception
+raised during allocation is propagated and Container is not modified.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Reserve_Capacity tampers with the
+cursors of Container.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This routine is used to preallocate the internal
+  hash table to the specified capacity such that future Inserts do not require
+  expansion of the hash table. Therefore, the implementation should allocate
+  the needed memory to make that true at this point, even though the visible
+  semantics could be preserved by waiting until enough elements are inserted.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[While Reserve_Capacity can be used to reduce the
+  capacity of a map, we do not specify whether an implementation actually
+  supports reduction of the capacity. Since the actual capacity can be anything
+  greater than or equal to @Chg{Version=[3],New=[Capacity],Old=[Count]},
+  an implementation never has to reduce the capacity.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Reserve_Capacity tampers with the cursors, as
+  rehashing probably will change the order that elements are stored in the
+  map.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Clear (Container : @key{in out} 
Map);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[In addition to the semantics
+described in @RefSecNum{Maps}, Clear does not affect the capacity of
+Container.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Assign (Target : @key[in out] Map; 
Source : @key[in] Map);]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0248-1]}
address@hidden,Type=[Trailing],Text=[In addition to the semantics
+described in @RefSecNum{Maps}, if the length of Source is greater than the
+capacity of Target,
+Reserve_Capacity (Target, Length (Source)) is called before assigning
+any elements.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Copy (Source : Map; Capacity : 
Count_Type := 0) @key[return] Map;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Type=[Trailing],Text=[Returns a map whose keys and
+elements are initialized from the keys and elements of Source. If Capacity is 
0,
+then the map capacity is the length of Source; if Capacity is equal to or
+greater than the length of Source, the map capacity is at least the specified
+value. Otherwise, the operation propagates Capacity_Error.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[In:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Move (Target : @key{in out} Map;
+                Source : @key{in out} Map);]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The intended implementation is that the internal
+hash table of Target is first deallocated; then the internal hash table is
+removed from Source and moved to Target.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} Map;
+                  Key       : @key{in}     Key_Type;
+                  New_Item  : @key{in}     Element_Type;
+                  Position  :    @key{out} Cursor;
+                  Inserted  :    @key{out} Boolean);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[In addition to the semantics
+described in @RefSecNum{Maps}, if Length (Container) equals Capacity
+(Container), then Insert first calls Reserve_Capacity to increase the capacity
+of Container to some larger value.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Insert should only compare keys that hash to the
+same bucket in the hash table.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[We specify when Reserve_Capacity is called to bound
+the overhead of capacity expansion operations (which are potentially
+expensive). Moreover, expansion can be predicted by comparing Capacity(Map) to
+Length(Map). Since we don't specify by how much the hash table is expanded,
+this only can be used to predict the next expansion, not later ones.]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[In:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Exclude (Container : @key{in out} 
Map;
+                   Key       : @key{in}     Key_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Exclude should only compare keys that hash to the same 
bucket in the hash
+table.]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[In:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete (Container : @key{in out} Map;
+                  Key       : @key{in}     Key_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Delete should only compare keys that hash to the
+same bucket in the hash table. The node containing the element may be
+deallocated now, or it may be saved and reused later.]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[In:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First (Container : Map) @key{return} 
Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[In a typical implementation, this will be the first node 
in the lowest numbered
+hash bucket that contains a node.]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[In:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Next (Position  : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[In a typical implementation, this will return the next 
node in a bucket; if
+Position is the last node in a bucket, this will return the first node in the
+next nonempty bucket.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[A typical implementation will need to a keep a pointer at 
the map container
+in the cursor in order to implement this function.]}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[In:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Find (Container : Map;
+               Key       : Key_Type) @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Find should only compare keys that hash to the same bucket 
in the hash table.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Equivalent_Keys (Left, Right : 
Cursor)
+      @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Equivalent_Keys (Key
+(Left), Key (Right)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Equivalent_Keys (Left  : Cursor;
+                          Right : Key_Type) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Equivalent_Keys (Key
+(Left), Right).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Equivalent_Keys (Left  : Key_Type;
+                          Right : Cursor) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Equivalent_Keys
+(Left, Key (Right)).]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Iterate (Container : @key[in] Map)
+   @key[return] Map_Iterator_Interfaces.Forward_Iterator'Class;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[Iterate returns an
+iterator object (see @RefSecNum{User-Defined Iterator Types}) that
+will generate a value for a loop parameter (see
address@hidden Loop Iteration}) designating
+each node in Container, starting with the first node and moving the cursor
+according to the successor relation.
+Tampering with the cursors of Container is prohibited while
+the iterator object exists (in particular, in
+the @nt{sequence_of_statements} of the @nt{loop_statement} whose
address@hidden denotes this object). The iterator object needs
+finalization.]}
+
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[If @i<N> is the length of a map, the average time
+complexity of the subprograms Element, Insert, Include, Replace, Delete,
+Exclude and Find that take a key parameter should be @i{O}(log @i<N>). The 
average
+time complexity of the subprograms that take a cursor parameter should be 
@i{O}(1).
+The average time complexity of Reserve_Capacity should be @i{O}(@i<N>).]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The average time complexity of Element, Insert, Include, Replace,
+Delete, Exclude and Find operations that
+take a key parameter for Containers.Hashed_Maps should be
address@hidden(log @i<N>). The average
+time complexity of the subprograms of Containers.Hashed_Maps that take
+a cursor parameter should be @i{O}(1). The average time complexity of
+Containers.Hashed_Maps.Reserve_Capacity should be @i{O}(@i<N>).]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We do not mean to overly constrain implementation
+  strategies here. However, it is important for portability that the
+  performance of large containers has roughly the same factors on different
+  implementations. If a program is moved to an implementation for which Find is
+  @i{O}(@i<N>), that program could be unusable when the maps are large. We 
allow
+  @i{O}(log @i<N>) access because the proportionality constant and caching 
effects
+  are likely to be larger than the log factor, and we don't want to discourage
+  innovative implementations.]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The generic package Containers.Hashed_Maps is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}Subprograms Assign and 
Copy
+  are added to Containers.Hashed_Maps. If an instance of Containers.Hashed_Maps
+  is referenced in a @nt{use_clause}, and an entity @i<E> with the same
+  @nt{defining_identifier} as a new entity in Containers.Hashed_Maps is
+  defined in a package that is also referenced in a @nt{use_clause}, the
+  entity @i<E> may no longer be use-visible, resulting in errors. This should
+  be rare and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Added iterator and indexing support to make hashed map containers more
+  convenient to use.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0084-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a pragma
+  Remote_Types so that containers can be used in distributed programs.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Ordered_Maps]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+package Containers.Ordered_Maps has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0084-1],ARef=[AI05-0212-1]}
address@hidden,address@hidden,address@hidden Ada.Iterator_Interfaces;
+],address@hidden
+   @key{type} Key_Type @key{is private};
+   @key{type} Element_Type @key{is private};
+   @key{with function} "<" (Left, Right : Key_Type) @key{return} Boolean 
@key{is} <>;
+   @key{with function} "=" (Left, Right : Element_Type) @key{return} Boolean 
@key{is} <>;
address@hidden Ada.Containers.Ordered_Maps @address@hidden,Child=[Ordered_Maps]}
+   @key{pragma} Preelaborate(Ordered_Maps);@Chg{Version=[3],New=[
+   @key{pragma} Remote_Types(Ordered_Maps);],Old=[]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Equivalent_Keys} (Left, 
Right : Key_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Map} @key{is tagged 
address@hidden,New=[
+      @key[with] Constant_Indexing => Constant_Reference,
+           Variable_Indexing => Reference,
+           Default_Iterator  => Iterate,
+           Iterator_Element  => Element_Type],Old=[]};
+   @key{pragma} Preelaborable_Initialization(Map);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Cursor} @key{is private};
+   @key{pragma} Preelaborable_Initialization(Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{Empty_Map} : @key{constant} Map;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{No_Element} : @key{constant} Cursor;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Has_Element} (Position : 
Cursor) @key{return} Boolean;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[package] @AdaPackDefn{Map_Iterator_Interfaces} 
@key[is new]
+       Ada.Iterator_Interfaces (Cursor, Has_Element);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "=" (Left, Right : Map) @key{return} 
Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Length} (Container : Map) 
@key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Empty} (Container : Map) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Clear} (Container : @key{in 
out} Map);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Key} (Position : Cursor) 
@key{return} Key_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Element} (Position : Cursor) 
@key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Replace_Element} (Container 
: @key{in out} Map;
+                              Position  : @key{in}     Cursor;
+                              New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Query_Element}
+     (Position : @key{in} Cursor;
+      Process  : @key{not null access procedure} (Key     : @key{in} Key_Type;
+                                            Element : @key{in} 
Element_Type));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Update_Element}
+     (Container : @key{in out} Map;
+      Position  : @key{in}     Cursor;
+      Process   : @key{not null access procedure}
+                      (Key     : @key{in}     Key_Type;
+                       Element : @key{in out} Element_Type));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] Constant_Reference_Type
+         (Element : @key[not null access constant] Element_Type) @key[is 
private]
+      @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Reference_Type} (Element : 
@key[not null access] Element_Type) @key[is private]
+      @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Constant_Reference} 
(Container : @key[aliased in] Map;
+                                Position  : @key[in] Cursor)
+      @key[return] Constant_Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Reference} (Container : 
@key[aliased in out] Map;
+                       Position  : @key[in] Cursor)
+      @key[return] Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Constant_Reference} 
(Container : @key[aliased in] Map;
+                                Key       : @key[in] Key_Type)
+      @key[return] Constant_Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Reference} (Container : 
@key[aliased in out] Map;
+                       Key       : @key[in] Key_Type)
+      @key[return] Reference_Type;]}
+
address@hidden,Kind=[Added],Aref=[AI05-0001-1]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Assign} (Target : @key[in 
out] Map; Source : @key[in] Map);]}
+
address@hidden,Kind=[Added],Aref=[AI05-0001-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Copy} (Source : Map) 
@key[return] Map;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Move} (Target : @key{in 
out} Map;
+                   Source : @key{in out} Map);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Map;
+                     Key       : @key{in}     Key_Type;
+                     New_Item  : @key{in}     Element_Type;
+                     Position  :    @key{out} Cursor;
+                     Inserted  :    @key{out} Boolean);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Map;
+                     Key       : @key{in}     Key_Type;
+                     Position  :    @key{out} Cursor;
+                     Inserted  :    @key{out} Boolean);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Map;
+                     Key       : @key{in}     Key_Type;
+                     New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Include} (Container : 
@key{in out} Map;
+                      Key       : @key{in}     Key_Type;
+                      New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Replace} (Container : 
@key{in out} Map;
+                      Key       : @key{in}     Key_Type;
+                      New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Exclude} (Container : 
@key{in out} Map;
+                      Key       : @key{in}     Key_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete} (Container : 
@key{in out} Map;
+                     Key       : @key{in}     Key_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete} (Container : 
@key{in out} Map;
+                     Position  : @key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_First} (Container : 
@key{in out} Map);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_Last} (Container : 
@key{in out} Map);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First} (Container : Map) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First_Element} (Container : 
Map) @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First_Key} (Container : Map) 
@key{return} Key_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Last} (Container : Map) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Last_Element} (Container : 
Map) @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Last_Key} (Container : Map) 
@key{return} Key_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Next} (Position : Cursor) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Next} (Position : @key{in 
out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Previous} (Position : 
Cursor) @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Previous} (Position : 
@key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Find} (Container : Map;
+                  Key       : Key_Type) @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Element} (Container : Map;
+                     Key       : Key_Type) @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Floor} (Container : Map;
+                   Key       : Key_Type) @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Ceiling} (Container : Map;
+                     Key       : Key_Type) @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Contains} (Container : Map;
+                      Key       : Key_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Deleted],ARef=[AI05-0212-1]}
address@hidden,address@hidden,New=[],Old=[   @key{function} 
@AdaSubDefn{Has_Element} (Position : Cursor) @key{return} Boolean;]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "<" (Left, Right : Cursor) @key{return} 
Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} ">" (Left, Right : Cursor) @key{return} 
Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "<" (Left : Cursor; Right : Key_Type) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} ">" (Left : Cursor; Right : Key_Type) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "<" (Left : Key_Type; Right : Cursor) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} ">" (Left : Key_Type; Right : Cursor) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Iterate}
+     (Container : @key{in} Map;
+      Process   : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Reverse_Iterate}
+     (Container : @key{in} Map;
+      Process   : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] Iterate (Container : @key[in] Map)
+      @key[return] Map_Iterator_Interfaces.Reversible_Iterator'Class;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0262-1]}
address@hidden,Text=[   @key[function] Iterate (Container : @key[in] Map; Start 
: @key[in] Cursor)
+      @key[return] Map_Iterator_Interfaces.Reversible_Iterator'Class;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ... -- @RI[not specified by the language]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Ordered_Maps;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden key},Sec={of an ordered map}}
+Two keys @i<K1> and @i<K2> are @i<equivalent> if both @i<K1> < @i<K2> and
address@hidden<K2> < @i<K1> return False, using the generic formal "<" operator 
for keys.
+Function Equivalent_Keys returns True if Left and Right are equivalent, and
+False otherwise.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0044-1]}
address@hidden,Text=[The actual function for the generic formal function
+"<" on Key_Type values is expected to return the same value each time it is
+called with a particular pair of key values. It should define a strict
address@hidden,New=[weak ],Old=[]}ordering address@hidden,
+New=[ (see @RefSecNum{Containers})],Old=[, that is, be irreflexive, asymmetric,
+and transitive]}. If the
+actual for "<" behaves in some other manner, the behavior of this package is
+unspecified. Which subprograms of this package call "<" and how many times they
+call it, is address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The implementation is not required to protect
+  against "<" raising an exception, or returning random results, or any
+  other @lquotes@;address@hidden behavior. It's not practical to do so, and a
+  broken "<" function makes the container unusable.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The implementation can call "<" whenever
+  it is needed; we don't want to specify how often that happens. The result
+  must remain the same (this is a logically pure function), or the behavior is
+  unspecified.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[If the value of a key stored in a map is changed
+other than by an operation in this package such that at least one of "<" or "="
+give different results, the behavior of this package is
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The implementation is not required to protect
+  against changes to key values other than via the operations declared in the
+  Ordered_Maps package.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[To see how this could happen,
+  imagine an instance of Ordered_Maps package where the key type is an
+  access-to-variable type and "<" returns a value derived from comparing the
+  components of the designated objects. Then, any operation that has a key
+  value (even if the key value is constant) could modify those components and
+  change the result of "<":]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Key (Map).Some_Component := New_Value;]}
address@hidden
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is really a design error on the part of the
+  user of the map; it shouldn't be possible to modify keys stored in a map such
+  that "<" changes. But we can't prevent this error anymore than we can prevent
+  someone passing as "<" a routine that produces random answers.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden,address@hidden node],Sec=[of an ordered map]}
address@hidden node],Sec=[of an ordered map]}
address@hidden node],Sec=[of an ordered address@hidden,New=[
address@hidden node],Sec=[of an ordered map]}],Old=[]}
+The @Chg{Version=[3],address@hidden<first node>],Old=[first node]}
+of a nonempty map is the one whose key is less than the key of
+all the other nodes in the map. The @Chg{Version=[3],address@hidden<last 
node>],Old=[last node]}
+of a nonempty map is the one
+whose key is greater than the key of all the other elements in the map. The
address@hidden,address@hidden<successor>],Old=[successor]}
+of a node is the node with the smallest key that is larger than the
+key of the given node. The 
@Chg{Version=[3],address@hidden<predecessor>],Old=[predecessor]}
+of a node is the node with the largest key that is smaller than the key of the
+given node. All comparisons are done using the generic formal "<" operator for
+keys.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Copy (Source : Map) @key[return] 
Map;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Type=[Trailing],Text=[Returns a map whose keys and
+elements are initialized from the corresponding keys and elements of Source.]}
+
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete_First (Container : @key{in 
out} Map);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Container is empty, Delete_First
+has no effect. address@hidden,New=[,],Old=[]}
+the node designated by First (Container) is removed
+from Container. Delete_First tampers with the cursors of Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete_Last (Container : @key{in 
out} Map);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Container is empty, Delete_Last
+has no effect. address@hidden,New=[,],Old=[]}
+the node designated by Last (Container) is removed
+from Container. Delete_Last tampers with the cursors of Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First_Element (Container : Map) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Element (First 
(Container)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First_Key (Container : Map) 
@key{return} Key_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Key (First (Container)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Last (Container : Map) @key{return} 
Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a cursor that designates
+the last node in Container. If Container is empty, returns No_Element.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Last_Element (Container : Map) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Element (Last (Container)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Last_Key (Container : Map) 
@key{return} Key_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Key (Last (Container)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Previous (Position : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Previous returns No_Element. address@hidden,New=[,],Old=[]}
+Previous returns a cursor designating the @Chg{Version=[3],New=[predecessor
+],Old=[]}node @Chg{Version=[3],New=[of],Old=[that precedes]} the one designated
+by Position. If Position designates the first element, then Previous returns
+No_Element.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Previous (Position : @key{in out} 
Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Position := Previous 
(Position).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Floor (Container : Map;
+                Key       : Key_Type) @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[Floor searches for the last node
+whose key is not greater than Key, using the generic formal "<" operator for 
keys.
+If such a node is found, a cursor that designates it is returned.
address@hidden,New=[,],Old=[]}
+No_Element is returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Ceiling (Container : Map;
+                  Key       : Key_Type) @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[Ceiling searches for the first node
+whose key is not less than Key, using the generic formal "<" operator for keys.
+If such a node is found, a cursor that designates it is returned.
address@hidden,New=[,],Old=[]} No_Element is returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "<" (Left, Right : Cursor) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Key (Left) < Key (Right).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden ">" (Left, Right : Cursor) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Key (Right) < Key (Left).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "<" (Left : Cursor; Right : 
Key_Type) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Key (Left) < Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden ">" (Left : Cursor; Right : 
Key_Type) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Right < Key (Left).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "<" (Left : Key_Type; Right : 
Cursor) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Left < Key (Right).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden ">" (Left : Key_Type; Right : 
Cursor) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Key (Right) < Left.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reverse_Iterate
+  (Container : @key{in} Map;
+   Process   : @key{not null access procedure} (Position : @key{in} Cursor));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[Iterates over the nodes in
+Container as per @Chg{Version=[3],New=[procedure ],Old=[]}Iterate,
+with the difference that the nodes are traversed in
+predecessor order, starting with the last node.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Iterate (Container : @key[in] Map)
+   @key[return] Map_Iterator_Interfaces.Reversible_Iterator'Class;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[Iterate returns a reversible
+iterator object (see @RefSecNum{User-Defined Iterator Types}) that
+will generate a value for a loop parameter
+(see @RefSecNum{Generalized Loop Iteration}) designating
+each node in Container, starting with the first node and moving the cursor
+according to the successor relation when used as a forward iterator, and
+starting with the last node and moving the cursor according to the predecessor
+relation when used as a reverse iterator.
+Tampering with the cursors of Container is prohibited while
+the iterator object exists (in particular, in
+the @nt{sequence_of_statements} of the @nt{loop_statement} whose
address@hidden denotes this object). The iterator object needs
+finalization.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Iterate (Container : @key[in] Map; 
Start : @key[in] Cursor)
+   @key[return] Map_Iterator_Interfaces.Reversible_Iterator'Class;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0262-1],ARef=[AI05-0265-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[If Start is not No_Element and does not 
designate an item in Container,
+then Program_Error is propagated. If Start is No_Element, then Constraint_Error
+is propagated. Otherwise, Iterate returns a reversible iterator object
+(see @RefSecNum{User-Defined Iterator Types}) that will generate
+a value for a loop parameter (see @RefSecNum{Generalized Loop Iteration})
+designating each node in Container, starting with
+the node designated by Start and moving the cursor according to the successor
+relation when used as a forward iterator, or moving the cursor according to the
+predecessor relation when used as a reverse iterator. Tampering with the 
cursors
+of Container is prohibited while the iterator object exists (in particular, in
+the @nt{sequence_of_statements} of the @nt{loop_statement} whose
address@hidden denotes this object). The iterator object needs
+finalization.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[Exits are allowed from the loops
+  created using the iterator objects. In particular, to stop the iteration at a
+  particular cursor, just add]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden when] Cur = Stop;]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[in the body of the loop (assuming
+  that @exam{Cur} is the loop parameter and @exam{Stop} is the cursor that you
+  want to stop at).]}
address@hidden
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[If @i<N> is the length of a map, then the
+worst-case time complexity of the
+Element, Insert, Include, Replace, Delete, Exclude and Find operations that
+take a key parameter should be @i{O}((log @i<N>)**2) or better. The worst-case
+time complexity of the subprograms that take a cursor parameter should be 
@i{O}(1).]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The worst-case time complexity of Element, Insert, Include, Replace,
+Delete, Exclude and Find operations that
+take a key parameter for Containers.Ordered_Maps should be
address@hidden((log @i<N>)**2) or better. The worst-case
+time complexity of the subprograms of Containers.Ordered_Maps that take
+a cursor parameter should be @i{O}(1).]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[A balanced (red-black) tree for keys has
+  @i{O}(log @i<N>) worst-case performance. Note that a @i{O}(@i<N>) worst-case
+  implementation (like a list) would be wrong.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We do not mean to overly constrain implementation
+  strategies here. However, it is important for portability that the
+  performance of large containers has roughly the same factors on different
+  implementations. If a program is moved to an implementation that takes 
@i{O}(@i<N>)
+  to find elements, that program could be unusable when the maps are large. We
+  allow the extra log @i<N> factors because the proportionality constant and
+  caching effects are likely to be larger than the log factor, and we don't
+  want to discourage innovative implementations.]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The generic package Containers.Ordered_Maps is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}Subprograms Assign and 
Copy
+  are added to Containers.Ordered_Maps. If an instance of 
Containers.Ordered_Maps
+  is referenced in a @nt{use_clause}, and an entity @i<E> with the same
+  @nt{defining_identifier} as a new entity in Containers.Ordered_Maps is
+  defined in a package that is also referenced in a @nt{use_clause}, the
+  entity @i<E> may no longer be use-visible, resulting in errors. This should
+  be rare and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Added iterator and indexing support to make ordered map containers more
+  convenient to use.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0044-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Redefined "<" actuals
+  to require a strict weak ordering; the old definition allowed
+  indeterminant comparisons that would not have worked in a container.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0084-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a pragma
+  Remote_Types so that containers can be used in distributed programs.]}
address@hidden
+
+
address@hidden,Name=[Sets]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The language-defined generic packages
+Containers.Hashed_Sets and Containers.Ordered_Sets provide private types Set
+and Cursor, and a set of operations for each type. A set container allows
+elements of an arbitrary type to be stored without duplication. A hashed set
+uses a hash function to organize elements, while an ordered set orders its
+element per a specified address@hidden container}
address@hidden,Sec=[set]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[section]}
+describes the declarations that are common to both kinds of sets.
+See @RefSecNum{The Generic Package Containers.Hashed_Sets} for a description 
of the
+semantics specific to
+Containers.Hashed_Sets and @RefSecNum{The Generic Package 
Containers.Ordered_Sets} for
+a description of the semantics specific to Containers.Ordered_Sets.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The actual function for the generic formal function
+"=" on Element_Type values is expected to define a reflexive and symmetric
+relationship and return the same result value each time it is called with a
+particular pair of values. If it behaves in some other manner, the function
+"=" on set values returns an unspecified value. The
+exact arguments and number of calls of this generic formal function by the
+function "=" on set values are address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If the actual function for "=" is not symmetric
+  and consistent, the result returned by the "=" for Set objects cannot be
+  predicted. The implementation is not required to protect
+  against "=" raising an exception, or returning random results, or any
+  other @lquotes@;address@hidden behavior. And it can call "=" in whatever
+  manner makes sense. But note that only the result of "=" for Set objects
+  is unspecified; other subprograms are not allowed to break if "=" is bad
+  (they aren't expected to use "=").]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The type Set is used to represent sets. The type
+Set needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[A set contains elements. Set cursors designate
+elements. There exists an equivalence relation on elements, whose definition is
+different for hashed sets and ordered sets. A set never contains two or more
+equivalent elements. The @i{length} of a set is the number of elements it
address@hidden,Sec={of a set}}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden element],Sec=[of a set]}
address@hidden element],Sec=[of a set]}
address@hidden element],Sec=[of a set]}
+Each nonempty set has two particular elements called the @i{first element} and
+the @i{last element} (which may be the same). Each element except for the last
+element has a @i{successor element}. If there are no other intervening
+operations, starting with the first element and repeatedly going to the
+successor element will visit each element in the set exactly once until the
+last element is reached. The exact definition of these terms is different for
+hashed sets and ordered sets.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden operations of these generic packages
+have access-to-subprogram parameters. To ensure such operations are
+well-defined, they guard against certain actions by the designated
+subprogram. In particular, some operations check for @lquotes@;tampering with
address@hidden of a container because they depend on the set of elements of
+the container remaining constant, and others check for @lquotes@;tampering with
address@hidden of a container because they depend on elements of the
+container not being replaced.]]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],address@hidden with cursors],Sec=[of a set]}
+A subprogram is said to @i{tamper with cursors} of a set object @i{S} if:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it inserts or deletes elements of @i{S}, that is,
+it calls the Insert, Include, Clear, Delete, Exclude, or Replace_Element
+procedures with @i{S} as a parameter; or]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Operations which are defined to be equivalent to
+  a call on one of these operations also are included. Similarly, operations
+  which call one of these as part of their definition are included.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We have to include Replace_Element here because
+  it might delete and reinsert the element if it moves in the set. That could
+  change the order of iteration, which is what this check is designed to
+  prevent. Replace is also included, as it is defined in terms of
+  Replace_Element.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it finalizes @i<S>; or]}
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Text=[it calls the Assign procedure with @i<S> as the Target 
parameter;
+or]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We don't need to explicitly mention
+  @nt{assignment_statement}, because that finalizes the target object
+  as part of the operation, and finalization of an object is already defined
+  as tampering with cursors.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it calls the Move procedure with @i<S> as a
+parameter; or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it calls one of the operations defined to tamper with 
cursors of @i<S>.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],address@hidden with elements],Sec=[of a set]}
+A subprogram is said to @i{tamper with elements} of a set
+object @i<S> if:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[it tampers with cursors of @i<S>.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Complete replacement of an element can cause its
+  memory to be deallocated while another operation is holding onto a reference
+  to it. That can't be allowed. However, a simple modification of (part of) an
+  element is not a problem, so address@hidden@address@hidden does not cause a
+  problem.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We don't need to list Replace and Replace_Element
+  here because they are covered by @lquotes@;tamper with address@hidden
+  For Set, @lquotes@;tamper with address@hidden@;
+  and @lquotes@;tamper with address@hidden are the same. We leave both
+  terms so that the rules for routines like Iterate and
+  Query_Element are consistent across all containers.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0265-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0110-1]}
address@hidden,address@hidden,Sec=[tampering with a set]}
address@hidden,Sec=[prohibited for a set]}
+When tampering with cursors is @i<prohibited> for a particular set object
address@hidden<S>, Program_Error is propagated by a call of any 
language-defined subprogram
+that is defined to tamper with the cursors of @i<S>, leaving @i<S> unmodified.
+Similarly, when tampering with elements is @i<prohibited> for a particular set
+object @i<S>, Program_Error is propagated by a call of any language-defined
+subprogram that is defined to tamper with the elements of @i<S> @Redundant[(or
+tamper with the cursors of @i<S>)], leaving @i<S>
address@hidden,New=[ These checks are made before any other
+defined behavior of the body of the language-defined subprogram.],Old=[]}]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Tampering with elements includes tampering with
+  cursors, so we mention it only from completeness in the second sentence.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Empty_Set represents the empty Set object. It has a
+length of 0. If an object of type Set is not otherwise initialized, it is
+initialized to the same value as Empty_Set.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[No_Element represents a cursor that designates no
+element. If an object of type Cursor is not otherwise initialized, it is
+initialized to the same value as No_Element.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The predefined "=" operator for type Cursor returns
+True if both cursors are No_Element, or designate the same element in the same
+container.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Execution of the default implementation of the
+Input, Output, Read, or Write attribute of type Cursor raises Program_Error.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[A cursor will probably be implemented in terms
+  of one or more access values, and the effects of streaming access values is
+  unspecified. Rather than letting the user stream junk by accident, we mandate
+  that streaming of cursors raise Program_Error by default. The attributes
+  can always be specified if there is a need to support streaming.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0262-1]}
address@hidden,Text=[Set'Write for a Set object @i<S> writes
+Length(@i<S>) elements of the set to the stream. It also may write
+additional information about the set.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0262-1]}
address@hidden,Text=[Set'Read reads the representation of a set
+from the stream, and assigns to @i<Item> a set with the same length and
+elements as was written by Set'Write.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Streaming more elements than the container
+  length is wrong. For implementation implications of this rule, see the 
Implementation Note in
+  @RefSecNum{The Generic Package Containers.Vectors}.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Has_Element (Position : Cursor) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[Returns True if Position designates
+an element, and returns False otherwise.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],Text=[This function might not detect cursors that
+  designate deleted elements; such cursors are invalid (see below) and the
+  result of calling Has_Element with an invalid cursor is unspecified (but
+  not erroneous).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "=" (Left, Right : Set) @key{return} 
Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Left and Right denote the same
+set object, then the function returns True. If Left and Right have different
+lengths, then the function returns False. Otherwise, for each element @i<E> in
+Left, the function returns False if an element equal to @i<E> (using
+the generic formal equality operator) is not present in Right. If the function
+has not returned a result after checking all of the elements, it returns True.
+Any exception raised during evaluation of element equality is propagated.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This wording describes the canonical semantics.
+However, the order and number of calls on the formal equality function is
+unspecified for all of the operations that use it in this package, so an
+implementation can call it as many or as few times as it needs to get the
+correct answer. Specifically, there is no requirement to call the formal
+equality additional times once the answer has been determined.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Equivalent_Sets (Left, Right : Set) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Left and Right denote the same
+set object, then the function returns True. If Left and Right have different
+lengths, then the function returns False. Otherwise, for each element @i<E> in
+Left, the function returns False if an element equivalent to @i<E> is not
+present in Right. If the function has not returned a result after checking all
+of the elements, it returns True. Any exception raised during evaluation of
+element equivalence is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden To_Set (New_Item : Element_Type) 
@key{return} Set;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a set containing the single 
element New_Item.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Length (Container : Set) 
@key{return} Count_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns the number of elements in
+Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Is_Empty (Container : Set) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Length (Container) = 0.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Clear (Container : @key{in out} 
Set);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Removes all the elements from
+Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Element (Position : Cursor) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Constraint_Error is propagated. Otherwise, Element returns the element
+designated by Position.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Replace_Element (Container : @key{in 
out} Set;
+                           Position  : @key{in}     Cursor;
+                           New_Item  : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Constraint_Error is propagated; if Position does not designate an element in
+Container, then Program_Error is propagated.
+If an element equivalent to New_Item is already present in Container at a
+position other than Position, Program_Error is propagated. Otherwise,
+Replace_Element assigns New_Item to the element designated by Position. Any
+exception raised by the assignment is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The final assignment may require that the node of
+  the element be moved in the Set's data structures. That could mean that
+  implementing this operation exactly as worded above could require the
+  overhead of searching twice. Implementations are encouraged to avoid this
+  extra overhead when possible, by prechecking if the old element is equivalent
+  to the new one, by inserting a placeholder node while checking for an
+  equivalent element, and similar optimizations.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The cursor still designates the same element
+  after this operation; only the value of that element has changed. Cursors
+  cannot include information about the relative position of an element in a
+  Set (as they must survive insertions and deletions of other elements), so
+  this should not pose an implementation hardship.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Query_Element
+  (Position : @key{in} Cursor;
+   Process  : @key{not null access procedure} (Element : @key{in} 
Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0021-1],ARef=[AI05-0265-1]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Constraint_Error is propagated. Otherwise, Query_Element calls
address@hidden with the element designated by Position as the argument.
address@hidden,New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the elements of @Chg{Version=[3],New=[the set that contains the
+element designated by Position is prohibited during the
+execution of the call on address@hidden,Old=[Container]}. Any exception
+raised by address@hidden is propagated.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden Constant_Reference_Type
+      (Element : @key[not null access constant] Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[The type Constant_Reference_Type
+needs address@hidden<needs finalization>,
+Sec=<language-defined type>}]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The default initialization of an object of type
+Constant_Reference_Type propagates Program_Error.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[It is expected that
+  Constant_Reference_Type will be a controlled type, for which finalization
+  will have some action to terminate the tampering check for the associated
+  container. If the object is created by default, however, there is no
+  associated container. Since this is useless, and supporting this case would
+  take extra work, we define it to raise an exception.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Constant_Reference (Container : 
@key[aliased in] Set;
+                             Position  : @key[in] Cursor)
+   @key[return] Constant_Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Constant_Indexing and Implicit_Dereference aspects) provides a convenient way 
to
+gain read access to an individual element of a set given a cursor.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Position equals No_Element, then Constraint_Error
+is propagated; if Position does not designate an element in Container, then
+Program_Error is propagated. Otherwise, Constant_Reference returns an object
+whose discriminant is an access value that designates the element designated by
+Position. Tampering with the elements of Container is prohibited while the
+object returned by Constant_Reference exists and has not been finalized.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Assign (Target : @key{in out} Set; 
Source : @key{in} Set);]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0248-1]}
address@hidden,Type=[Trailing],Text=[If Target denotes the same object as 
Source, the operation has no
+effect. Otherwise, the elements of Source are copied to Target as
+for an @nt{assignment_statement} assigning Source to Target.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[3],Text=[This routine exists for compatibility with the
+  bounded set containers. For an unbounded set, @exam{Assign(A, B)} and
+  @exam{A := B} behave identically. For a bounded set, := will raise an
+  exception if the container capacities are different, while Assign will
+  not raise an exception if there is enough room in the target.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Move (Target : @key{in out} Set;
+                Source : @key{in out} Set);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0001-1],ARef=[AI05-0248-1],ARef=[AI05-0262-1]}
address@hidden,Type=[Trailing],Text=[If Target denotes the same object
+as Source, then @Chg{Version=[3],New=[the operation],Old=[Move]}
+has no effect. Otherwise, @Chg{Version=[3],New=[the operation is equivalent
+to Assign (Target, Source) followed by Clear (Source)],Old=[Move first clears
+Target. Then, each element from Source is removed from Source and inserted into
+Target. The length of Source is 0 after a successful call to Move]}.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} Set;
+                  New_Item  : @key{in}     Element_Type;
+                  Position  :    @key{out} Cursor;
+                  Inserted  :    @key{out} Boolean);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Insert checks if an element
+equivalent to New_Item is already present in Container. If a match is found,
+Inserted is set to False and Position designates the matching element.
+Otherwise, Insert adds New_Item to Container; Inserted is set to True and
+Position designates the newly-inserted element. Any exception raised during
+allocation is propagated and Container is not modified.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} Set;
+                  New_Item  : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Insert inserts New_Item into
+Container as per the four-parameter Insert, with the difference that if an
+element equivalent to New_Item is already in the set, then Constraint_Error is
+propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[This is equivalent to:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+  Inserted : Boolean; C : Cursor;
address@hidden
+  Insert (Container, New_Item, C, Inserted);
+  @key{if not} Inserted @key{then}
+     @key{raise} Constraint_Error;
+  @key{end if};
address@hidden;]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[but doesn't require the hassle of @key{out}
+  parameters.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Include (Container : @key{in out} 
Set;
+                   New_Item  : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Include inserts New_Item into
+Container as per the four-parameter Insert, with the difference that if an
+element equivalent to New_Item is already in the set, then it is replaced. Any
+exception raised during assignment is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Replace (Container : @key{in out} 
Set;
+                   New_Item  : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Replace checks if an element
+equivalent to New_Item is already in the set. If a match is found, that element
+is replaced with New_Item; otherwise, Constraint_Error is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Exclude (Container : @key{in out} 
Set;
+                   Item      : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Exclude checks if an element
+equivalent to Item is present in Container. If a match is found, Exclude
+removes the element from the set.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete (Container : @key{in out} Set;
+                  Item      : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Delete checks if an element
+equivalent to Item is present in Container. If a match is found, Delete removes
+the element from the set; otherwise, Constraint_Error is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete (Container : @key{in out} Set;
+                  Position  : @key{in out} Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element,
+then Constraint_Error is propagated. If Position does not designate an element
+in Container, then Program_Error is propagated. Otherwise, Delete removes the
+element designated by Position from the set. Position is set to No_Element on
+return.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The check on Position checks that the cursor does
+  not belong to some other set. This check implies that a reference to the set
+  is included in the cursor value. This wording is not meant to require
+  detection of dangling cursors; such cursors are defined to be invalid, which
+  means that execution is erroneous, and any result is allowed (including not
+  raising an exception).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Union (Target : @key{in out} Set;
+                 Source : @key{in}     Set);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Union inserts into Target the
+elements of Source that are not equivalent to some element already in Target.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If the objects are the same, the result is the
+  same as the original object. The implementation needs to take care so that
+  aliasing effects do not make the result trash; Union (S, S); must work.]}
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Union (Left, Right : Set) 
@key{return} Set;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a set comprising all of the
+elements of Left, and the elements of Right that are not equivalent to some
+element of Left.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Intersection (Target : @key{in out} 
Set;
+                        Source : @key{in}     Set);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[AddedNormal],ARef=[AI05-0004-1]}
address@hidden,Type=[Trailing],address@hidden,New=[Intersection],Old=[Union]} 
deletes from Target the
+elements of Target that are not equivalent to some element of Source.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If the objects are the same, the result is the
+  same as the original object. The implementation needs to take care so that
+  aliasing effects do not make the result trash; Intersection (S, S); must
+  work.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Intersection (Left, Right : Set) 
@key{return} Set;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a set comprising all the
+elements of Left that are equivalent to the some element of Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Difference (Target : @key{in out} 
Set;
+                      Source : @key{in}     Set);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Target denotes the same object
+as Source, then Difference clears Target. Otherwise, it deletes from Target the
+elements that are equivalent to some element of Source.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Difference (Left, Right : Set) 
@key{return} Set;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a set comprising the
+elements of Left that are not equivalent to some element of Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Symmetric_Difference (Target : 
@key{in out} Set;
+                                Source : @key{in}     Set);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Target denotes the same object
+as Source, then Symmetric_Difference clears Target. Otherwise, it deletes from
+Target the elements that are equivalent to some element of Source, and inserts
+into Target the elements of Source that are not equivalent to some element of
+Target.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Symmetric_Difference (Left, Right : 
Set) @key{return} Set;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a set comprising the
+elements of Left that are not equivalent to some element of Right, and the
+elements of Right that are not equivalent to some element of Left.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Overlap (Left, Right : Set) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If an element of Left is equivalent
+to some element of Right, then Overlap returns True.
address@hidden,New=[,],Old=[]} it returns False.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This operation is commutative. If Overlap returns
+  False, the two sets are disjoint.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Is_Subset (Subset : Set;
+                    Of_Set : Set) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If an element of Subset is not
+equivalent to some element of Of_Set, then Is_Subset returns False.
address@hidden,New=[,],Old=[]} it returns True.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This operation is not commutative, so we use
+  parameter names that make it clear in named notation which set is which.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First (Container : Set) @key{return} 
Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Length (Container) = 0, then
+First returns No_Element. Otherwise, First returns a cursor that designates the
+first element in Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Next (Position  : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a cursor that designates the 
successor of the element
+designated by Position. If Position designates the last element, then
+No_Element is returned. If Position equals No_Element, then No_Element is
+returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Next (Position  : @key{in out} 
Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Position := Next 
(Position).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Deleted],ARef=[AI05-0004-1]}
address@hidden,Type=[Trailing],address@hidden,New=[Equivalent to Find 
(Container, Item) /= No_Element.],Old=[]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Find (Container : Set;
+               Item      : Element_Type) @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Length (Container) equals 0,
+then Find returns No_Element. Otherwise, Find checks if an element equivalent
+to Item is present in Container. If a match is found, a cursor designating the
+matching element is returned; otherwise, No_Element is returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Contains (Container : Set;
+                   Item      : Element_Type) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0004-1]}
address@hidden,Type=[Trailing],Text=[Equivalent to Find (Container, Item) /= 
No_Element.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,KeepNext=[T],address@hidden,New=[],address@hidden Has_Element 
(Position : Cursor) @key{return} Boolean;]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],address@hidden,New=[],Old=[Returns True if 
Position designates
+an element, and returns False otherwise.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[DeletedNoDelMsg],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[2],address@hidden,New=[],Old=[This function may not 
detect cursors that
+  designate deleted elements; such cursors are invalid (see below) and the
+  result of calling Has_Element with an invalid cursor is unspecified (but
+  not erroneous).]}]}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraphs 83 and 84
+were moved above.>address@hidden message should be
+deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Iterate
+  (Container : @key{in} Set;
+   Process   : @key{not null access procedure} (Position : @key{in} Cursor));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0265-1]}
address@hidden,Type=[Trailing],Text=[Iterate calls address@hidden
+with a cursor that designates each element in Container, starting with the
+first element and moving the cursor according to the successor relation.
address@hidden,New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the cursors of address@hidden,New=[ is prohibited during the
+execution of a call on address@hidden,Old=[]}. Any exception raised by
address@hidden is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The @lquotes@;tamper with address@hidden@;
+  check takes place when the operations that insert or delete elements, and
+  so on are called.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[See Iterate for vectors
+  (@RefSecNum{The Generic Package Containers.Vectors}) for a suggested
+  implementation of the check.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Both Containers.Hashed_Set and
+Containers.Ordered_Set declare a nested generic package Generic_Keys, which
+provides operations that allow set manipulation in terms of a key (typically, a
+portion of an element) instead of a complete element. The formal function Key
+of Generic_Keys extracts a key value from an element. It is expected to return
+the same value each time it is called with a particular element. The behavior
+of Generic_Keys is unspecified if Key behaves in some other
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[A key is expected to unambiguously determine a
+single equivalence class for elements. The behavior of Generic_Keys is
+unspecified if the formal parameters of this package behave in some other
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Key (Position : Cursor) @key{return} 
Key_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Key (Element (Position)).]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The subprograms in package Generic_Keys named
+Contains, Find, Element, Delete, and Exclude, are equivalent to the
+corresponding subprograms in the parent package, with the difference that the
+Key parameter is used to locate an element in the set.]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Replace (Container : @key{in out} 
Set;
+                   Key       : @key{in}     Key_Type;
+                   New_Item  : @key{in}     Element_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Replace_Element (Container, 
Find (Container, Key), New_Item).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Update_Element_Preserving_Key
+  (Container : @key{in out} Set;
+   Position  : @key{in}     Cursor;
+   Process   : @key{not null access procedure}
+                                 (Element : @key{in out} Element_Type));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0265-1]}
address@hidden,Text=[If Position equals No_Element, then
+Constraint_Error is propagated; if Position does not designate an element in
+Container, then Program_Error is propagated. Otherwise,
address@hidden@!Preserving_Key uses Key to save the key value @i<K> of the
+element designated by Position. address@hidden@!Preserving_Key then calls
address@hidden with that element as the argument.
address@hidden,New=[Tampering],Old=[Program_Error
+is propagated if address@hidden tampers]}
+with the elements of address@hidden,New=[ is prohibited during the
+execution of the call on address@hidden,Old=[]}. Any
+exception raised by address@hidden is propagated. After address@hidden
+returns, address@hidden@!Preserving_Key checks if @i<K> determines the same
+equivalence class as that for the new element; if not, the element is removed
+from the set and Program_Error is propagated.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The key check ensures that the invariants of
+  the set are preserved by the modification. The @lquotes@;tampers with
+  the address@hidden@; check prevents data loss (if Element_Type is by-copy)
+  or erroneous execution (if element type is unconstrained and indefinite).]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[If Element_Type is unconstrained
+and definite, then the actual Element parameter of address@hidden shall be
+unconstrained.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This means that the elements cannot be
+  directly allocated from the heap; it must be possible to change the
+  discriminants of the element in place.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Reference_Type (Element : @key[not 
null access] Element_Type) @key[is private]
+   @key[with] Implicit_Dereference => Element;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[The type Reference_Type needs
address@hidden<needs finalization>,
+Sec=<language-defined type>}]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[The default initialization of an object of type
+Reference_Type propagates Program_Error.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Reference_Preserving_Key (Container 
: @key[aliased in out] Set;
+                                   Position  : @key[in] Cursor)
+   @key[return] Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Implicit_Dereference aspect) provides a convenient way to
+gain read and write access to an individual element of a set given a cursor.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1]}
address@hidden,Text=[If Position equals No_Element, then Constraint_Error
+is propagated; if Position does not designate an element in Container, then
+Program_Error is propagated. Otherwise, Reference_Preserving_Key uses Key to
+save the key value @i<K>; then returns an object whose discriminant is an 
access
+value that designates the element designated by
+Position. Tampering with the elements of Container is prohibited while the
+object returned by Reference_Preserving_Key exists and has not been finalized.
+When the object returned by Reference_Preserving_Key is finalized, a check is
+made if @i<K> determines the same equivalence class as that for the new 
element;
+if not, the element is removed from the set and Program_Error is propagated.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Constant_Reference (Container : 
@key[aliased in] Set;
+                             Key       : @key[in] Key_Type)
+   @key[return] Constant_Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Implicit_Dereference aspect) provides a convenient way to
+gain read access to an individual element of a set given a key value.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Equivalent to
+Constant_Reference (Container, Find (Container, Key)).]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Reference_Preserving_Key (Container 
: @key[aliased in out] Set;
+                                   Key       : @key[in] Key_Type)
+   @key[return] Reference_Type;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[This function (combined with the
+Implicit_Dereference aspect) provides a convenient way to gain
+read and write access to an individual element of a set given a key value.]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Equivalent to Reference_Preserving_Key (Container, Find 
(Container, Key)).]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0022-1],ARef=[AI05-0248-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error for the actual function
+associated with a generic formal subprogram, when called as part of an
+operation of a set package, to tamper with elements of any set parameter of
+the operation. Either Program_Error is raised, or the operation works as
+defined on the value of the set either prior to, or subsequent to, some or
+all of the modifications to the set.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0027-1]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to call any subprogram
+declared in the visible part of a set package
+when the associated container has been finalized. If the operation takes
+Container as an @key[in out] parameter, then it raises Constraint_Error or
+Program_Error. Otherwise, the operation either proceeds as it would
+for an empty container, or it raises Constraint_Error or Program_Error.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Leading],Text=[
+A Cursor value is @i<invalid> if any of the following have occurred since it 
was
+created:@Defn2{Term=[invalid cursor],Sec=[of a set]}
address@hidden,Sec=[invalid]}]}
+
address@hidden
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The set that contains the element it designates
+  has been finalized;]}
+
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0160-1]}
+  @ChgAdded{Version=[3],Text=[The set that contains the element it designates 
has been used as the Target of
+  a call to Assign, or as the target of an @nt{assignment_statement};]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The set that contains the element it designates
+  has been used as the Source or Target of a call to Move; or]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0160-1],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[2],Text=[The element it designates has been
+  @Chg{Version=[3],New=[removed],Old=[deleted]} from the
+  address@hidden,New=[ that previously contained the element],Old=[]}.]}
+  @begin{Ramification}
+    @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0160-1]}
+    @ChgAdded{Version=[3],Text=[This can happen directly via calls to Clear,
+    Exclude, Delete, and Update_Element_Preserving_Key, and indirectly via 
calls
+    to procedures Intersection, Difference, and Symmetric_Difference.]}
+  @end{Ramification}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The result of "=" or Has_Element is
+unspecified if these functions are called with an invalid cursor
address@hidden Execution is erroneous if any other subprogram
+declared in Containers.Hashed_Sets or Containers.Ordered_Sets is called with an
+invalid cursor address@hidden(erroneous execution),Sec=(cause)}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The list above is intended to be
+  exhaustive. In other cases, a cursor value continues to designate its
+  original element. For instance, cursor values survive the insertion and
+  deletion of other elements.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[While it is possible to check for these cases, in
+  many cases the overhead necessary to make the check is substantial in time or
+  space. Implementations are encouraged to check for as many of these cases as
+  possible and raise Program_Error if detected.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[Execution is erroneous if the set associated with
+the result of a call to Reference or Constant_Reference is finalized before the
+result object returned by the call to Reference or Constant_Reference is
+finalized.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Each object of Reference_Type and
+  Constant_Reference_Type probably contains some reference to the originating
+  container. If that container is prematurely finalized (which is only possible
+  via Unchecked_Deallocation, as accessibility checks prevent passing a
+  container to Reference that will not live as long as the result), the
+  finalization of the object of Reference_Type will try to access a nonexistent
+  object. This is a normal case of a dangling pointer created by
+  Unchecked_Deallocation; we have to explicitly mention it here as the pointer
+  in question is not visible in the specification of the type. (This is the 
same
+  reason we have to say this for invalid cursors.)]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[No storage associated with a Set object shall be
+lost upon assignment or scope exit.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden,Text=[The execution of an @nt{assignment_statement} for
+a set shall have the effect of copying the elements from the source set
+object to the target set address@hidden,New=[ and changing the length
+of the target object to that of the source object],Old=[]}.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0298-1]}
+  @ChgAdded{Version=[2],Text=[An assignment of a Set is a 
@lquotes@;address@hidden
+  copy; that is the elements are copied as well as the data structures.
+  We say @lquotes@;effect address@hidden in order to allow the implementation 
to
+  avoid copying elements immediately if it wishes. For instance, an
+  implementation that avoided copying until one of the containers is modified
+  would be address@hidden,New=[ (Note that this implementation would
+  require care, see @RefSecNum{The Generic Package Containers.Vectors} for 
more.)],Old=[]}]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Move should not copy elements, and should minimize
+copying of internal data structures.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Move for sets should not copy elements, and should minimize
+copying of internal data structures.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Usually that can be accomplished simply by
+  moving the pointer(s) to the internal data structures from the Source
+  container to the Target container.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[If an exception is propagated from a set
+operation, no storage should be lost, nor any elements removed from a set
+unless specified by the operation.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If an exception is propagated from a set
+operation, no storage should be lost, nor any elements removed from a set
+unless specified by the operation.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is important so that programs can recover
+  from errors. But we don't want to require heroic efforts, so we just require
+  documentation of cases where this can't be accomplished.]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],Text=[This description of sets is new; the
+  extensions are documented with the specific packages.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Added reference support to make set containers more
+  convenient to use.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],Text=[Added procedure Assign;
+  the extension and incompatibility is documented with the specific packages.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],Text=[Generalized the definition
+  of Move. Specified which elements are read/written by stream attributes.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0022-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a @BoundedName
+  to cover tampering by generic actual subprograms.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0027-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a @BoundedName
+  to cover access to finalized set containers.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0160-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Revised the definition
+  of invalid cursors to cover missing (and new) cases.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0265-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Defined when a container
+  prohibits tampering in order to more clearly define where the check is
+  made and the exception raised.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0110-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that tampering 
checks
+  precede all other checks made by a subprogram (but come after those 
associated
+  with the call).]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Hashed_Sets]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+package Containers.Hashed_Sets has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0084-1],ARef=[AI05-0212-1]}
address@hidden,address@hidden,address@hidden Ada.Iterator_Interfaces;
+],address@hidden
+   @key{type} Element_Type @key{is private};
+   @key{with function} Hash (Element : Element_Type) @key{return} Hash_Type;
+   @key{with function} Equivalent_Elements (Left, Right : Element_Type)
+                 @key{return} Boolean;
+   @key{with function} "=" (Left, Right : Element_Type) @key{return} Boolean 
@key{is} <>;
address@hidden Ada.Containers.Hashed_Sets @address@hidden,Child=[Hashed_Sets]}
+   @key{pragma} Preelaborate(Hashed_Sets);@Chg{Version=[3],New=[
+   @key{pragma} Remote_Types(Hashed_Sets);],Old=[]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Set} @key{is tagged 
address@hidden,New=[
+      @key[with] Constant_Indexing => Constant_Reference,
+           Default_Iterator  => Iterate,
+           Iterator_Element  => Element_Type],Old=[]};
+   @key{pragma} Preelaborable_Initialization(Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Cursor} @key{is private};
+   @key{pragma} Preelaborable_Initialization(Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{Empty_Set} : @key{constant} Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{No_Element} : @key{constant} Cursor;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Has_Element} (Position : 
Cursor) @key{return} Boolean;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[package] @AdaPackDefn{Set_Iterator_Interfaces} 
@key[is new]
+       Ada.Iterator_Interfaces (Cursor, Has_Element);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "=" (Left, Right : Set) @key{return} 
Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Equivalent_Sets} (Left, 
Right : Set) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{To_Set} (New_Item : 
Element_Type) @key{return} Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Capacity} (Container : Set) 
@key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Reserve_Capacity} 
(Container : @key{in out} Set;
+                               Capacity  : @key{in}     Count_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Length} (Container : Set) 
@key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Empty} (Container : Set) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Clear} (Container : @key{in 
out} Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Element} (Position : Cursor) 
@key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Replace_Element} (Container 
: @key{in out} Set;
+                              Position  : @key{in}     Cursor;
+                              New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Query_Element}
+     (Position : @key{in} Cursor;
+      Process  : @key{not null access procedure} (Element : @key{in} 
Element_Type));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] Constant_Reference_Type
+         (Element : @key[not null access constant] Element_Type) @key[is 
private]
+      @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Constant_Reference} 
(Container : @key[aliased in] Set;
+                                Position  : @key[in] Cursor)
+      @key[return] Constant_Reference_Type;]}
+
address@hidden,Kind=[Added],Aref=[AI05-0001-1]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Assign} (Target : @key[in 
out] Set; Source : @key[in] Set);]}
+
address@hidden,Kind=[Added],Aref=[AI05-0001-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Copy} (Source : Set; 
Capacity : Count_Type := 0) @key[return] Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Move} (Target : @key{in 
out} Set;
+                   Source : @key{in out} Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Set;
+                     New_Item  : @key{in}     Element_Type;
+                     Position  :    @key{out} Cursor;
+                     Inserted  :    @key{out} Boolean);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Set;
+                     New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Include} (Container : 
@key{in out} Set;
+                      New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Replace} (Container : 
@key{in out} Set;
+                      New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Exclude} (Container : 
@key{in out} Set;
+                      Item      : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete} (Container : 
@key{in out} Set;
+                     Item      : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete} (Container : 
@key{in out} Set;
+                     Position  : @key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Union} (Target : @key{in 
out} Set;
+                    Source : @key{in}     Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Union} (Left, Right : Set) 
@key{return} Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "@key{or}" (Left, Right : Set) 
@key{return} Set @key{renames} Union;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Intersection} (Target : 
@key{in out} Set;
+                           Source : @key{in}     Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Intersection} (Left, Right : 
Set) @key{return} Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "@key{and}" (Left, Right : Set) 
@key{return} Set @key{renames} Intersection;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Difference} (Target : 
@key{in out} Set;
+                         Source : @key{in}     Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Difference} (Left, Right : 
Set) @key{return} Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "-" (Left, Right : Set) @key{return} Set 
@key{renames} Difference;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Symmetric_Difference} 
(Target : @key{in out} Set;
+                                   Source : @key{in}     Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Symmetric_Difference} (Left, 
Right : Set) @key{return} Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "@key{xor}" (Left, Right : Set) 
@key{return} Set
+     @key{renames} Symmetric_Difference;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Overlap} (Left, Right : Set) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Subset} (Subset : Set;
+                       Of_Set : Set) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First} (Container : Set) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Next} (Position : Cursor) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Next} (Position : @key{in 
out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Find} (Container : Set;
+                  Item      : Element_Type) @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Contains} (Container : Set;
+                      Item      : Element_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Deleted],ARef=[AI05-0212-1]}
address@hidden,address@hidden,New=[],Old=[   @key{function} 
@AdaSubDefn{Has_Element} (Position : Cursor) @key{return} Boolean;]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Equivalent_Elements} (Left, 
Right : Cursor)
+     @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Equivalent_Elements} (Left  
: Cursor;
+                                 Right : Element_Type)
+     @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Equivalent_Elements} (Left  
: Element_Type;
+                                 Right : Cursor)
+     @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Iterate}
+     (Container : @key{in} Set;
+      Process   : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] Iterate (Container : @key[in] Set)
+      @key[return] Set_Iterator_Interfaces.Forward_Iterator'Class;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{generic}
+      @key{type} Key_Type (<>) @key{is private};
+      @key{with function} Key (Element : Element_Type) @key{return} Key_Type;
+      @key{with function} Hash (Key : Key_Type) @key{return} Hash_Type;
+      @key{with function} Equivalent_Keys (Left, Right : Key_Type)
+                                     @key{return} Boolean;
+   @key{package} @AdaPackDefn{Generic_Keys} @key{is}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{function} @AdaSubDefn{Key} (Position : Cursor) 
@key{return} Key_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{function} @AdaSubDefn{Element} (Container : Set;
+                        Key       : Key_Type)
+        @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{procedure} @AdaSubDefn{Replace} (Container : 
@key{in out} Set;
+                         Key       : @key{in}     Key_Type;
+                         New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{procedure} @AdaSubDefn{Exclude} (Container : 
@key{in out} Set;
+                         Key       : @key{in}     Key_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{procedure} @AdaSubDefn{Delete} (Container : 
@key{in out} Set;
+                        Key       : @key{in}     Key_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{function} @AdaSubDefn{Find} (Container : Set;
+                     Key       : Key_Type)
+         @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{function} @AdaSubDefn{Contains} (Container : 
Set;
+                         Key       : Key_Type)
+         @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[      @key{procedure} 
@AdaSubDefn{Update_Element_Preserving_Key}
+        (Container : @key{in out} Set;
+         Position  : @key{in}     Cursor;
+         Process   : @key{not null access procedure}
+                         (Element : @key{in out} Element_Type));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[      @key[type] @AdaTypeDefn{Reference_Type}
+            (Element : @key[not null access] Element_Type) @key[is private]
+         @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[      @key[function] @AdaSubDefn{Reference_Preserving_Key} 
(Container : @key[aliased in out] Set;
+                                         Position  : @key[in] Cursor)
+         @key[return] Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[      @key[function] @AdaSubDefn{Constant_Reference} 
(Container : @key[aliased in] Set;
+                                   Key       : @key[in] Key_Type)
+         @key[return] Constant_Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[      @key[function] @AdaSubDefn{Reference_Preserving_Key} 
(Container : @key[aliased in out] Set;
+                                         Key       : @key[in] Key_Type)
+         @key[return] Reference_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{end} Generic_Keys;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ... -- @RI[not specified by the language]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Hashed_Sets;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden,Sec=[of a hashed set]}
+An object of type Set contains an expandable hash
+table, which is used to provide direct access to elements. The @i<capacity> of
+an object of type Set is the maximum number of elements that can be inserted
+into the hash table prior to it being automatically expanded.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden element],Sec=[of a hashed set]}
+Two elements @i<E1> and @i<E2> are defined to be @i<equivalent> if
+Equivalent_Elements (@i<E1>, @i<E2>) returns True.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The actual function for the generic formal function
+Hash is expected to return the same value each time it is called with a
+particular element value. For any two equivalent elements, the actual for Hash
+is expected to return the same value. If the actual for Hash behaves in some
+other manner, the behavior of this package is unspecified. Which subprograms of
+this package call Hash, and how many times they call it, is
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The actual function for the generic formal function
+Equivalent_Elements is expected to return the same value each time it is called
+with a particular pair of Element values. It should define an equivalence
+relationship, that is, be reflexive, symmetric, and transitive. If the actual
+for Equivalent_Elements behaves in some other manner, the behavior of this
+package is unspecified. Which subprograms of this package call
+Equivalent_Elements, and how many times they call it, is
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0044-1]}
address@hidden,Text=[If the actual function for the generic formal
+function "=" returns True for any pair of nonequivalent elements, then the
+behavior of the container function "=" is address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[If the value of an element stored in a set is
+changed other than by an operation in this package such that at least one of
+Hash or Equivalent_Elements give different results, the behavior of this
+package is address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[See @RefSec{The Generic Package 
Containers.Hashed_Maps}
+  for a suggested implementation, and for justification of the restrictions
+  regarding Hash and Equivalent_Elements. Note that sets only need to store
+  elements, not key/element pairs.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,address@hidden element],Sec=[of a hashed set]}
address@hidden element],Sec=[of a hashed set]}
address@hidden element],Sec=[of a hashed set]}
+Which elements are the first element and the last
+element of a set, and which element is the successor of a given element, are
+unspecified, other than the general semantics described in
address@hidden@PDefn{unspecified}]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Capacity (Container : Set) 
@key{return} Count_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns the capacity of Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reserve_Capacity (Container : 
@key{in out} Set;
+                            Capacity  : @key{in}     Count_Type);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Reserve_Capacity allocates a new hash table such
+that the length of the resulting set can become at least the value Capacity
+without requiring an additional call to Reserve_Capacity, and is large enough
+to hold the current length of Container. Reserve_Capacity then rehashes the
+elements in Container onto the new hash table. It replaces the old hash table
+with the new hash table, and then deallocates the old hash table. Any exception
+raised during allocation is propagated and Container is not modified.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Reserve_Capacity tampers with the
+cursors of Container.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Trailing],Text=[Reserve_Capacity tampers with the
+  cursors, as rehashing probably will change the relationships of the elements
+  in Container.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Clear (Container : @key{in out} 
Set);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[In addition to the semantics
+described in @RefSecNum{Sets}, Clear does not affect the capacity of
+Container.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Assign (Target : @key[in out] Set; 
Source : @key[in] Set);]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0248-1]}
address@hidden,Type=[Trailing],Text=[In addition to the semantics
+described in @RefSecNum{Sets}, if the length of Source is greater than the
+capacity of Target, Reserve_Capacity (Target, Length (Source)) is called
+before assigning any elements.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Copy (Source : Set; Capacity : 
Count_Type := 0) @key[return] Set;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Type=[Trailing],Text=[Returns a set whose elements are
+initialized from the elements of Source. If Capacity is 0, then the set 
capacity
+is the length of Source; if Capacity is equal to or greater than the length of
+Source, the set capacity is at least the specified value. Otherwise, the
+operation propagates Capacity_Error.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Insert (Container : @key{in out} Set;
+                  New_Item  : @key{in}     Element_Type;
+                  Position  :    @key{out} Cursor;
+                  Inserted  :    @key{out} Boolean);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[In addition to the semantics
+described in @RefSecNum{Sets}, if Length (Container) equals Capacity
+(Container), then Insert first calls Reserve_Capacity to increase the capacity
+of Container to some larger value.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First (Container : Set) @key{return} 
Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[If Length (Container) = 0, then
+First returns No_Element. Otherwise, First returns a cursor that designates the
+first hashed element in Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Equivalent_Elements (Left, Right : 
Cursor)
+      @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Equivalent_Elements
+(Element (Left), Element (Right)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Equivalent_Elements (Left  : Cursor;
+                              Right : Element_Type) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Equivalent_Elements
+(Element (Left), Right).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Equivalent_Elements (Left  : 
Element_Type;
+                              Right : Cursor) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Equivalent_Elements (Left, 
Element (Right)).]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Iterate (Container : @key[in] Set)
+   @key[return] Set_Iterator_Interfaces.Forward_Iterator'Class;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[Iterate returns an
+iterator object (see @RefSecNum{User-Defined Iterator Types}) that
+will generate a value for a loop parameter
+(see @RefSecNum{Generalized Loop Iteration}) designating
+each element in Container, starting with the first element and moving the 
cursor
+according to the successor relation.
+Tampering with the cursors of Container is prohibited while
+the iterator object exists (in particular, in
+the @nt{sequence_of_statements} of the @nt{loop_statement} whose
address@hidden denotes this object). The iterator object needs
+finalization.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[For any element @i{E}, the actual function for the
+generic formal function Generic_Keys.Hash is expected to be such that Hash
+(@i{E}) = Generic_Keys.Hash (Key (@i{E})). If the actuals for Key or
+Generic_Keys.Hash behave in some other manner, the behavior of Generic_Keys is
+unspecified. Which subprograms of Generic_Keys call Generic_Keys.Hash, and how
+many times they call it, is address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[For any two elements @i{E1} and @i{E2}, the boolean
+values Equivalent_Elements (@i{E1}, @i{E2}) and Equivalent_Keys (Key (@i{E1}),
+Key (@i{E2})) are expected to be equal. If the actuals for Key or
+Equivalent_Keys behave in some other manner, the behavior of Generic_Keys is
+unspecified. Which subprograms of Generic_Keys call Equivalent_Keys, and how
+many times they call it, is address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[If @i<N> is the length of a set, the
+average time complexity of the subprograms
+Insert, Include, Replace, Delete, Exclude and Find that take an element
+parameter should be @i{O}(log @i<N>). The average time complexity of the
+subprograms that take a cursor parameter should be @i{O}(1). The average time
+complexity of Reserve_Capacity should be @i{O}(@i<N>).]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The average time complexity of the Insert, Include, Replace, Delete, 
Exclude and
+Find operations of Containers.Hashed_Sets that take an element parameter
+should be @i{O}(log @i<N>). The average time complexity of the subprograms
+of Containers.Hashed_Sets that take a cursor parameter should be @i{O}(1). The
+average time complexity of address@hidden@!Reserve_Capacity should be
address@hidden(@i<N>).]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],Text=[See @RefSec{The Generic Package 
Containers.Hashed_Maps}
+  for implementation notes regarding some of the operations of this package.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The generic package Containers.Hashed_Sets is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}Subprograms Assign and 
Copy
+  are added to Containers.Hashed_Sets. If an instance of Containers.Hashed_Sets
+  is referenced in a @nt{use_clause}, and an entity @i<E> with the same
+  @nt{defining_identifier} as a new entity in Containers.Hashed_Sets is
+  defined in a package that is also referenced in a @nt{use_clause}, the
+  entity @i<E> may no longer be use-visible, resulting in errors. This should
+  be rare and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Added iterator and indexing support to make hashed set containers more
+  convenient to use.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0044-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added wording to require
+  the formal function be such that equal elements are also equivalent.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0084-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a pragma
+  Remote_Types so that containers can be used in distributed programs.]}
address@hidden
+
+
address@hidden,Name=[The Generic Package Containers.Ordered_Sets]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+package Containers.Ordered_Sets has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0084-1],ARef=[AI05-0212-1]}
address@hidden,address@hidden,address@hidden Ada.Iterator_Interfaces;
+],address@hidden
+   @key{type} Element_Type @key{is private};
+   @key{with function} "<" (Left, Right : Element_Type) @key{return} Boolean 
@key{is} <>;
+   @key{with function} "=" (Left, Right : Element_Type) @key{return} Boolean 
@key{is} <>;
address@hidden Ada.Containers.Ordered_Sets @address@hidden,Child=[Ordered_Sets]}
+   @key{pragma} Preelaborate(Ordered_Sets);@Chg{Version=[3],New=[
+   @key{pragma} Remote_Types(Ordered_Sets);],Old=[]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Equivalent_Elements} (Left, 
Right : Element_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Set} @key{is tagged 
address@hidden,New=[
+      @key[with] Constant_Indexing => Constant_Reference,
+           Default_Iterator  => Iterate,
+           Iterator_Element  => Element_Type],Old=[]};
+   @key{pragma} Preelaborable_Initialization(Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Cursor} @key{is private};
+   @key{pragma} Preelaborable_Initialization(Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{Empty_Set} : @key{constant} Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{No_Element} : @key{constant} Cursor;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Has_Element} (Position : 
Cursor) @key{return} Boolean;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[package] @AdaPackDefn{Set_Iterator_Interfaces} 
@key[is new]
+       Ada.Iterator_Interfaces (Cursor, Has_Element);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "=" (Left, Right : Set) @key{return} 
Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Equivalent_Sets} (Left, 
Right : Set) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{To_Set} (New_Item : 
Element_Type) @key{return} Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Length} (Container : Set) 
@key{return} Count_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Empty} (Container : Set) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Clear} (Container : @key{in 
out} Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Element} (Position : Cursor) 
@key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Replace_Element} (Container 
: @key{in out} Set;
+                              Position  : @key{in}     Cursor;
+                              New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Query_Element}
+     (Position : @key{in} Cursor;
+      Process  : @key{not null access procedure} (Element : @key{in} 
Element_Type));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[type] Constant_Reference_Type
+         (Element : @key[not null access constant] Element_Type) @key[is 
private]
+      @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Constant_Reference} 
(Container : @key[aliased in] Set;
+                                Position  : @key[in] Cursor)
+      @key[return] Constant_Reference_Type;]}
+
address@hidden,Kind=[Added],Aref=[AI05-0001-1]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Assign} (Target : @key[in 
out] Set; Source : @key[in] Set);]}
+
address@hidden,Kind=[Added],Aref=[AI05-0001-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Copy} (Source : Set) 
@key[return] Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Move} (Target : @key{in 
out} Set;
+                   Source : @key{in out} Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Set;
+                     New_Item  : @key{in}     Element_Type;
+                     Position  :    @key{out} Cursor;
+                     Inserted  :    @key{out} Boolean);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Insert} (Container : 
@key{in out} Set;
+                     New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Include} (Container : 
@key{in out} Set;
+                      New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Replace} (Container : 
@key{in out} Set;
+                      New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Exclude} (Container : 
@key{in out} Set;
+                      Item      : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete} (Container : 
@key{in out} Set;
+                     Item      : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete} (Container : 
@key{in out} Set;
+                     Position  : @key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_First} (Container : 
@key{in out} Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_Last} (Container : 
@key{in out} Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Union} (Target : @key{in 
out} Set;
+                    Source : @key{in}     Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Union} (Left, Right : Set) 
@key{return} Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "@key{or}" (Left, Right : Set) 
@key{return} Set @key{renames} Union;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Intersection} (Target : 
@key{in out} Set;
+                           Source : @key{in}     Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Intersection} (Left, Right : 
Set) @key{return} Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "@key{and}" (Left, Right : Set) 
@key{return} Set @key{renames} Intersection;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Difference} (Target : 
@key{in out} Set;
+                         Source : @key{in}     Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Difference} (Left, Right : 
Set) @key{return} Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "-" (Left, Right : Set) @key{return} Set 
@key{renames} Difference;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Symmetric_Difference} 
(Target : @key{in out} Set;
+                                   Source : @key{in}     Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Symmetric_Difference} (Left, 
Right : Set) @key{return} Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "@key{xor}" (Left, Right : Set) 
@key{return} Set @key{renames}
+      Symmetric_Difference;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Overlap} (Left, Right : Set) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Subset} (Subset : Set;
+                       Of_Set : Set) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First} (Container : Set) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{First_Element} (Container : 
Set) @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Last} (Container : Set) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Last_Element} (Container : 
Set) @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Next} (Position : Cursor) 
@key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Next} (Position : @key{in 
out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Previous} (Position : 
Cursor) @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Previous} (Position : 
@key{in out} Cursor);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Find} (Container : Set;
+                  Item      : Element_Type)
+      @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Floor} (Container : Set;
+                   Item      : Element_Type)
+      @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Ceiling} (Container : Set;
+                     Item      : Element_Type)
+      @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Contains} (Container : Set;
+                      Item      : Element_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Deleted],ARef=[AI05-0212-1]}
address@hidden,address@hidden,New=[],Old=[   @key{function} 
@AdaSubDefn{Has_Element} (Position : Cursor) @key{return} Boolean;]}]}
+
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "<" (Left, Right : Cursor) @key{return} 
Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} ">" (Left, Right : Cursor) @key{return} 
Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "<" (Left : Cursor; Right : Element_Type)
+      @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} ">" (Left : Cursor; Right : Element_Type)
+      @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "<" (Left : Element_Type; Right : Cursor)
+      @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} ">" (Left : Element_Type; Right : Cursor)
+      @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Iterate}
+     (Container : @key{in} Set;
+      Process   : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Reverse_Iterate}
+     (Container : @key{in} Set;
+      Process   : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[   @key[function] Iterate (Container : @key[in] Set)
+      @key[return] Set_Iterator_Interfaces.Reversible_Iterator'Class;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0262-1]}
address@hidden,Text=[   @key[function] Iterate (Container : @key[in] Set; Start 
: @key[in] Cursor)
+      @key[return] Set_Iterator_Interfaces.Reversible_Iterator'Class;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{generic}
+      @key{type} Key_Type (<>) @key{is private};
+      @key{with function} Key (Element : Element_Type) @key{return} Key_Type;
+      @key{with function} "<" (Left, Right : Key_Type)
+         @key{return} Boolean @key{is} <>;
+   @key{package} @AdaPackDefn{Generic_Keys} @key{is}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[       @key{function} @AdaSubDefn{Equivalent_Keys} (Left, 
Right : Key_Type)
+          @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[       @key{function} @AdaSubDefn{Key} (Position : Cursor) 
@key{return} Key_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[       @key{function} @AdaSubDefn{Element} (Container : 
Set;
+                         Key       : Key_Type)
+          @key{return} Element_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[       @key{procedure} @AdaSubDefn{Replace} (Container : 
@key{in out} Set;
+                          Key       : @key{in}     Key_Type;
+                          New_Item  : @key{in}     Element_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[       @key{procedure} @AdaSubDefn{Exclude} (Container : 
@key{in out} Set;
+                          Key       : @key{in}     Key_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[       @key{procedure} @AdaSubDefn{Delete} (Container : 
@key{in out} Set;
+                         Key       : @key{in}     Key_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[       @key{function} @AdaSubDefn{Find} (Container : Set;
+                      Key       : Key_Type)
+          @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[       @key{function} @AdaSubDefn{Floor} (Container : Set;
+                       Key       : Key_Type)
+          @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[       @key{function} @AdaSubDefn{Ceiling} (Container : 
Set;
+                         Key       : Key_Type)
+          @key{return} Cursor;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[       @key{function} @AdaSubDefn{Contains} (Container : 
Set;
+                          Key       : Key_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[       @key{procedure} 
@AdaSubDefn{Update_Element_Preserving_Key}
+         (Container : @key{in out} Set;
+          Position  : @key{in}     Cursor;
+          Process   : @key{not null access procedure}
+                          (Element : @key{in out} Element_Type));]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[      @key[type] @AdaTypeDefn{Reference_Type}
+            (Element : @key[not null access] Element_Type) @key[is private]
+         @key[with] Implicit_Dereference => Element;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[      @key[function] @AdaSubDefn{Reference_Preserving_Key} 
(Container : @key[aliased in out] Set;
+                                         Position  : @key[in] Cursor)
+         @key[return] Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[      @key[function] @AdaSubDefn{Constant_Reference} 
(Container : @key[aliased in] Set;
+                                   Key       : @key[in] Key_Type)
+         @key[return] Constant_Reference_Type;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1]}
address@hidden,Text=[      @key[function] @AdaSubDefn{Reference_Preserving_Key} 
(Container : @key[aliased in out] Set;
+                                         Key       : @key[in] Key_Type)
+         @key[return] Reference_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{end} Generic_Keys;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ... -- @RI[not specified by the language]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Containers.Ordered_Sets;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[Two elements @i<E1> and @i<E2> are @i<equivalent>
+if both @i<E1> < @i<E2> and @i<E2> < @i<E1> return False, using the generic
+formal "<" operator for address@hidden element],Sec=[of an ordered set]}
+Function Equivalent_Elements returns True if Left and Right are equivalent,
+and False otherwise.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0044-1]}
address@hidden,Text=[The actual function for the generic formal function
+"<" on Element_Type values is expected to return the same value each time it is
+called with a particular pair of key values. It should define a strict
address@hidden,New=[weak ],Old=[]}ordering address@hidden,
+New=[ (see @RefSecNum{Containers})],Old=[, that is, be irreflexive, asymmetric,
+and transitive]}. If the
+actual for "<" behaves in some other manner, the behavior of this package is
+unspecified. Which subprograms of this package call "<" and how many times they
+call it, is address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0044-1]}
address@hidden,Text=[If the actual function for the generic formal
+function "=" returns True for any pair of nonequivalent elements, then the
+behavior of the container function "=" is address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[If the value of an element stored in a set is changed
+other than by an operation in this package such that at least one of
+"<" or "=" give different
+results, the behavior of this package is address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[See @RefSec{The Generic Package Containers.Ordered_Maps}
+for a suggested implementation, and for justification of the restrictions
+regarding "<" and "=". Note that sets only need to store elements, not
+key/element pairs.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden,address@hidden element],Sec=[of an ordered set]}
address@hidden element],Sec=[of an ordered set]}
address@hidden element],Sec=[of an ordered address@hidden,New=[
address@hidden element],Sec=[of an ordered set]}],Old=[]}
+The @Chg{Version=[3],address@hidden<first element>],Old=[first element]}
+of a nonempty set is the one
+which is less than all the other elements in the set.
+The @Chg{Version=[3],address@hidden<last element>],Old=[last element]} of a
+nonempty set is the one which is greater than all the other elements in the
+set. The @Chg{Version=[3],address@hidden<successor>],Old=[successor]}
+of an element is the smallest element that is larger than
+the given element. The 
@Chg{Version=[3],address@hidden<predecessor>],Old=[predecessor]}
+of an element is the largest element that is
+smaller than the given element. All comparisons are done using the generic
+formal "<" operator for elements.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Copy (Source : Set) @key[return] 
Set;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1]}
address@hidden,Type=[Trailing],Text=[Returns a set whose
+elements are initialized from the corresponding elements of Source.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete_First (Container : @key{in 
out} Set);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Container is empty, Delete_First
+has no effect. address@hidden,New=[,],Old=[]}
+the element designated by First (Container) is removed
+from Container. Delete_First tampers with the cursors of Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Delete_Last (Container : @key{in 
out} Set);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If Container is empty, Delete_Last
+has no effect. address@hidden,New=[,],Old=[]}
+the element designated by Last (Container) is removed
+from Container. Delete_Last tampers with the cursors of Container.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden First_Element (Container : Set) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to
+Element (First (Container)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Last (Container : Set) @key{return} 
Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Returns a cursor that designates
+the last element in Container. If Container is empty, returns No_Element.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Last_Element (Container : Set) 
@key{return} Element_Type;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to
+Element (Last (Container)).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Previous (Position : Cursor) 
@key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden,Type=[Trailing],Text=[If Position equals No_Element, then
+Previous returns No_Element. address@hidden,New=[,],Old=[]}
+Previous returns a cursor designating
+the @Chg{Version=[3],New=[predecessor ],Old=[]}element
address@hidden,New=[of],Old=[that precedes]} the one designated by Position.
+If Position designates the first element, then Previous returns No_Element.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Previous (Position : @key{in out} 
Cursor);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Position := Previous 
(Position).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Floor (Container : Set;
+                Item      : Element_Type) @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[Floor searches for the last element
+which is not greater than Item. If such an element is found, a cursor that
+designates it is returned. address@hidden,New=[,],Old=[]}
+No_Element is returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Ceiling (Container : Set;
+                  Item      : Element_Type) @key{return} Cursor;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[Ceiling searches for the first
+element which is not less than Item. If such an element is found, a cursor that
+designates it is returned. address@hidden,New=[,],Old=[]}
+No_Element is returned.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "<" (Left, Right : Cursor) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Element (Left) < Element 
(Right).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden ">" (Left, Right : Cursor) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Element (Right) < Element 
(Left).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "<" (Left : Cursor; Right : 
Element_Type) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Element (Left) < Right.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden ">" (Left : Cursor; Right : 
Element_Type) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Right < Element (Left).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden "<" (Left : Element_Type; Right : 
Cursor) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Left < Element (Right).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden ">" (Left : Element_Type; Right : 
Cursor) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Type=[Trailing],Text=[Equivalent to Element (Right) < Left.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Reverse_Iterate
+   (Container : @key{in} Set;
+    Process   : @key{not null access procedure} (Position : @key{in} 
Cursor));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0212-1]}
address@hidden,Type=[Trailing],Text=[Iterates over the elements in
+Container as per @Chg{Version=[3],New=[procedure ],Old=[]}Iterate,
+with the difference that the elements are traversed
+in predecessor order, starting with the last element.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Iterate (Container : @key[in] Set)
+   @key[return] Set_Iterator_Interfaces.Reversible_Iterator'Class;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0212-1],ARef=[AI05-0265-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[Iterate returns a reversible
+iterator object (see @RefSecNum{User-Defined Iterator Types}) that
+will generate a value for a loop parameter
+(see @RefSecNum{Generalized Loop Iteration}) designating
+each element in Container, starting with the first element and moving the 
cursor
+according to the successor relation when used as a forward iterator, and
+starting with the last element and moving the cursor according to the
+predecessor relation when used as a reverse iterator.
+Tampering with the cursors of Container is prohibited while
+the iterator object exists (in particular, in
+the @nt{sequence_of_statements} of the @nt{loop_statement} whose
address@hidden denotes this object). The iterator object needs
+finalization.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Iterate (Container : @key[in] Set; 
Start : @key[in] Cursor)
+   @key[return] Set_Iterator_Interfaces.Reversible_Iterator'Class;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0262-1],ARef=[AI05-0265-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[If Start is not No_Element and does
+not designate an item in Container, then Program_Error is propagated. If Start
+is No_Element, then Constraint_Error is propagated. Otherwise, Iterate returns
+a reversible iterator object (see @RefSecNum{User-Defined Iterator Types}) that
+will generate a value for a loop parameter
+(see @RefSecNum{Generalized Loop Iteration}) designating
+each element in Container, starting with the element designated by Start and
+moving the cursor according to the successor relation when used as a forward
+iterator, or moving the cursor according to the predecessor relation when used
+as a reverse iterator. Tampering with the cursors of Container is prohibited
+while the iterator object exists (in particular, in the
address@hidden of the @nt{loop_statement} whose
address@hidden denotes this object). The iterator object needs
+finalization.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[Exits are allowed from the loops
+  created using the iterator objects. In particular, to stop the iteration at a
+  particular cursor, just add]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden when] Cur = Stop;]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Trailing],Text=[in the body of the loop (assuming
+  that @exam{Cur} is the loop parameter and @exam{Stop} is the cursor that you
+  want to stop at).]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[For any two elements @i<E1> and @i<E2>, the
+boolean values (@i<E1> < @i<E2>) and (Key(@i<E1>) < Key(@i<E2>)) are expected
+to be equal. If the actuals for Key or Generic_Keys."<" behave in some other
+manner, the behavior of this package is unspecified. Which subprograms of this
+package call Key and Generic_Keys."<", and how many times the functions are
+called, is address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[In addition to the semantics described in
address@hidden, the subprograms in package Generic_Keys named
+Floor and Ceiling, are equivalent to the corresponding subprograms in the
+parent package, with the difference that the
+Key subprogram parameter is compared to elements in the container using the
+Key and "<" generic formal functions. The function named Equivalent_Keys
+in package Generic_Keys returns True if both Left < Right and Right < Left
+return False using the generic formal "<" operator, and returns True 
otherwise.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[If @i<N> is the length of a set, then the
+worst-case time complexity of the Insert, Include, Replace, Delete, Exclude and
+Find operations that take an element parameter should be @i{O}((log @i<N>)**2) 
or
+better. The worst-case time complexity of the subprograms that take a cursor
+parameter should be @i{O}(1).]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The worst-case time complexity of the Insert, Include, Replace, Delete, 
Exclude and
+Find operations of Containers.Ordered_Sets that take an element parameter
+should be @i{O}((log @i<N>)**2). The worst-case time complexity of the 
subprograms
+of Containers.Ordered_Sets that take a cursor parameter should be @i{O}(1).]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],Text=[See @RefSec{The Generic Package 
Containers.Ordered_Maps}
+  for implementation notes regarding some of the operations of this package.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The generic package Containers.Ordered_Sets is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}Subprograms Assign and 
Copy
+  are added to Containers.Ordered_Sets. If an instance of 
Containers.Ordered_Sets
+  is referenced in a @nt{use_clause}, and an entity @i<E> with the same
+  @nt{defining_identifier} as a new entity in Containers.Ordered_Sets is
+  defined in a package that is also referenced in a @nt{use_clause}, the
+  entity @i<E> may no longer be use-visible, resulting in errors. This should
+  be rare and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0212-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Added iterator and indexing support to make ordered set containers more
+  convenient to use.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0044-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added wording to
+  require the formal function be such that equal elements are also
+  equivalent.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0044-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Redefined "<" actuals
+  to require a strict weak ordering; the old definition allowed
+  indeterminant comparisons that would not have worked in a container.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0084-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a pragma
+  Remote_Types so that containers can be used in distributed programs.]}
address@hidden
+
+
+
diff --git a/packages/ada-ref-man/source_2012/pre_dirs.mss 
b/packages/ada-ref-man/source_2012/pre_dirs.mss
new file mode 100755
index 0000000..046d434
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pre_dirs.mss
@@ -0,0 +1,1561 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/pre_dirs.mss,v $ }
address@hidden $Revision: 1.49 $ $Date: 2012/11/28 23:53:05 $ $Author: randy $ }
address@hidden(predefdirs, Root="ada.mss")
+
address@hidden: 2012/11/28 23:53:05 $}
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden,Name=[The Package Directories]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00248-01]}
address@hidden,Text=[The package Directories provides operations
+for manipulating files and directories, and their names.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[The notes for this 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+contain the expected
+interpretations of some of the operations on various target systems.
address@hidden@;address@hidden@; refers to the address@hidden(174) operating 
system,
+and in most cases also covers Unix-like systems such as Linux and POSIX.
address@hidden@;address@hidden(174)@rquotes@; refers to the address@hidden(174)
address@hidden(174) 2000 operating system and usually also covers most
+other versions that use the Win32 API.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00248-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library package
+Directories has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.IO_Exceptions;
address@hidden Ada.Calendar;
address@hidden Ada.Directories @address@hidden,Child=[Directories]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[Directory and file operations:]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Current_Directory} 
@key{return} String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Set_Directory} (Directory : 
in String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Create_Directory} 
(New_Directory : @key{in} String;
+                               Form          : @key{in} String := "");]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_Directory} 
(Directory : @key{in} String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Create_Path} (New_Directory 
: @key{in} String;
+                          Form          : @key{in} String := "");]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_Tree} (Directory : 
@key{in} String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Delete_File} (Name : 
@key{in} String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Rename} (Old_Name, New_Name 
: @key{in} String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Copy_File} (Source_Name,
+                        Target_Name : @key{in} String;
+                        Form        : @key{in} String := "");]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI[File and directory name operations:]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Full_Name} (Name : @key{in} 
String) @key{return} String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Simple_Name} (Name : 
@key{in} String) @key{return} String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Containing_Directory} (Name 
: @key{in} String) @key{return} String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Extension} (Name : @key{in} 
String) @key{return} String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Base_Name} (Name : @key{in} 
String) @key{return} String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Compose} 
(Containing_Directory : @key{in} String := "";
+                     Name                 : @key{in} String;
+                     Extension            : @key{in} String := "") 
@key{return} String;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0049-1]}
address@hidden,Text=[   @Key{type} @AdaTypeDefn{Name_Case_Kind} @key{is}
+      (Unknown, Case_Sensitive, Case_Insensitive, Case_Preserving);]}
+
address@hidden,Kind=[Added],ARef=[AI05-0049-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Name_Case_Equivalence} (Name 
: @key{in} String) @key{return} Name_Case_Kind;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{File and directory queries:}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{File_Kind} @key{is} (Directory, 
Ordinary_File, Special_File);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{File_Size} @key{is range} 0 .. 
@RI{implementation-defined};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Exists} (Name : @key{in} 
String) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Kind} (Name : @key{in} 
String) @key{return} File_Kind;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Size} (Name : @key{in} 
String) @key{return} File_Size;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Modification_Time} (Name : 
@key{in} String) @key{return} Ada.Calendar.Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Directory searching:}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Directory_Entry_Type} @key{is 
limited private};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Filter_Type} @key{is array} 
(File_Kind) @key{of} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Search_Type} @key{is limited 
private};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Start_Search} (Search    : 
@key{in out} Search_Type;
+                           Directory : @key{in} String;
+                           Pattern   : @key{in} String;
+                           Filter    : @key{in} Filter_Type := (@key{others} 
=> True));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{End_Search} (Search : 
@key{in out} Search_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{More_Entries} (Search : 
@key{in} Search_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Get_Next_Entry} (Search : 
@key{in out} Search_Type;
+                             Directory_Entry : @key{out} 
Directory_Entry_Type);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} Search (
+      Directory : @key{in} String;
+      Pattern   : @key{in} String;
+      Filter    : @key{in} Filter_Type := (@key{others} => True);
+      Process   : @key{not null access procedure} (
+          Directory_Entry : @key{in} Directory_Entry_Type));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @RI{Operations on Directory Entries:}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Simple_Name} 
(Directory_Entry : @key{in} Directory_Entry_Type)
+       @key{return} String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Full_Name} (Directory_Entry 
: @key{in} Directory_Entry_Type)
+       @key{return} String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Kind} (Directory_Entry : 
@key{in} Directory_Entry_Type)
+       @key{return} File_Kind;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Size} (Directory_Entry : 
@key{in} Directory_Entry_Type)
+       @key{return} File_Size;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Modification_Time} 
(Directory_Entry : @key{in} Directory_Entry_Type)
+       @key{return} Ada.Calendar.Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaExcDefn{Status_Error} : @key{exception renames} 
Ada.IO_Exceptions.Status_Error;
+   @AdaExcDefn{Name_Error}   : @key{exception renames} 
Ada.IO_Exceptions.Name_Error;
+   @AdaExcDefn{Use_Error}    : @key{exception renames} 
Ada.IO_Exceptions.Use_Error;
+   @AdaExcDefn{Device_Error} : @key{exception renames} 
Ada.IO_Exceptions.Device_Error;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
address@hidden,address@hidden
+    @Chg{Version=[3],New=[... ],Old=[]}-- @address@hidden,New=[not],Old=[Not]} 
specified by the address@hidden,New=[],Old=[.]}}
address@hidden Ada.Directories;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00248-01]}
address@hidden,Text=[External files may be classified as directories,
+special files, or ordinary
+files. A @i<directory> is an external file that is a container for files on
+the target system. A @i<special file> is an external file that cannot be
+created or read by a predefined Ada input-output package. External files that
+are not special files or directories are called @i<ordinary files>.
address@hidden
address@hidden file}
address@hidden file}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[A directory is an external file, although it may
+  not have a name on some targets. A directory is not a special file, as it
+  can be created and read by Directories.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Devices and soft links are examples of
+  special files on address@hidden(174) and Unix.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Even if an implementation provides a package
+  to create and read soft links, such links are still special files.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00248-01]}
address@hidden,Text=[A @i<file name> is a string identifying an external
+file. Similarly, a
address@hidden<directory name> is a string identifying a directory. The 
interpretation of
+file names and directory names is implementation-defined.
address@hidden name}
address@hidden name}]}
address@hidden,Kind=[AddedNormal],address@hidden,New=[The
+interpretation of file names and directory names.],Old=[]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00248-01]}
address@hidden,Text=[The @i<full name> of an external file is a
+full specification of the name of
+the file. If the external environment allows alternative specifications of the
+name (for example, abbreviations), the full name should not use such
+alternatives. A full name typically will include the names of all of the
+directories that contain the item. The @i<simple name> of an external file is
+the name of the item, not including any containing directory names. Unless
+otherwise specified, a file name or directory name parameter in a call to
+a predefined Ada input-output subprogram can be a full name, a simple name,
+or any other form of name supported by the implementation.
address@hidden name],Sec=[of a file]}
address@hidden name],Sec=[of a file]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The full name on Unix is a complete path to the
+   root. For address@hidden(174), the full name includes a complete path, as 
well as a disk
+   name ("C:") or network share name. For both systems, the simple name is
+   the part of the name following the last '/' (or '\' for 
address@hidden(174)). For
+   example, in the name "/usr/randy/ada-directories.ads",
+   "ada-directories.ads" is the simple name.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[It is possible for a file or directory name to be
+    neither a full name nor a simple name. For instance, the Unix name
+    "../parent/myfile" is neither a full name nor a simple name.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00248-01]}
address@hidden,Text=[The @i<default directory> is the directory that is
+used if a directory or
+file name is not a full name (that is, when the name does not fully identify
+all of the containing directories).
address@hidden directory}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The default directory is the one maintained by
+   the familiar @lquotes@;address@hidden@; command on Unix and 
address@hidden(174). Note that
+   address@hidden(174) maintains
+   separate default directories for each disk drive; implementations should
+   use the natural implementation.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00248-01]}
address@hidden,Text=[A @i<directory entry> is a single item in a
+directory, identifying a single
+external file (including directories and special files).
address@hidden entry}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00248-01]}
address@hidden,Text=[For each function that returns a string, the
+lower bound of the returned value is 1.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00248-01]}
address@hidden,Type=[Leading],
+Text=[The following file and directory operations are provided:]}
+
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Current_Directory @key{return} 
String;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the full directory name
+for the current default directory.
+The name returned shall be suitable for a future call to Set_Directory.
+The exception Use_Error is propagated if a default directory is not
+supported by the external environment.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Set_Directory (Directory : @key{in} 
String);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Sets the current default directory.
+The exception Name_Error is
+propagated if the string given as Directory does not identify an existing
+directory. The exception Use_Error is propagated if the external environment
+does not support making Directory (in the absence of Name_Error) a default
+directory.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Create_Directory (New_Directory : 
@key{in} String;
+                            Form          : @key{in} String := "");]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Creates a directory with name
+New_Directory. The Form parameter can be
+used to give system-dependent characteristics of the directory; the
+interpretation of the Form parameter is implementation-defined. A null string
+for Form specifies the use of the default options of the implementation of the
+new directory. The exception Name_Error is propagated if the string given as
+New_Directory does not allow the identification of a directory. The exception
+Use_Error is propagated if the external environment does not support the
+creation of a directory with the given name (in the absence of Name_Error) and
+form.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Delete_Directory (Directory : 
@key{in} String);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0231-1]}
address@hidden,Type=[Trailing],Text=[Deletes an existing empty directory
+with name Directory. The exception
+Name_Error is propagated if the string given as Directory does not identify an
+existing directory. The exception Use_Error is propagated if the
address@hidden,New=[directory is not empty or the ],Old=[]}external
+environment does not support the deletion of the directory
address@hidden,New=[],Old=[(or some portion of its contents) ]}with
+the given name (in the absence of Name_Error).]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Create_Path (New_Directory : 
@key{in} String;
+                       Form          : @key{in} String := "");]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0271-1]}
address@hidden,Type=[Trailing],Text=[Creates zero or more directories with
+name New_Directory. Each
+nonexistent directory named by New_Directory is address@hidden For example, on 
a
+typical Unix system, Create_Path ("/usr/me/my"); would create directory "me" in
+directory "usr", then create directory "my" in directory "me".] The Form 
parameter
+can be used to give system-dependent characteristics of the directory; the
+interpretation of the Form parameter is implementation-defined. A null string
+for Form specifies the use of the default options of the implementation of the
+new directory. The exception Name_Error is propagated if the string given as
+New_Directory does not allow the identification of any directory. The exception
+Use_Error is propagated if the external environment does not support the
+creation of any directories with the given name (in the absence of Name_Error)
+and address@hidden,New=[ If Use_Error is propagated, it is unspecified
+whether a portion of the directory path is created.],Old=[]}]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Delete_Tree (Directory : @key{in} 
String);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Deletes an existing directory with
+name Directory. The directory and
+all of its contents (possibly including other directories) are deleted. The
+exception Name_Error is propagated if the string given as Directory does not
+identify an existing directory. The exception Use_Error is propagated if the
+external environment does not support the deletion of the directory or some
+portion of its contents with the given name (in the absence of Name_Error). If
+Use_Error is propagated, it is unspecified whether a portion of the contents of
+the directory is deleted.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Delete_File (Name : @key{in} 
String);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Deletes an existing ordinary or
+special file with name Name. The exception
+Name_Error is propagated if the string given as Name does not identify an
+existing ordinary or special external file. The exception Use_Error is
+propagated if the external environment does not support the deletion of the
+file with the given name (in the absence of Name_Error).]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Rename (Old_Name, New_Name : 
@key{in} String);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0231-1]}
address@hidden,Type=[Trailing],Text=[Renames an existing external file
+(including directories) with name Old_Name
+to New_Name. The exception Name_Error is propagated if the string given as
+Old_Name does not identify an existing external address@hidden,New=[
+or if the string given as New_Name does not allow the identification
+of an external file],Old=[]}. The exception Use_Error
+is propagated if the external environment does not support the renaming of the
+file with the given name (in the absence of Name_Error). In particular,
+Use_Error is propagated if a file or directory already exists with name
+New_Name.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This operation is expected to work within a
+  single directory, and implementers are encouraged to support it across
+  directories on a single device. Copying files from one device to another
+  is discouraged (that's what Copy_File is for). However, there is no
+  requirement to detect file copying by the target system. If the target
+  system has an API that gives that for @lquotes@;address@hidden, it can be
+  used. For address@hidden(174), for instance, MoveFile can be used to
+  implement Rename.]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
address@hidden,Keepnext=[T],address@hidden Copy_File (Source_Name,
+                     Target_Name : @key{in} String;
+                     Form        : @key{in} address@hidden,New=[ := 
""],Old=[]});]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0271-1]}
address@hidden,Type=[Trailing],Text=[Copies the contents of the existing
+external file with name Source_Name to an external file with name Target_Name.
+The resulting external file is a duplicate of the source external file. The
+Form parameter can be used to give system-dependent characteristics of the
+resulting external file; the interpretation of the Form parameter is
+implementation-defined. Exception Name_Error is propagated if the string given
+as Source_Name does not identify an existing external ordinary or special file,
+or if the string given as Target_Name does not allow the identification of an
+external file. The exception Use_Error is propagated if the external
+environment does not support creating the file with the name given by
+Target_Name and form given by Form, or copying of the file with the name given
+by Source_Name (in the absence of Name_Error)address@hidden,New=[ If
+Use_Error is propagated, it is unspecified whether a portion of the file
+is copied.],Old=[]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Name_Error is always raised if Source_Name
+  identifies a directory. It is up to the implementation whether
+  special files can be copied, or if Use_Error will be raised.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00248-01]}
address@hidden,Type=[Leading],Text=[The following file and directory
+name operations are provided:]}
+
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Full_Name (Name : @key{in} String) 
@key{return} String;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the full name corresponding
+to the file name specified by
+Name. The exception Name_Error is propagated if the string given as Name does
+not allow the identification of an external file (including directories and
+special files).]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Full name means that no abbreviations are
+  used in the returned name, and that it is a full specification of the name.
+  Thus, for Unix and address@hidden(174), the result should be a full path 
that does not
+  contain any "." or ".." directories. Typically, the default directory
+  is used to fill in any missing information.]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Simple_Name (Name : @key{in} String) 
@key{return} String;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the simple name portion of
+the file name specified by Name.
+The exception Name_Error is propagated if the string given as Name does not
+allow the identification of an external file (including directories and special
+files).]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Containing_Directory (Name : 
@key{in} String) @key{return} String;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the name of the containing
+directory of the external file
+(including directories) identified by Name. (If more than one directory can
+contain Name, the directory name returned is implementation-defined.) The
+exception Name_Error is propagated if the string given as Name does not allow
+the identification of an external file. The exception Use_Error is propagated
+if the external file does not have a containing directory.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is purely a string manipulation function.
+  If Name is not given as a full name, the containing directory probably
+  won't be one, either. For example, if Containing_Directory ("..\AARM\RM-A-8")
+  is called on address@hidden(174), the result should be "..\AARM". If there 
is no
+  path at all on the name, the result should be "." (which represents the
+  current directory). Use Full_Name on the result of Containing_Directory
+  if the full name is needed.]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Extension (Name : @key{in} String) 
@key{return} String;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the extension name
+corresponding to Name. The extension name
+is a portion of a simple name (not including any separator characters),
+typically used to identify the file class. If the external environment does not
+have extension names, then the null string is returned. The exception
+Name_Error is propagated if the string given as Name does not allow the
+identification of an external file.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[For Unix and address@hidden(174), the extension 
is the
+  portion of the simple name following the rightmost period. For example,
+  in the simple name "RM-A-8.html", the extension is "html".]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Base_Name (Name : @key{in} String) 
@key{return} String;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the base name corresponding
+to Name. The base name is the
+remainder of a simple name after removing any extension and extension
+separators. The exception Name_Error is propagated if the string given as Name
+does not allow the identification of an external file (including directories 
and
+special files).]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[For Unix and address@hidden(174), the base name 
is the
+  portion of the simple name preceding the rightmost period (except for the
+  special directory names "." and "..", whose Base_Name is "." and "..").
+  For example, in the simple name "RM-A-8.html", the base name is "RM-A-8".]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Compose (Containing_Directory : 
@key{in} String := "";
+                  Name                 : @key{in} String;
+                  Extension            : @key{in} String := "") @key{return} 
String;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[Returns the name of the external
+file with the specified
+Containing_Directory, Name, and Extension. If Extension is the null string,
+then Name is interpreted as a simple name;
address@hidden,New=[,],Old=[]} Name is interpreted as a
+base name. The exception Name_Error is propagated if the string given as
+Containing_Directory is not null and does not allow the identification of a
+directory, or if the string given as Extension is not null and is not a
+possible extension, or if the string given as Name is not a possible simple
+name (if Extension is null) or base name (if Extension is nonnull).]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The above definition implies that if
+  the Extension is null, for Unix and address@hidden(174) no '.' is added to 
Name.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If Name is null, Name_Error should be raised,
+  as nothing is not a possible simple name or base name.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Generally, Compose(Containing_Directory(F),
+  Base_Name(F),Extension(F)) = F. However, this is not true on Unix or
+  address@hidden(174) for file names that end with a '.';
+  Compose(Base_Name("Fooey."),Extension("Fooey.")) = "Fooey".
+  This is not a problem for address@hidden(174), as the names have the same 
meaning with
+  or without the '.', but these are different names for Unix. Thus,
+  care needs to be taken on Unix; if Extension is null, Base_Name should
+  be avoided. (That's not usually a problem with file names generated by a
+  program.)]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0049-1]}
address@hidden,Keepnext=[T],address@hidden Name_Case_Equivalence (Name : 
@key{in} String) @key{return} Name_Case_Kind;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0049-1],ARef=[AI05-0248-1]}
address@hidden,Text=[Returns the file name equivalence rule for the
+directory containing Name. Raises Name_Error if Name is not a full name. 
Returns
+Case_Sensitive if file names that differ only in the case of letters are
+considered different names. If file names that differ only in the case of
+letters are considered the same name, then Case_Preserving is returned if
+names have the case of the file name used when a file is created; and
+Case_Insensitive is returned otherwise. Returns Unknown if the file name
+equivalence is not known.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[Added]}
+  @ChgAdded{Version=[3],Text=[Unix, Linux, and their relatives are 
Case_Sensitive
+  systems. address@hidden(174) address@hidden(174) is a Case_Preserving system
+  (unless the rarely used POSIX mode is used). Ancient systems like CP/M and
+  early MS-DOS were Case_Insensitive systems (file names were always in UPPER
+  CASE). Unknown is provided in case it is impossible to tell (such as could be
+  the case for network files).]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00248-01]}
address@hidden,Type=[Leading],Text=[The following file and directory
+queries and types are provided:]}
+
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden File_Kind @key{is} (Directory, 
Ordinary_File, Special_File);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[The type File_Kind represents the
+kind of file represented by an external file or directory.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden File_Size @key{is range} 0 .. 
@RI<implementation-defined>;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[The type File_Size represents the
+size of an external file.]}
address@hidden,Kind=[AddedNormal],address@hidden,New=[The
+maximum value for a file size in Directories.],Old=[]}]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Exists (Name : @key{in} String) 
@key{return} Boolean;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns True if an external file
+represented by Name exists, and False
+otherwise. The exception Name_Error is propagated if the string given as Name
+does not allow the identification of an external file (including directories
+and special files).]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Kind (Name : @key{in} String) 
@key{return} File_Kind;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the kind of
+external file represented by Name. The exception
+Name_Error is propagated if the string given as Name does not allow the
+identification of an existing external file.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Size (Name : @key{in} String) 
@key{return} File_Size;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the size of the
+external file represented by Name. The size of
+an external file is the number of stream elements contained in the file.
+If the external file is not an ordinary file, the
+result is implementation-defined. The exception Name_Error is propagated if the
+string given as Name does not allow the identification of an existing external
+file. The exception Constraint_Error is propagated if the file size is not a
+value of type File_Size.]}
address@hidden,Kind=[AddedNormal],address@hidden,New=[The
+result for Directories.Size for a directory or special file],Old=[]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Trailing],Text=[We allow raising 
Constraint_Error,
+  so that an implementation for a system with 64-bit file sizes does not
+  need to support full numerics on 64-bit integers just to implement
+  this package. Of course, if 64-bit integers are available on such a system,
+  they should be used when defining type File_Size.]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Modification_Time (Name : @key{in} 
String) @key{return} Ada.Calendar.Time;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the time that the
+external file represented by Name was most
+recently modified. If the external file is not an ordinary file, the result is
+implementation-defined. The exception Name_Error is propagated if the string
+given as Name does not allow the identification of an existing external file.
+The exception Use_Error is propagated if the external environment does not
+support reading the modification time of the file with the name given by
+Name (in the absence of Name_Error).]}
address@hidden,Kind=[AddedNormal],address@hidden,New=[The
+result for Directories.Modification_Time for a directory or special file.],
+Old=[]}]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00248-01]}
address@hidden,Type=[Leading],Text=[The following directory searching
+operations and types are provided:]}
+
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Directory_Entry_Type @key{is limited 
private};]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[The type Directory_Entry_Type represents a 
single item in a directory.
+These items can only be created by the Get_Next_Entry procedure in this
+package. Information about the item can be obtained from the functions declared
+in this package. A default-initialized object of this type is invalid; objects
+returned from Get_Next_Entry are valid.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Filter_Type @key{is array} 
(File_Kind) @key{of} Boolean;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[The type Filter_Type specifies which 
directory entries are provided
+from a search operation. If the Directory component is True, directory entries
+representing directories are provided. If the Ordinary_File component is True,
+directory entries representing ordinary files are provided. If the Special_File
+component is True, directory entries representing special files are provided.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Search_Type @key{is limited 
private};]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[The type Search_Type contains the
+state of a directory search. A
+default-initialized Search_Type object has no entries available (function
+More_Entries returns False). Type Search_Type
+needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization}).]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Start_Search (Search    : @key{in 
out} Search_Type;
+                        Directory : @key{in} String;
+                        Pattern   : @key{in} String;
+                        Filter    : @key{in} Filter_Type := (@key{others} => 
True));]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0092-1],ARef=[AI05-0262-1]}
address@hidden,Type=[Trailing],Text=[Starts a search
+in the directory named by
+Directory for entries matching address@hidden,New=[ and Filter],Old=[]}.
+Pattern represents a pattern for matching file names. If Pattern is
address@hidden,New=[the ],address@hidden,New=[ string],Old=[]},
+all items in the directory are matched; otherwise,
+the interpretation of Pattern is implementation-defined. Only items that match
+Filter will be returned. After a successful call on Start_Search, the object
+Search may have entries available, but it may have no entries available if no
+files or directories match Pattern and Filter. The exception Name_Error is
+propagated if the string given by Directory does not identify an existing
+directory, or if Pattern does not allow the identification of any possible
+external file or directory. The exception Use_Error is propagated if the
+external environment does not support the searching of the directory with the
+given name (in the absence of Name_Error). When Start_Search propagates
+Name_Error or Use_Error, the object Search will have no entries available.]}
address@hidden,Kind=[AddedNormal],address@hidden,New=[The
+interpretation of a nonnull search pattern in Directories.],Old=[]}]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden End_Search (Search : @key{in out} 
Search_Type);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Ends the search represented
+by Search. After a successful call on
+End_Search, the object Search will have no entries available.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The only way that a call to End_Search could be
+  unsuccessful if Device_Error (see @RefSecNum{Exceptions in Input-Output}) is
+  raised because of an underlying failure (or bug).]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden More_Entries (Search : @key{in} 
Search_Type) @key{return} Boolean;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns True if more entries are
+available to be returned by a call
+to Get_Next_Entry for the specified search object, and False otherwise.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Get_Next_Entry (Search : @key{in 
out} Search_Type;
+                          Directory_Entry : @key{out} Directory_Entry_Type);]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0262-1]}
address@hidden,Type=[Trailing],Text=[Returns the next Directory_Entry
+for the search described by Search
+that matches the pattern and filter. If no further matches are available,
+Status_Error is raised. It is implementation-defined as to whether the results
+returned by this @Chg{Version=[3],New=[subprogram],Old=[routine]} are altered
+if the contents of the directory are
+altered while the Search object is valid (for example, by another program). The
+exception Use_Error is propagated if the external environment does not support
+continued searching of the directory represented by Search.]}
address@hidden,Kind=[AddedNormal],address@hidden,New=[The
+results of a Directories search if the contents of the directory are
+altered while a search is in progress.],Old=[]}]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Search (
+    Directory : @key{in} String;
+    Pattern   : @key{in} String;
+    Filter    : @key{in} Filter_Type := (@key{others} => True);
+    Process   : @key{not null access procedure} (
+        Directory_Entry : @key{in} Directory_Entry_Type));]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0092-1],ARef=[AI05-0262-1]}
address@hidden,Type=[Trailing],Text=[Searches in the directory named by
+Directory for entries matching address@hidden,New=[ and Filter],Old=[]}.
+The subprogram designated by Process is called with each matching entry in
+turn. Pattern represents a pattern for matching file names. If Pattern is
address@hidden,New=[the ],address@hidden,New=[ string],Old=[]},
+all items in the directory are matched;
+otherwise, the interpretation of Pattern is implementation-defined. Only
+items that match Filter will be returned.
+The exception Name_Error is propagated if the string given by Directory
+does not identify an existing directory, or if Pattern does not allow the
+identification of any possible external file or directory. The exception
+Use_Error is propagated if the external environment does not support the
+searching of the directory with the given name (in the absence of
+Name_Error).]}
address@hidden implementation-defined case is handled above.}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],address@hidden@;In address@hidden means that the
+  calls to the subprogram designated by Process are not made in parallel;
+  they can be made in any order but must be in sequence.]}
address@hidden
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Simple_Name (Directory_Entry : 
@key{in} Directory_Entry_Type)
+     @key{return} String;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the simple external name
+of the external file (including
+directories) represented by Directory_Entry. The format of the name returned is
+implementation-defined. The exception Status_Error is propagated if
+Directory_Entry is invalid.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Full_Name (Directory_Entry : 
@key{in} Directory_Entry_Type)
+     @key{return} String;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the full external name of
+the external file (including
+directories) represented by Directory_Entry. The format of the name returned is
+implementation-defined. The exception Status_Error is propagated if
+Directory_Entry is invalid.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Kind (Directory_Entry : @key{in} 
Directory_Entry_Type)
+     @key{return} File_Kind;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the kind of external file
+represented by Directory_Entry. The
+exception Status_Error is propagated if Directory_Entry is invalid.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Size (Directory_Entry : @key{in} 
Directory_Entry_Type)
+     @key{return} File_Size;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the size of the external
+file represented by Directory_Entry.
+The size of an external file is the number of stream elements contained in
+the file. If the external file represented by
+Directory_Entry is not an ordinary file, the result is implementation-defined.
+The exception Status_Error is propagated if Directory_Entry is invalid. The
+exception Constraint_Error is propagated if the file size is not a value of
+type File_Size.]}
+
address@hidden@ChgRef{Version=[2],Kind=[AddedNormal]}
address@hidden,Keepnext=[T],address@hidden Modification_Time (Directory_Entry : 
@key{in} Directory_Entry_Type)
+     @key{return} Ada.Calendar.Time;]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the time that the external
+file represented by Directory_Entry
+was most recently modified. If the external file represented by Directory_Entry
+is not an ordinary file, the result is implementation-defined. The exception
+Status_Error is propagated if Directory_Entry is invalid. The exception
+Use_Error is propagated if the external environment does not support
+reading the modification time of the file represented by Directory_Entry.]}
+
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[For Copy_File, if Source_Name identifies an
+existing external ordinary file created by a predefined Ada input-output
+package, and Target_Name and Form can be used in the Create operation of that
+input-output package with mode Out_File without raising an exception, then
+Copy_File shall not propagate Use_Error.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This means that Copy_File will copy any file
+  that the Ada programmer could copy (by writing some possibly complicated
+  Ada code).]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If other information about a file
+(such as the owner or creation date) is available in a directory entry,
+the implementation
+should provide functions in a child package Directories.Information to
+retrieve address@hidden,Child=[Information]}]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Package Directories.Information should be provided to retrieve
+other information about a file.]}]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[For address@hidden(174),
+Directories.Information should contain at least the following routines:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Directories.Information @key{is}
+    -- @RI[System-specific directory information.]
+    -- @RI[Version for the address@hidden(174) address@hidden(174) operating 
system.]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Creation_Time (Name : @key{in} String) 
@key{return} Ada.Calendar.Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Last_Access_Time (Name : @key{in} 
String) @key{return} Ada.Calendar.Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Read_Only (Name : @key{in} String) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Needs_Archiving (Name : @key{in} 
String) @key{return} Boolean;
+        -- @RI[This generally means that the file needs to be backed up.]
+        -- @RI[The flag is only cleared by backup programs.]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Compressed (Name : @key{in} String) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Encrypted (Name : @key{in} String) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Hidden (Name : @key{in} String) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_System (Name : @key{in} String) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Offline (Name : @key{in} String) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Temporary (Name : @key{in} String) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Sparse (Name : @key{in} String) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Not_Indexed (Name : @key{in} String) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Creation_Time (Directory_Entry : 
@key{in} Directory_Entry_Type)
+         @key{return} Ada.Calendar.Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Last_Access_Time (Directory_Entry : 
@key{in} Directory_Entry_Type)
+         @key{return} Ada.Calendar.Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Read_Only (Directory_Entry : 
@key{in} Directory_Entry_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Needs_Archiving (Directory_Entry : 
@key{in} Directory_Entry_Type) @key{return} Boolean;
+        -- @RI[This generally means that the file needs to be backed up.]
+        -- @RI[The flag is only cleared by backup programs.]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Compressed (Directory_Entry : 
@key{in} Directory_Entry_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Encrypted (Directory_Entry : 
@key{in} Directory_Entry_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Hidden (Directory_Entry : @key{in} 
Directory_Entry_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_System (Directory_Entry : @key{in} 
Directory_Entry_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Offline (Directory_Entry : @key{in} 
Directory_Entry_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Temporary (Directory_Entry : 
@key{in} Directory_Entry_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Sparse (Directory_Entry : @key{in} 
Directory_Entry_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Not_Indexed (Directory_Entry : 
@key{in} Directory_Entry_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    -- @RI[Additional implementation-defined subprograms 
allowed here.]
address@hidden Ada.Directories.Information;]}
address@hidden
+
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[For Unix-like systems (Unix,
+POSIX, Linux, etc.), Directories.Information should contain at least the
+following routines:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Directories.Information @key{is}
+    -- @RI[System-specific directory information.]
+    -- @RI[Unix and similar systems version.]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Last_Access_Time (Name : @key{in} 
String) @key{return} Ada.Calendar.Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Last_Status_Change_Time (Name : 
@key{in} String) @key{return} Ada.Calendar.Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{type} Permission @key{is}
+      (Others_Execute, Others_Write, Others_Read,
+       Group_Execute,  Group_Write,  Group_Read,
+       Owner_Execute,  Owner_Write,  Owner_Read,
+       Set_Group_ID,   Set_User_ID);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{type} Permission_Set_Type @key{is array} 
(Permission) @key{of} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Permission_Set (Name : @key{in} String) 
@key{return} Permission_Set_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Owner (Name : @key{in} String) 
@key{return} String;
+        -- @RI[Returns the image of the User_Id. If a definition of User_Id]
+        -- @RI[is available, an implementation-defined version of Owner]
+        -- @RI[returning User_Id should also be defined.]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
address@hidden,Text=[    @key{function} Group (Name : @key{in} String) 
@key{return} String;
+        -- @RI[Returns the image of the 
@Chg{Version=[3],New=[Group_Id],Old=[User_Id]}. If a definition of Group_Id]
+        -- @RI[is available, an implementation-defined version of Group]
+        -- @RI[returning Group_Id should also be defined.]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Block_Special_File (Name : @key{in} 
String) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Character_Special_File (Name : 
@key{in} String) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_FIFO (Name : @key{in} String) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Symbolic_Link (Name : @key{in} 
String) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Socket (Name : @key{in} String) 
@key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Last_Access_Time (Directory_Entry : 
@key{in} Directory_Entry_Type)
+       @key{return} Ada.Calendar.Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Last_Status_Change_Time 
(Directory_Entry : @key{in} Directory_Entry_Type)
+       @key{return} Ada.Calendar.Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Permission_Set (Directory_Entry : 
@key{in} Directory_Entry_Type)
+       @key{return} Permission_Set_Type;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Owner (Directory_Entry : @key{in} 
Directory_Entry_Type) @key{return} String;
+       -- @RI[See Owner above.]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Group (Directory_Entry : @key{in} 
Directory_Entry_Type) @key{return} String;
+       -- @RI[See Group above.]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Block_Special_File (Directory_Entry 
: @key{in} Directory_Entry_Type)
+       @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Character_Special_File 
(Directory_Entry : @key{in} Directory_Entry_Type)
+       @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_FIFO (Directory_Entry : @key{in} 
Directory_Entry_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Symbolic_Link (Directory_Entry : 
@key{in} Directory_Entry_Type)
+       @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    @key{function} Is_Socket (Directory_Entry : @key{in} 
Directory_Entry_Type) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[    -- @RI[Additional implementation-defined subprograms 
allowed here.]
address@hidden Ada.Directories.Information;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[We give these definitions to give guidance so that
+every implementation for a given target is not unnecessarily different.
+Implementers are encouraged to make packages for other targets as similar to
+these as possible.]}
+
address@hidden
+
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0231-1]}
address@hidden,Text=[Start_Search and Search should raise
address@hidden,New=[Name_Error],Old=[Use_Error]} if Pattern is malformed, but
+not if it could represent a file in the directory but does not actually do 
so.]}
+
address@hidden,Kind=[Revised],InitialVersion=[2],
address@hidden,
+Text=[Directories.Start_Search and Directories.Search should raise
address@hidden,New=[Name_Error],Old=[Use_Error]} for malformed patterns.]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Rename should be supported at least when both
+New_Name and Old_Name are simple names and New_Name does not identify an
+existing external file.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Directories.Rename should be supported at least when both New_Name and
+Old_Name are simple names and New_Name does not identify an existing
+external file.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],address@hidden@;address@hidden@; includes raising
+  an exception if either name is malformed, the file to rename doesn't exist,
+  insufficient permission for the operation exists, or similar problems. But
+  this advice requires implementations to document what they do, and tells
+  implementers that simply raising Use_Error isn't acceptable.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The operations Containing_Directory,
+Full_Name, Simple_Name,
+Base_Name, Extension, and Compose operate on file names, not external files.
+The files identified by these operations do not need to exist. Name_Error is
+raised only if the file name is malformed and cannot possibly identify a file.
+Of these operations, only the result of Full_Name depends on the current
+default directory; the result of the others depends only on their parameters.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Using access types, values of Search_Type and
+Directory_Entry_Type can be
+saved and queried later. However, another task or application can modify or
+delete the file represented by a Directory_Entry_Type value or the directory
+represented by a Search_Type value; such a value can only give the information
+valid at the time it is created. Therefore, long-term storage of these values
+is not recommended.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If the target system does not support directories
+inside of directories, then Kind will never return Directory and
+Containing_Directory will always raise Use_Error.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If the target system does not support creation or
+deletion of directories, then Create_Directory, Create_Path, Delete_Directory,
+and Delete_Tree will always propagate Use_Error.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[To move a file or directory to a different
+location, use Rename. Most target systems will allow renaming of files from one
+directory to another. If the target file or directory might already exist, it
+should be deleted first.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[While Rename is only guaranteed to
+  work for name changes within a single directory, its unlikely that
+  implementers would purposely prevent functionality present in the underlying
+  system from working. To move a file totally portably, it's necessary to
+  handle failure of the Rename and fall back to Copy_File and Delete:]}
address@hidden
address@hidden,address@hidden
+   Rename (Source, Target);
address@hidden
+   @key[when] Use_Error =>
+      Copy_File (Source, Target);
+      Delete (Source);
address@hidden;]}
address@hidden
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00248-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Package Ada.Directories is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0231-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction>:
+  Clarified when and which
+  exceptions are raised for Start_Search, Search, Delete_Directory, and
+  Rename. If an implementation followed the original incorrect wording, it 
might
+  raise Use_Error instead of Name_Error for Start_Search and Search,
+  Name_Error instead of Use_Error for Rename, and might have deleted a
+  nonempty directory instead of raising Use_Error for Delete_Directory.
+  The first two cases are very unlikely to matter in practice, and it unlikely
+  that an implementation would have followed the latter implementation
+  strategy, as it would be more work and would make Delete_Directory
+  identical to Delete_Tree (which is obvious nonsense).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0049-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  A new enumeration type Name_Case_Kind and a new function
+  Name_Case_Equivalence is added to Directories. If Directories
+  is referenced in a @nt{use_clause}, and an
+  entity @i<E> with a @nt{defining_identifier} of one of the new entities is
+  defined in a package that is also referenced in a @nt{use_clause}, the entity
+  @i<E> may no longer be use-visible, resulting in errors. This should be rare
+  and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0271-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> We now explicitly say that
+  the behavior of Create_Path and Copy_File is unspecified when Use_Error
+  is raised. Nothing has changed here, as the behavior was (implicitly)
+  unspecified in the 2007 Amendment.]}
address@hidden
+
+
+
address@hidden,Name=[The Package Directories.Hierarchical_File_Names]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0049-1]}
address@hidden,Text=[The library package Directories.Hierarchical_File_Names is 
an optional package
+providing operations for file name construction and decomposition for
+targets with hierarchical file naming.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0049-1]}
address@hidden,Type=[Leading],Text=[If provided, the library package
+Directories.Hierarchical_File_Names has the following declaration:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Directories.Hierarchical_File_Names 
@address@hidden,Child=[Hierarchical_File_Names]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Simple_Name} (Name : 
@key{in} String) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Root_Directory_Name} 
(Name : @key{in} String) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Parent_Directory_Name} 
(Name : @key{in} String) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Current_Directory_Name} 
(Name : @key{in} String) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Full_Name} (Name : 
@key{in} String) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Is_Relative_Name} (Name : 
@key{in} String) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Simple_Name} (Name : 
@key{in} String) @key{return} String
+      @key{renames} Ada.Directories.Simple_Name;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Containing_Directory} (Name 
: @key{in} String) @key{return} String
+      @key{renames} Ada.Directories.Containing_Directory;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Initial_Directory} (Name : 
@key{in} String) @key{return} String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Relative_Name} (Name : 
@key{in} String) @key{return} String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Compose} (Directory      : 
@key{in} String := "";
+                     Relative_Name  : @key{in} String;
+                     Extension      : @key{in} String := "") @key{return} 
String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Directories.Hierarchical_File_Names;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0049-1],ARef=[AI05-0269-1]}
address@hidden,Text=[In addition to the operations provided in package
+Directories.Hierarchical_File_Names, the operations in package Directories can
+be used with hierarchical file names. In particular, functions Full_Name,
+Base_Name, and Extension provide additional capabilities for hierarchical
+file names.]}
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Is_Simple_Name (Name : @key{in} String) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Returns True if Name is a simple name, and returns
+False otherwise.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Is_Root_Directory_Name (Name : @key{in} String) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Returns True if Name is syntactically a root (a
+directory that cannot be decomposed further), and returns False otherwise.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[For Unix and Unix-like systems, "/" is the root.
+  For Windows, "C:\" and "\\Computer\Share" are roots.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Is_Parent_Directory_Name (Name : @key{in} String) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Returns True if Name can be used to indicate
+symbolically the parent directory of any directory, and returns False
+otherwise.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Is_Parent_Directory_Name returns True if and only
+  if Name is ".." for both Unix and Windows.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Is_Current_Directory_Name (Name : @key{in} 
String) @key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Returns True if Name can be used to indicate
+symbolically the directory itself for any directory, and returns False
+otherwise.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Is_Current_Directory_Name returns True if and 
only
+  if Name is "." for both Unix and Windows.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Is_Full_Name (Name : @key{in} String) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Returns True if the leftmost directory part of Name
+is a root, and returns False otherwise.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Is_Relative_Name (Name : @key{in} String) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0049-1],ARef=[AI05-0269-1]}
address@hidden,Text=[Returns True if Name allows the identification of an
+external file (including directories and special files) but is not a full name,
+and returns False otherwise.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Relative names include simple names as a special 
case.
+  This function returns False if the syntax of the name is incorrect.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Initial_Directory (Name : @key{in} String) 
@key{return} String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0049-1],ARef=[AI05-0248-1]}
address@hidden,Text=[Returns the leftmost directory
+part in Name. @Redundant[That is, it returns a root directory name (for a full
+name), or one of a parent directory name, a current directory name, or a simple
+name (for a relative name).] The exception Name_Error is propagated if the
+string given as Name does not allow the identification of an external file
+(including directories and special files).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Relative_Name (Name : @key{in} String) 
@key{return} String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Returns the entire file name except
+the Initial_Directory portion. The exception Name_Error is propagated if the
+string given as Name does not allow the identification of an external file
+(including directories and special files), or if Name has a single part (this
+includes if any of Is_Simple_Name, Is_Root_Directory_Name,
+Is_Parent_Directory_Name, or Is_Current_Directory_Name are True).]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The result might be a simple name.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Compose (Directory      : @key{in} String := "";
+                  Relative_Name  : @key{in} String;
+                  Extension      : @key{in} String := "") @key{return} 
String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Returns the name of the external file with the
+specified Directory, Relative_Name, and Extension. The exception Name_Error is
+propagated if the string given as Directory is not the null string and does
+not allow the identification of a directory, or if Is_Relative_Name
+(Relative_Name) is False, or if the string given as Extension is not the null
+string and is not a possible extension, or if Extension is not the null string
+and Simple_Name (Relative_Name) is not a base name.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The result of Compose is a full name if Is_Full_Name
+(Directory) is True; result is a relative name otherwise.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Name_Error is raised by Compose if Directory is
+  not the null string, and both Is_Full_Name and Is_Relative_Name return
+  False.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[A common security problem is to include a parent
+  directory name in the middle of a file name; this is often used to navigate
+  outside of an intended root directory. We considered attempting to prevent
+  that case by having Compose detect it and raise an exception. But the extra
+  rules necessary were more confusing than helpful.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We can say more about the details of these
+  operations by adopting the notation of a subscript to specify how many path
+  fragments a particular result has. Then, we can abbreviate "Full Name" as
+  "Full" and "Relative Name" as "Rel". In this notation, Unix file name "a/b" 
is
+  a Rel(2), "../c/d" is a Rel(3), and "/a/b" is a Full(2). Rel(1) is equivalent
+  to a simple name; thus we don't have to describe that separately.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[In this notation,]}
+  @begin{Example}
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[For N>1,
+Containing_Directory(Rel(N)) = Leftmost Rel(N-1),
+Containing_Directory(Full(N)) = Leftmost Full(N-1),
+Else if N = 1, raise Name_Error.]}
+  @end{Example}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[Similarly,]}
+  @begin{Example}
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[For N>1,
+Relative_Name(Rel(N)) = Rightmost Rel(N-1),
+Relative_Name(Full(N)) = Rightmost Full(N-1),
+Else if N = 1, raise Name_Error.]}
+  @end{Example}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Type=[Leading],Text=[Finally, for Compose (ignoring 
the extension here):]}
+  @begin{Example}
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Compose (Directory => Full(N), Relative_Name => Rel(M)) => 
Full(N+M)
+Compose (Directory => Rel(N), Relative_Name => Rel(M)) => Rel(N+M)
+Name_Error if Relative_Name is a Full(M).]}
+  @end{Example}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[We didn't try to write wording to reflect these
+  details of these functions.]}
address@hidden
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0049-1]}
address@hidden,Text=[Directories.Hierarchical_File_Names should be
+provided for systems with hierarchical file naming, and should not be provided
+on other systems.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Directories.Hierarchical_File_Names should be
+provided for systems with hierarchical file naming, and should not be provided
+on other systems.]}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This package should be provided when targeting
+  address@hidden(174) address@hidden(174), Unix, Linux, and most Unix-like
+  systems.]}
address@hidden
+
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0049-1]}
address@hidden,Text=[These operations operate on file names, not external
+files. The files identified by these operations do not need to exist. 
Name_Error
+is raised only as specified or if the file name is malformed and cannot 
possibly
+identify a file. The result of these operations depends only on their
+parameters.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0049-1]}
address@hidden,Text=[Containing_Directory raises Use_Error if Name does
+not have a containing directory, including when any of Is_Simple_Name,
+Is_Root_Directory_Name, Is_Parent_Directory_Name, or Is_Current_Directory_Name
+are True.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[In particular, the default directory is not used
+  to find the containing directory either when Is_Parent_Directory_Name or
+  Is_Current_Directory_Name is True. As noted above, these functions operate
+  purely on the syntax of the file names and do not attempt to interpret them.
+  If interpretation is needed, Directories.Full_Name can be to expand any
+  shorthands used before calling Containing_Directory.]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0049-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Package Ada.Directories.Hierarchical_File_Names is new.]}
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/pre_environ.mss 
b/packages/ada-ref-man/source_2012/pre_environ.mss
new file mode 100755
index 0000000..0958bb1
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pre_environ.mss
@@ -0,0 +1,259 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/pre_environ.mss,v $ }
address@hidden $Revision: 1.13 $ $Date: 2012/03/20 06:13:59 $ $Author: randy $ }
address@hidden(predefenviron, Root="ada.mss")
+
address@hidden: 2012/03/20 06:13:59 $}
+
address@hidden,Name=[The Package Environment_Variables]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,address@hidden variable}
+The package Environment_Variables allows a program to
+read or modify environment variables. Environment variables are name-value
+pairs, where both the name and value are strings. The definition of what
+constitutes an @i{environment variable}, and the meaning of the name and value,
+are implementation defined.]}
address@hidden,Kind=[AddedNormal],address@hidden,New=[The
+definition and meaning of an environment variable.],Old=[]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library package
+Environment_Variables has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Environment_Variables 
@address@hidden,Child=[Environment_Variables]}
+   @key{pragma} Preelaborate(Environment_Variables);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Value} (Name : @key{in} 
String) @key{return} String;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0285-1]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Value} (Name : @key{in} 
String; Default : @key{in} String) @key{return} String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Exists} (Name : @key{in} 
String) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Set} (Name : @key{in} 
String; Value : @key{in} String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Clear} (Name : @key{in} 
String);
+   @key{procedure} @AdaSubDefn{Clear};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0248-1]}
address@hidden,Text=[   @key{procedure} @address@hidden,New=[],Old=[ (]}
+      @Chg{Version=[3],New=[(],Old=[ ]}Process : @key{not null access 
procedure} (Name, Value : @key{in} String));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],address@hidden Ada.Environment_Variables;]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Value (Name : @key{in} String) 
@key{return} String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,Type=[Trailing],Text=[If the external execution
+environment supports environment variables, then Value returns the value of the
+environment variable with the given name. If no environment variable with the
+given name exists, then Constraint_Error is propagated. If the execution
+environment does not support environment variables, then Program_Error is
+propagated.]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Value (Name : @key{in} String; 
Default : @key{in} String) @key{return} String;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0285-1]}
address@hidden,Type=[Trailing],Text=[If the external execution
+environment supports environment variables and an environment variable with the
+given name currently exists, then Value returns its value; otherwise, it 
returns
+Default.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Exists (Name : @key{in} String) 
@key{return} Boolean;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If the external execution environment
+supports environment variables and an environment variable with the given name
+currently exists, then Exists returns True;
address@hidden,New=[,],Old=[]}
+it returns False.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Set (Name : @key{in} String; Value : 
@key{in} String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[If the external execution
+environment supports environment variables, then Set first clears any existing
+environment variable with the given name, and then defines a single new
+environment variable with the given name and value.
address@hidden,New=[,],Old=[]} Program_Error is
+propagated.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If implementation-defined circumstances prohibit
+the definition of an environment variable with the given name and value, then
+Constraint_Error is propagated.]}
address@hidden,Kind=[AddedNormal],
address@hidden,New=[The circumstances where an environment variable
+cannot be defined.],Old=[]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[It is implementation defined
+whether there exist values for which the call Set(Name, Value) has the same
+effect as Clear (Name).]}
address@hidden,Kind=[AddedNormal],
address@hidden,New=[Environment names for which Set has the effect of
+Clear.],Old=[]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Clear (Name : @key{in} String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[If the external execution
+environment supports environment variables, then Clear deletes all existing
+environment @Chg{Version=[3],New=[variables],Old=[variable]} with the given
+name. address@hidden,New=[,],Old=[]} Program_Error is propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Clear;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Type=[Trailing],Text=[If the external execution
+environment supports environment variables,
+then Clear deletes all existing environment variables.
address@hidden,New=[,],Old=[]} Program_Error is
+propagated.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0248-1]}
address@hidden,address@hidden address@hidden,New=[],Old=[ (]}
+   @Chg{Version=[3],New=[(],Old=[  ]}Process : @key{not null access procedure} 
(Name, Value : @key{in} String));]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[If the external execution environment supports
+environment variables, then Iterate calls the subprogram designated by Process
+for each existing environment variable, passing the name and value of that
+environment variable.
address@hidden,New=[,],Old=[]} Program_Error is
+propagated.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If several environment variables exist that have
+the same name, Process is called once for each such variable.]}
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,Type=[Leading],address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to call Value if more than one environment variable
+exists with the given name; the possible outcomes are that:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[one of the values is returned, and that
+same value is returned in subsequent calls in the absence of changes to
+the environment; or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Program_Error is propagated.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,address@hidden(erroneous execution),Sec=(cause)}
+Making calls to the procedures Set or Clear concurrently with calls to any
+subprogram of package Environment_Variables, or to any instantiation of 
Iterate,
+results in erroneous execution.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Making calls to the procedures Set or Clear in the actual 
subprogram
+corresponding to the Process parameter of Iterate results in erroneous
+execution.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,Text=[An implementation shall document how the
+operations of this package behave if
+environment variables are changed by external mechanisms (for instance,
+calling operating system services).]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The behavior of package Environment_Variables when environment variables
+are changed by external mechanisms.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,Text=[An implementation running on a system that does
+not support environment variables is permitted to define the operations of
+package Environment_Variables with the semantics corresponding to the case
+where the external execution environment does support environment variables. In
+this case, it shall provide a mechanism to initialize a nonempty set of
+environment variables prior to the execution of a partition.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,Text=[If the execution environment supports subprocesses,
+the currently defined environment variables should be used to initialize the
+environment variables of a subprocess.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If the execution environment supports subprocesses,
+the current environment variables should be used to initialize the
+environment variables of a subprocess.]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Changes to the environment variables made outside the 
control of this package
+should be reflected immediately in the effect of the operations of this 
package.
+Changes to the environment variables made using this package should be 
reflected
+immediately in the external execution environment. This package should not
+perform any buffering of the environment variables.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Changes to the environment variables made outside the control of
+Environment_Variables should be reflected immediately.]}]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00370-01]}
address@hidden,address@hidden to Ada 95}
+Package Environment_Variables is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0285-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  A new overloaded function Value is added to Environment_Variables.
+  If Environment_Variables is referenced in a @nt{use_clause}, and an entity
+  @i<E> with the name Value is defined in a package that is also referenced in 
a
+  @nt{use_clause}, the entity @i<E> may no longer be use-visible, resulting in
+  errors. This should be rare and is easily fixed if it does occur.]}
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/pre_io.mss 
b/packages/ada-ref-man/source_2012/pre_io.mss
new file mode 100755
index 0000000..2554398
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pre_io.mss
@@ -0,0 +1,4096 @@
address@hidden(predefio, Root="ada.mss")
+
address@hidden: 2015/04/03 04:12:42 $}
+
address@hidden: e:\\cvsroot/ARM/Source/pre_io.mss,v $}
address@hidden: 1.71 $}
address@hidden
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden@address@hidden
+Input-output is provided through
+language-defined packages, each of which is a child of the root package Ada.
+The generic packages Sequential_IO and Direct_IO
+define input-output operations applicable to files containing elements
+of a given type. The generic package Storage_IO supports reading from and
+writing to an in-memory buffer.
+Additional operations for text input-output are
+supplied in the packages address@hidden,New=[,],Old=[ and]}
address@hidden,New=[, and Wide_Wide_Text_IO],Old=[]}.
+Heterogeneous input-output is provided through the child packages
address@hidden and address@hidden@!Streams
+(see also @RefSecNum{Streams}).
+The package IO_Exceptions defines the
+exceptions needed by the predefined input-output packages.]
address@hidden
+
address@hidden
address@hidden with Ada 83}
+The introduction of Append_File as a new element of the enumeration type
+File_Mode in Sequential_IO and Text_IO, and the introduction of
+several new declarations
+in Text_IO, may result in name clashes in the
+presence of @key[use] clauses.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Text_IO enhancements
+(Get_Immediate, Look_Ahead, Standard_Error, Modular_IO, Decimal_IO),
+Wide_Text_IO, and the stream input-output facilities are new in Ada 95.
address@hidden
+
address@hidden
+RM83-14.6, "Low Level Input-Output,"
+is removed. This has no semantic effect,
+since the package was entirely implementation defined,
+nobody actually implemented it,
+and if they did, they can always provide it as a vendor-supplied
+package.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[Included package Wide_Wide_Text_IO
+  in this description.]}
address@hidden
+
+
address@hidden Files and File Objects}
+
address@hidden
address@hidden file}
address@hidden, Sec=(of an external file)}
address@hidden, Sec=(of an external file)}
+Values input from the external environment of the program, or output to
+the external environment,
+are considered to occupy @i{external files}.
+An external file can be anything external to the program that can
+produce a value to be read or receive a value to be written. An
+external file is identified by a string (the @i{name}). A second string
+(the @i{form}) gives further system-dependent characteristics that may
+be associated with the file, such as the physical organization or access
+rights. The conventions governing the interpretation of such strings
+shall be documented.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden, Sec=(as file object)}
+Input and output operations are expressed as operations on objects of
+some @i{file type}, rather than directly in terms of the external files. In
+the remainder of this @Chg{Version=[3],New=[clause],Old=[section]}, the term
address@hidden is always used to refer to a file object; the term @i{external 
file} is
+used otherwise.
+
+Input-output for sequential files of values of a single element type is
+defined by means of the generic package Sequential_IO.
+In order to define sequential input-output for a given element type, an
+instantiation of this generic unit, with the given type as actual
+parameter, has to be declared. The resulting package contains the
+declaration of a file type (called File_Type) for files of such
+elements, as well as the operations applicable to these files, such as
+the Open, Read, and Write procedures.
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+Input-output for direct access files is likewise defined by a generic
+package called Direct_IO. Input-output in human-readable form is
+defined by the (nongeneric) packages Text_IO for Character and String
+data, @Chg{Version=[2],New=[],Old=[and ]}Wide_Text_IO for Wide_Character and
+Wide_String address@hidden,New=[, and Wide_Wide_Text_IO for
+Wide_Wide_Character and Wide_Wide_String data],Old=[]}.
+Input-output for files containing streams of
+elements representing values of possibly different types is defined by means of
+the (nongeneric) package Streams.Stream_IO.
+
+Before input or output operations can be performed on a file, the file
+first has to be associated with an external file. While such an
+association is in effect, the file is said to be @i{open}, and otherwise the
+file is said to be @i{closed}.
+
+The language does not define what happens to external files after the
+completion of the main program and all the library tasks (in particular,
+if corresponding files have not been closed).
address@hidden types], Sec=(input-output unspecified)}
address@hidden, Sec=(unspecified for access types)}
address@hidden
+The effect of input-output for access types is unspecified.
+
address@hidden@address@hidden mode], Sec=(of an open file)}
+An open file has a @i{current mode}, which is a value of one of the
+following enumeration types:
address@hidden
address@hidden
address@hidden File_Mode @key[is] (In_File, Inout_File, Out_File);  
address@hidden  for Direct_IO}
address@hidden
+
+These values correspond respectively to the cases where only reading,
+both reading and writing, or only writing are to be performed.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden File_Mode @key[is] (In_File, Out_File, Append_File);
address@hidden  for Sequential_IO, Text_IO, Wide_Text_IO, 
@Chg{Version=[2],New=[Wide_Wide_Text_IO, ],
+Old=[]}and Stream_IO}
address@hidden
+
+These values correspond respectively to the cases where only reading,
+only writing, or only appending are to be performed.
+
address@hidden@;The mode of a file can be changed.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+Several file management operations are common to Sequential_IO,
+Direct_IO, Text_IO, @Chg{Version=[2],New=[],Old=[and address@hidden,
+New=[, and Wide_Wide_Text_IO],Old=[]}.
+These operations are described in subclause
address@hidden Management} for
+sequential and direct files.
+Any additional effects concerning text
+input-output are described in subclause @RefSecNum{Text File Management}.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The exceptions that can be propagated by the execution of an input-output
+subprogram are defined in the package IO_Exceptions; the situations
+in which they can be propagated are described following the description of
+the subprogram (and in @Chg{Version=[3],New=[subclause],Old=[clause]}
address@hidden in Input-Output}).
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,Sec=(raised by failure of run-time check)}
+The exceptions Storage_Error and Program_Error may be propagated.
+(Program_Error can only be propagated due to errors made by the
+caller of the subprogram.) Finally, exceptions can be propagated
+in certain implementation-defined situations.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Any implementation-defined characteristics of the
+input-output packages.]}]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The last sentence here is referring to the
+documentation requirements in @RefSec{Exceptions in Input-Output}, and
+the documentation summary item is provided there.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+Each instantiation of the generic packages Sequential_IO and Direct_IO
+declares a different type File_Type. In the case of Text_IO, Wide_Text_IO,
address@hidden,New=[Wide_Wide_Text_IO, ],Old=[]}and Streams.Stream_IO,
+the corresponding type File_Type is unique.
+
+A bidirectional device can often be modeled as two sequential files
+associated with the device, one of mode In_File, and one of mode
+Out_File. An implementation may restrict the number of files that may
+be associated with a given external file.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[Included package Wide_Wide_Text_IO
+  in this description.]}
address@hidden
+
+
address@hidden@Comment{Break here so printed Ada 95 w/ corrigendum RM looks 
better.}
address@hidden and Direct Files}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00283-01]}
address@hidden file}
address@hidden address@hidden,address@hidden file}],Old=[]}
+Two kinds of access to external files are defined in this subclause:
address@hidden access} and @i{direct access}.
+The corresponding file types and the associated
+operations are provided by the generic packages Sequential_IO and
+Direct_IO. A file
+object to be used for sequential access is called a @i{sequential file},
+and one to be used for direct access is called a @i{direct file}.
+Access to @Chg{Version=[2],address@hidden file}s],Old=[stream files]}
+is described in @RefSecNum(The Package Streams.Stream_IO).
+
address@hidden access}
+For sequential access, the file is viewed as a sequence of values that
+are transferred in the order of their appearance (as produced by the
+program or by the external environment).
+When the file is opened with mode
+In_File or Out_File, transfer starts respectively
+from or to the beginning of the file. When the file is opened with mode
+Append_File, transfer to the file starts after the last element of the
+file.
address@hidden
+Adding stream I/O necessitates a review of the terminology. In
+Ada 83, `sequential' implies both the access method (purely sequential
address@hidden that is, no indexing or positional access) and homogeneity. 
Direct
+access includes purely sequential access and indexed access, as well as
+homogeneity. In Ada 95, streams allow purely sequential access but also
+positional access to an individual
+element, and are
+heterogeneous. We considered generalizing the notion of
+`sequential file' to include both Sequential_IO and Stream_IO files, but
+since streams allow positional access it seems misleading to call them
+sequential files. Or, looked at differently, if the criterion for
+calling something a sequential file is whether it permits (versus
+requires) purely sequential access, then one could just as soon regard a
+Direct_IO file as a sequential file.
+
+It seems better to regard `sequential file' as meaning `only permitting
+purely sequential access'; hence we have decided to supplement `sequential
+access' and `direct access' with a third category, informally called `access
+to streams'. (We decided against the term `stream access' because of possible
+confusion with the Stream_Access type declared in one of the stream 
packages.)@end{discussion}
+
address@hidden access}
address@hidden, Sec=(of an element of an open direct file)}
address@hidden size], Sec=(of an external file)}
+For direct access, the file is viewed as a set of elements occupying
+consecutive positions in linear order; a value can be transferred to or
+from an element of the file at any selected position. The position of
+an element is specified by its @i{index}, which is a number, greater than
+zero, of the implementation-defined integer type Count. The first
+element, if any, has index one; the index of the last element, if any,
+is called the @i{current size}; the current size is zero if there are no
+elements. The current size is a property of the external file.
+
address@hidden index], Sec=(of an open direct file)}
+An open direct file has a @i{current index}, which is the index that will be
+used by the next read or write operation. When a direct file is opened,
+the current index is set to one. The current index of a direct file is
+a property of a file object, not of an external file.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00283-01]}
+  @ChgAdded{Version=[2],Text=[Italicized @lquotes@;stream address@hidden@;
+  to clarify that this is another kind of file.]}
address@hidden
+
+
address@hidden Generic Package Sequential_IO}
+
address@hidden
address@hidden@;The generic library package Sequential_IO has the following 
declaration:
address@hidden
address@hidden Ada.IO_Exceptions;
address@hidden
+   @key[type] Element_Type(<>) @key[is] @key[private];
address@hidden Ada.Sequential_IO @address@hidden,Child=[Sequential_IO]}
+
+   @key[type] @AdaTypeDefn{File_Type} @key[is] @key[limited] @key[private];
+
+   @key[type] @AdaTypeDefn{File_Mode} @key[is] (In_File, Out_File, 
Append_File);
+
+   @RI{-- File management}
+
+   @key[procedure] @AdaSubDefn{Create}(File : @key[in] @key[out] File_Type;
+                    Mode : @key[in] File_Mode := Out_File;
+                    Name : @key[in] String := "";
+                    Form : @key[in] String := "");
+
+   @key[procedure] @AdaSubDefn{Open}  (File : @key[in] @key[out] File_Type;
+                    Mode : @key[in] File_Mode;
+                    Name : @key[in] String;
+                    Form : @key[in] String := "");
+
+   @key[procedure] @AdaSubDefn{Close} (File : @key[in] @key[out] File_Type);
+   @key[procedure] @AdaSubDefn{Delete}(File : @key[in] @key[out] File_Type);
+   @key[procedure] @AdaSubDefn{Reset} (File : @key[in] @key[out] File_Type; 
Mode : @key[in] File_Mode);
+   @key[procedure] @AdaSubDefn{Reset} (File : @key[in] @key[out] File_Type);
+
+   @key[function] @AdaSubDefn{Mode}   (File : @key[in] File_Type) @key[return] 
File_Mode;
+   @key[function] @AdaSubDefn{Name}   (File : @key[in] File_Type) @key[return] 
String;
+   @key[function] @AdaSubDefn{Form}   (File : @key[in] File_Type) @key[return] 
String;
+
+   @key[function] @AdaSubDefn{Is_Open}(File : @key[in] File_Type) @key[return] 
Boolean;
+
address@hidden,Kind=[Added],ARef=[AI12-0130-1]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Flush} (File : @key[in] 
File_Type);]}
+
+   address@hidden Input and output operations}
+
+   @key[procedure] @AdaSubDefn{Read}  (File : @key[in] File_Type; Item : 
@key[out] Element_Type);
+   @key[procedure] @AdaSubDefn{Write} (File : @key[in] File_Type; Item : 
@key[in] Element_Type);
+
+   @key[function] @AdaSubDefn{End_Of_File}(File : @key[in] File_Type) 
@key[return] Boolean;
+
address@hidden   address@hidden Exceptions}
+
+   @AdaExcDefn{Status_Error} : @key[exception] @key[renames] 
IO_Exceptions.Status_Error;
+   @AdaExcDefn{Mode_Error}   : @key[exception] @key[renames] 
IO_Exceptions.Mode_Error;
+   @AdaExcDefn{Name_Error}   : @key[exception] @key[renames] 
IO_Exceptions.Name_Error;
+   @AdaExcDefn{Use_Error}    : @key[exception] @key[renames] 
IO_Exceptions.Use_Error;
+   @AdaExcDefn{Device_Error} : @key[exception] @key[renames] 
IO_Exceptions.Device_Error;
+   @AdaExcDefn{End_Error}    : @key[exception] @key[renames] 
IO_Exceptions.End_Error;
+   @AdaExcDefn{Data_Error}   : @key[exception] @key[renames] 
IO_Exceptions.Data_Error;
+
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden Ada.Sequential_IO;
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00360-01]}
address@hidden,Text=[The type File_Type
+needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization})
+in every instantiation of Sequential_IO.]}
+
address@hidden
+
address@hidden
address@hidden with Ada 83}
+The new enumeration element Append_File may introduce upward incompatibilities.
+It is possible that a program based on the assumption that File_Mode'Last = 
Out_File
+will be illegal (e.g., case statement choice coverage)
+or execute with a different effect in Ada 95.
address@hidden
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0097],ARef=[AI95-00115-01]}
address@hidden,Kind=[DeletedAdded],ARef=[AI95-00344-01]}
address@hidden,address@hidden,New=[File_Type cannot be
+implemented as a (directly) controlled type, as Ada.Sequential_IO can be
+instantiated at any nesting depth. File_Type could have a component of a
+controlled type, as long as that type is declared in some other (nongeneric)
+package.],address@hidden allows controlled types to be declared at
+any nesting depth, so this note is obsolete.}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00360-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @B[Amendment Correction:] File_Type in
+  an instance of Sequential_IO is defined to need finalization. If the
+  restriction No_Nested_Finalization (see @RefSecNum{Tasking Restrictions})
+  applies to the partition, and File_Type does not have a controlled part, it
+  will not be allowed in local objects in Ada 2005 whereas it would be allowed
+  in original Ada 95. Such code is not portable, as another Ada compiler
+  may have a controlled part in File_Type, and thus would be illegal.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0130-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada 2012}
+  @b<Corrigendum:> The Flush procedure is newly added to Ada.Sequential_IO.
+  If an instance of Ada.Sequential_IO is referenced in a @nt{use_clause}, and
+  a procedure Flush is defined in some other package that is also referenced
+  in a @nt{use_clause}, the user-defined Flush may no longer be use-visible,
+  resulting in errors. This should be rare and is easily fixed if it does 
occur.]}
address@hidden
+
+
address@hidden Management}
+
address@hidden
+
+The procedures and functions described in this subclause provide for the
+control of external files; their declarations are repeated in each of
+the packages for sequential, direct,
+text, and stream
+input-output. For
+text input-output, the procedures Create, Open, and Reset have
+additional effects described in subclause
address@hidden File Management}.
address@hidden
address@hidden@Keepnext
address@hidden Create(File : @key[in] @key[out] File_Type;
+                 Mode : @key[in] File_Mode := @RI{default_mode};
+                 Name : @key[in] String := "";
+                 Form : @key[in] String := "");
address@hidden
+    @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00283-01]}
+    Establishes a new external file, with the given name and form,
+    and associates this external file with the given file. The
+    given file is left open. The current mode of the given file
+    is set to the given access mode. The default access mode is
+    the mode Out_File for address@hidden,New=[, stream,],Old=[]}
+    and text input-output; it is
+    the mode Inout_File for direct input-output. For direct
+    access, the size of the created file is implementation defined.
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[4],Text=[For a direct file, the initial value of current
+  index is 1 (see @RefSecNum{Sequential and Direct Files}).]}
address@hidden
+
+    A null string for Name specifies an
+    external file that is not accessible after the completion of
+    the main program (a temporary file). A null string for Form
+    specifies the use of the default options of the implementation
+    for the external file.
+
+    @Trailing@;The exception Status_Error is propagated if the given file is
+    already open. The exception Name_Error is propagated if the
+    string given as Name does not allow the identification of an
+    external file. The exception Use_Error is propagated if, for the
+    specified mode, the external environment does not support creation of
+    an external file with the given name (in the absence of
+    Name_Error) and form.
+
address@hidden@Keepnext
address@hidden Open(File : @key[in] @key[out] File_Type;
+               Mode : @key[in] File_Mode;
+               Name : @key[in] String;
+               Form : @key[in] String := "");
address@hidden
+    Associates the given file with an existing external file
+    having the given name and form, and sets the current mode of
+    the given file to the given mode. The given file is left open.
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[4],Text=[For a direct file, the initial value of current
+  index is 1 (see @RefSecNum{Sequential and Direct Files}).]}
address@hidden
+
+    @Trailing@;The exception Status_Error is propagated if the given file is
+    already open. The exception Name_Error is propagated if the
+    string given as Name does not allow the identification of an
+    external file; in particular, this exception is propagated if no
+    external file with the given name exists. The exception
+    Use_Error is propagated if, for the specified mode, the
+    external environment does not support opening for an external file with
+    the given name (in the absence of Name_Error) and form.
+
address@hidden@Keepnext
address@hidden Close(File : @key[in] @key[out] File_Type);
address@hidden
+    Severs the association between the given file and its
+    associated external file. The given file is left closed.
+    In addition, for sequential files, if the file
+    being closed has mode Out_File or Append_File, then the last element
+    written since the most recent open or reset is the last element that
+    can be read from the file. If no elements have been written and the
+    file mode is Out_File, then the closed file is empty.
+    If no elements have been written and the file mode is Append_File,
+    then the closed file is unchanged.
+
+    @Trailing@;The exception Status_Error is propagated if the given file is 
not open.
+
address@hidden@Keepnext
address@hidden Delete(File : @key[in] @key[out] File_Type);
address@hidden
+    Deletes the external file associated with the given file. The
+    given file is closed, and the external file ceases to exist.
+
+    @Trailing@;The exception Status_Error is propagated if the given file is 
not
+    open. The exception Use_Error is propagated if
+    deletion of the external file is not supported
+    by the external environment.
+
address@hidden@Keepnext
address@hidden Reset(File : @key[in] @key[out] File_Type; Mode : @key[in] 
File_Mode);
address@hidden Reset(File : @key[in] @key[out] File_Type);
address@hidden
+    @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00085-01]}
+    Resets the given file so that reading from its
+    elements can be restarted from the beginning of the
+    @Chg{Version=[2],New=[external ],Old=[]}file (for
+    modes In_File and Inout_File), and so that writing to its elements can be
+    restarted at the beginning of the
+    @Chg{Version=[2],New=[external ],Old=[]}file (for modes Out_File and 
Inout_File)
+    or after the last element of the @Chg{Version=[2],New=[external 
],Old=[]}file
+    (for mode Append_File).
+    In particular, for direct access this means that the current
+    index is set to one. If a Mode parameter is supplied, the
+    current mode of the given file is set to the given mode. In addition, for
+    sequential files, if the given file has mode Out_File or Append_File when
+    Reset is called, the last element written since the most recent open or
+    reset is the last element that can be read from the
+    @Chg{Version=[2],New=[external ],Old=[]}file. If no elements
+    have been written and the file mode is Out_File, the reset file is empty.
+    If no elements have been written and the file mode is Append_File,
+    then the reset file is unchanged.
+
+    @Trailing@;The exception Status_Error is propagated if the file is not 
open.
+    The exception Use_Error is propagated if the external environment
+    does not support resetting for the external file and, also, if the
+    external environment does not support resetting to the specified mode
+    for the external file.
+
address@hidden@Keepnext
address@hidden Mode(File : @key[in] File_Type) @key[return] File_Mode;
address@hidden
+    Returns the current mode of the given file.
+
+    @Trailing@;The exception Status_Error is propagated if the file is not 
open.
+
address@hidden@Keepnext
address@hidden Name(File : @key[in] File_Type) @key[return] String;
address@hidden
+    @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00248-01]}
+    Returns a string which uniquely identifies the external file
+    currently associated with the given file (and may thus be used
+    in an Open operation)address@hidden,New=[],Old=[ If an external
+    environment allows alternative
+    specifications of the name (for example, abbreviations), the string
+    returned by the function should correspond to a full specification of
+    the name.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00248-01]}
+  @ChgAdded{Version=[2],Text=[Retrieving the full path can be
+  accomplished by passing the result of Name to Directories.Full_Name
+  (see @RefSecNum{The Package Directories}). It is important to drop the
+  requirement on Name, as the only way to accomplish this requirement given
+  that the current directory can be changed with package Directories is to
+  store the full path when the file is opened. That's expensive, and it's
+  better for users that need the full path to explicitly request it.]}
address@hidden
+
+    @Trailing@;The exception Status_Error is propagated if the given file is 
not
+    open. The exception Use_Error is propagated if the associated
+    external file is a temporary file that cannot be opened
+    by any name.
+
address@hidden@Keepnext
address@hidden Form(File : @key[in] File_Type) @key[return] String;
address@hidden
+    Returns the form string for the external file currently
+    associated with the given file. If an
+    external environment allows
+    alternative specifications of the form (for example,
+    abbreviations using default options), the string returned by
+    the function should correspond to a full specification (that
+    is, it should indicate explicitly all options selected,
+    including default options).
+
+    @Trailing@;The exception Status_Error is propagated if the given file is 
not open.
+
address@hidden@Keepnext
address@hidden Is_Open(File : @key[in] File_Type) @key[return] Boolean;
address@hidden
+    @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+    Returns True if the file is open (that is, if it is associated
+    with an external file)@Chg{Version=[3],New=[;],Old=[,]}
+    address@hidden,New=[,],Old=[]} returns False.
+
address@hidden@Keepnext
address@hidden,Kind=[Added],ARef=[AI12-0130-1]}
address@hidden,Type=[Leading],address@hidden Flush(File : @key[in] File_Type);]}
address@hidden
+    @ChgRef{Version=[4],Kind=[Added]}
+    @ChgAdded{Version=[4],Text=[The Flush procedure synchronizes the external
+    file with the internal file (by flushing any internal buffers) without
+    closing the file. For a direct file, the current index is unchanged; for a
+    stream file (see @RefSecNum{The Package Streams.Stream_IO}), the current
+    position is unchanged.]}
+
+    @ChgRef{Version=[4],Kind=[Added]}
+    @ChgAdded{Version=[4],Type=[Trailing],Text=[The exception Status_Error is
+    propagated if the file is not open. The exception Mode_Error is propagated
+    if the mode of the file is In_File.]}
+
address@hidden
address@hidden
+
address@hidden
+An implementation may propagate
+Name_Error or Use_Error if an attempt is
+made to use an I/O feature that cannot be supported by the
+implementation due to limitations in the external environment.
+Any such restriction should be documented.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00085-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that Reset affects and depends on the
+  external file.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00248-01]}
+  @ChgAdded{Version=[2],Text=[Removed the requirement for Name to return
+  a full path; this is now accomplished by Directories.Full_Name(Name(File))
+  (see @RefSecNum{The Package Directories}). This is not documented as
+  an inconsistency, because there is no requirement for implementations to
+  change @em the Ada 95 behavior is still allowed, it just is no longer
+  required.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00283-01]}
+  @ChgAdded{Version=[2],Text=[Added text to specify the default mode for
+  a stream file.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0130-1]}
+  @ChgAdded{Version=[4],Text=[Procedure Flush is now defined here, so it
+  can be used for all of the I/O packages.]}
address@hidden
+
+
address@hidden Input-Output Operations}
+
address@hidden
+The operations available for sequential input and output are described
+in this subclause. The exception Status_Error is propagated if any of these
+operations is attempted for a file that is not open.
address@hidden
address@hidden@Keepnext
address@hidden Read(File : @key[in] File_Type; Item : @key[out] Element_Type);
address@hidden
+Operates on a file of mode In_File. Reads an element
+from the given file, and returns the value of this element
+in the Item parameter.
address@hidden
+  We considered basing Sequential_IO.Read on Element_Type'Read from
+  an implicit stream associated with the sequential file.
+  However, Element_Type'Read is a type-related
+  attribute, whereas Sequential_IO should take advantage of the
+  particular constraints of the actual subtype corresponding
+  to Element_Type to minimize the size of the external file.
+  Furthermore, forcing the implementation of Sequential_IO to
+  be based on Element_Type'Read would create an upward incompatibility
+  since existing data files written by an Ada 83 program using
+  Sequential_IO might not be readable by the identical program
+  built with an Ada 95 implementation of Sequential_IO.
+
+  An Ada 95 implementation might still use an implementation-defined
+  attribute analogous to 'Read to implement the procedure Read,
+  but that attribute will likely have to be subtype-specific
+  rather than type-related, and it need not be user-specifiable.
+  Such an attribute will presumably be needed to implement the
+  generic package Storage_IO (see @RefSecNum{The Generic Package Storage_IO}).
address@hidden
+
address@hidden@;The exception Mode_Error is propagated if the mode is not 
In_File.
+The exception End_Error is propagated if no more elements can be
+read from the given file.
+The exception Data_Error can be propagated if the element read cannot
+be interpreted as a value of the subtype Element_Type
+(see @RefSec{Exceptions in Input-Output}).
address@hidden
+  Data_Error need not be propagated if the check is too complex.
+  See @RefSec{Exceptions in Input-Output}.
address@hidden
+
address@hidden@Keepnext
address@hidden Write(File : @key[in] File_Type; Item : @key[in] Element_Type);
address@hidden
+Operates on a file of mode Out_File or Append_File.
+Writes the value of Item to the given file.
+
address@hidden@;The exception Mode_Error is propagated if the mode is not
+Out_File or Append_File. The exception Use_Error is propagated if the capacity
+of the external file is exceeded.
+
address@hidden@Keepnext
address@hidden End_Of_File(File : @key[in] File_Type) @key[return] Boolean;
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
+Operates on a file of mode In_File. Returns True if no more
+elements can be read from the given file;
address@hidden,New=[,],Old=[]} returns False.
+
+The exception Mode_Error is propagated if the mode is not In_File.
address@hidden
address@hidden
+
address@hidden Generic Package Direct_IO}
+
address@hidden
address@hidden@;The generic library package Direct_IO has the following 
declaration:
address@hidden
address@hidden Ada.IO_Exceptions;
address@hidden
+   @key[type] Element_Type @key[is] @key[private];
address@hidden Ada.Direct_IO @address@hidden,Child=[Direct_IO]}
+
+   @key[type] @AdaTypeDefn{File_Type} @key[is] @key[limited] @key[private];
+
+   @key[type] @AdaTypeDefn{File_Mode} @key[is] (In_File, Inout_File, Out_File);
+   @key[type] @AdaTypeDefn{Count}     @key[is] @key[range] 0 .. 
@RI[implementation-defined];
+   @key[subtype] @AdaSubtypeDefn{Name=[Positive_Count],Of=[Count]} @key[is] 
Count @key[range] 1 .. Count'Last;
+
+   address@hidden File management}
+
+   @key[procedure] @AdaSubDefn{Create}(File : @key[in] @key[out] File_Type;
+                    Mode : @key[in] File_Mode := Inout_File;
+                    Name : @key[in] String := "";
+                    Form : @key[in] String := "");
+
+   @key[procedure] @AdaSubDefn{Open}  (File : @key[in] @key[out] File_Type;
+                    Mode : @key[in] File_Mode;
+                    Name : @key[in] String;
+                    Form : @key[in] String := "");
+
+   @key[procedure] @AdaSubDefn{Close} (File : @key[in] @key[out] File_Type);
+   @key[procedure] @AdaSubDefn{Delete}(File : @key[in] @key[out] File_Type);
+   @key[procedure] @AdaSubDefn{Reset} (File : @key[in] @key[out] File_Type; 
Mode : @key[in] File_Mode);
+   @key[procedure] @AdaSubDefn{Reset} (File : @key[in] @key[out] File_Type);
+
+   @key[function] @AdaSubDefn{Mode}   (File : @key[in] File_Type) @key[return] 
File_Mode;
+   @key[function] @AdaSubDefn{Name}   (File : @key[in] File_Type) @key[return] 
String;
+   @key[function] @AdaSubDefn{Form}   (File : @key[in] File_Type) @key[return] 
String;
+
+   @key[function] @AdaSubDefn{Is_Open}(File : @key[in] File_Type) @key[return] 
Boolean;
+
address@hidden,Kind=[Added],ARef=[AI12-0130-1]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Flush} (File : @key[in] 
File_Type);]}
+
+   address@hidden Input and output operations}
+
+   @key[procedure] @AdaSubDefn{Read} (File : @key[in] File_Type; Item : 
@key[out] Element_Type;
+                                        From : @key[in] Positive_Count);
+   @key[procedure] @AdaSubDefn{Read} (File : @key[in] File_Type; Item : 
@key[out] Element_Type);
+
+   @key[procedure] @AdaSubDefn{Write}(File : @key[in] File_Type; Item : 
@key[in]  Element_Type;
+                                        To   : @key[in] Positive_Count);
+   @key[procedure] @AdaSubDefn{Write}(File : @key[in] File_Type; Item : 
@key[in] Element_Type);
+
+   @key[procedure] @AdaSubDefn{Set_Index}(File : @key[in] File_Type; To : 
@key[in] Positive_Count);
+
+   @key[function] @AdaSubDefn{Index}(File : @key[in] File_Type) @key[return] 
Positive_Count;
+   @key[function] @AdaSubDefn{Size} (File : @key[in] File_Type) @key[return] 
Count;
+
+   @key[function] @AdaSubDefn{End_Of_File}(File : @key[in] File_Type) 
@key[return] Boolean;
+
address@hidden   address@hidden Exceptions}
+
+   @AdaExcDefn{Status_Error} : @key[exception] @key[renames] 
IO_Exceptions.Status_Error;
+   @AdaExcDefn{Mode_Error}   : @key[exception] @key[renames] 
IO_Exceptions.Mode_Error;
+   @AdaExcDefn{Name_Error}   : @key[exception] @key[renames] 
IO_Exceptions.Name_Error;
+   @AdaExcDefn{Use_Error}    : @key[exception] @key[renames] 
IO_Exceptions.Use_Error;
+   @AdaExcDefn{Device_Error} : @key[exception] @key[renames] 
IO_Exceptions.Device_Error;
+   @AdaExcDefn{End_Error}    : @key[exception] @key[renames] 
IO_Exceptions.End_Error;
+   @AdaExcDefn{Data_Error}   : @key[exception] @key[renames] 
IO_Exceptions.Data_Error;
+
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden Ada.Direct_IO;
address@hidden
address@hidden
+The Element_Type formal of Direct_IO does not have an
address@hidden (unlike Sequential_IO)
+so that the implementation can make use of the ability to declare
+uninitialized variables of the type.
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00360-01]}
address@hidden,Text=[The type File_Type
+needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization})
+in every instantiation of Direct_IO.]}
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0097],ARef=[AI95-00115-01]}
address@hidden,Kind=[DeletedAdded],ARef=[AI95-00344-01]}
address@hidden,address@hidden,New=[File_Type cannot be
+implemented as a (directly)
+controlled type, as Ada.Direct_IO can be instantiated at any nesting depth.
+File_Type could have a component of a controlled type, as long as that type is
+declared in some other (nongeneric) package.],Old=[]}]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00360-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @B[Amendment Correction:] File_Type in
+  an instance of Direct_IO is defined to need finalization. If the
+  restriction No_Nested_Finalization (see @RefSecNum{Tasking Restrictions})
+  applies to the partition, and File_Type does not have a controlled part, it
+  will not be allowed in local objects in Ada 2005 whereas it would be allowed
+  in original Ada 95. Such code is not portable, as another Ada compiler
+  may have a controlled part in File_Type, and thus would be illegal.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0130-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada 2012}
+  @b<Corrigendum:> The Flush procedure is newly added to Ada.Direct_IO.
+  If an instance of Ada.Direct_IO is referenced in a @nt{use_clause}, and
+  a procedure Flush is defined in some other package that is also referenced
+  in a @nt{use_clause}, the user-defined Flush may no longer be use-visible,
+  resulting in errors. This should be rare and is easily fixed if it does 
occur.]}
address@hidden
+
+
address@hidden Input-Output Operations}
+
address@hidden
+The operations available for direct input and output are described in
+this subclause. The exception Status_Error is propagated if any of these
+operations is attempted for a file that is not open.
address@hidden
address@hidden@Keepnext
address@hidden Read(File : @key[in] File_Type; Item : @key[out] Element_Type;
+                                    From : @key[in]  Positive_Count);
address@hidden Read(File : @key[in] File_Type; Item : @key[out] Element_Type);
address@hidden
+Operates on a file of mode In_File or Inout_File. In the case
+of the first form, sets the current index of the given file to
+the index value given by the parameter From. Then (for both
+forms) returns, in the parameter Item, the value of the
+element whose position in the given file is specified by the
+current index of the file; finally, increases the current
+index by one.
+
address@hidden@;The exception Mode_Error is propagated if the mode of the given
+file is Out_File. The exception End_Error is propagated if the
+index to be used exceeds the size of the external file. The
+exception Data_Error can be propagated if the element read cannot be
+interpreted as a value of the subtype Element_Type
+(see @RefSecNum{Exceptions in Input-Output}).
+
address@hidden@Keepnext
address@hidden Write(File : @key[in] File_Type; Item : @key[in] Element_Type;
+                                     To   : @key[in] Positive_Count);
address@hidden Write(File : @key[in] File_Type; Item : @key[in] Element_Type);
address@hidden
+Operates on a file of mode Inout_File or Out_File. In the
+case of the first form, sets the index of the given file to
+the index value given by the parameter To. Then (for both
+forms) gives the value of the parameter Item to the element
+whose position in the given file is specified by the current
+index of the file; finally, increases the current index by
+one.
+
address@hidden@;The exception Mode_Error is propagated if the mode of the given
+file is In_File. The exception Use_Error is propagated if the
+capacity of the external file is exceeded.
+
address@hidden@Keepnext
address@hidden Set_Index(File : @key[in] File_Type; To : @key[in] 
Positive_Count);
address@hidden
address@hidden@;Operates on a file of any mode. Sets the current index of the
+given file to the given index value (which may exceed the
+current size of the file).
+
address@hidden@Keepnext
address@hidden Index(File : @key[in] File_Type) @key[return] Positive_Count;
address@hidden
address@hidden@;Operates on a file of any mode. Returns the current index of
+the given file.
+
address@hidden@Keepnext
address@hidden Size(File : @key[in] File_Type) @key[return] Count;
address@hidden
address@hidden@;Operates on a file of any mode. Returns the current size of
+the external file that is associated with the given file.
+
address@hidden@Keepnext
address@hidden End_Of_File(File : @key[in] File_Type) @key[return] Boolean;
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
+Operates on a file of mode In_File or Inout_File. Returns
+True if the current index exceeds the size of the external
+file; address@hidden,New=[,],Old=[]} returns False.
+
+The exception Mode_Error is propagated if the mode of the given file is
+Out_File.
+
address@hidden
address@hidden
+
address@hidden
+Append_File mode is not supported for the generic package Direct_IO.
address@hidden
+
address@hidden Generic Package Storage_IO}
+
address@hidden
+The generic package Storage_IO provides for reading from and
+writing to an in-memory buffer. This generic package supports
+the construction of user-defined input-output packages.
address@hidden
+  This package exists to allow the portable construction of
+  user-defined direct-access-oriented input-output packages.
+  The Write procedure writes a value of type Element_Type into a
+  Storage_Array of size Buffer_Size, flattening out any implicit
+  levels of indirection used in the representation of the
+  type. The Read procedure reads
+  a value of type Element_Type from the buffer, reconstructing
+  any implicit levels of indirection used in the representation
+  of the type. It also properly initializes any type tags that appear
+  within the value, presuming that the buffer was written by
+  a different program and that tag values for address@hidden@;address@hidden@; 
type
+  might vary from one executable to another.
address@hidden
address@hidden
+
address@hidden
address@hidden@;The generic library package Storage_IO has the following 
declaration:
address@hidden
address@hidden Ada.IO_Exceptions;
address@hidden System.Storage_Elements;
address@hidden
+   @key[type] Element_Type @key[is] @key[private];
address@hidden Ada.Storage_IO @address@hidden,Child=[Storage_IO]}
+   @key[pragma] Preelaborate(Storage_IO);
+
+   @AdaObjDefn{Buffer_Size} : @key(constant) 
System.Storage_Elements.Storage_Count :=
+      @RI(implementation-defined);
+   @key(subtype) @AdaSubtypeDefn{Name=[Buffer_Type],Of=[Storage_Array]} 
@key(is)
+      System.Storage_Elements.Storage_Array(1..Buffer_Size);
+
+   address@hidden Input and output operations}
+
+   @key[procedure] @AdaSubDefn{Read} (Buffer : @key[in]  Buffer_Type; Item : 
@key[out] Element_Type);
+
+   @key[procedure] @AdaSubDefn{Write}(Buffer : @key[out] Buffer_Type; Item : 
@key[in]  Element_Type);
+
address@hidden   address@hidden Exceptions}
+
+   @AdaExcDefn{Data_Error}   : @key[exception] @key[renames] 
IO_Exceptions.Data_Error;
address@hidden Ada.Storage_IO;
address@hidden
+
+In each instance,
+the constant Buffer_Size has a value that is the size (in storage elements)
+of the buffer required to represent the content of an object of
+subtype Element_Type, including any implicit levels of indirection used by
+the implementation.
+The Read and Write procedures of Storage_IO correspond to the Read and Write
+procedures of Direct_IO (see @RefSecNum{The Generic Package Direct_IO}),
+but with the content of the Item parameter being read from
+or written into the specified Buffer, rather than an external file.
+
address@hidden
address@hidden@;As with Direct_IO, the Element_Type formal of Storage_IO does 
not
+have an @nt{unknown_discriminant_part}
+so that there is a well-defined upper bound on the size of
+the buffer needed to hold the content of an object of the
+formal subtype (i.e. Buffer_Size). If there are no implicit levels
+of indirection, Buffer_Size will typically equal:
address@hidden
+(Element_Type'Size + System.Storage_Unit - 1) / System.Storage_Unit
address@hidden
address@hidden
address@hidden value of Buffer_Size in Storage_IO.}
address@hidden
+
address@hidden
+A buffer used for Storage_IO holds only one element at a time; an external
+file used for Direct_IO holds a sequence of elements.
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0005-1]}
address@hidden,address@hidden to Ada 83}
+Storage_IO is new in Ada 95.]}
address@hidden
+
+
address@hidden Input-Output}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} describes the
+package Text_IO, which provides facilities
+for input and output in human-readable form. Each file is read or
+written sequentially, as a sequence of characters grouped into lines,
+and as a sequence of lines grouped into pages. The specification of the
+package is given below in subclause
address@hidden Package Text_IO}.
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The facilities for file management given above, in subclauses
address@hidden Management} and
address@hidden Input-Output Operations},
+are available for text input-output. In place of Read and
+Write, however, there are procedures Get and Put that input values of
+suitable types from text files, and output values to them. These values
+are provided to the Put procedures, and returned by the Get procedures,
+in a parameter Item. Several overloaded procedures of these names
+exist, for different types of Item. These Get procedures analyze the
+input sequences of characters based on
+lexical elements (see
address@hidden,New=[Clause],Old=[Section]} @RefSecNum{Lexical Elements}) and
+return the corresponding values; the Put procedures output the given
+values as appropriate lexical elements. Procedures Get and Put are also
+available that input and output individual characters treated as
+character values rather than as lexical elements.
+Related to character input are procedures to look ahead at the
+next character without reading it, and to read a character 
@lquotes@;address@hidden@;
+without waiting for an end-of-line to signal availability.
+
+In addition to the procedures Get and Put for numeric and enumeration
+types of Item that operate on text files, analogous procedures are
+provided that read from and write to a parameter of type String. These
+procedures perform the same analysis and composition of character
+sequences as their counterparts which have a file parameter.
+
+For all Get and Put procedures that operate on text files, and for many
+other subprograms, there are forms with and without a file parameter.
+Each such Get procedure operates on an input file, and each such Put
+procedure operates on an output file. If no file is specified, a
+default input file or a default output file is used.
+
address@hidden input file}
address@hidden output file}
+At the beginning of program execution the default input and output files
+are the so-called standard input file and standard output file. These
+files are open, have respectively the current modes In_File and
+Out_File, and are associated with two implementation-defined external
+files. Procedures are provided to change the current default input file
+and the current default output file.
address@hidden following was poorly formatted.}
address@hidden,Kind=[Revised],InitialVersion=[0],
address@hidden,New=[The ],
+Old=[]}external files @Chg{Version=[2],New=[associated with the],Old=[for]} 
standard
+input, standard output, and standard address@hidden,New=[ files.],Old=[]}]}
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0113],ARef=[AI95-00087-01]}
address@hidden,Text=[The default input file and default output file
+are not the names
+of distinct file objects, but rather the @i<role> played by one or more
+(other) file object(s). Thus, they generally will be implemented as accesses
+to another file object. An implementation that implements them by copying
+them is incorrect.]}
address@hidden
+
address@hidden error file}
+At the beginning of program execution a default file for
+program-dependent error-related text output is the
+so-called standard error file. This file is open, has the current
+mode Out_File, and is associated with an implementation-defined
+external file. A procedure is provided to change the current
+default error file.
+
address@hidden terminator}
address@hidden terminator}
address@hidden terminator}
+From a logical point of view, a text file is a sequence of pages, a page
+is a sequence of lines, and a line is a sequence of characters; the end
+of a line is marked by a @i{line terminator}; the end of a page is marked by
+the combination of a line terminator immediately followed by a @i{page
+terminator}; and the end of a file is marked by the combination of a line
+terminator immediately followed by a page terminator and then a @i{file
+terminator}. Terminators are generated during output; either by calls of
+procedures provided expressly for that purpose; or implicitly as part of
+other operations, for example, when a bounded line length, a bounded
+page length, or both, have been specified for a file.
+
+The actual nature of terminators is not defined by the language and
+hence depends on the implementation. Although terminators are
+recognized or generated by certain of the procedures that follow, they
+are not necessarily implemented as characters or as sequences of
+characters. Whether they are characters (and if so which ones) in any
+particular implementation need not concern a user who neither explicitly
+outputs nor explicitly inputs control characters. The effect of input
+(Get)
+or output (Put)
+of control characters (other than horizontal tabulation) is
+not specified by the language.
address@hidden
+
address@hidden number}
address@hidden column number}
address@hidden line number}
address@hidden page number}
+The characters of a line are numbered, starting from one; the number of
+a character is called its @i{column number}. For a line terminator, a
+column number is also defined: it is one more than the number of
+characters in the line. The lines of a page, and the pages of a file,
+are similarly numbered. The current column number is the column number
+of the next character or line terminator to be transferred. The current
+line number is the number of the current line. The current page number
+is the number of the current page. These numbers are values of the
+subtype Positive_Count of the type Count (by convention, the value zero
+of the type Count is used to indicate special conditions).
address@hidden
address@hidden@key[type] Count @key[is] @key[range] 0 .. 
@RI[implementation-defined];
address@hidden Positive_Count @key[is] Count @key[range] 1 .. Count'Last;
address@hidden
+
address@hidden line length}
address@hidden page length}
+For an output file or an append file, a @i{maximum line length} can be 
specified
+and a @i{maximum page length} can be specified. If a value to be output cannot
+fit on the current line, for a specified maximum line length, then a new line
+is automatically started before the value is output; if, further, this new
+line cannot fit on the current page, for a specified maximum page
+length, then a new page is automatically started before the value is
+output. Functions are provided to determine the maximum line length and
+the maximum page length. When a file is opened with mode Out_File
+or Append_File, both values are zero: by convention, this means that the line
+lengths and
+page lengths are unbounded. (Consequently, output consists of a single
+line if the subprograms for explicit control of line and page structure
+are not used.) The constant Unbounded is provided for this purpose.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Append_File is new in Ada 95.
address@hidden
+
address@hidden Package Text_IO}
+
address@hidden
address@hidden@;The library package Text_IO has the following declaration:
address@hidden
address@hidden Ada.IO_Exceptions;
address@hidden Ada.Text_IO @address@hidden,Child=[Text_IO]}
+
+   @key[type] @AdaTypeDefn{File_Type} @key[is] @key[limited] @key[private];
+
+   @key[type] @AdaTypeDefn{File_Mode} @key[is] (In_File, Out_File, 
Append_File);
+
+   @key[type] @AdaTypeDefn{Count} @key[is] @key[range] 0 .. 
@RI[implementation-defined];
+   @key[subtype] @AdaSubtypeDefn{Name=[Positive_Count],Of=[Count]} @key[is] 
Count @key[range] 1 .. Count'Last;
+   @AdaObjDefn{Unbounded} : @key[constant] Count := 0; address@hidden line and 
page length}
+
+   @key[subtype] @AdaSubtypeDefn{Name=[Field],Of=[Integer]}       @key[is] 
Integer @key[range] 0 .. @RI[implementation-defined];
+   @key[subtype] @AdaSubtypeDefn{Name=[Number_Base],Of=[Integer]} @key[is] 
Integer @key[range] 2 .. 16;
+
+   @key[type] @AdaTypeDefn{Type_Set} @key[is] (Lower_Case, Upper_Case);
+
+   address@hidden File Management}
+
+   @key[procedure] @AdaSubDefn{Create} (File : @key[in] @key[out] File_Type;
+                     Mode : @key[in] File_Mode := Out_File;
+                     Name : @key[in] String    := "";
+                     Form : @key[in] String    := "");
+
+   @key[procedure] @AdaSubDefn{Open}   (File : @key[in] @key[out] File_Type;
+                     Mode : @key[in] File_Mode;
+                     Name : @key[in] String;
+                     Form : @key[in] String := "");
+
+   @key[procedure] @AdaSubDefn{Close}  (File : @key[in] @key[out] File_Type);
+   @key[procedure] @AdaSubDefn{Delete} (File : @key[in] @key[out] File_Type);
+   @key[procedure] @AdaSubDefn{Reset}  (File : @key[in] @key[out] File_Type; 
Mode : @key[in] File_Mode);
+   @key[procedure] @AdaSubDefn{Reset}  (File : @key[in] @key[out] File_Type);
+
+   @key[function]  @AdaSubDefn{Mode}   (File : @key[in] File_Type) 
@key[return] File_Mode;
+   @key[function]  @AdaSubDefn{Name}   (File : @key[in] File_Type) 
@key[return] String;
+   @key[function]  @AdaSubDefn{Form}   (File : @key[in] File_Type) 
@key[return] String;
+
+   @key[function]  @AdaSubDefn{Is_Open}(File : @key[in] File_Type) 
@key[return] Boolean;
+
+   address@hidden Control of default input and output files}
+
+   @key[procedure] @AdaSubDefn{Set_Input} (File : @key[in] File_Type);
+   @key[procedure] @AdaSubDefn{Set_Output}(File : @key[in] File_Type);
+   @key[procedure] @AdaSubDefn{Set_Error} (File : @key[in] File_Type);
+
+   @key[function] @AdaSubDefn{Standard_Input}  @key[return] File_Type;
+   @key[function] @AdaSubDefn{Standard_Output} @key[return] File_Type;
+   @key[function] @AdaSubDefn{Standard_Error}  @key[return] File_Type;
+
+   @key[function] @AdaSubDefn{Current_Input}   @key[return] File_Type;
+   @key[function] @AdaSubDefn{Current_Output}  @key[return] File_Type;
+   @key[function] @AdaSubDefn{Current_Error}   @key[return] File_Type;
+
+   @key[type] @AdaTypeDefn{File_Access} @key[is] @key[access] @key[constant] 
File_Type;
+
+   @key[function] @AdaSubDefn{Standard_Input}  @key[return] File_Access;
+   @key[function] @AdaSubDefn{Standard_Output} @key[return] File_Access;
+   @key[function] @AdaSubDefn{Standard_Error}  @key[return] File_Access;
+
+   @key[function] @AdaSubDefn{Current_Input}   @key[return] File_Access;
+   @key[function] @AdaSubDefn{Current_Output}  @key[return] File_Access;
+   @key[function] @AdaSubDefn{Current_Error}   @key[return] File_Access;
+
+
address@hidden,Kind=[Revised],Ref=[8652/0051],ARef=[AI95-00057-01]}
address@hidden control}
+   @key[procedure] @AdaSubDefn{Flush} (File : @key[in] 
@Chg{New=[],address@hidden ]}File_Type);
+   @key[procedure] @AdaSubDefn{Flush};
+
+
+   address@hidden Specification of line and page lengths}
+
+   @key[procedure] @AdaSubDefn{Set_Line_Length}(File : @key[in] File_Type; To 
: @key[in] Count);
+   @key[procedure] @AdaSubDefn{Set_Line_Length}(To   : @key[in] Count);
+
+   @key[procedure] @AdaSubDefn{Set_Page_Length}(File : @key[in] File_Type; To 
: @key[in] Count);
+   @key[procedure] @AdaSubDefn{Set_Page_Length}(To   : @key[in] Count);
+
+   @key[function]  @AdaSubDefn{Line_Length}(File : @key[in] File_Type) 
@key[return] Count;
+   @key[function]  @AdaSubDefn{Line_Length} @key[return] Count;
+
+   @key[function]  @AdaSubDefn{Page_Length}(File : @key[in] File_Type) 
@key[return] Count;
+   @key[function]  @AdaSubDefn{Page_Length} @key[return] Count;
+
+   address@hidden Column, Line, and Page Control}
+
+   @key[procedure] @AdaSubDefn{New_Line}   (File    : @key[in] File_Type;
+                         Spacing : @key[in] Positive_Count := 1);
+   @key[procedure] @AdaSubDefn{New_Line}   (Spacing : @key[in] Positive_Count 
:= 1);
+
+   @key[procedure] @AdaSubDefn{Skip_Line}  (File    : @key[in] File_Type;
+                         Spacing : @key[in] Positive_Count := 1);
+   @key[procedure] @AdaSubDefn{Skip_Line}  (Spacing : @key[in] Positive_Count 
:= 1);
+
+   @key[function]  @AdaSubDefn{End_Of_Line}(File : @key[in] File_Type) 
@key[return] Boolean;
+   @key[function]  @AdaSubDefn{End_Of_Line} @key[return] Boolean;
+
+   @key[procedure] @AdaSubDefn{New_Page}   (File : @key[in] File_Type);
+   @key[procedure] @AdaSubDefn{New_Page};
+
+   @key[procedure] @AdaSubDefn{Skip_Page}  (File : @key[in] File_Type);
+   @key[procedure] @AdaSubDefn{Skip_Page};
+
+   @key[function]  @AdaSubDefn{End_Of_Page}(File : @key[in] File_Type) 
@key[return] Boolean;
+   @key[function]  @AdaSubDefn{End_Of_Page} @key[return] Boolean;
+
+   @key[function]  @AdaSubDefn{End_Of_File}(File : @key[in] File_Type) 
@key[return] Boolean;
+   @key[function]  @AdaSubDefn{End_Of_File} @key[return] Boolean;
+
+   @key[procedure] @AdaSubDefn{Set_Col} (File : @key[in] File_Type; To : 
@key[in] Positive_Count);
+   @key[procedure] @AdaSubDefn{Set_Col} (To   : @key[in] Positive_Count);
+
+   @key[procedure] @AdaSubDefn{Set_Line}(File : @key[in] File_Type; To : 
@key[in] Positive_Count);
+   @key[procedure] @AdaSubDefn{Set_Line}(To   : @key[in] Positive_Count);
+
+   @key[function] @AdaSubDefn{Col} (File : @key[in] File_Type) @key[return] 
Positive_Count;
+   @key[function] @AdaSubDefn{Col}  @key[return] Positive_Count;
+
+   @key[function] @AdaSubDefn{Line}(File : @key[in] File_Type) @key[return] 
Positive_Count;
+   @key[function] @AdaSubDefn{Line} @key[return] Positive_Count;
+
+   @key[function] @AdaSubDefn{Page}(File : @key[in] File_Type) @key[return] 
Positive_Count;
+   @key[function] @AdaSubDefn{Page} @key[return] Positive_Count;
+
+   address@hidden Character Input-Output}
+
+   @key[procedure] @AdaSubDefn{Get}(File : @key[in]  File_Type; Item : 
@key[out] Character);
+   @key[procedure] @AdaSubDefn{Get}(Item : @key[out] Character);
+
+   @key[procedure] @AdaSubDefn{Put}(File : @key[in]  File_Type; Item : 
@key[in] Character);
+   @key[procedure] @AdaSubDefn{Put}(Item : @key[in]  Character);
+
+   @key[procedure] @AdaSubDefn{Look_Ahead} (File        : @key[in]  File_Type;
+                         Item        : @key[out] Character;
+                         End_Of_Line : @key[out] Boolean);
+   @key[procedure] @AdaSubDefn{Look_Ahead} (Item        : @key[out] Character;
+                         End_Of_Line : @key[out] Boolean);
+
+   @key[procedure] @AdaSubDefn{Get_Immediate}(File      : @key[in]  File_Type;
+                           Item      : @key[out] Character);
+   @key[procedure] @AdaSubDefn{Get_Immediate}(Item      : @key[out] Character);
+
+   @key[procedure] @AdaSubDefn{Get_Immediate}(File      : @key[in]  File_Type;
+                           Item      : @key[out] Character;
+                           Available : @key[out] Boolean);
+   @key[procedure] @AdaSubDefn{Get_Immediate}(Item      : @key[out] Character;
+                           Available : @key[out] Boolean);
+
+   address@hidden String Input-Output}
+
+   @key[procedure] @AdaSubDefn{Get}(File : @key[in]  File_Type; Item : 
@key[out] String);
+   @key[procedure] @AdaSubDefn{Get}(Item : @key[out] String);
+
+   @key[procedure] @AdaSubDefn{Put}(File : @key[in]  File_Type; Item : 
@key[in] String);
+   @key[procedure] @AdaSubDefn{Put}(Item : @key[in]  String);
+
+   @key[procedure] @AdaSubDefn{Get_Line}(File : @key[in]  File_Type;
+                      Item : @key[out] String;
+                      Last : @key[out] Natural);
+   @key[procedure] @AdaSubDefn{Get_Line}(Item : @key[out] String; Last : 
@key[out] Natural);
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Get_Line}(File : @key[in]  
File_Type) @key[return] String;
+   @key[function] @AdaSubDefn{Get_Line} @key[return] String;]}
+
+   @key[procedure] @AdaSubDefn{Put_Line}(File : @key[in]  File_Type; Item : 
@key[in] String);
+   @key[procedure] @AdaSubDefn{Put_Line}(Item : @key[in]  String);
+
address@hidden Generic packages for Input-Output of Integer Types}
+
+   @key[generic]
+      @key[type] Num @key[is] @key[range] <>;
+   @key[package] @AdaPackDefn{Integer_IO} @key[is]
+
+      @AdaObjDefn{Default_Width} : Field := Num'Width;
+      @AdaObjDefn{Default_Base}  : Number_Base := 10;
+
+      @key[procedure] @AdaSubDefn{Get}(File  : @key[in]  File_Type;
+                    Item  : @key[out] Num;
+                    Width : @key[in] Field := 0);
+      @key[procedure] @AdaSubDefn{Get}(Item  : @key[out] Num;
+                    Width : @key[in]  Field := 0);
+
+      @key[procedure] @AdaSubDefn{Put}(File  : @key[in] File_Type;
+                    Item  : @key[in] Num;
+                    Width : @key[in] Field := Default_Width;
+                    Base  : @key[in] Number_Base := Default_Base);
+      @key[procedure] @AdaSubDefn{Put}(Item  : @key[in] Num;
+                    Width : @key[in] Field := Default_Width;
+                    Base  : @key[in] Number_Base := Default_Base);
+      @key[procedure] @AdaSubDefn{Get}(From : @key[in]  String;
+                    Item : @key[out] Num;
+                    Last : @key[out] Positive);
+      @key[procedure] @AdaSubDefn{Put}(To   : @key[out] String;
+                    Item : @key[in] Num;
+                    Base : @key[in] Number_Base := Default_Base);
+
+   @key[end] Integer_IO;
+
+   @key[generic]
+      @key[type] Num @key[is] @key[mod] <>;
+   @key[package] @AdaPackDefn{Modular_IO} @key[is]
+
+      @AdaObjDefn{Default_Width} : Field := Num'Width;
+      @AdaObjDefn{Default_Base}  : Number_Base := 10;
+
+      @key[procedure] @AdaSubDefn{Get}(File  : @key[in]  File_Type;
+                    Item  : @key[out] Num;
+                    Width : @key[in] Field := 0);
+      @key[procedure] @AdaSubDefn{Get}(Item  : @key[out] Num;
+                    Width : @key[in]  Field := 0);
+
+      @key[procedure] @AdaSubDefn{Put}(File  : @key[in] File_Type;
+                    Item  : @key[in] Num;
+                    Width : @key[in] Field := Default_Width;
+                    Base  : @key[in] Number_Base := Default_Base);
+      @key[procedure] @AdaSubDefn{Put}(Item  : @key[in] Num;
+                    Width : @key[in] Field := Default_Width;
+                    Base  : @key[in] Number_Base := Default_Base);
+      @key[procedure] @AdaSubDefn{Get}(From : @key[in]  String;
+                    Item : @key[out] Num;
+                    Last : @key[out] Positive);
+      @key[procedure] @AdaSubDefn{Put}(To   : @key[out] String;
+                    Item : @key[in] Num;
+                    Base : @key[in] Number_Base := Default_Base);
+
+   @key[end] Modular_IO;
+
+   address@hidden Generic packages for Input-Output of Real Types}
+
+   @key[generic]
+      @key[type] Num @key[is] @key[digits] <>;
+   @key[package] @AdaPackDefn{Float_IO} @key[is]
+
+      @AdaObjDefn{Default_Fore} : Field := 2;
+      @AdaObjDefn{Default_Aft}  : Field := Num'Digits-1;
+      @AdaObjDefn{Default_Exp}  : Field := 3;
+
+      @key[procedure] @AdaSubDefn{Get}(File  : @key[in]  File_Type;
+                    Item  : @key[out] Num;
+                    Width : @key[in]  Field := 0);
+      @key[procedure] @AdaSubDefn{Get}(Item  : @key[out] Num;
+                    Width : @key[in]  Field := 0);
+
+      @key[procedure] @AdaSubDefn{Put}(File : @key[in] File_Type;
+                    Item : @key[in] Num;
+                    Fore : @key[in] Field := Default_Fore;
+                    Aft  : @key[in] Field := Default_Aft;
+                    Exp  : @key[in] Field := Default_Exp);
+      @key[procedure] @AdaSubDefn{Put}(Item : @key[in] Num;
+                    Fore : @key[in] Field := Default_Fore;
+                    Aft  : @key[in] Field := Default_Aft;
+                    Exp  : @key[in] Field := Default_Exp);
+
+      @key[procedure] @AdaSubDefn{Get}(From : @key[in] String;
+                    Item : @key[out] Num;
+                    Last : @key[out] Positive);
+      @key[procedure] @AdaSubDefn{Put}(To   : @key[out] String;
+                    Item : @key[in] Num;
+                    Aft  : @key[in] Field := Default_Aft;
+                    Exp  : @key[in] Field := Default_Exp);
+   @key[end] Float_IO;
+
+   @key[generic]
+      @key[type] Num @key[is] @key[delta] <>;
+   @key[package] @AdaPackDefn{Fixed_IO} @key[is]
+
+      @AdaObjDefn{Default_Fore} : Field := Num'Fore;
+      @AdaObjDefn{Default_Aft}  : Field := Num'Aft;
+      @AdaObjDefn{Default_Exp}  : Field := 0;
+
+      @key[procedure] @AdaSubDefn{Get}(File  : @key[in]  File_Type;
+                    Item  : @key[out] Num;
+                    Width : @key[in]  Field := 0);
+      @key[procedure] @AdaSubDefn{Get}(Item  : @key[out] Num;
+                    Width : @key[in]  Field := 0);
+
+      @key[procedure] @AdaSubDefn{Put}(File : @key[in] File_Type;
+                    Item : @key[in] Num;
+                    Fore : @key[in] Field := Default_Fore;
+                    Aft  : @key[in] Field := Default_Aft;
+                    Exp  : @key[in] Field := Default_Exp);
+      @key[procedure] @AdaSubDefn{Put}(Item : @key[in] Num;
+                    Fore : @key[in] Field := Default_Fore;
+                    Aft  : @key[in] Field := Default_Aft;
+                    Exp  : @key[in] Field := Default_Exp);
+
+      @key[procedure] @AdaSubDefn{Get}(From : @key[in]  String;
+                    Item : @key[out] Num;
+                    Last : @key[out] Positive);
+      @key[procedure] @AdaSubDefn{Put}(To   : @key[out] String;
+                    Item : @key[in] Num;
+                    Aft  : @key[in] Field := Default_Aft;
+                    Exp  : @key[in] Field := Default_Exp);
+   @key[end] Fixed_IO;
+
+   @key[generic]
+      @key[type] Num @key[is] @key[delta] <> @key[digits] <>;
+   @key[package] @AdaPackDefn{Decimal_IO} @key[is]
+
+      @AdaObjDefn{Default_Fore} : Field := Num'Fore;
+      @AdaObjDefn{Default_Aft}  : Field := Num'Aft;
+      @AdaObjDefn{Default_Exp}  : Field := 0;
+
+      @key[procedure] @AdaSubDefn{Get}(File  : @key[in]  File_Type;
+                    Item  : @key[out] Num;
+                    Width : @key[in]  Field := 0);
+      @key[procedure] @AdaSubDefn{Get}(Item  : @key[out] Num;
+                    Width : @key[in]  Field := 0);
+
+      @key[procedure] @AdaSubDefn{Put}(File : @key[in] File_Type;
+                    Item : @key[in] Num;
+                    Fore : @key[in] Field := Default_Fore;
+                    Aft  : @key[in] Field := Default_Aft;
+                    Exp  : @key[in] Field := Default_Exp);
+      @key[procedure] @AdaSubDefn{Put}(Item : @key[in] Num;
+                    Fore : @key[in] Field := Default_Fore;
+                    Aft  : @key[in] Field := Default_Aft;
+                    Exp  : @key[in] Field := Default_Exp);
+
+      @key[procedure] @AdaSubDefn{Get}(From : @key[in]  String;
+                    Item : @key[out] Num;
+                    Last : @key[out] Positive);
+      @key[procedure] @AdaSubDefn{Put}(To   : @key[out] String;
+                    Item : @key[in] Num;
+                    Aft  : @key[in] Field := Default_Aft;
+                    Exp  : @key[in] Field := Default_Exp);
+   @key[end] Decimal_IO;
+
+   address@hidden Generic package for Input-Output of Enumeration Types}
+
+   @key[generic]
+      @key[type] Enum @key[is] (<>);
+   @key[package] @AdaPackDefn{Enumeration_IO} @key[is]
+
+      @AdaObjDefn{Default_Width}   : Field := 0;
+      @AdaObjDefn{Default_Setting} : Type_Set := Upper_Case;
+
+      @key[procedure] @AdaSubDefn{Get}(File : @key[in]  File_Type;
+                    Item : @key[out] Enum);
+      @key[procedure] @AdaSubDefn{Get}(Item : @key[out] Enum);
+
+      @key[procedure] @AdaSubDefn{Put}(File  : @key[in] File_Type;
+                    Item  : @key[in] Enum;
+                    Width : @key[in] Field    := Default_Width;
+                    Set   : @key[in] Type_Set := Default_Setting);
+      @key[procedure] @AdaSubDefn{Put}(Item  : @key[in] Enum;
+                    Width : @key[in] Field    := Default_Width;
+                    Set   : @key[in] Type_Set := Default_Setting);
+
+      @key[procedure] @AdaSubDefn{Get}(From : @key[in]  String;
+                    Item : @key[out] Enum;
+                    Last : @key[out] Positive);
+      @key[procedure] @AdaSubDefn{Put}(To   : @key[out] String;
+                    Item : @key[in]  Enum;
+                    Set  : @key[in]  Type_Set := Default_Setting);
+   @key[end] Enumeration_IO;
+
address@hidden@;address@hidden Exceptions}
+
+   @AdaExcDefn{Status_Error} : @key[exception] @key[renames] 
IO_Exceptions.Status_Error;
+   @AdaExcDefn{Mode_Error}   : @key[exception] @key[renames] 
IO_Exceptions.Mode_Error;
+   @AdaExcDefn{Name_Error}   : @key[exception] @key[renames] 
IO_Exceptions.Name_Error;
+   @AdaExcDefn{Use_Error}    : @key[exception] @key[renames] 
IO_Exceptions.Use_Error;
+   @AdaExcDefn{Device_Error} : @key[exception] @key[renames] 
IO_Exceptions.Device_Error;
+   @AdaExcDefn{End_Error}    : @key[exception] @key[renames] 
IO_Exceptions.End_Error;
+   @AdaExcDefn{Data_Error}   : @key[exception] @key[renames] 
IO_Exceptions.Data_Error;
+   @AdaExcDefn{Layout_Error} : @key[exception] @key[renames] 
IO_Exceptions.Layout_Error;
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden Ada.Text_IO;
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00360-01]}
address@hidden,Text=[The type File_Type
+needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization}).]}
+
address@hidden
+
address@hidden
address@hidden with Ada 83}
+Append_File is a new element of enumeration type File_Mode.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Get_Immediate, Look_Ahead, the subprograms for dealing with
+standard error, the type File_Access and its associated subprograms,
+and the
+generic packages Modular_IO and Decimal_IO are new in Ada 95.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00360-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @B[Amendment Correction:] Text_IO.File_Type is defined to need finalization. 
If the
+  restriction No_Nested_Finalization (see @RefSecNum{Tasking Restrictions})
+  applies to the partition, and File_Type does not have a controlled part, it
+  will not be allowed in local objects in Ada 2005 whereas it would be allowed
+  in original Ada 95. Such code is not portable, as another Ada compiler
+  may have a controlled part in File_Type, and thus would be illegal.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0051],ARef=[AI95-00057-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the parameter 
mode
+  of Flush; otherwise it could not be used on Standard_Output.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00301-01]}
+  @ChgAdded{Version=[2],Text=[The Text_IO.Get_Line functions are new;
+  they are described in @RefSec{Input-Output of Characters and Strings}.]}
address@hidden
+
+
address@hidden File Management}
+
address@hidden
address@hidden@;The only allowed file modes for text files are the modes 
In_File,
+Out_File, and Append_File.
+The subprograms given in subclause @RefSecNum{File Management} for the control 
of
+external files, and the function End_Of_File given in subclause
address@hidden Input-Output Operations} for
+sequential input-output, are also available for text files. There is
+also a version of End_Of_File that refers to the current default input
+file. For text files, the procedures have the following additional
+effects:
address@hidden
+     For the procedures Create and Open: After a file with mode Out_File or
+     Append_File is opened, the page length and line length are unbounded 
(both have
+     the conventional value zero). After a file (of any mode)
+     is opened, the current column, current line, and current
+     page numbers are set to one. If the mode is Append_File, it
+     is implementation defined whether a page terminator will separate
+     preexisting text in the file from the new text to be written.
address@hidden
+For a file with mode Append_File, although it may seem more
+sensible for Open to set the current column, line, and page number based on
+the number of pages in the file, the number of lines on the last
+page, and the number of columns in the last line, we rejected this
+approach because of implementation costs; it would require
+the implementation to scan the file before doing the append,
+or to do processing that would be equivalent in effect.
+
+For similar reasons, there is no requirement to erase
+the last page terminator of the file, nor to insert
+an explicit page terminator in the case when the final
+page terminator of a file is represented implicitly by the
+implementation.
address@hidden
+
+     For the procedure Close: If the file has the current mode Out_File
+     or Append_File, has the effect of calling New_Page, unless the current
+     page is already terminated; then outputs a file terminator.
+
+
+  For the procedure Reset: If the file has the current mode Out_File
+  or Append_File, has the effect of calling New_Page, unless the
+  current page is already terminated; then outputs a file terminator.
+  The current column, line, and page numbers are set to
+  one, and the line and page lengths to Unbounded.
+  If the new mode is Append_File, it is implementation defined whether
+  a page terminator will separate preexisting text in the file from the
+  new text to be written.
address@hidden
+The behavior of Reset should be similar to closing a file and
+       reopening it with the given address@hidden
address@hidden
+
+The exception Mode_Error is propagated by the procedure Reset upon an
+attempt to change the mode of a file that is
+the current default
+input file, the current default output file,
+or the current default error file.
address@hidden
+
address@hidden
address@hidden@;An implementation can define the Form parameter of
+Create and Open to control effects including the following:
address@hidden
+the interpretation of line and column numbers for an interactive file,
+and
+
+the interpretation of text formats in
+a file created by a foreign program.
address@hidden
address@hidden
+
address@hidden Input, Output, and Error Files}
+
address@hidden
+The following subprograms provide for the control of the particular
+default files that are used when a file parameter is omitted from a Get,
+Put, or other operation of text input-output described below,
+or when application-dependent error-related text is to be output.
address@hidden
address@hidden@Keepnext
address@hidden Set_Input(File : @key[in] File_Type);
address@hidden
+  Operates on a file of mode In_File. Sets the current default
+  input file to File.
+
+  @Trailing@;The exception Status_Error is propagated if the given file is not
+  open. The exception Mode_Error is propagated if the mode of the
+  given file is not In_File.
+
address@hidden@Keepnext
address@hidden Set_Output(File : @key[in] File_Type);
address@hidden Set_Error (File : @key[in] File_Type);
address@hidden
+  @Trailing@;Each operates on a file of mode Out_File or Append_File.
+  Set_Output sets the current default output file to File.
+  Set_Error sets the current default error file to File.
+  The exception Status_Error is propagated if the given file is not
+  open. The exception Mode_Error is propagated if the mode of the
+  given file is not Out_File or Append_File.
+
address@hidden@Keepnext
address@hidden Standard_Input @key[return] File_Type;
address@hidden Standard_Input @key[return] File_Access;
address@hidden
+  @Trailing@;Returns the standard input file (see @RefSecNum{Text 
Input-Output}),
+  or an access value designating the standard input file, respectively.
+
address@hidden@Keepnext
address@hidden Standard_Output @key[return] File_Type;
address@hidden Standard_Output @key[return] File_Access;
address@hidden
+  @Trailing@;Returns the standard output file (see @RefSecNum{Text 
Input-Output})
+  or an access value designating the standard output file, respectively.
+
address@hidden@Keepnext
address@hidden Standard_Error @key[return] File_Type;
address@hidden Standard_Error @key[return] File_Access;
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0052],ARef=[AI95-00194-01]}
+  @Trailing@;Returns the standard error file (see @RefSecNum{Text 
Input-Output}),
+  or an access value designating the standard @Chg{New=[error],Old=[output]} 
file, respectively.
+
address@hidden
address@hidden following paragraph was originally in a DescribeCode section; but
+that clearly was not intended; I've fixed it. (This changes the indentation of
+the paragraph in the old version too, but the change is harmless.) 
RLB-21-08-2000}
address@hidden@;The Form strings implicitly associated with the opening of
+Standard_Input, Standard_Output, and
+Standard_Error at the start of program execution are implementation defined.
address@hidden
+
address@hidden@Keepnext
address@hidden Current_Input @key[return] File_Type;
address@hidden Current_Input @key[return] File_Access;
address@hidden
+  @Trailing@;Returns the current default input file,
+  or an access value designating the current default input file,
+  respectively.
+
address@hidden@Keepnext
address@hidden Current_Output @key[return] File_Type;
address@hidden Current_Output @key[return] File_Access;
address@hidden
+  @Trailing@;Returns the current default output file,
+  or an access value designating the current default output file,
+  respectively.
+
address@hidden@Keepnext
address@hidden Current_Error @key[return] File_Type;
address@hidden Current_Error @key[return] File_Access;
address@hidden
+  @Trailing@;Returns the current default error file,
+  or an access value designating the current default error file,
+  respectively.
+
address@hidden@ChgRef{Version=[1],Kind=[Revised],Ref=[8652/0051],address@hidden
address@hidden Flush (File : @key[in] @Chg{New=[],address@hidden ]}File_Type);
address@hidden Flush;
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI12-0130-1]}
address@hidden effect of Flush is the same as the corresponding subprogram
+in @Chg{Version=[4],New=[Sequential_IO (see @RefSecNum{File Management})],
+Old=[Streams.Stream_IO (see @RefSecNum[The Package Streams.Stream_IO])]}.]
+If File is not explicitly specified, Current_Output is used.
address@hidden first sentence is redundant for version 4 and later only, but
+I didn't want to delete the entire sentence and replace it (the only way to
+make that conditional).}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0052-1]}
+  @ChgAdded{Version=[4],Text=[For the purpose of determining whether concurrent
+  calls on text input-output subprograms are required to perform as specified,
+  subprograms that implicitly operate on one of the default input-output files
+  are considered to have a parameter of Current_Input or Current_Output (as
+  appropriate). The result of Current_Output is considered to be overlapping
+  with the file given to the latest call of Set_Output (or Standard_Output if
+  Set_Output hasn't been called); a corresponding consideration applies to the
+  result of Current_Input. See the introduction of
+  @RefSecNum{Predefined Language Environment} for details.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0053],ARef=[AI95-00063-01]}
address@hidden(erroneous execution),Sec=(cause)}
+The execution of a program is erroneous if it @Chg{New=[invokes an operation 
on],
+Old=[attempts to use]} a current default
+input, default output, or default error address@hidden, and if the
+corresponding file object is closed or],Old=[ that]} no longer exists.
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0053],ARef=[AI95-00063-01]}
address@hidden,Text=[Closing a default file, then setting the default
+file to another open file before accessing it is not erroneous.]}
address@hidden
+
address@hidden,Kind=[Deleted],Ref=[8652/0053],ARef=[AI95-00063-01]}
address@hidden,Text=[If the Close operation is applied to a file
+object that is also serving as the default input, default output, or default
+error file, then subsequent operations on such a default file are erroneous.]}
address@hidden
+
address@hidden
+The standard input, standard output, and standard error
+files cannot be opened, closed, reset, or deleted, because the
+parameter File of the corresponding procedures has the mode @key[in] @key[out].
+
+The standard input, standard output, and standard error files are different
+file objects, but not necessarily different external files.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0051],ARef=[AI95-00057-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the parameter 
mode
+  of Flush; otherwise it could not be used on Standard_Output.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0052],ARef=[AI95-00194-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected Standard_Error 
so it
+  refers to the correct file.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0053],ARef=[AI95-00063-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that execution
+  is erroneous only when a closed default file is accessed.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0130-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Moved the definition of
+  Flush to @RefSecNum{File Management}, as all input-output packages now
+  have it.]}
address@hidden
+
+
address@hidden of Line and Page Lengths}
+
address@hidden
+The subprograms described in this subclause are concerned with the line
+and page structure of a file of mode Out_File or Append_File. They operate
+either on
+the file given as the first parameter, or, in the absence of such a file
+parameter, on the current default output file. They provide for output
+of text with a specified maximum line length or page length. In these
+cases, line and page terminators are output implicitly and automatically
+when needed. When line and page lengths are unbounded (that is, when
+they have the conventional value zero), as in the case of a newly opened
+file, new lines and new pages are only started when explicitly called
+for.
+
+In all cases, the exception Status_Error is propagated if the file to be
+used is not open; the exception Mode_Error is propagated if the mode of the
+file is not Out_File or Append_File.
address@hidden
address@hidden@Keepnext
address@hidden Set_Line_Length(File : @key[in] File_Type; To : @key[in] Count);
address@hidden Set_Line_Length(To   : @key[in] Count);
address@hidden
+  Sets the maximum line length of the specified output or
+  append file to the number of characters specified by To. The value zero for
+  To specifies an unbounded line length.
address@hidden
+The setting
+does not affect the lengths of lines in the existing file, rather it only
+influences subsequent output address@hidden
+
+  @Trailing@;The exception Use_Error is propagated if the specified line length
+  is inappropriate for the associated external file.
+
address@hidden@Keepnext
address@hidden Set_Page_Length(File : @key[in] File_Type; To : @key[in] Count);
address@hidden Set_Page_Length(To   : @key[in] Count);
address@hidden
+  Sets the maximum page length of the specified output or append file to
+  the number of lines specified by To. The value zero for To
+  specifies an unbounded page length.
+
+  @Trailing@;The exception Use_Error is propagated if the specified page length
+  is inappropriate for the associated external file.
+
address@hidden@Keepnext
address@hidden Line_Length(File : @key[in] File_Type) @key[return] Count;
address@hidden Line_Length @key[return] Count;
address@hidden
+  @Trailing@;Returns the maximum line length currently set for the
+  specified output or append file, or zero if the line length is unbounded.
+
address@hidden@Keepnext
address@hidden Page_Length(File : @key[in] File_Type) @key[return] Count;
address@hidden Page_Length @key[return] Count;
address@hidden
+  Returns the maximum page length currently set for the
+  specified output or append file, or zero if the page length is unbounded.
address@hidden
address@hidden
+
address@hidden on Columns, Lines, and Pages}
+
address@hidden
+The subprograms described in this subclause provide for explicit control
+of line and page structure; they operate either on the file given as the
+first parameter, or, in the absence of such a file parameter, on the
+appropriate (input or output) current default file. The exception
+Status_Error is propagated by any of these subprograms if the file to be
+used is not open.
address@hidden
address@hidden@Keepnext
address@hidden New_Line(File : @key[in] File_Type; Spacing : @key[in] 
Positive_Count := 1);
address@hidden New_Line(Spacing : @key[in] Positive_Count := 1);
address@hidden
+
+  Operates on a file of mode Out_File or Append_File.
+
+  For a Spacing of one: Outputs a line terminator and sets the
+  current column number to one. Then increments the current
+  line number by one, except in the case that the current line
+  number is already greater than or equal to the maximum page
+  length, for a bounded page length; in that case a page
+  terminator is output, the current page number is incremented
+  by one, and the current line number is set to one.
+
+  For a Spacing greater than one, the above actions are
+  performed Spacing times.
+
+  @Trailing@;The exception Mode_Error is propagated if the mode is not
+  Out_File or Append_File.
+
address@hidden@Keepnext
address@hidden Skip_Line(File  : @key[in] File_Type; Spacing : @key[in] 
Positive_Count := 1);
address@hidden Skip_Line(Spacing : @key[in] Positive_Count := 1);
address@hidden
+
+  Operates on a file of mode In_File.
+
+  For a Spacing of one: Reads and discards all characters until
+  a line terminator has been read, and then sets the current
+  column number to one. If the line terminator is not
+  immediately followed by a page terminator, the current line
+  number is incremented by one. Otherwise, if the line
+  terminator is immediately followed by a page terminator, then
+  the page terminator is skipped, the current page number is
+  incremented by one, and the current line number is set to one.
+
+  For a Spacing greater than one, the above actions are
+  performed Spacing times.
+
+  @Trailing@;The exception Mode_Error is propagated if the mode is not In_File.
+  The exception End_Error is propagated if an attempt is made to
+  read a file terminator.
+
address@hidden@Keepnext
address@hidden End_Of_Line(File : @key[in] File_Type) @key[return] Boolean;
address@hidden End_Of_Line @key[return] Boolean;
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+  Operates on a file of mode In_File. Returns True if a line
+  terminator or a file terminator is next;
+  address@hidden,New=[,],Old=[]} returns False.
+
+  @Trailing@;The exception Mode_Error is propagated if the mode is not In_File.
+
address@hidden@Keepnext
address@hidden New_Page(File : @key[in] File_Type);
address@hidden New_Page;
address@hidden
+
+  Operates on a file of mode Out_File or Append_File. Outputs a line
+  terminator if the current line is not terminated, or if the
+  current page is empty (that is, if the current column and line
+  numbers are both equal to one). Then outputs a page
+  terminator, which terminates the current page. Adds one to
+  the current page number and sets the current column and line
+  numbers to one.
+
+  @Trailing@;The exception Mode_Error is propagated if the mode is not
+  Out_File or Append_File.
+
address@hidden@Keepnext
address@hidden Skip_Page(File : @key[in] File_Type);
address@hidden Skip_Page;
address@hidden
+  Operates on a file of mode In_File. Reads and discards all
+  characters and line terminators until a page terminator has
+  been read. Then adds one to the current page number, and sets
+  the current column and line numbers to one.
+
+  @Trailing@;The exception Mode_Error is propagated if the mode is not In_File.
+  The exception End_Error is propagated if an attempt is made to
+  read a file terminator.
+
address@hidden@Keepnext
address@hidden End_Of_Page(File : @key[in] File_Type) @key[return] Boolean;
address@hidden End_Of_Page @key[return] Boolean;
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+  Operates on a file of mode In_File. Returns True if the
+  combination of a line terminator and a page terminator is
+  next, or if a file terminator is next;
+  address@hidden,New=[,],Old=[]} returns False.
+
+  @Trailing@;The exception Mode_Error is propagated if the mode is not In_File.
+
address@hidden@Keepnext
address@hidden End_Of_File(File : @key[in] File_Type) @key[return] Boolean;
address@hidden End_Of_File @key[return] Boolean;
address@hidden
+
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+  Operates on a file of mode In_File. Returns True if a file
+  terminator is next, or if the combination of a line, a page,
+  and a file terminator is next;
+  address@hidden,New=[,],Old=[]} returns False.
+
+  @Trailing@;The exception Mode_Error is propagated if the mode is not In_File.
+
address@hidden
address@hidden following paragraph was originally in a DescribeCode section; but
+that clearly was not intended; I've fixed it. (This changes the indentation of
+the paragraph in the old version too, but the change is harmless.) 
RLB-21-08-2000}
+The following subprograms provide for the control of the current
+position of reading or writing in a file. In all cases, the default
+file is the current output file.
address@hidden
+
address@hidden@Keepnext
address@hidden Set_Col(File : @key[in] File_Type; To : @key[in] Positive_Count);
address@hidden Set_Col(To   : @key[in] Positive_Count);
address@hidden
+  @Leading@;If the file mode is Out_File or Append_File:
address@hidden
+               If the value specified by To is greater than the current
+               column number, outputs spaces, adding one to the current
+               column number after each space, until the current column
+               number equals the specified value. If the value
+               specified by To is equal to the current column number,
+               there is no effect. If the value specified by To is less
+               than the current column number, has the effect of calling
+               New_Line (with a spacing of one), then outputs (To @en 1)
+               spaces, and sets the current column number to the
+               specified value.
+
+               The exception Layout_Error is propagated if the value
+               specified by To exceeds Line_Length when the line length
+               is bounded (that is, when it does not have the
+               conventional value zero).
address@hidden
+
+  @Leading@;If the file mode is In_File:
address@hidden
+               Reads (and discards) individual characters, line
+               terminators, and page terminators, until the next
+               character to be read has a column number that equals the
+               value specified by To; there is no effect if the current
+               column number already equals this value. Each transfer
+               of a character or terminator maintains the current
+               column, line, and page numbers in the same way as a Get
+               procedure (see @RefSecNum{Get and Put Procedures}).
+               (Short lines will be skipped
+               until a line is reached that has a character at the
+               specified column position.)
+
+    @Trailing@;The exception End_Error is propagated if an attempt is made
+    to read a file terminator.
address@hidden
+
address@hidden@Keepnext
address@hidden Set_Line(File : @key[in] File_Type; To : @key[in] 
Positive_Count);
address@hidden Set_Line(To   : @key[in] Positive_Count);
address@hidden
+
+  @Leading@;If the file mode is Out_File or Append_File:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0038-1]}
+               If the value specified by To is greater than the current
+               line number, has the effect of repeatedly calling
+               New_Line (with a spacing of one), until the current line
+               number equals the specified value. If the value
+               specified by To is equal to the current line number,
+               there is no effect. If the value specified by To is less
+               than the current line number, has the effect of calling
+               New_Page address@hidden,New=[, if To is greater
+               than 1,],Old=[]} by a call of New_Line with a spacing
+               equal to (To @en 1).
+
+               The exception Layout_Error is propagated if the value
+               specified by To exceeds Page_Length when the page length
+               is bounded (that is, when it does not have the
+               conventional value zero).
address@hidden
+
+  @Leading@;If the mode is In_File:
address@hidden
+               Has the effect of repeatedly calling Skip_Line (with a
+               spacing of one), until the current line number equals the
+               value specified by To; there is no effect if the current
+               line number already equals this value. (Short pages will
+               be skipped until a page is reached that has a line at the
+               specified line position.)
+
+    @Trailing@;The exception End_Error is propagated if an attempt is made
+    to read a file terminator.
address@hidden
address@hidden@Keepnext
address@hidden Col(File : @key[in] File_Type) @key[return] Positive_Count;
address@hidden Col @key[return] Positive_Count;
address@hidden
+
+  Returns the current column number.
+
+  @Trailing@;The exception Layout_Error is propagated if this number exceeds
+  Count'Last.
+
address@hidden@Keepnext
address@hidden Line(File : @key[in] File_Type) @key[return] Positive_Count;
address@hidden Line @key[return] Positive_Count;
address@hidden
+
+          Returns the current line number.
+
+  @Trailing@;The exception Layout_Error is propagated if this number exceeds
+  Count'Last.
+
address@hidden@Keepnext
address@hidden Page(File : @key[in] File_Type) @key[return] Positive_Count;
address@hidden Page @key[return] Positive_Count;
address@hidden
+  Returns the current page number.
+
+  @Trailing@;The exception Layout_Error is propagated if this number exceeds
+  Count'Last.
+
address@hidden
+
+The column number, line number, or page number are allowed to exceed
+Count'Last (as a consequence of the input or output of sufficiently many
+characters, lines, or pages). These events do not cause any exception
+to be propagated.
+However, a call of Col, Line, or Page propagates the
+exception Layout_Error if the corresponding number exceeds Count'Last.
address@hidden
+
address@hidden
+A page terminator is always skipped whenever the preceding line
+terminator is skipped. An implementation may represent the combination
+of these terminators by a single character, provided that it is properly
+recognized on input.
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0038-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Fixed a glitch in Set_Line such that we could have called New_Line(0), which
+  would have to raise Constraint_Error. It's now defined to work. The bug
+  occurred in Ada 95 and Ada 2005. It's very unlikely that
+  any real programs depend on this exception being raised.]}
address@hidden
+
+
address@hidden and Put Procedures}
+
address@hidden
+The procedures Get and Put for items of the type Character, String,
+numeric types, and enumeration types are described in subsequent
+subclauses.
+Features of these procedures that are common to most of these
+types are described in this subclause. The Get and Put procedures for
+items of type Character and String deal with individual character
+values; the Get and Put procedures for numeric and enumeration types
+treat the items as lexical elements.
+
+All procedures Get and Put have forms with a
+file parameter, written
+first. Where this parameter is omitted, the appropriate (input or
+output) current default file is understood to be specified. Each
+procedure Get operates on a
+file of mode In_File. Each procedure Put
+operates on a file of mode Out_File or Append_File.
+
+All procedures Get and Put maintain the current column, line, and page
+numbers of the specified file: the effect of each of these procedures
+upon these numbers is the result of the effects of individual
+transfers of characters and of individual output or skipping of
+terminators. Each transfer of a character adds one to the current
+column number. Each output of a line terminator sets the current column
+number to one and adds one to the current line number. Each output of a
+page terminator sets the current column and line numbers to one and adds
+one to the current page number. For input, each skipping of a line
+terminator sets the current column number to one and adds one to the
+current line number; each skipping of a page terminator sets the current
+column and line numbers to one and adds one to the current page number.
+Similar considerations apply to the procedures Get_Line, Put_Line, and
+Set_Col.
+
+Several Get and Put procedures, for numeric and enumeration types, have
address@hidden parameters which specify field lengths; these parameters are of
+the nonnegative subtype Field of the type Integer.
+
address@hidden,Kind=[Revised],ARef=[AI95-00223-01]}
address@hidden, Sec=(in text input for enumeration and numeric types)}
+Input-output of enumeration values uses the syntax of the corresponding
+lexical elements. Any Get procedure for an enumeration type begins by
+skipping any leading blanks, or line or page terminators. @Chg{Version=[2],
+New=[A],Old=[Get procedures
+for numeric or enumeration types start by skipping leading blanks, where
+a]} @i{blank} is defined as a space or a horizontal tabulation character.
+Next,
+characters are input only so long as the sequence input is an initial
+sequence of an identifier or of a character literal (in particular,
+input ceases when a line terminator is encountered). The character or
+line terminator that causes input to cease remains available for
+subsequent input.
+
+For a numeric type, the Get procedures have a format parameter called
+Width. If the value given for this parameter is zero, the Get procedure
+proceeds in the same manner as for enumeration types, but using the
+syntax of numeric literals instead of that of enumeration literals. If
+a nonzero value is given, then exactly Width characters are input, or
+the characters up to a line terminator, whichever comes first; any
+skipped leading blanks are included in the count. The syntax used for
+numeric literals is an extended syntax that allows a leading sign (but
+no intervening blanks, or line or page terminators)
+and that also allows (for real types) an integer literal
+as well as forms that have digits only before the point
+or only after the point.
+
+Any Put procedure, for an item of a numeric or an enumeration type,
+outputs the value of the item as a numeric literal, identifier, or
+character literal, as appropriate. This is preceded by leading spaces
+if required by the format parameters Width or Fore (as described in
+later subclauses), and then a minus sign for a negative value; for an
+enumeration type, the spaces follow instead of leading. The format
+given for a Put procedure is overridden if it is insufficiently wide,
+by using the minimum needed width.
+
+Two further cases arise for Put procedures for numeric and enumeration
+types, if the line length of the specified output file is bounded (that
+is, if it does not have the conventional value zero). If the number of
+characters to be output does not exceed the maximum line length, but is
+such that they cannot fit on the current line, starting from the current
+column, then (in effect) New_Line is called (with a spacing of one)
+before output of the item. Otherwise, if the number of characters
+exceeds the maximum line length, then the exception Layout_Error is
+propagated and nothing is output.
+
+The exception Status_Error is propagated by any of the procedures Get,
+Get_Line, Put, and Put_Line if the file to be used is not open. The
+exception Mode_Error is propagated by the procedures Get and Get_Line if the
+mode of the file to be used is not In_File; and by the procedures Put
+and Put_Line, if the mode is not Out_File or Append_File.
+
+The exception End_Error is propagated by a Get procedure if an attempt is
+made to skip a file terminator. The exception Data_Error is propagated by a
+Get procedure if the sequence finally input is not a lexical element
+corresponding to the type, in particular if no characters were input;
+for this test, leading blanks are ignored; for an item of a numeric
+type, when a sign is input, this rule applies to the succeeding numeric
+literal. The exception Layout_Error is propagated by a Put procedure that
+outputs to a parameter of type String, if the length of the actual
+string is insufficient for the output of the item.
address@hidden
+
address@hidden
+In the examples, here and in subclauses
address@hidden for Integer Types}
+and @RefSecNum{Input-Output for Real Types}, the string
+quotes and the lower case letter b are not transferred: they are shown
+only to reveal the layout and spaces.
+
address@hidden
+N : Integer;
+   ...
+Get(N);
+
address@hidden()@tabset(P4, P22, P38)
address@hidden  @\Characters at input @\Sequence input @\Value of N]
address@hidden line.}
address@hidden  @address@hidden@|12535b @address@hidden@|12535 
@address@hidden@|12535]
address@hidden  @\bb12_535e1b @\12_535e1 @\125350]
address@hidden  @\bb12_535e; @\12_535e @\(none) Data_Error raised]
address@hidden
+
address@hidden
address@hidden@;Example of overridden width parameter:
address@hidden
+
address@hidden
+Put(Item => -23, Width => 2);  address@hidden  "@en@|23"}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00223-01]}
+  @ChgAdded{Version=[2],Text=[Removed conflicting text describing the
+  skipping of blanks for a Get procedure.]}
address@hidden
+
+
address@hidden of Characters and Strings}
+
address@hidden
address@hidden@Keepnext@;For an item of type Character the following procedures 
are
+provided:
address@hidden
address@hidden@Keepnext
address@hidden Get(File : @key[in] File_Type; Item : @key[out] Character);
address@hidden Get(Item : @key[out] Character);
address@hidden
+  After skipping any line terminators and any page terminators,
+  reads the next character from the specified input file and
+  returns the value of this character in the out parameter Item.
+
+  @Trailing@;The exception End_Error is propagated if an attempt is made to
+  skip a file terminator.
+
address@hidden@Keepnext
address@hidden Put(File : @key[in] File_Type; Item : @key[in] Character);
address@hidden Put(Item : @key[in] Character);
address@hidden
+  @Trailing@;If the line length of the specified output file is bounded
+  (that is, does not have the conventional value zero), and the
+  current column number exceeds it, has the effect of calling
+  New_Line with a spacing of one. Then, or otherwise, outputs
+  the given character to the file.
+
address@hidden@Keepnext
address@hidden Look_Ahead (File        : @key[in]  File_Type;
+                      Item        : @key[out] Character;
+                      End_Of_Line : @key[out] Boolean);
address@hidden Look_Ahead (Item        : @key[out] Character;
+                      End_Of_Line : @key[out] Boolean);
address@hidden
+  @address@hidden,Kind=[Revised]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0038-1],address@hidden,
+  New=[Status_Error is propagated if the file is not open. ],Old=[]}Mode_Error
+  is propagated if
+  the mode of the file is not In_File. Sets End_Of_Line to True if at end of
+  line, including if at end of page or at end of file; in each of these cases
+  the value of Item is not specified.
+  @PDefn{unspecified}
+  address@hidden,New=[,],Old=[]} End_Of_Line is set to
+  False and Item is set to @Chg{New=[],Old=[the ]}the next character (without
+  consuming it) from the file.
+
address@hidden@Keepnext
address@hidden Get_Immediate(File : @key[in]  File_Type;
+                        Item : @key[out] Character);
address@hidden Get_Immediate(Item : @key[out] Character);
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0038-1]}Reads
+the next character, either control or graphic, from the specified
+File or the default input file. @Chg{Version=[3],New=[Status_Error is
+propagated if the file is not open. ],Old=[]}Mode_Error is propagated
+if the mode of the
+file is not In_File. End_Error is propagated if at the end of the file.
+The current column, line and page numbers for the file are not affected.
+
address@hidden@Keepnext
address@hidden Get_Immediate(File      : @key[in]  File_Type;
+                        Item      : @key[out] Character;
+                        Available : @key[out] Boolean);
address@hidden Get_Immediate(Item      : @key[out] Character;
+                        Available : @key[out] Boolean);
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0038-1]}If
+a character, either control or graphic, is available from the
+specified File or the default input file, then the character is read;
+Available is True and Item contains the value of this character. If a character
+is not available, then Available is False and the value of
+Item is not specified.
address@hidden
address@hidden,New=[Status_Error is propagated if the file is
+not open. ],Old=[]}Mode_Error is propagated if the mode of the
+file is not In_File. End_Error is propagated if at the end of the file.
+The current column, line and page numbers for the file are not affected.
+
address@hidden
address@hidden following paragraph was originally in a DescribeCode section; but
+that clearly was not intended; I've fixed it. (This changes the indentation of
+the paragraph in the old version too, but the change is harmless.) 
RLB-21-08-2000}
address@hidden@;
address@hidden,Kind=[Revised],ARef=[AI95-00301-01]}
+For an item of type String the following @Chg{Version=[2],New=[subprograms],
+Old=[procedures]} are provided:
address@hidden
+
address@hidden@Keepnext
address@hidden Get(File : @key[in] File_Type; Item : @key[out] String);
address@hidden Get(Item : @key[out] String);
address@hidden
+  @Trailing@;Determines the length of the given string and attempts that
+  number of Get operations for successive characters of the
+  string (in particular, no operation is performed if the string is null).
+
address@hidden@Keepnext
address@hidden Put(File : @key[in] File_Type; Item : @key[in] String);
address@hidden Put(Item : @key[in] String);
address@hidden
+  @Trailing@;Determines the length of the given string and attempts that
+  number of Put operations for successive characters of the
+  string (in particular, no operation is performed if the string is null).
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Keepnext=[T],address@hidden Get_Line(File : @key{in} File_Type) 
@key{return} String;
address@hidden Get_Line @b<return> String;]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00301-01]}
+  @ChgAdded{Version=[2],Type=[Trailing],Text=[Returns a result string
+  constructed by reading successive characters from the specified input file,
+  and assigning them to successive characters of the result string. The result
+  string has a lower bound of 1 and an upper bound of the number of characters
+  read. Reading stops when the end of the line is met; Skip_Line is then (in
+  effect) called with a spacing of 1.]}
+
+  @ChgRef{Version=[2],Kind=[Added],ARef=[AI95-00301-01]}
+  @ChgAdded{Version=[2],Type=[Trailing],Text=[Constraint_Error is raised if the
+  length of the line exceeds Positive'Last; in this case, the line number and 
page
+  number are unchanged, and the column number is unspecified but no less than
+  it was before the address@hidden The exception End_Error is
+  propagated if an attempt is made to skip a file terminator.]}
+
+  @begin{Ramification}
+    @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00301-01]}
+    @ChgAdded{Version=[2],Text=[Precisely what is left in the file is 
unspecified
+    if Constraint_Error is raised because the line doesn't fit in a String; it
+    should be consistent with column number. This allows implementers to use
+    whatever buffering scheme makes sense. But the line terminator is not
+    skipped in this case.]}
+  @end{Ramification}
+
address@hidden@Keepnext
address@hidden Get_Line(File : @key[in] File_Type;
+                   Item : @key[out] String;
+                   Last : @key[out] Natural);
address@hidden Get_Line(Item : @key[out] String;
+                   Last : @key[out] Natural);
address@hidden
+  Reads successive characters from the specified input file and assigns
+  them to successive characters of the specified string.
+  Reading stops if the end of the string is met. Reading also stops if
+  the end of the line is met before meeting the end of the string;
+  in this case Skip_Line is (in effect) called with a spacing of 1.
+  @PDefn{unspecified}
+  The values of characters not assigned are not specified.
+
+  @Trailing@;If characters are read, returns in Last the index value such
+  that Item(Last) is the last character assigned (the index of
+  the first character assigned is Item'First). If no characters
+  are read, returns in Last an index value that is one less than
+  Item'First. The exception End_Error is propagated if an attempt
+  is made to skip a file terminator.
+
address@hidden@Keepnext
address@hidden Put_Line(File : @key[in] File_Type; Item : @key[in] String);
address@hidden Put_Line(Item : @key[in] String);
address@hidden
+   Calls the procedure Put for the given string, and then the
+   procedure New_Line with a spacing of one.
address@hidden
address@hidden
+
address@hidden
+The Get_Immediate procedures should be implemented with unbuffered
+input. For a device such as a keyboard, input should be 
@lquotes@;address@hidden@;
+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.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Get_Immediate should be implemented with unbuffered input; input
+should be available immediately; line-editing should be disabled.]}]}
address@hidden
+
address@hidden
+Get_Immediate can be used to read a single key from the
+keyboard @lquotes@;address@hidden@;; that is, without waiting for an end of 
line.
+In a call of Get_Immediate without the parameter Available,
+the caller will wait until a character is available.
+
+In a literal string parameter of Put, the enclosing string bracket
+characters are not output. Each doubled string bracket character in the
+enclosed string is output as a single string bracket character, as a
+consequence of the rule for string literals (see @RefSecNum{String Literals}).
+
+A string read by Get or written by Put can extend over several lines.
+An implementation is allowed to assume that certain external files do
+not contain page terminators, in which case Get_Line and Skip_Line can
+return as soon as a line terminator is read.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00301-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  The Get_Line functions are @Chg{Version=[3],New=[],Old=[newly ]}added
+  to Ada.Text_IO.
+  If Ada.Text_IO is referenced in a @nt{use_clause}, and a function Get_Line
+  is defined in a package that is also referenced in a @nt{use_clause}, the
+  user-defined Get_Line may no longer be use-visible, resulting in errors.
+  This should be rare and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00301-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The Text_IO.Get_Line functions are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0038-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added missing wording about
+  raising Status_Error to Look_Ahead and Get_Immediate.]}
address@hidden
+
+
+
address@hidden for Integer Types}
+
address@hidden
+The following procedures are defined in the generic packages Integer_IO
+and Modular_IO, which have to be
+instantiated for the appropriate signed
+integer or modular
+type respectively
+(indicated by Num in the specifications).
+
address@hidden@;Values are output as decimal or based literals, without low line
+characters or exponent, and, for Integer_IO, preceded by a minus sign if 
negative. The
+format (which includes any leading spaces and minus sign) can be
+specified by an optional field width parameter. Values of widths of
+fields in output formats are of the nonnegative integer subtype Field.
+Values of bases are of the integer subtype Number_Base.
address@hidden
address@hidden@key[subtype] Number_Base @key[is] Integer @key[range] 2 .. 16;
address@hidden
+
address@hidden@;The default field width and base to be used by output 
procedures are
+defined by the following variables that are declared in the generic
+packages Integer_IO and Modular_IO:
+
address@hidden
address@hidden@;Default_Width : Field := Num'Width;
+Default_Base  : Number_Base := 10;
address@hidden
+
address@hidden@Keepnext@;The following procedures are provided:
address@hidden
address@hidden@Keepnext
address@hidden Get(File : @key[in] File_Type; Item : @key[out] Num; Width : 
@key[in] Field := 0);
address@hidden Get(Item : @key[out] Num; Width : @key[in] Field := 0);
address@hidden
+      If the value of the parameter Width is zero, skips any leading
+      blanks, line terminators, or page terminators, then
+      reads a plus sign if present or (for a signed type only)
+      a minus sign if present, then reads the longest possible
+      sequence of characters matching the syntax of a numeric
+      literal without a point.
+      If a nonzero value of Width is supplied, then exactly Width
+      characters are input, or the characters (possibly none) up to
+      a line terminator, whichever comes first; any skipped leading
+      blanks are included in the count.
+
+      Returns, in the parameter Item, the value of type Num
+      that corresponds to the sequence input.
+
address@hidden,Kind=[Revised],ARef=[AI05-0038-1]}
+      @Trailing@;The exception Data_Error is propagated if the sequence of 
characters
+      read does not form a legal integer literal or if the value obtained is
+      not of the subtype address@hidden,New=[],Old=[ (for Integer_IO) or
+      is not in the base range of Num (for Modular_IO)]}.
+
address@hidden@Keepnext
address@hidden Put(File  : @key[in] File_Type;
+              Item  : @key[in] Num;
+              Width : @key[in] Field := Default_Width;
+              Base  : @key[in] Number_Base := Default_Base);
address@hidden Line}
address@hidden Put(Item  : @key[in] Num;
+              Width : @key[in] Field := Default_Width;
+              Base  : @key[in] Number_Base := Default_Base);
address@hidden
+          Outputs the value of the parameter Item as an integer literal,
+          with no low lines, no exponent, and no leading zeros (but a
+          single zero for the value zero), and a preceding minus sign
+          for a negative value.
+
+          If the resulting sequence of characters to be output has fewer
+          than Width characters, then leading spaces are first output to
+          make up the difference.
+
+          @Trailing@;Uses the syntax for decimal literal if the parameter Base 
has
+          the value ten (either explicitly or through Default_Base);
+          otherwise, uses the syntax for based literal, with any letters
+          in upper case.
+
address@hidden@Keepnext
address@hidden Get(From : @key[in] String; Item : @key[out] Num; Last : 
@key[out] Positive);
address@hidden
+          Reads an integer value from the beginning of the given string,
+          following the same rules as the Get procedure that reads an
+          integer value from a file, but treating the end of the string
+          as a file terminator. Returns, in the parameter Item, the
+          value of type Num that corresponds to the sequence input.
+          Returns in Last the index value such that From(Last) is the
+          last character read.
+
+          @Trailing@;The exception Data_Error is propagated if the sequence 
input does
+          not have the required syntax or if the value obtained is not
+          of the subtype Num.
+
address@hidden@Keepnext
address@hidden Put(To   : @key[out] String;
+              Item : @key[in] Num;
+              Base : @key[in] Number_Base := Default_Base);
address@hidden
+          @Trailing@;Outputs the value of the parameter Item to the given 
string,
+          following the same rule as for output to a file, using the
+          length of the given string as the value for Width.
address@hidden
+
address@hidden@;Integer_Text_IO is a library package that is a nongeneric 
equivalent
+to Text_IO.Integer_IO for the predefined type Integer:
address@hidden
address@hidden Ada.Text_IO;@ChildUnit{Parent=[Ada],address@hidden
address@hidden Ada.Integer_Text_IO @key[is] @key[new] 
Ada.Text_IO.Integer_IO(Integer);
address@hidden
+
+For each predefined signed integer type,
+a nongeneric equivalent to Text_IO.Integer_IO is provided,
+with names such as Ada.Long_Integer_Text_IO.
+
+
address@hidden
+
address@hidden
+
+The nongeneric equivalent packages may, but need not,
+be actual instantiations of the generic package for the appropriate
+predefined type.
+
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0038-1]}
address@hidden,Text=[For Modular_IO, execution of Get propagates
+Data_Error if the sequence of
+characters read forms an integer literal outside the range
+0..Num'Last.]}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraphs 24 and 25 were
+deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered. This includes the next paragraph.}
address@hidden
+
address@hidden
address@hidden
address@hidden, Kind=[DeletedNoDelMsg]}
address@hidden,Text=<@ @;@comment{Empty paragraph to hang junk paragraph number 
from original RM}>]
+
address@hidden, Kind=[Revised],ARef=[AI05-0298-1]}
address@hidden,address@hidden Byte_Int @key[is] Integer @key[range] -127 .. 127;
+],address@hidden Int_IO @key[is] @key[new] 
Integer_IO(@Chg{Version=[3],New=[Byte_Int],Old=[Small_Int]}); @key[use] Int_IO;
address@hidden default format used at instantiation,}
address@hidden Default_Width = 4, Default_Base = 10}
+
+Put(126);                            address@hidden "b126"}
+Put(-126, 7);                        address@hidden "address@hidden@|126"}
+Put(126, Width => 13, Base => 2);    address@hidden "bbb2#1111110#"}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0038-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Changed wording to make Integer_IO and Modular_IO raise Data_Error in the 
same
+  way when the bounds of the subtype are exceeded. There is no value to
+  different behavior, and all surveyed compilers already treat integer and
+  modular values the same way. This could only cause a problem if a
+  program was compiled with some unsurveyed compiler, and the Ada 95-defined
+  behavior is expected for Modular_IO. But note that such code is not portable
+  anyway, as most widely used compilers behave consistently with the
+  new wording, so it is unlikely that such code exists.]}
address@hidden
+
+
address@hidden for Real Types}
+
address@hidden
+The following procedures are defined in the generic packages Float_IO,
+Fixed_IO, and Decimal_IO, which have to be instantiated for the
+appropriate floating point, ordinary fixed point, or decimal fixed point
+type respectively (indicated by Num in the specifications).
+
address@hidden@;Values are output as decimal literals without low line 
characters.
+The format of each value output consists of a Fore field, a decimal point,
+an Aft field, and (if a nonzero Exp parameter is supplied) the letter E
+and an Exp field. The two possible formats thus correspond to:
+
address@hidden
+Fore  .  Aft
address@hidden
+
address@hidden@;and to:
+
address@hidden
+Fore  .  Aft  E  Exp
address@hidden
+
+without any spaces between these fields. The Fore field may include
+leading spaces, and a minus sign for negative values. The Aft field
+includes only decimal digits (possibly with trailing zeros). The Exp
+field includes the sign (plus or minus) and the exponent (possibly with
+leading zeros).
+
address@hidden@;For floating point types, the default lengths of these fields 
are
+defined by the following variables that are declared in the generic
+package Float_IO:
+
address@hidden
address@hidden@;Default_Fore : Field := 2;
+Default_Aft  : Field := Num'Digits-1;
+Default_Exp  : Field := 3;
address@hidden
+
address@hidden@;For ordinary or decimal fixed point types, the default lengths 
of these
+fields are defined by the following variables that are declared in the
+generic packages Fixed_IO and Decimal_IO, respectively:
+
address@hidden
address@hidden@;Default_Fore : Field := Num'Fore;
+Default_Aft  : Field := Num'Aft;
+Default_Exp  : Field := 0;
address@hidden
+
address@hidden@Keepnext@;The following procedures are provided:
address@hidden
address@hidden@Keepnext
address@hidden Get(File : @key[in] File_Type; Item : @key[out] Num; Width : 
@key[in] Field := 0);
address@hidden Get(Item : @key[out] Num; Width : @key[in] Field := 0);
address@hidden
+
address@hidden@;If the value of the parameter Width is zero, skips any leading
+blanks, line terminators, or page terminators, then reads the longest
+possible sequence of characters matching the syntax of any of the following
+(see @RefSecNum(Numeric Literals)):
address@hidden
+[+|@address@hidden
+
+[+|@address@hidden@nt[exponent]]
+
+[+|@address@hidden@nt[exponent]]
+
+[+|@address@hidden@address@hidden
+
+[+|@address@hidden@address@hidden
address@hidden
+
+
+          If a nonzero value of Width is supplied, then exactly Width
+          characters are input, or the characters (possibly none) up to
+          a line terminator, whichever comes first; any skipped leading
+          blanks are included in the count.
+
+          Returns in the parameter Item the value of type Num that
+          corresponds to the sequence input, preserving the sign (positive
+          if none has been specified) of a zero value if Num is a floating
+          point type and Num'Signed_Zeros is True.
+
+          @Trailing@;The exception Data_Error is propagated if the sequence 
input does
+          not have the required syntax or if the value obtained is not
+          of the subtype Num.
+
address@hidden@Keepnext
address@hidden Put(File : @key[in] File_Type;
+              Item : @key[in] Num;
+              Fore : @key[in] Field := Default_Fore;
+              Aft  : @key[in] Field := Default_Aft;
+              Exp  : @key[in] Field := Default_Exp);
address@hidden Line}
address@hidden Put(Item : @key[in] Num;
+              Fore : @key[in] Field := Default_Fore;
+              Aft  : @key[in] Field := Default_Aft;
+              Exp  : @key[in] Field := Default_Exp);
address@hidden
+Outputs the value of the parameter Item as a decimal literal
+with the format defined by Fore, Aft and Exp. If the value is
+negative, or if Num is a floating point type where Num'Signed_Zeros is True and
+the value is a negatively signed zero, then
+a minus sign is included in the integer part.
+If Exp has the value zero, then the integer part to be output has
+as many digits as are needed to represent the integer part of
+the value of Item, overriding Fore if necessary, or consists
+of the digit zero if the value of Item has no integer part.
+
+If Exp has a value greater than zero, then the integer part to
+be output has a single digit, which is nonzero except for the
+value 0.0 of Item.
+
+In both cases, however, if the integer part to be output has
+fewer than Fore characters, including any minus sign, then
+leading spaces are first output to make up the difference.
+The number of digits of the fractional part is given by Aft,
+or is one if Aft equals zero.
+The value is rounded; a value of exactly one half in the last place
+is rounded away from zero.
+
address@hidden@;If Exp has the value zero, there is no exponent part. If Exp
+has a value greater than zero, then the exponent part to be
+output has as many digits as are needed to represent the
+exponent part of the value of Item (for which a single digit
+integer part is used), and includes an initial sign (plus or
+minus). If the exponent part to be output has fewer than Exp
+characters, including the sign, then leading zeros precede the
+digits, to make up the difference. For the value 0.0 of Item,
+the exponent has the value zero.
+
address@hidden@Keepnext
address@hidden Get(From : @key[in] String; Item : @key[out] Num; Last : 
@key[out] Positive);
address@hidden
+          Reads a real value from the beginning of the given string,
+          following the same rule as the Get procedure that reads a real
+          value from a file, but treating the end of the string as a
+          file terminator. Returns, in the parameter Item, the value of
+          type Num that corresponds to the sequence input. Returns in
+          Last the index value such that From(Last) is the last
+          character read.
+
+          @Trailing@;The exception Data_Error is propagated if the sequence 
input does
+          not have the required syntax, or if the value obtained is not
+          of the subtype Num.
+
address@hidden@Keepnext
address@hidden Put(To   : @key[out] String;
+              Item : @key[in] Num;
+              Aft  : @key[in] Field := Default_Aft;
+              Exp  : @key[in] Field := Default_Exp);
address@hidden
+          @Trailing@;Outputs the value of the parameter Item to the given 
string,
+          following the same rule as for output to a file, using a value
+          for Fore such that the sequence of characters output exactly
+          fills the string, including any leading spaces.
address@hidden
+
+
address@hidden@;Float_Text_IO is a library package that is a nongeneric 
equivalent
+to Text_IO.Float_IO for the predefined type Float:
address@hidden
address@hidden Ada.Text_IO;@ChildUnit{Parent=[Ada],address@hidden
address@hidden Ada.Float_Text_IO @key[is] @key[new] Ada.Text_IO.Float_IO(Float);
address@hidden
+
+For each predefined floating point type,
+a nongeneric equivalent to Text_IO.Float_IO is provided,
+with names such as Ada.Long_Float_Text_IO.
+
+
address@hidden
+
address@hidden
+
+An implementation may extend Get @Redundant[and Put] for floating point
+types to support special values such as infinities and NaNs.
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+See also the similar permission for the @Chg{Version=[3],New=[Wide_Wide_Value, 
],Old=[]}
address@hidden,New=[, and Value attributes],Old=[attribute]}
+in @RefSecNum{Scalar Types}.
address@hidden
+
+
+The implementation of Put need not produce an output value with greater
+accuracy than is supported for the base subtype.
+The additional accuracy, if any,
+of the value produced by Put when the number of
+requested digits in the integer and fractional parts exceeds
+the required accuracy
+is implementation defined.
address@hidden
+The required accuracy is thus Num'Base'Digits digits if Num is
+a floating point subtype.
+For a fixed point subtype the required accuracy is a function
+of the subtype's Fore, Aft, and Delta attributes.
address@hidden
+
address@hidden accuracy of the value produced by Put.}
+
+
+The nongeneric equivalent packages may, but need not,
+be actual instantiations of the generic package for the appropriate
+predefined type.
+
address@hidden
+
address@hidden
+For an item with a positive value, if output to a string exactly fills
+the string without leading spaces, then output of the corresponding
+negative value will propagate Layout_Error.
+
+The rules for the Value attribute
+(see @RefSecNum(Scalar Types)) and the rules for Get are based on the
+same set of formats.
address@hidden
+
address@hidden
address@hidden
address@hidden, Kind=[Deleted]}
address@hidden,Text=<@ @;@comment{Empty paragraph to hang junk paragraph number 
from original RM}>]
+
address@hidden Real_IO @key[is] @key[new] Float_IO(Real); @key[use] Real_IO;
address@hidden default format used at instantiation, Default_Exp = 3}
+
+X : Real := -123.4567;  address@hidden  digits 8      (see @RefSecNum{Floating 
Point Types})}
+
address@hidden()@tabset(P50)
+Put(X);  @RI[-- default format] @address@hidden"@en@|1.2345670E+02"]
+Put(X, Fore => 5, Aft => 3, Exp => 2); @address@hidden 
"address@hidden@|1.235E+2"]
+Put(X, 5, 3, 0);             @address@hidden "address@hidden@|123.457"]
address@hidden
address@hidden
+
address@hidden for Enumeration Types}
+
address@hidden
+The following procedures are defined in the generic package
+Enumeration_IO, which has to be instantiated for the appropriate
+enumeration type (indicated by Enum in the specification).
+
+Values are output using either upper or lower case letters for
+identifiers. This is specified by the parameter Set, which is of the
+enumeration type Type_Set.
+
address@hidden
address@hidden@key[type] Type_Set @key[is] (Lower_Case, Upper_Case);
address@hidden
+
address@hidden@;The format (which includes any trailing spaces) can be specified
+by an optional field width parameter. The default field width and letter case
+are defined by the following variables that are declared in the generic
+package Enumeration_IO:
+
address@hidden
address@hidden@;Default_Width   : Field := 0;
+Default_Setting : Type_Set := Upper_Case;
address@hidden
+
address@hidden@Keepnext@;The following procedures are provided:
address@hidden
address@hidden@Keepnext
address@hidden Get(File : @key[in] File_Type; Item : @key[out] Enum);
address@hidden Get(Item : @key[out] Enum);
address@hidden
+          After skipping any leading blanks, line terminators, or page
+          terminators, reads an identifier according to the syntax of
+          this lexical element (lower and upper case being considered
+          equivalent), or a character literal according to the syntax of
+          this lexical element (including the apostrophes). Returns, in
+          the parameter Item, the value of type Enum that corresponds to
+          the sequence input.
+
+          @Trailing@;The exception Data_Error is propagated if the sequence 
input does
+          not have the required syntax, or if the identifier or
+          character literal does not correspond to a value of the
+          subtype Enum.
+
address@hidden@Keepnext
address@hidden Put(File  : @key[in] File_Type;
+              Item  : @key[in] Enum;
+              Width : @key[in] Field := Default_Width;
+              Set   : @key[in] Type_Set := Default_Setting);
address@hidden Line}
address@hidden Put(Item  : @key[in] Enum;
+              Width : @key[in] Field := Default_Width;
+              Set   : @key[in] Type_Set := Default_Setting);
address@hidden
+          @Trailing@;Outputs the value of the parameter Item as an enumeration
+          literal (either an identifier or a character literal). The
+          optional parameter Set indicates whether lower case or upper
+          case is used for identifiers; it has no effect for character
+          literals. If the sequence of characters produced has fewer
+          than Width characters, then trailing spaces are finally output
+          to make up the difference. If Enum is a character type,
+          the sequence of characters produced is as for
+          Enum'Image(Item), as modified by the Width
+          and Set parameters.
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  For a character type, the literal might be a
+  @Chg{Version=[3],New=[Wide_Wide_Character, ],address@hidden,New=[,],Old=[]}
+  or a control character.
+  Whatever Image does for these things is appropriate here,
+  too.
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0036-1]}
+  @ChgAdded{Version=[3],Text=[The @ldquote@;characters address@hidden@;
+  defines the @ldquote@;characters to be address@hidden in the sense of
+  @RefSecNum{Get and Put Procedures}, so a result that cannot fit on any 
bounded
+  line will raise Layout_Error.]}
address@hidden
+
address@hidden@Keepnext
address@hidden Get(From : @key[in] String; Item : @key[out] Enum; Last : 
@key[out] Positive);
address@hidden
+          Reads an enumeration value from the beginning of the given
+          string, following the same rule as the Get procedure that
+          reads an enumeration value from a file, but treating the end
+          of the string as a file terminator. Returns, in the parameter
+          Item, the value of type Enum that corresponds to the sequence
+          input. Returns in Last the index value such that From(Last)
+          is the last character read.
+
+          @Trailing@;The exception Data_Error is propagated if the sequence 
input does
+          not have the required syntax, or if the identifier or
+          character literal does not correspond to a value of the
+          subtype Enum.
address@hidden
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  For a character type, it is permissible for the implementation to make
+  Get do the inverse of what Put does,
+  in the case of address@hidden,New=[ and wide_wide],Old=[]}
+  @nt{character_literal}s and control characters.
address@hidden
+
address@hidden@Keepnext
address@hidden Put(To   : @key[out] String;
+              Item : @key[in] Enum;
+              Set  : @key[in] Type_Set := Default_Setting);
address@hidden
+          @Trailing@;Outputs the value of the parameter Item to the given 
string,
+          following the same rule as for output to a file, using the
+          length of the given string as the value for Width.
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0054],ARef=[AI95-00007-01]}
+Although the specification of the generic package Enumeration_IO would allow
+instantiation for an @Chg{New=[integer],Old=[float]} type, this is not the
+intended purpose of this generic package, and the effect of such instantiations
+is not defined by the language.
address@hidden
+
address@hidden
+There is a difference between Put defined for characters, and for
+enumeration values. Thus
address@hidden
+   Ada.Text_IO.Put('A');  address@hidden  outputs the character A}
+
+   @key[package] Char_IO @key[is] @key[new] 
Ada.Text_IO.Enumeration_IO(Character);
+   Char_IO.Put('A');  address@hidden  outputs the character 'A', between 
apostrophes}
address@hidden
+
+The type Boolean is an enumeration type, hence Enumeration_IO can be
+instantiated for this type.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0054],ARef=[AI95-00007-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the wording to
+  say Enumeration_IO can be instantiated with an integer type, not a float
+  type.]}
address@hidden
+
+
address@hidden,Name=[Input-Output for Bounded Strings]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00428-01]}
address@hidden,Text=[The package Text_IO.Bounded_IO provides
+input-output in human-readable form for Bounded_Strings.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00428-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+package Text_IO.Bounded_IO has the following declaration:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Strings.Bounded;
address@hidden
+   @key{with package} Bounded @key{is}
+                     @key{new} Ada.Strings.Bounded.Generic_Bounded_Length (<>);
address@hidden Ada.Text_IO.Bounded_IO @address@hidden,Child=[Bounded_IO]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Put}
+      (File : @key{in} File_Type;
+       Item : @key{in} Bounded.Bounded_String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Put}
+      (Item : @key{in} Bounded.Bounded_String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Put_Line}
+      (File : @key{in} File_Type;
+       Item : @key{in} Bounded.Bounded_String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Put_Line}
+      (Item : @key{in} Bounded.Bounded_String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Get_Line}
+      (File : @key{in} File_Type)
+      @key{return} Bounded.Bounded_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Get_Line}
+      @key{return} Bounded.Bounded_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Get_Line}
+      (File : @key{in} File_Type; Item : @key{out} Bounded.Bounded_String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Get_Line}
+      (Item : @key{out} Bounded.Bounded_String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Text_IO.Bounded_IO;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00428-01]}
address@hidden,Type=[Leading],Text=[For an item of type
+Bounded_String, the following subprograms are provided:]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Put
+   (File : @key{in} File_Type;
+    Item : @key{in} Bounded.Bounded_String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00428-01]}
address@hidden,Text=[Equivalent to Text_IO.Put (File,
+Bounded.To_String(Item));]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Put
+   (Item : @key{in} Bounded.Bounded_String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00428-01]}
address@hidden,Text=[Equivalent to Text_IO.Put
+(Bounded.To_String(Item));]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Put_Line
+   (File : @key{in} File_Type;
+    Item : @key{in} Bounded.Bounded_String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00428-01]}
address@hidden,Text=[Equivalent to Text_IO.Put_Line (File,
+Bounded.To_String(Item));]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Put_Line
+   (Item : @key{in} Bounded.Bounded_String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00428-01]}
address@hidden,Text=[Equivalent to Text_IO.Put_Line
+(Bounded.To_String(Item));]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Get_Line
+   (File : @key{in} File_Type)
+   @key{return} Bounded.Bounded_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00428-01]}
address@hidden,Text=[Returns
+Bounded.To_Bounded_String(Text_IO.Get_Line(File));]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Get_Line
+   @key{return} Bounded.Bounded_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00428-01]}
address@hidden,Text=[Returns
+Bounded.To_Bounded_String(Text_IO.Get_Line);]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Get_Line
+   (File : @key{in} File_Type; Item : @key{out} Bounded.Bounded_String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00428-01]}
address@hidden,Text=[Equivalent to Item := Get_Line (File);]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Get_Line
+   (Item : @key{out} Bounded.Bounded_String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00428-01]}
address@hidden,Text=[Equivalent to Item := Get_Line;]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00428-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Package Text_IO.Bounded_IO is new.]}
address@hidden
+
+
address@hidden,Name=[Input-Output for Unbounded Strings]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00301-01]}
address@hidden,Text=[The package Text_IO.Unbounded_IO provides
+input-output in human-readable form for Unbounded_Strings.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00301-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library package
+Text_IO.Unbounded_IO has the following declaration:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Strings.Unbounded;
address@hidden Ada.Text_IO.Unbounded_IO @address@hidden,Child=[Unbounded_IO]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Put}
+      (File : @key{in} File_Type;
+       Item : @key{in} Strings.Unbounded.Unbounded_String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Put}
+      (Item : @key{in} Strings.Unbounded.Unbounded_String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Put_Line}
+      (File : @key{in} File_Type;
+       Item : @key{in} Strings.Unbounded.Unbounded_String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Put_Line}
+      (Item : @key{in} Strings.Unbounded.Unbounded_String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Get_Line}
+      (File : @key{in} File_Type)
+      @key{return} Strings.Unbounded.Unbounded_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Get_Line}
+      @key{return} Strings.Unbounded.Unbounded_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Get_Line}
+      (File : @key{in} File_Type; Item : @key{out} 
Strings.Unbounded.Unbounded_String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Get_Line}
+      (Item : @key{out} Strings.Unbounded.Unbounded_String);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Text_IO.Unbounded_IO;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00301-01]}
address@hidden,Type=[Leading],Text=[For an item of type
+Unbounded_String, the following subprograms are provided:]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Put
+   (File : @key{in} File_Type;
+    Item : @key{in} Strings.Unbounded.Unbounded_String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00301-01]}
address@hidden,Text=[Equivalent to Text_IO.Put (File,
+Strings.Unbounded.To_String(Item));]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Put
+   (Item : @key{in} Strings.Unbounded.Unbounded_String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00301-01]}
address@hidden,Text=[Equivalent to Text_IO.Put
+(Strings.Unbounded.To_String(Item));]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Put_Line
+   (File : @key{in} File_Type;
+    Item : @key{in} Strings.Unbounded.Unbounded_String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00301-01]}
address@hidden,Text=[Equivalent to Text_IO.Put_Line (File,
+Strings.Unbounded.To_String(Item));]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Put_Line
+   (Item : @key{in} Strings.Unbounded.Unbounded_String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00301-01]}
address@hidden,Text=[Equivalent to Text_IO.Put_Line
+(Strings.Unbounded.To_String(Item));]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Get_Line
+   (File : @key{in} File_Type)
+   @key{return} Strings.Unbounded.Unbounded_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00301-01]}
address@hidden,Text=[Returns
+Strings.Unbounded.To_Unbounded_String(Text_IO.Get_Line(File));]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Get_Line
+   @key{return} Strings.Unbounded.Unbounded_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00301-01]}
address@hidden,Text=[Returns
+Strings.Unbounded.To_Unbounded_String(Text_IO.Get_Line);]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Get_Line
+   (File : @key{in} File_Type; Item : @key{out} 
Strings.Unbounded.Unbounded_String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00301-01]}
address@hidden,Text=[Equivalent to Item := Get_Line (File);]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,KeepNext=[T],address@hidden Get_Line
+   (Item : @key{out} Strings.Unbounded.Unbounded_String);]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00301-01]}
address@hidden,Text=[Equivalent to Item := Get_Line;]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00301-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Package Text_IO.Unbounded_IO is new.]}
address@hidden
+
+
address@hidden,New=[Wide Text Input-Output and Wide Wide Text 
Input-Output],Old=[Wide Text Input-Output]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+The @Chg{Version=[2],New=[packages],Old=[package]} Wide_Text_IO
address@hidden,New=[and Wide_Wide_Text_IO provide],Old=[provides]} facilities
+for input and output in human-readable form. Each file is read or
+written sequentially, as a sequence of wide characters
address@hidden,New=[(or wide wide characters) ],Old=[]}grouped
+into lines, and as a sequence of lines grouped into pages.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01],ARef=[AI95-00301-01]}
address@hidden,address@hidden
+The specification of package Wide_Text_IO is the same as that for
+Text_IO, except that in each Get,
+Look_Ahead, Get_Immediate,
+Get_Line, Put, and Put_Line @Chg{Version=[2],New=[subprogram],Old=[procedure]},
+any occurrence of Character is replaced by Wide_Character, and any
+occurrence of String is replaced by address@hidden,New=[
address@hidden,address@hidden@!Text_IO]}
address@hidden,address@hidden@!Text_IO]}
+Nongeneric equivalents of Wide_Text_IO.Integer_IO
+and address@hidden are provided (as for Text_IO)
+for each predefined numeric type,
+with names such as address@hidden,
address@hidden@!Wide_Text_IO,
address@hidden,
address@hidden@!Wide_Text_IO.],Old=[]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01],ARef=[AI95-00301-01]}
address@hidden,New=[
address@hidden,address@hidden
+The specification of package Wide_Wide_Text_IO is the same as that for
+Text_IO, except that in each Get,
+Look_Ahead, Get_Immediate,
+Get_Line, Put, and Put_Line subprogram,
+any occurrence of Character is replaced by Wide_Wide_Character, and any
+occurrence of String is replaced by Wide_Wide_String.
address@hidden,address@hidden@!Text_IO]}
address@hidden,address@hidden@!Text_IO]}
+Nongeneric equivalents of Wide_Wide_Text_IO.Integer_IO
+and address@hidden@!Float_IO are provided (as for Text_IO)
+for each predefined numeric type,
+with names such as address@hidden@!Text_IO,
address@hidden@address@hidden,
address@hidden@!Text_IO,
address@hidden@address@hidden,
+Old=[
address@hidden,address@hidden@!Text_IO]}
address@hidden,address@hidden@!Text_IO]}
+Nongeneric equivalents of Wide_Text_IO.Integer_IO
+and address@hidden are provided (as for Text_IO)
+for each predefined numeric type,
+with names such as address@hidden,
address@hidden@!Wide_Text_IO,
address@hidden,
address@hidden@!Wide_Text_IO.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01],ARef=[AI95-00428-01]}
address@hidden,Kind=[AddedNormal],ARef=[AI05-0004-1],ARef=[AI05-0092-1]}
address@hidden,Text=[
address@hidden@!Text_IO],Child=[Bounded_IO]}
address@hidden@!Text_IO],Child=[Bounded_IO]}
+The specification of package address@hidden is the same as that
+for Text_IO.Bounded_IO, except that any occurrence of Bounded_String is
+replaced by @Chg{Version=[3],address@hidden@!String],address@hidden@!String]},
+and any occurrence of package Bounded is
+replaced by Wide_Bounded. The specification of package
address@hidden,address@hidden@!Bounded_IO],
address@hidden@!Bounded_IO]} is the same as that for
address@hidden, except that any occurrence of address@hidden is
+replaced by @Chg{Version=[3],address@hidden@!String],
address@hidden@!String]}, and any occurrence of package Bounded
+is replaced by address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[3],address@hidden@;package address@hidden refers
+  to both the package Ada.Strings.Bounded and the formal package
+  parameter named Bounded.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01],ARef=[AI95-00301-01]}
address@hidden,Kind=[AddedNormal],ARef=[AI05-0092-1]}
address@hidden,Text=[
address@hidden@!Text_IO],Child=[Unbounded_IO]}
address@hidden@!Text_IO],Child=[Unbounded_IO]}
+The specification of package address@hidden is the same as that
+for address@hidden, except that any occurrence of address@hidden is
+replaced by @Chg{Version=[3],address@hidden@!String],address@hidden@!String]},
+and any occurrence of package Unbounded is
+replaced by address@hidden The specification of package
address@hidden is the same as that for
+Text_IO.Unbounded_IO, except that any occurrence of Unbounded_String is
+replaced by @Chg{Version=[3],address@hidden@!String],
address@hidden@!String]}, and any occurrence of package Unbounded
+is replaced by address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Support for Wide_Character and Wide_String I/O is new in Ada 95.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Package Wide_Wide_Text_IO is new. Be glad it wasn't called
+  Double_Wide_Text_IO (for use in trailer parks) or Really_Wide_Text_IO.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00301-01]}
+  @ChgAdded{Version=[2],Text=[Packages
+  Wide_Text_IO.Wide_Unbounded_IO and
+  Wide_Wide_Text_IO.Wide_Wide_Unbounded_IO are also new.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00428-01]}
+  @ChgAdded{Version=[2],Text=[Packages
+  Wide_Text_IO.Wide_Bounded_IO and
+  Wide_Wide_Text_IO.Wide_Wide_Bounded_IO are new as well.]}
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0092-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction>: Corrected the names of
+  various entities in the above description. Since the previously named
+  entities don't exist and the intent is obvious, this is just considered
+  a presentation change.]}
address@hidden
+
+
address@hidden Input-Output}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
+The packages Streams.Stream_IO, Text_IO.Text_Streams, @Chg{Version=[2],
+New=[],Old=[and address@hidden,New=[, and
+Wide_Wide_Text_IO.Text_Streams],Old=[]} provide stream-oriented operations
+on files.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[Included package Wide_Wide_Text_IO.Text_Streams
+  in this description.]}
address@hidden
+
+
address@hidden Package Streams.Stream_IO}
+
address@hidden
address@hidden input-output}
address@hidden subprograms in the child package Streams.Stream_IO provide 
control
+over stream files. Access to a stream file is either sequential,
+via a call on Read or Write to transfer an array of stream elements,
+or positional (if supported by the implementation for the given file),
+by specifying a relative index for an element. Since a stream
+file can be converted to a Stream_Access value, calling stream-oriented
+attribute subprograms of different element types with the same
+Stream_Access value provides heterogeneous input-output.]
+See @RefSecNum{Streams} for a general discussion of streams.
address@hidden
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0055],ARef=[AI95-00026-01]}
address@hidden,Text=[The elements of a stream file are stream elements.
+If positioning is
+supported for the specified external file, a current index and current size
+are maintained for the file as described in @RefSecNum(Sequential and Direct 
Files).
+If positioning is not supported, a current index is not maintained, and the
+current size is implementation address@hidden(Current index),
+Sec=(of an open stream file)address@hidden(Current size),Sec=(of a stream 
file)}]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Current size for a stream file for which positioning is not 
supported.]}]}
+
address@hidden@;The library package Streams.Stream_IO has the following 
declaration:
address@hidden(example)
address@hidden,Kind=[Revised],ARef=[AI05-0283-1]}
address@hidden(with) 
Ada.IO_Exceptions;@ChildUnit{Parent=[Ada.Streams],address@hidden
address@hidden(package) Ada.Streams.Stream_IO @key(is)@Chg{Version=[3],New=[
+    @key(pragma) Preelaborate(Stream_IO);],Old=[]}
+
+    @key[type] @AdaTypeDefn{Stream_Access} @key[is] @key[access] @key[all] 
Root_Stream_Type'Class;
+
address@hidden,Kind=[Revised],ARef=[AI12-0102-1]}
+    @key(type) @AdaTypeDefn{File_Type} @key(is) @key(limited) 
@key(private);@Chg{Version=[4],New=[
+    @key(pragma) Preelaborable_Initialization(File_Type);],Old=[]}
+
+    @key(type) @AdaTypeDefn{File_Mode} @key(is) (In_File, Out_File, 
Append_File);
+
+    @key[type]    @AdaTypeDefn{Count}          @key[is] @key[range] 0 .. 
@RI[implementation-defined];
+    @key[subtype] @AdaSubtypeDefn{Name=[Positive_Count],Of=[Count]} @key[is] 
Count @key[range] 1 .. Count'Last;
+      -- @RI(Index into file, in stream elements.)
+
+    @key(procedure) @AdaSubDefn{Create} (File : @key(in) @key(out) File_Type;
+                      Mode : @key(in) File_Mode := Out_File;
+                      Name : @key(in) String    := "";
+                      Form : @key(in) String    := "");
+
+    @key(procedure) @AdaSubDefn{Open} (File : @key(in) @key(out) File_Type;
+                    Mode : @key(in) File_Mode;
+                    Name : @key(in) String;
+                    Form : @key(in) String := "");
+
+    @key(procedure) @AdaSubDefn{Close}  (File : @key(in) @key(out) File_Type);
+    @key(procedure) @AdaSubDefn{Delete} (File : @key(in) @key(out) File_Type);
+    @key(procedure) @AdaSubDefn{Reset}  (File : @key(in) @key(out) File_Type; 
Mode : @key(in) File_Mode);
+    @key(procedure) @AdaSubDefn{Reset}  (File : @key(in) @key(out) File_Type);
+
+    @key(function) @AdaSubDefn{Mode} (File : @key(in) File_Type) @key(return) 
File_Mode;
+    @key(function) @AdaSubDefn{Name} (File : @key(in) File_Type) @key(return) 
String;
+    @key(function) @AdaSubDefn{Form} (File : @key(in) File_Type) @key(return) 
String;
+
+    @key(function) @AdaSubDefn{Is_Open}     (File : @key(in) File_Type) 
@key(return) Boolean;
+    @key(function) @AdaSubDefn{End_Of_File} (File : @key(in) File_Type) 
@key(return) Boolean;
+
+    @key(function) @AdaSubDefn{Stream} (File : @key(in) File_Type) 
@key(return) Stream_Access;
+        -- @RI(Return stream access for use with T'Input and T'Output)
+
address@hidden, Kind=[Deleted]}
address@hidden,Text=<@ @;@comment{Empty paragraph to hang junk paragraph number 
from original RM}>]
+
+    -- @RI(Read array of stream elements from file)
+    @key(procedure) @AdaSubDefn{Read} (File : @key(in)  File_Type;
+                    Item : @key(out) Stream_Element_Array;
+                    Last : @key(out) Stream_Element_Offset;
+                    From : @key(in)  Positive_Count);
+
+    @key(procedure) @AdaSubDefn{Read} (File : @key(in)  File_Type;
+                    Item : @key(out) Stream_Element_Array;
+                    Last : @key(out) Stream_Element_Offset);
+
address@hidden, Kind=[Deleted]}
address@hidden,Text=<@ @;@comment{Empty paragraph to hang junk paragraph number 
from original RM}>]
+
+    -- @RI(Write array of stream elements into file)
+    @key(procedure) @AdaSubDefn{Write} (File : @key(in) File_Type;
+                     Item : @key(in) Stream_Element_Array;
+                     To   : @key(in) Positive_Count);
+
+    @key(procedure) @AdaSubDefn{Write} (File : @key(in) File_Type;
+                     Item : @key(in) Stream_Element_Array);
+
address@hidden, Kind=[Deleted]}
address@hidden,Text=<@ @;@comment{Empty paragraph to hang junk paragraph number 
from original RM}>]
+
+    -- @RI(Operations on position within file)
+
+    @key[procedure] @AdaSubDefn{Set_Index}(File : @key[in] File_Type; To : 
@key[in] Positive_Count);
+
+    @key[function] @AdaSubDefn{Index}(File : @key[in] File_Type) @key[return] 
Positive_Count;
+    @key[function] @AdaSubDefn{Size} (File : @key[in] File_Type) @key[return] 
Count;
+
+    @key(procedure) @AdaSubDefn{Set_Mode}(File : @key(in) @key(out) File_Type; 
Mode : @key(in) File_Mode);
+
address@hidden,Kind=[Revised],Ref=[8652/0051],ARef=[AI95-00057-01]}
+    @key(procedure) @AdaSubDefn{Flush}(File : @key(in) 
@Chg{New=[],address@hidden(out) ]}File_Type);
+
+
+    -- @RI(exceptions)
+    @AdaExcDefn{Status_Error} : @key(exception) @key(renames) 
IO_Exceptions.Status_Error;
+    @AdaExcDefn{Mode_Error}   : @key(exception) @key(renames) 
IO_Exceptions.Mode_Error;
+    @AdaExcDefn{Name_Error}   : @key(exception) @key(renames) 
IO_Exceptions.Name_Error;
+    @AdaExcDefn{Use_Error}    : @key(exception) @key(renames) 
IO_Exceptions.Use_Error;
+    @AdaExcDefn{Device_Error} : @key(exception) @key(renames) 
IO_Exceptions.Device_Error;
+    @AdaExcDefn{End_Error}    : @key(exception) @key(renames) 
IO_Exceptions.End_Error;
+    @AdaExcDefn{Data_Error}   : @key(exception) @key(renames) 
IO_Exceptions.Data_Error;
+
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden(end) Ada.Streams.Stream_IO;
address@hidden(example)
+
address@hidden,Kind=[Added],ARef=[AI95-00360-01]}
address@hidden,Text=[The type File_Type
+needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization}).]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00283-01]}
address@hidden,Kind=[Revised],ARef=[AI12-0130-1]}
+The subprograms @Chg{Version=[2],New=[given in subclause
address@hidden(File Management) for the control of external files 
(],Old=[]}Create,
+Open, Close, Delete, Reset, Mode, Name,
+Form,@Chg{Version=[2],address@hidden,New=[],Old=[ and]}],Old=[]}
address@hidden,address@hidden,New=[, and Flush],Old=[]})
+are available for stream files],
+Old=[, and End_of_File have the same effect as the corresponding
+subprograms in Sequential_IO (see @RefSecNum(File Management))]}.
+
address@hidden,Kind=[Added],ARef=[AI95-00283-01]}
address@hidden,Type=[Leading],Text=[The End_Of_File function:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[Propagates Mode_Error if the mode of the file
+is not In_File;]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0264-1]}
address@hidden,Text=[If positioning is supported for the given external
+file, the function returns True if the current index exceeds the size of the
+external file; address@hidden,New=[,],Old=[]}
+it returns False;]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0264-1]}
address@hidden,Text=[If positioning is not supported for the given
+external file, the function returns True if no more elements can be read from
+the given file; address@hidden,New=[,],Old=[]}
+it returns False.]}
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0055],ARef=[AI95-00026-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00085-01]}
address@hidden,Text=[The Set_Mode
+procedure @Chg{Version=[2],New=[sets],Old=[changes]} the mode of the
+file. If the new mode is Append_File, the file is positioned to its end;
+otherwise, the position in the file is unchanged.]}
+
address@hidden,Kind=[Added],Ref=[8652/0055],ARef=[AI95-00026-01]}
address@hidden,Kind=[DeletedAdded],ARef=[AI12-0130-1]}
address@hidden,address@hidden,New=[],Old=[The Flush procedure
+synchronizes the external file with the internal file (by flushing any internal
+buffers) without closing the file or changing the position. Mode_Error is
+propagated if the mode of the file is In_File.]}]}
+
address@hidden,Kind=[Revised],Ref=[8652/0056],ARef=[AI95-00001-01]}
+The Stream function returns a Stream_Access result from a File_Type
+object, thus allowing the stream-oriented attributes Read, Write,
+Input, and Output to be used on the same file for multiple types.
address@hidden propagates Status_Error if File is not open.],Old=[]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00256-01]}
+The procedures Read and Write are equivalent to the corresponding operations
+in the package Streams. Read propagates Mode_Error if the mode of File is
+not In_File. Write propagates Mode_Error if the mode of File is not
+Out_File or Append_File. The Read procedure with a Positive_Count
+parameter starts reading at the specified index.
+The Write procedure with a Positive_Count
+parameter starts writing at the specified address@hidden,New=[ For
+a file that supports positioning, Read without a Positive_Count parameter
+starts reading at the current index, and Write without a Positive_Count
+parameter starts writing at the current index.],Old=[]}
+
address@hidden,Kind=[Added],Ref=[8652/0055],ARef=[AI95-00026-01]}
address@hidden,Text=[The Size function returns the current size of the
+file.]}
+
address@hidden,Kind=[Revised],Ref=[8652/0055],ARef=[AI95-00026-01]}
+The Index function returns the current @Chg{New=[],Old=[file address@hidden,
+Old=[, as a count (in stream elements) from the beginning of the file.
+The position of the first element in the file is 1]}.
address@hidden
address@hidden,Kind=[Deleted]}
address@hidden ramification is now part of the official wording.}
address@hidden,Text=[The notion of Index for Stream_IO is analogous
+to that of Index in Direct_IO, except that the former is measured in
+Stream_Element units, whereas the latter is in terms of Element_Type values.]}
address@hidden
+
+The Set_Index procedure sets the current index to the
+specified value.
+
address@hidden,Kind=[Added],Ref=[8652/0055],ARef=[AI95-00026-01]}
address@hidden,Type=[Leading],Text=[If positioning is supported for the
+external file, the current index is maintained as follows:]}
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0055],ARef=[AI95-00026-01]}
address@hidden,Text=[For Open and Create, if the Mode parameter is
+Append_File, the current index is set to the current size of the file plus one;
+otherwise, the current index is set to one.]}
+
address@hidden,Kind=[Added],Ref=[8652/0055],ARef=[AI95-00026-01]}
address@hidden,Text=[For Reset, if the Mode parameter is Append_File, or
+no Mode parameter is given and the current mode is Append_File, the current
+index is set to the current size of the file plus one; otherwise, the current
+index is set to one.]}
+
address@hidden,Kind=[Added],Ref=[8652/0055],ARef=[AI95-00026-01]}
address@hidden,Text=[For Set_Mode, if the new mode is Append_File, the
+current index is set to current size plus one; otherwise, the current index is
+unchanged.]}
+
address@hidden,Kind=[Added],Ref=[8652/0055],ARef=[AI95-00026-01]}
address@hidden,Text=[For Read and Write without a Positive_Count
+parameter, the current index is incremented by the number of stream elements
+read or written.]}
+
address@hidden,Kind=[Added],Ref=[8652/0055],ARef=[AI95-00026-01]}
address@hidden,Text=[For Read and Write with a Positive_Count parameter,
+the value of the current index is set to the value of the Positive_Count
+parameter plus the number of stream elements read or written.]}
address@hidden
+
+If positioning is not supported for the given file, then a call
+of Index or Set_Index propagates Use_Error. Similarly, a call of
+Read or Write with a Positive_Count parameter propagates Use_Error.
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00085-01]}
address@hidden,Text=[It is permissible for an implementation to
+implement mode Append_File using the Unix append mode (the
+O_APPEND bit). Such an implementation does not support positioning when
+the mode is Append_File, and therefore the operations listed above must
+raise Use_Error. This is acceptable as there is no requirement that any
+particular file support positioning; therefore it is acceptable that a
+file support positioning when opened with mode Out_File, and the same file
+not support positioning when opened with mode Append_File. But it is not
+acceptable for a file to support positioning (by allowing the above
+operations), but to do something other than the defined semantics (that is,
+always write at the end, even when explicitly commanded to write somewhere
+else).]}
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 34 
through 36
+were deleted.>address@hidden message should be
+deleted if the paragraphs are ever renumbered.}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],Ref=[8652/0055],ARef=[AI95-00026-01]}
address@hidden,Text=[The Size function returns the current size of
+the file, in stream elements.]}
+
address@hidden,Kind=[DeletedNoDelMsg],Ref=[8652/0055],ARef=[AI95-00026-01]}
address@hidden,Text=[The Set_Mode procedure changes the mode of the
+file. If the new mode is Append_File, the file is positioned to its end;
+otherwise, the position in the file is unchanged.]}
+
address@hidden,Kind=[DeletedNoDelMsg],Ref=[8652/0055],ARef=[AI95-00026-01]}
address@hidden,Text=[The Flush procedure synchronizes the external
+file with the internal file (by flushing any internal buffers) without closing
+the file or changing the position.
+Mode_Error is propagated if the mode of the file is In_File.]}
address@hidden
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0056],ARef=[AI95-00001-01]}
address@hidden,address@hidden(erroneous execution),Sec=(cause)}
+If the File_Type object passed to the Stream function is later
+closed or finalized, and the stream-oriented attributes are subsequently
+called (explicitly or implicitly) on the Stream_Access value returned by
+Stream, execution is erroneous. This rule applies even if the File_Type object
+was opened again after it had been closed.]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[These rules are analogous to the rule for the result of the
+Current_Input, Current_Output, and Current_Error functions. These rules make
+it possible to represent a value of (some descendant of) Root_Stream_Type which
+represents a file as an access value, with a null value corresponding to a
+closed file.]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00283-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] The description of the subprograms for
+  managing files was corrected so that they do not require truncation of the
+  external file @em a stream file is not a sequential file. An Ada 95
+  program that expects truncation of the stream file
+  @Chg{Version=[3],New=[might],Old=[may]} not work under Ada 2005.
+  Note that the Ada 95 standard was ambiguous on this point (the normative
+  wording seemed to require truncation, but didn't explain where; the
+  AARM notes seemed to expect behavior like Direct_IO), and implementations
+  varied widely. Therefore, as a practical matter, code that depends on
+  stream truncation @Chg{Version=[3],New=[might],Old=[may]} not work
+  even in Ada 95; deleting the file before
+  opening it provides truncation that works in both Ada 95 and Ada 2005.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00360-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @B[Amendment Correction:] Stream_IO.File_Type is defined to need 
finalization. If the
+  restriction No_Nested_Finalization (see @RefSecNum{Tasking Restrictions})
+  applies to the partition, and File_Type does not have a controlled part, it
+  will not be allowed in local objects in Ada 2005 whereas it would be allowed
+  in original Ada 95. Such code is not portable, as another Ada compiler
+  may have a controlled part in File_Type, and thus would be illegal.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0051],ARef=[AI95-00057-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the parameter 
mode
+  of Flush; otherwise it could not be used on Standard_Output.]}
+
+  
@ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0055],ARef=[AI95-00026-01],ARef=[AI95-00256-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Added wording to describe 
the
+  effects of the various operations on the current index. The Amendment adds
+  an explanation of the use of current index for Read and Write.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0056],ARef=[AI95-00001-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that Stream can
+  raise Status_Error, and clarified that using a Stream_Access whose file
+  has been closed is erroneous.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00085-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that Set_Mode can
+  be called with the current mode.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0283-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Package Ada.Streams.Stream_IO is now preelaborated, allowing it to be
+  used in more contexts (including in distributed systems). Note that it
+  is @i<not> a remote types package; File_Type objects cannot be
+  passed between partitions.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0102-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada 2012}
+  @b{Corrigendum:} Type Ada.Streams.Stream_IO.File_Type now has
+  preelaborable initialization. This allows declaring library-level
+  file objects in preelaborable packages (an oversight from the
+  change above).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0130-1]}
+  @ChgAdded{Version=[4],address@hidden:} The definition of the Flush
+  procedure was moved to @RefSecNum{File Management}, so that it could be
+  shared by all of the I/O packages.]}
address@hidden
+
+
address@hidden Package Text_IO.Text_Streams}
address@hidden
+The package Text_IO.Text_Streams provides a function for treating
+a text file as a stream.
address@hidden
+
address@hidden
address@hidden@;The library package Text_IO.Text_Streams has the following 
declaration:
address@hidden
address@hidden Ada.Streams;@ChildUnit{Parent=[Ada.Text_IO],address@hidden
address@hidden Ada.Text_IO.Text_Streams @key[is]
+   @key[type] @AdaTypeDefn{Stream_Access} @key[is] @key[access] @key[all] 
Streams.Root_Stream_Type'Class;
+
+   @key[function] @AdaSubDefn{Stream} (File : @key[in] File_Type) @key[return] 
Stream_Access;
address@hidden Ada.Text_IO.Text_Streams;
address@hidden
+
+The Stream function has the same effect as the corresponding function
+in Streams.Stream_IO.
address@hidden
address@hidden
+The ability to obtain a stream for a text file allows Current_Input,
+Current_Output, and Current_Error to be processed with the functionality
+of streams, including the mixing of text and binary input-output,
+and the mixing of binary input-output for different types.
+
+Performing operations on the stream associated with a text file does not
+affect the column, line, or page counts.
address@hidden
+
+
address@hidden Package Wide_Text_IO.Text_Streams}
address@hidden
+The package Wide_Text_IO.Text_Streams provides a function for treating
+a wide text file as a stream.
address@hidden
+
address@hidden
address@hidden@;The library package Wide_Text_IO.Text_Streams
+has the following declaration:
address@hidden
address@hidden Ada.Streams;@address@hidden,address@hidden
address@hidden Ada.Wide_Text_IO.Text_Streams @key[is]
+   @key[type] @AdaTypeDefn{Stream_Access} @key[is] @key[access] @key[all] 
Streams.Root_Stream_Type'Class;
+
+   @key[function] @AdaSubDefn{Stream} (File : @key[in] File_Type) @key[return] 
Stream_Access;
address@hidden Ada.Wide_Text_IO.Text_Streams;
address@hidden
+
+The Stream function has the same effect as the corresponding function
+in Streams.Stream_IO.
address@hidden
+
+
address@hidden,Name=[The Package Wide_Wide_Text_IO.Text_Streams]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,Text=[The package Wide_Wide_Text_IO.Text_Streams provides
+a function for treating a wide wide text file as a stream.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,Type=[Leading],address@hidden@;The library package
+Wide_Wide_Text_IO.Text_Streams has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Streams;@address@hidden,address@hidden
address@hidden Ada.Wide_Wide_Text_IO.Text_Streams @key[is]
+   @key[type] @AdaTypeDefn{Stream_Access} @key[is] @key[access] @key[all] 
Streams.Root_Stream_Type'Class;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Stream} (File : @key[in] 
File_Type) @key[return] Stream_Access;
address@hidden Ada.Wide_Wide_Text_IO.Text_Streams;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,Text=[The Stream function has the same effect as the
+corresponding function in Streams.Stream_IO.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Package Wide_Wide_Text_IO.Text_Streams is new.]}
address@hidden
+
+
address@hidden in Input-Output}
address@hidden
+The package IO_Exceptions defines the exceptions needed by the
+predefined input-output packages.
address@hidden
+
address@hidden
address@hidden@;The library package IO_Exceptions has the following declaration:
address@hidden
address@hidden Ada.IO_Exceptions @address@hidden,Child=[IO_Exceptions]}
+   @key[pragma] Pure(IO_Exceptions);
+
+   @AdaExcDefn{Status_Error} : @key[exception];
+   @AdaExcDefn{Mode_Error}   : @key[exception];
+   @AdaExcDefn{Name_Error}   : @key[exception];
+   @AdaExcDefn{Use_Error}    : @key[exception];
+   @AdaExcDefn{Device_Error} : @key[exception];
+   @AdaExcDefn{End_Error}    : @key[exception];
+   @AdaExcDefn{Data_Error}   : @key[exception];
+   @AdaExcDefn{Layout_Error} : @key[exception];
+
address@hidden Ada.IO_Exceptions;
address@hidden
+
+If more than one error condition exists, the corresponding exception
+that appears earliest in the following list is the one that is propagated.
+
+The exception Status_Error is propagated by an attempt to operate upon a
+file that is not open, and by an attempt to open a file that is already
+open.
+
+The exception Mode_Error is propagated by an attempt to read from, or test
+for the end of, a file whose current mode is Out_File or Append_File, and
+also by an
+attempt to write to a file whose current mode is In_File. In the case
+of Text_IO, the exception Mode_Error is also propagated by specifying a file
+whose current mode is Out_File or Append_File in a call of Set_Input, 
Skip_Line,
+End_Of_Line, Skip_Page, or End_Of_Page; and by specifying a file whose
+current mode is In_File in a call of Set_Output, Set_Line_Length,
+Set_Page_Length, Line_Length, Page_Length, New_Line, or New_Page.
+
+The exception Name_Error is propagated by a call of Create or Open if the
+string given for the parameter Name does not allow the identification of
+an external file. For example, this exception is propagated if the string
+is improper, or, alternatively, if either none or more than one external
+file corresponds to the string.
+
+The exception Use_Error is propagated if an operation is attempted that is
+not possible for reasons that depend on characteristics of the external
+file. For example, this exception is propagated by the procedure Create,
+among other circumstances, if the given mode is Out_File but the form
+specifies an input only device, if the parameter Form specifies invalid
+access rights, or if an external file with the given name already exists
+and overwriting is not allowed.
+
+The exception Device_Error is propagated if an input-output operation cannot
+be completed because of a malfunction of the underlying system.
+
+The exception End_Error is propagated by an attempt to skip (read past) the
+end of a file.
+
+The exception Data_Error can be propagated by the
+procedure Read (or by the Read attribute) if the
+element read cannot be interpreted as a value of the required subtype.
+This exception is also propagated by a procedure Get (defined in the package
+Text_IO) if the input character sequence fails to satisfy the required
+syntax, or if the value input does not belong to the range of the
+required subtype.
+
+The exception Layout_Error is propagated (in text input-output) by Col,
+Line, or Page if the value returned exceeds Count'Last. The exception
+Layout_Error is also propagated on output by an attempt to set column or
+line numbers in excess of specified maximum line or page lengths,
+respectively (excluding the unbounded cases). It is also propagated by an
+attempt to Put too many characters to a string.
+
address@hidden,Kind=[Added],ARef=[AI05-0262-1]}
address@hidden,Text=[These exceptions are also propagated by various
+other language-defined packages and operations, see the definition of those
+entities for other reasons that these exceptions are propagated.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[3],Text=[This 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+  is based in Ada 95. Later versions of
+  Ada (starting with Technical Corrigendum 1) have added a number of additional
+  places and reasons that cause these exceptions. In particular, TC1 says that
+  stream attributes need to raise End_Error in some circumstances; Amendment 1
+  adds Ada.Directories and a number of new places and reasons that Name_Error 
and
+  Use_Error are raised. There are more. We don't want to try to update this 
text
+  (or even this note!) for every possible reason and place that might raise one
+  of these exceptions, so we add this blanket statement.]}
address@hidden
+
address@hidden
+
+
address@hidden
+The implementation shall document the conditions under which
+Name_Error, Use_Error and Device_Error are propagated.
address@hidden,Kind=[AddedNormal],address@hidden,Text=[
+The conditions under which Io_Exceptions.Name_Error, Io_Exceptions.Use_Error,
+and Io_Exceptions.Device_Error are propagated.]}]}
address@hidden
+
+
address@hidden
+If the associated check is too complex, an implementation need
+not propagate Data_Error as part of a procedure Read
+(or the Read attribute) if the value read cannot be interpreted as a value
+of the required subtype.
address@hidden
+An example where the implementation may choose not to
+perform the check is an enumeration type with a representation clause
+with @lquotes@;address@hidden@; in the range of internal address@hidden
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)address@hidden the element read
+by the procedure Read (or by the Read attribute)
+cannot be interpreted as a value of the required subtype,
+but this is not detected and Data_Error is not propagated,
+then the resulting value can be abnormal,
+and subsequent references to the value
+can lead to erroneous execution,
+as explained in @RefSecNum{Data Validity}.
address@hidden state of an object}
address@hidden state of an object}]
address@hidden
+
address@hidden Sharing}
+
address@hidden
address@hidden
address@hidden@;It is not specified by the language whether the same external 
file
+can be associated with more than one file object. If such sharing
+is supported by the implementation, the following effects are defined:
address@hidden
+Operations on one text file object do not affect the column,
+line, and page numbers of any other file object.
+
address@hidden,Kind=[Deleted],Ref=[8652/0057],ARef=[AI95-00050-01]}
address@hidden,Text=[Standard_Input and Standard_Output are associated
+with distinct external files, so operations on one of these files cannot affect
+operations on the other file. In particular, reading from
+Standard_Input does not affect the current page, line, and column
+numbers for Standard_Output, nor does writing to Standard_Output
+affect the current page, line, and column numbers for Standard_Input.]}
+
+For direct and stream files, the current index is a
+property of each file object;
+an operation on one file object does not affect the current
+index of any other file object.
+
+For direct and stream files, the current size of the file is a property of
+the external file.
address@hidden
+
+All other effects are identical.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0057],ARef=[AI95-00050-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Removed the incorrect 
statement
+  that the external files associated with the standard input, standard output,
+  and standard error files are distinct.]}
address@hidden
diff --git a/packages/ada-ref-man/source_2012/pre_locales.mss 
b/packages/ada-ref-man/source_2012/pre_locales.mss
new file mode 100755
index 0000000..05a1f2e
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pre_locales.mss
@@ -0,0 +1,132 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/pre_locales.mss,v $ }
address@hidden $Revision: 1.9 $ $Date: 2015/04/03 04:12:42 $ $Author: randy $ }
address@hidden(predefenviron, Root="ada.mss")
+
address@hidden: 2015/04/03 04:12:42 $}
+
address@hidden,Name=[The Package Locales]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0127-2],ARef=[AI05-0248-1]}
address@hidden,Text=[A @address@hidden identifies a geopolitical
+place or region and its associated language, which can be used to determine
+other internationalization-related characteristics.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0127-2]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library package
+Locales has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Locales @address@hidden,Child=[Locales]}
+   @key{pragma} Preelaborate(Locales);
+   @key{pragma} Remote_Types(Locales);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0037-1]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Language_Code} @key[is 
@Chg{Version=[4],New=[new],Old=[array]}] @Chg{Version=[4],New=[String 
],Old=[]}(1 .. 3)@Chg{Version=[4],New=[
+      @key[with] Dynamic_Predicate =>
+         (@key[for all] E @key[of] Language_Code => E @key[in]],Old=[ @key[of] 
Character @key[range]]} 'a' .. 'z'@Chg{Version=[4],New=[)],Old=[]};
+   @key[type] @AdaTypeDefn{Country_Code} @key[is 
@Chg{Version=[4],New=[new],Old=[array]}] @Chg{Version=[4],New=[String 
],Old=[]}(1 .. 2)@Chg{Version=[4],New=[
+      @key[with] Dynamic_Predicate =>
+         (@key[for all] E @key[of] Country_Code  => E @key[in]],Old=[ @key[of] 
Character @key[range]]} 'A' .. 'Z'@Chg{Version=[4],New=[)],Old=[]};]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0037-1]}
+  @ChgAdded{Version=[4],Text=[These types are derived from type
+  String so that they can easily be converted to or from type String. That's
+  important if one of these values needs to be input or displayed (via Text_IO,
+  perhaps). We use the predicate to ensure that only possible component values
+  are used. Ada does not allow converting between unrelated types with
+  components that don't statically match, so we cannot declare new types with
+  constrained components if we want conversions to or from type String.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{Language_Unknown} : @key[constant] 
Language_Code := "und";
+   @AdaObjDefn{Country_Unknown} : @key[constant] Country_Code := "ZZ";]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Language} @key[return] 
Language_Code;
+   @key[function] @AdaSubDefn{Country} @key[return] Country_Code;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Locales;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0127-2],ARef=[AI05-0233-1]}
address@hidden,Text=[The @i{active address@hidden
address@hidden,Sec=[active]} is the locale associated with the
+partition of the current task.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0233-1]}
+  @ChgAdded{Version=[3],Text=[Some environments define both a system locale and
+  the locale of the current user. For such environments, the active locale is
+  that of current user if any; otherwise (as in a partition running on a server
+  without a user), the system locale should be used.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0127-2]}
address@hidden,Text=[Language_Code is a lower-case string representation
+of an ISO 639-3 alpha-3 code that identifies a language.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Some common language codes are: "eng" @en 
English;
+  "fra" @en French; "deu" @en German; "zho" @en Chinese. These are the same
+  codes as used by POSIX systems. We considered including
+  constants for the most common languages, but that was rejected as the
+  likely source of continual arguments about the constant names and which
+  languages are important enough to include.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0127-2]}
address@hidden,Text=[Country_Code is an upper-case string representation
+of an ISO 3166-1 alpha-2 code that identifies a country.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Some common country codes are: "CA" @en Canada;
+  "FR" @en France; "DE" @en Germany; "IT" @en Italy; "ES" @en Spain;
+  "GB" @en United Kingdom; "US" @en United States. These are the same codes
+  as used by POSIX systems. We didn't include any
+  country constants for the same reasons that we didn't include any language
+  constants.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0127-2],ARef=[AI05-0248-1]}
address@hidden,Text=[Function Language returns the code of the language
+associated with the active locale. If the Language_Code associated with the
+active locale cannot be determined from the environment, then Language returns
+Language_Unknown.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0127-2],ARef=[AI05-0248-1]}
address@hidden,Text=[Function Country returns the code of the country
+associated with the active locale. If the Country_Code associated with the
+active locale cannot be determined from the environment, then Country returns
+Country_Unknown.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0127-2],ARef=[AI05-0233-1]}
address@hidden,address@hidden to Ada 2005}
+Package Locales is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0037-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  Types Language_Code and Country_Code are defined with predicates rather than
+  constrained components so that they can be converted to/from type String.
+  This changes the exception raised from Constraint_Error to Assertion_Error
+  if an assignment is attempted with an incorrect value. This could only
+  matter if there is a handler specifically for Constraint_Error surrounding
+  this assignment; as this exception raise is certainly caused by a bug
+  (why would anyone want to use invalid language or country codes?), such a
+  handler seems very unlikely. (In addition, this is a new Ada 2012 package,
+  so there is not likely to be a lot of code using it.)]}
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/pre_math.mss 
b/packages/ada-ref-man/source_2012/pre_math.mss
new file mode 100755
index 0000000..8df5a1c
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pre_math.mss
@@ -0,0 +1,927 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/pre_math.mss,v $ }
address@hidden $Revision: 1.43 $ $Date: 2012/02/19 01:58:37 $ $Author: randy $ }
address@hidden(predefmath, Root="ada.mss")
+
address@hidden: 2012/02/19 01:58:37 $}
+
address@hidden Numerics Packages}
+
address@hidden
+The library package Numerics is the parent of several child units that provide
+facilities for mathematical computation. One child, the generic package
+Generic_Elementary_Functions, is defined in @RefSecNum{Elementary Functions},
+together with nongeneric equivalents;
+two others,
+the package Float_Random and the generic package Discrete_Random,
+are defined in @RefSecNum{Random Number Generation}.
+Additional (optional)
+children are defined in @RefSec{Numerics}.
address@hidden
+
address@hidden
address@hidden, Kind=[Deleted]}
address@hidden,Text=<@ @;@comment{Empty paragraph to hang junk paragraph number 
from original RM}>]
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00388-01]}
address@hidden Ada.Numerics @address@hidden,Child=[Numerics]}
+   @key[pragma] Pure(Numerics);
+   @AdaExcDefn{Argument_Error} : @key[exception];
+   @AdaObjDefn{Pi} : @key[constant] :=
+          
3.14159_26535_89793_23846_26433_83279_50288_41971_69399_37511;@Chg{Version=[2],New=[
+   @pi  : @key[constant] := Pi;],Old=[]}
+   @AdaObjDefn{e}  : @key[constant] :=
+          2.71828_18284_59045_23536_02874_71352_66249_77572_47093_69996;
address@hidden Ada.Numerics;
address@hidden
+
+The Argument_Error exception is raised by a subprogram in
+a child unit of Numerics
+to signal that one or more of the actual subprogram parameters are outside the
+domain of the corresponding mathematical function.
+
address@hidden
+
address@hidden
+The implementation may specify the values of Pi and e to a larger number of
+significant digits.
address@hidden
+   51 digits seem more than adequate for all present computers; converted to
+   binary, the values given above are accurate to more than 160 bits.
+   Nevertheless, the permission allows implementations to accommodate
+   unforeseen hardware advances.
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Numerics and its children were not predefined in Ada 83.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00388-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The alternative declaration of @pi is new.]}
address@hidden
+
+
address@hidden Functions}
+
address@hidden
+Implementation-defined
+approximations to the mathematical functions known as the @lquotes@;elementary
address@hidden@; are provided by the subprograms in
address@hidden@address@hidden Nongeneric equivalents of this generic
+package for each of the predefined floating point types are also provided as
+children of Numerics.
address@hidden accuracy actually achieved by the elementary functions.}
address@hidden
+
address@hidden
address@hidden@;The generic library package
+Numerics.Generic_Elementary_Functions has the following declaration:
address@hidden
address@hidden
+   @key{type} Float_Type @key{is} @key{digits} <>;
address@hidden,address@hidden@!Functions]}
address@hidden Ada.Numerics.Generic_Elementary_Functions @key{is}
+   @key[pragma] Pure(Generic_Elementary_Functions);
+
+   @key{function} @AdaSubDefn{Sqrt}    (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Log}     (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Log}     (X, Base     : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Exp}     (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} "**"    (Left, Right : Float_Type'Base) @key{return} 
Float_Type'Base;
+
+   @key{function} @AdaSubDefn{Sin}     (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Sin}     (X, Cycle    : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Cos}     (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Cos}     (X, Cycle    : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Tan}     (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Tan}     (X, Cycle    : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Cot}     (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Cot}     (X, Cycle    : Float_Type'Base) 
@key{return} Float_Type'Base;
+
+   @key{function} @AdaSubDefn{Arcsin}  (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Arcsin}  (X, Cycle    : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Arccos}  (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Arccos}  (X, Cycle    : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Arctan}  (Y           : Float_Type'Base;
+                     X           : Float_Type'Base := 1.0)
+                                                    @key{return} 
Float_Type'Base;
+   @key{function} @AdaSubDefn{Arctan}  (Y           : Float_Type'Base;
+                     X           : Float_Type'Base := 1.0;
+                     Cycle       : Float_Type'Base) @key{return} 
Float_Type'Base;
+   @key{function} @AdaSubDefn{Arccot}  (X           : Float_Type'Base;
+                     Y           : Float_Type'Base := 1.0)
+                                                    @key{return} 
Float_Type'Base;
+   @key{function} @AdaSubDefn{Arccot}  (X           : Float_Type'Base;
+                     Y           : Float_Type'Base := 1.0;
+                     Cycle       : Float_Type'Base) @key{return} 
Float_Type'Base;
+
+   @key{function} @AdaSubDefn{Sinh}    (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Cosh}    (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Tanh}    (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Coth}    (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Arcsinh} (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Arccosh} (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Arctanh} (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+   @key{function} @AdaSubDefn{Arccoth} (X           : Float_Type'Base) 
@key{return} Float_Type'Base;
+
address@hidden Ada.Numerics.Generic_Elementary_Functions;
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0020],ARef=[AI95-00126-01]}
address@hidden,address@hidden
+The library package Numerics.Elementary_Functions
address@hidden declared pure and ],Old=[]}defines the same subprograms as
address@hidden@address@hidden,
+except that the predefined type Float is systematically substituted for
+Float_Type'Base throughout. Nongeneric equivalents of
address@hidden@address@hidden for each of the other predefined
+floating point types are defined similarly, with the names
address@hidden@address@hidden, address@hidden@address@hidden, etc.
address@hidden
+   The nongeneric equivalents are provided to allow the programmer to
+   construct simple mathematical applications without being required to
+   understand and use generics.
address@hidden
+
+The functions have their usual mathematical meanings. When the Base parameter
+is specified, the Log function computes the logarithm to the given base;
+otherwise, it computes the natural logarithm. When the Cycle parameter is
+specified, the parameter X of the forward trigonometric functions (Sin, Cos,
+Tan, and Cot) and the results of the inverse trigonometric functions (Arcsin,
+Arccos, Arctan, and Arccot) are measured in units such that a full cycle of
+revolution has the given value; otherwise, they are measured in radians.
+
address@hidden@;The computed results of the mathematically multivalued 
functions are
+rendered single-valued by the following conventions, which are meant to imply
+the principal branch:
address@hidden
+   The results of the Sqrt and Arccosh functions and that of the exponentiation
+   operator are nonnegative.
+
+   The result of the Arcsin function is in the quadrant containing the point
+   (1.0, @i[x]), where @i[x] is the value of the parameter X. This quadrant is
+   I or IV; thus, the range of the Arcsin function is approximately
+   @address@hidden/2.0 to @Pi/2.0
+   (@address@hidden/4.0 to @R[Cycle]/4.0,
+   if the parameter Cycle is specified).
+
+   The result of the Arccos function is in the quadrant containing the point
+   (@i{x}, 1.0), where @i[x] is the value of the parameter X. This quadrant is
+   I or II; thus, the Arccos function ranges from 0.0 to approximately
+   @Pi (@R[Cycle]/2.0, if the parameter Cycle is specified).
+
+   The results of the Arctan and Arccot functions are in the quadrant
+   containing the point (@i[x], @i[y]), where @i[x] and @i[y] are the values of
+   the parameters X and Y, respectively. This may be any quadrant (I through
+   IV) when the parameter X (resp., Y) of Arctan (resp., Arccot) is specified,
+   but it is restricted to quadrants I and IV (resp., I and II) when that
+   parameter is omitted. Thus, the range when that parameter is specified is
+   approximately @address@hidden to @Pi
+   (@address@hidden/2.0 to @R[Cycle]/2.0,
+   if the parameter Cycle is specified); when omitted, the range of Arctan
+   (resp., Arccot) is that of Arcsin (resp., Arccos), as given above. When the
+   point (@i[x], @i[y]) lies on the negative x-axis, the result approximates
+   @begin{Itemize}
+      @Pi (resp., @address@hidden) when the sign of the parameter Y is
+      positive (resp., negative), if Float_Type'Signed_Zeros is True;
+
+      @Pi, if Float_Type'Signed_Zeros is False.
+   @end{Itemize}
address@hidden
+
+(In the case of the inverse trigonometric functions, in which a result lying on
+or near one of the axes may not be exactly representable, the approximation
+inherent in computing the result may place it in an adjacent quadrant, close to
+but on the wrong side of the axis.)
address@hidden
+
address@hidden
address@hidden@;The exception Numerics.Argument_Error is raised, signaling a
+parameter value outside the domain of the corresponding mathematical function,
+in the following cases:
address@hidden
+   by any forward or inverse trigonometric function with specified cycle, when
+   the value of the parameter Cycle is zero or negative;
+
+   by the Log function with specified base, when the value of the parameter
+   Base is zero, one, or negative;
+
+   by the Sqrt and Log functions, when the value of the parameter X is
+   negative;
+
+   by the exponentiation operator, when the value of the left operand is
+   negative or when both operands have the value zero;
+
+   by the Arcsin, Arccos, and Arctanh functions, when the absolute value of the
+   parameter X exceeds one;
+
+   by the Arctan and Arccot functions, when the parameters X and Y both have
+   the value zero;
+
+   by the Arccosh function, when the value
+   of the parameter X is less than one; and
+
+   by the Arccoth function, when the absolute value
+   of the parameter X is less than one.
address@hidden
+
address@hidden@IndexCheck{Division_Check}
address@hidden,Sec=(raised by failure of run-time check)}
+The exception Constraint_Error is raised, signaling a pole of the mathematical
+function (analogous to dividing by zero), in the following cases, provided that
+Float_Type'Machine_Overflows is True:
address@hidden
+   by the Log, Cot, and Coth functions, when the value of the parameter X is
+   zero;
+
+   by the exponentiation operator, when the value of the left operand is zero
+   and the value of the exponent is negative;
+
+   by the Tan function with specified cycle, when the value of the parameter X
+   is an odd multiple of the quarter cycle;
+
+   by the Cot function with specified cycle, when the value of the parameter X
+   is zero or a multiple of the half cycle; and
+
+   by the Arctanh and Arccoth functions, when the absolute value of the
+   parameter X is one.
address@hidden
+
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden can also be raised
+when a finite result overflows
+(see @RefSecNum{Accuracy Requirements for the Elementary Functions}); this may
+occur for parameter values sufficiently @i{near} poles, and, in the case of
+some of the functions, for parameter values with sufficiently large
address@hidden When Float_Type'Machine_Overflows is False,
+the result at poles is unspecified.
address@hidden
+   The purpose of raising Constraint_Error (rather than
+   Numerics.Argument_Error) at the poles of a function, when
+   Float_Type'Machine_Overflows is True, is to provide continuous behavior as
+   the actual parameters of the function approach the pole and finally reach
+   it.
address@hidden
address@hidden
+   It is anticipated that an Ada binding to IEC 559:1989 will be developed
+   in the future. As part of such a binding, the Machine_Overflows attribute
+   of a conformant floating point type will be specified to yield False, which
+   will permit both the predefined arithmetic operations and implementations of
+   the elementary functions to deliver signed infinities (and set the overflow
+   flag defined by the binding) instead of raising Constraint_Error in overflow
+   situations, when traps are disabled. Similarly, it is appropriate for the
+   elementary functions to deliver signed infinities (and set the zero-divide
+   flag defined by the binding) instead of raising Constraint_Error at poles,
+   when traps are disabled. Finally, such a binding should also specify the
+   behavior of the elementary functions, when sensible, given parameters with
+   infinite values.
address@hidden
+
+When one parameter of a function with multiple parameters represents a pole and
+another is outside the function's domain, the latter takes precedence (i.e.,
+Numerics.Argument_Error is raised).
address@hidden
+
address@hidden
+In the implementation of Numerics.Generic_Elementary_Functions,
+the range of intermediate values allowed during the calculation
+of a final result shall not be affected by any
+range constraint of the subtype Float_Type.
address@hidden
+   Implementations of Numerics.Generic_Elementary_Functions written in Ada
+   should therefore avoid declaring local variables of subtype Float_Type; the
+   subtype Float_Type'Base should be used instead.
address@hidden
+
address@hidden@Defn2{Term=[prescribed result],
+Sec=[for the evaluation of an elementary function]}
+In the following cases, evaluation of an elementary function shall yield the
address@hidden result},
+provided that the preceding rules do not call for an exception to be
+raised:
address@hidden
+   When the parameter X has the value zero, the Sqrt, Sin, Arcsin, Tan, Sinh,
+   Arcsinh, Tanh, and Arctanh functions yield a result of zero, and the Exp,
+   Cos, and Cosh functions yield a result of one.
+
+   When the parameter X has the value one, the Sqrt function yields a result
+   of one, and the Log, Arccos, and Arccosh functions yield a result of zero.
+
+   When the parameter Y has the value zero and the parameter X has a positive
+   value, the Arctan and Arccot functions yield a result of zero.
+
+   The results of the Sin, Cos, Tan, and Cot functions with specified cycle are
+   exact when the mathematical result is zero; those of the first two are also
+   exact when the mathematical result is @PorM 1.0.
+
+   Exponentiation by a zero exponent yields the value one. Exponentiation by
+   a unit exponent yields the value of the left operand. Exponentiation of
+   the value one yields the value one. Exponentiation of the value zero
+   yields the value zero.
address@hidden
+
+Other accuracy requirements for the elementary functions, which apply only in
+implementations conforming to the Numerics Annex, and then only in the
address@hidden@;address@hidden@; mode defined there (see @RefSecNum{Numeric 
Performance Requirements}),
+are given in @RefSecNum{Accuracy Requirements for the Elementary Functions}.
+
address@hidden@;When Float_Type'Signed_Zeros is True, the sign of a zero result
+shall be as follows:
address@hidden
+   A prescribed zero result delivered
+   @i{at the origin} by one of the odd functions (Sin, Arcsin, Sinh,
+   Arcsinh, Tan, Arctan or Arccot as a function of Y when X is fixed and
+   positive, Tanh, and Arctanh) has the sign of the parameter X (Y, in the case
+   of Arctan or Arccot).
+
+   A prescribed zero result delivered by one of the odd functions @i{away from
+   the origin}, or by some other elementary function, has
+   an implementation-defined sign.
+   @ImplDef{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.}
+
+   @redundant[A zero result that is not a prescribed result
+   (i.e., one that results from
+   rounding or underflow) has the correct mathematical sign.]
+   @begin{Reason}
+      This is a consequence of the rules specified in IEC 559:1989 as they
+      apply to underflow situations with traps disabled.
+   @end{Reason}
address@hidden
address@hidden
+
address@hidden
+The nongeneric equivalent packages may, but need not, be actual
+instantiations of the generic package for the appropriate predefined type.
address@hidden
+
address@hidden
address@hidden@;The semantics of Numerics.Generic_Elementary_Functions differs 
from
+Generic_Elementary_Functions as defined in ISO/IEC DIS 11430 (for Ada 83)
+in the following ways:
address@hidden
+   The generic package is a child unit of the package defining the
+   Argument_Error exception.
+
+   DIS 11430 specified names for the nongeneric equivalents, if provided.
+   Here, those nongeneric equivalents are required.
+
+   Implementations are not allowed to impose an optional restriction that the
+   generic actual parameter associated with Float_Type be unconstrained.
+   (In view of the ability to declare variables of subtype Float_Type'Base in
+   implementations of Numerics.Generic_Elementary_Functions, this flexibility
+   is no longer needed.)
+
+   The sign of a prescribed zero result at the origin of the odd functions is
+   specified, when Float_Type'Signed_Zeros is True. This conforms with
+   recommendations of Kahan and other numerical analysts.
+
+   The dependence of Arctan and Arccot on the sign of a parameter value of zero
+   is tied to the value of Float_Type'Signed_Zeros.
+
+   Sqrt is prescribed to yield a result of one when its parameter has the
+   value one. This guarantee makes it easier to achieve certain prescribed
+   results of the complex elementary functions
+   (see @RefSec{Complex Elementary Functions}).
+
+   Conformance to accuracy requirements is conditional.
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0020],ARef=[AI95-00126-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Explicitly stated that the
+  nongeneric equivalents of Generic_Elementary_Functions are pure.]}
address@hidden
+
+
address@hidden Number Generation}
+
address@hidden
address@hidden for the generation of pseudo-random floating point numbers are
+provided in the package Numerics.Float_Random; the generic package
+Numerics.Discrete_Random provides similar facilities for the generation of
+pseudo-random integers and pseudo-random values of enumeration
+types.
address@hidden number}
+For brevity, pseudo-random values of any of these types are called @i{random
+numbers}.
+
+Some of the facilities provided are basic to all applications of random
+numbers. These include a limited private type each of whose objects serves as
+the generator of a (possibly distinct) sequence of random numbers; a function
+to obtain the @lquotes@;address@hidden@; random number from a given sequence 
of random numbers
+(that is, from its generator); and subprograms to initialize or reinitialize a
+given generator to a time-dependent state or a state denoted by a single
+integer.
+
+Other facilities are provided specifically for advanced applications. These
+include subprograms to save and restore the state of a given generator; a
+private type whose objects can be used to hold the saved state of a
+generator;
+and subprograms to obtain a string representation of a given generator state,
+or, given such a string representation, the corresponding state.]
address@hidden
+These facilities support a variety of requirements ranging from repeatable
+sequences (for debugging) to unique sequences in each execution of a program.
address@hidden
address@hidden
+
address@hidden
address@hidden@;The library package Numerics.Float_Random has the following 
declaration:
address@hidden
address@hidden Ada.Numerics.Float_Random @address@hidden,address@hidden
+
+   -- @RI{Basic facilities}
+
+   @key[type] @AdaTypeDefn{Generator} @key[is] @key[limited] @key[private];
+
+
+   @key[subtype] @AdaSubtypeDefn{Name=[Uniformly_Distributed],Of=[Float]} 
@key[is] Float @key[range] 0.0 .. 1.0;
+   @key[function] @AdaSubDefn{Random} (Gen : Generator) @key[return] 
Uniformly_Distributed;
+
+
+   @key[procedure] @AdaSubDefn{Reset} (Gen       : @key[in] Generator;
+                    Initiator : @key[in] Integer);
+   @key[procedure] @AdaSubDefn{Reset} (Gen       : @key[in] Generator);
+
+
+   -- @RI{Advanced facilities}
+
+   @key[type] @AdaTypeDefn{State} @key[is] @key[private];
+
+
+   @key[procedure] @AdaSubDefn{Save}  (Gen        : @key[in]  Generator;
+                    To_State   : @key[out] State);
+   @key[procedure] @AdaSubDefn{Reset} (Gen        : @key[in]  Generator;
+                    From_State : @key[in]  State);
+
+
+   @AdaObjDefn{Max_Image_Width} : @key[constant] := @RI{implementation-defined 
integer value};
+
+
+   @key[function] @AdaSubDefn{Image} (Of_State    : State)  @key[return] 
String;
+   @key[function] @AdaSubDefn{Value} (Coded_State : String) @key[return] State;
+
+
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden Ada.Numerics.Float_Random;
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00360-01]}
address@hidden,Text=[The type Generator
+needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization}).]}
+
+The generic library package Numerics.Discrete_Random has the following
+declaration:
address@hidden
address@hidden,address@hidden
address@hidden
+   @key[type] Result_Subtype @key[is] (<>);
address@hidden Ada.Numerics.Discrete_Random @key[is]
+
+   -- @RI{Basic facilities}
+
+   @key[type] @AdaTypeDefn{Generator} @key[is] @key[limited] @key[private];
+
+
+   @key[function] @AdaSubDefn{Random} (Gen : Generator) @key[return] 
Result_Subtype;
+
+
+   @key[procedure] @AdaSubDefn{Reset} (Gen       : @key[in] Generator;
+                    Initiator : @key[in] Integer);
+   @key[procedure] @AdaSubDefn{Reset} (Gen       : @key[in] Generator);
+
+
+   -- @RI{Advanced facilities}
+
+   @key[type] @AdaTypeDefn{State} @key[is] @key[private];
+
+
+   @key[procedure] @AdaSubDefn{Save}  (Gen        : @key[in]  Generator;
+                    To_State   : @key[out] State);
+   @key[procedure] @AdaSubDefn{Reset} (Gen        : @key[in]  Generator;
+                    From_State : @key[in]  State);
+
+
+   @AdaObjDefn{Max_Image_Width} : @key[constant] := @RI{implementation-defined 
integer value};
+
+
+   @key[function] @AdaSubDefn{Image} (Of_State    : State)  @key[return] 
String;
+   @key[function] @AdaSubDefn{Value} (Coded_State : String) @key[return] State;
+
+
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden Ada.Numerics.Discrete_Random;
address@hidden
address@hidden value of Numerics.Float_Random.Max_Image_Width.}
address@hidden value of Numerics.Discrete_Random.Max_Image_Width.}
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0097],ARef=[AI95-00115-01]}
address@hidden@;
+The following is a possible implementation of the private part of
address@hidden, Old=[each package]} (assuming the presence
+of @lquotes@;@key[with] Ada.Finalization;@rquotes@; as a context clause):
address@hidden
address@hidden State @key[is] ...;
address@hidden Access_State @key[is] @key[access] State;
address@hidden Generator @key[is] @key[new] Finalization.Limited_Controlled 
@key[with]
+   @key[record]
+      S : Access_State := @key[new] State'(...);
+   @key[end] @key[record];
address@hidden Finalize (G : @key[in] @key[out] Generator);
address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0097],ARef=[AI95-00115-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00344-01]}
address@hidden,address@hidden,New=[],
+Old=[Unfortunately, ]}Numerics.Discrete_Random.Generator 
@Chg{Version=[2],New=[also can],Old=[cannot]} be
+implemented this address@hidden,New=[],Old=[, as Numerics.Discrete_Random can 
be instantiated at any
+nesting depth. However, Generator could have a component of a controlled type,
+as long as that type is declared in some other (nongeneric) package. One
+possible solution would be to implement address@hidden@!Random in terms
+of address@hidden@!Random, using a component of 
address@hidden@!Random.Generator
+to implement address@hidden@address@hidden
+
+Clearly some level of indirection is required in the implementation of a
+Generator, since the parameter mode is @key(in) for all operations on a
+Generator. For this reason, Numerics.Float_Random and Numerics.Discrete_Random
+cannot be declared pure.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00360-01]}
address@hidden,Text=[The type Generator
+needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization})
+in every instantiation of Numerics.Discrete_Random.]}
+
+An object of the limited private type Generator is associated with a sequence
+of random numbers. Each generator has a hidden (internal) state, which the
+operations on generators use to determine the position in the associated
+sequence.
address@hidden
+All generators are implicitly initialized to an unspecified state
+that does not vary from one program execution to another;
+they may also be explicitly initialized, or reinitialized, to a time-dependent
+state, to a previously saved state, or to a state uniquely denoted by an
+integer value.
address@hidden
+The repeatability provided by the implicit initialization may be exploited for
+testing or debugging purposes.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0280-1]}
+An object of the private type State can be used to hold the internal state of a
+generator. Such objects are only needed if the application is designed to
+save and restore generator states or to examine or manufacture
address@hidden,New=[ The implicit initial value of type State
+corresponds to the implicit initial value of all generators.],Old=[]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0280-1]}
+  @ChgAdded{Version=[3],Text=[All generators are implicitly initialized to
+  the same unchanging value, and using Reset on a default initialized object
+  of type State will produce a generator with that same value.]}
address@hidden
+
address@hidden@;The operations on generators affect the state and therefore the 
future values
+of the associated sequence. The semantics of the operations on generators and
+states are defined below.
address@hidden
address@hidden
address@hidden Random (Gen : Generator) @key[return] Uniformly_Distributed;
address@hidden Random (Gen : Generator) @key[return] Result_Subtype;
address@hidden
address@hidden@;Obtains the @lquotes@;address@hidden@; random number from the 
given generator,
+relative to its current state, according to an implementation-defined 
algorithm.
+The result of the function in Numerics.Float_Random is delivered as a value of
+the subtype Uniformly_Distributed, which is a subtype of the predefined type
+Float having a range of
+0.0 .. 1.0.
+The result of the function in an
+instantiation of Numerics.Discrete_Random is delivered as a value of the
+generic formal subtype Result_Subtype.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,Text=[The
+algorithms for random number generation.]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[The algorithm is the subject of a @DocReqName@;,
+  so we don't separately summarize this implementation-defined item.]}
address@hidden
address@hidden
+   The requirement for a level of indirection in accessing the internal state
+   of a generator arises from the desire to make Random a function, rather than
+   a procedure.
address@hidden
+
address@hidden
address@hidden Reset (Gen       : @key[in] Generator;
+                 Initiator : @key[in] Integer);
address@hidden Reset (Gen       : @key[in] Generator);
address@hidden
address@hidden@PDefn{unspecified}
+Sets the state of the specified generator to one that is an unspecified
+function of the value of the parameter Initiator (or to a time-dependent state,
+if only a generator parameter is
+specified).
address@hidden Reset procedure],Sec=(of the random number generator)}
+The latter form of the procedure is known as the @i{time-dependent Reset
+procedure}.
address@hidden
+   The time-dependent Reset procedure can be implemented by mapping the current
+   time and date as determined by the system clock into a state, but other
+   implementations are possible. For example, a white-noise generator or
+   a radioactive source can be used to generate time-dependent states.
address@hidden
+
address@hidden
address@hidden Save  (Gen        : @key[in]  Generator;
+                 To_State   : @key[out] State);
address@hidden Reset (Gen        : @key[in]  Generator;
+                 From_State : @key[in]  State);
address@hidden
address@hidden@;Save obtains the current state of a generator. Reset gives a
+generator the specified state. A generator that is reset to a state previously
+obtained by invoking Save is restored to the state it had when Save was
+invoked.
+
address@hidden
address@hidden Image (Of_State    : State)  @key[return] String;
address@hidden Value (Coded_State : String) @key[return] State;
address@hidden
+Image provides a representation of a state coded (in an implementation-defined
+way) as a string whose length is bounded by the value of Max_Image_Width.
+Value is the inverse of Image: Value(Image(S)) = S for each state S that can be
+obtained from a generator by invoking Save.
address@hidden string representation of a random number generator's state.}
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+Instantiation of Numerics.Discrete_Random with a subtype having a null range
+raises Constraint_Error.
+
address@hidden,Kind=[Deleted],Ref=[8652/0050],ARef=[AI95-00089]}
address@hidden,address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+Invoking Value with a string that is not the image of any generator
+state raises Constraint_Error.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0050],ARef=[AI95-00089]}
address@hidden,Text=[It is a bounded error to invoke Value with a
+string that is not the image of any generator state.
address@hidden,Sec=(raised by failure of run-time check)}
address@hidden,Sec=(raised by failure of run-time check)}
+If the error is detected, Constraint_Error or
+Program_Error is raised. Otherwise, a call to Reset with the resulting state
+will produce a generator such that calls to Random with this generator will
+produce a sequence of values of the appropriate subtype, but which might not
+be random in character. That is, the sequence of values might not fulfill the
+implementation requirements of this subclause.]}
address@hidden
+
address@hidden
+A sufficiently long sequence of random numbers obtained by successive calls to
+Random is approximately uniformly distributed over the range of the result
+subtype.
+
+The Random function in an instantiation of Numerics.Discrete_Random is
+guaranteed to yield each value in its result subtype in a finite number of
+calls, provided that the number of such values does not exceed
+2 @+[15].
+
+Other performance requirements for the random number generator, which apply
+only in implementations conforming to the Numerics Annex, and then only in the
address@hidden@;address@hidden@; mode defined there (see @RefSecNum{Numeric 
Performance Requirements}),
+are given in @RefSecNum{Performance Requirements for Random Number Generation}.
address@hidden
+
address@hidden
+No one algorithm for random number generation is best for all applications. To
+enable the user to determine the suitability of the random number generators
+for the intended application, the implementation shall describe the algorithm
+used and shall give its period, if known exactly, or a lower bound on the
+period, if the exact period is unknown. Periods that are so long that the
+periodicity is unobservable in practice can be described in such terms, without
+giving a numerical bound.
address@hidden,Kind=[AddedNormal],address@hidden,Text=[The
+algorithm used for random number generation, including a description of its
+period.]}]}
+
+The implementation also shall document the minimum time interval between calls
+to the time-dependent Reset procedure that are guaranteed to initiate
+different sequences, and it shall document the nature of the strings that
+Value will accept without raising Constraint_Error.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,Text=[The
+minimum time interval between
+calls to the time-dependent Reset procedure that are guaranteed to initiate
+different random number sequences.]}]}
address@hidden,Kind=[AddedNormal],address@hidden,Text=[The
+minimum time interval between
+calls to the time-dependent Reset procedure that is guaranteed to initiate
+different random number sequences.]}]}
address@hidden
+
address@hidden
+Any storage associated with an object of type Generator should be
+reclaimed on exit from the scope of the object.
address@hidden,Kind=[Added],address@hidden,Text=[Any
+storage associated with an object of type Generator of the random
+number packages should be reclaimed on exit from the scope of the object.]}]}
address@hidden
+  A level of indirection is implicit in the semantics of the
+  operations, given that they all take parameters of mode @key(in).
+  This implies that the full type of Generator probably should be a controlled
+  type, with appropriate finalization to reclaim any heap-allocated storage.
address@hidden
+
+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.
address@hidden,Kind=[AddedNormal],address@hidden,Text=[Each
+value of Initiator passed to Reset for the random number packages should
+initiate a distinct sequence of random numbers, or, if that is not possible,
+be at least a rapidly varying function of the initiator value.]}]}
address@hidden
+
address@hidden
+If two or more tasks are to share the same generator, then the tasks have to
+synchronize their access to the generator as for any shared variable
+(see @RefSecNum(Shared Variables)).
+
+Within a given implementation, a repeatable random number sequence can be
+obtained by relying on the implicit initialization of generators or by
+explicitly initializing a generator with a repeatable initiator value.
+Different sequences of random numbers can be obtained from a given generator in
+different program executions by explicitly initializing the generator to a
+time-dependent state.
+
+A given implementation of the Random function in Numerics.Float_Random may or
+may not be capable of delivering the values 0.0 or 1.0. Portable applications
+should assume that these values, or values sufficiently close to them to behave
+indistinguishably from them, can occur. If a sequence of random integers from
+some fixed range is needed, the application should use the Random function in
+an appropriate instantiation of Numerics.Discrete_Random, rather than
+transforming the result of the Random function in Numerics.Float_Random.
+However, some applications with unusual requirements, such as for a sequence of
+random integers each drawn from a different range, will find it more convenient
+to transform the result of the floating point Random function. For
address@hidden @geq 1, the expression
address@hidden
+   Integer(Float(M) * Random(G)) mod M
address@hidden
+
address@hidden@;transforms the result of Random(G) to an integer uniformly 
distributed over the
+range 0 .. @address@hidden@;1; it is valid even if Random delivers 0.0 or 1.0.
+Each value of the result range is possible, provided that M is not too large.
+Exponentially distributed (floating point) random numbers with mean and
+standard deviation 1.0 can be obtained by the transformation
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+   -Log(Random(G) + Float'Model_Small)@Chg{Version=[2],New=[],Old=[)]}
address@hidden
+
address@hidden@;where Log comes from Numerics.Elementary_Functions
+(see @RefSecNum{Elementary Functions});
+in this expression, the addition of Float'Model_Small avoids the
+exception that would be raised were Log to be given the value zero, without
+affecting the result (in most implementations) when Random returns a nonzero
+value.
address@hidden
+
address@hidden
address@hidden@address@hidden of a program that plays a simulated dice game:}
address@hidden@Trailing
address@hidden Ada.Numerics.Discrete_Random;
address@hidden Dice_Game @address@hidden
+   @key[subtype] Die @key[is] Integer @key[range] 1 .. 6;
+   @key[subtype] Dice @key[is] Integer @key[range] 2*Die'First .. 2*Die'Last;
+   @key[package] Random_Die @key[is] @key[new] Ada.Numerics.Discrete_Random 
(Die);
+   @key[use] Random_Die;
+   G : Generator;
+   D : Dice;@Softpage
address@hidden@Softpage
+   Reset (G);  -- @RI{Start the generator in a unique state in each run}
+   @key[loop]
+      -- @RI{Roll a pair of dice; sum and process the results}
+      D := Random(G) + Random(G);
+      ...
+   @key[end] @key[loop];@Softpage
address@hidden Dice_Game;
address@hidden
+
address@hidden@address@hidden of a program that simulates coin tosses:}
address@hidden@Trailing
address@hidden Ada.Numerics.Discrete_Random;
address@hidden Flip_A_Coin @address@hidden
+   @key[type] Coin @key[is] (Heads, Tails);
+   @key[package] Random_Coin @key[is] @key[new] Ada.Numerics.Discrete_Random 
(Coin);
+   @key[use] Random_Coin;
+   G : Generator;@Softpage
address@hidden@Softpage
+   Reset (G);  -- @RI{Start the generator in a unique state in each run}
+   @key[loop]
+      -- @RI{Toss a coin and process the result}
+      @key[case] Random(G) @key[is]
+          @key[when] Heads =>
+             ...
+          @key[when] Tails =>
+             ...
+      @key[end] @key[case];
+   ...
+   @key[end] @key[loop];@Softpage
address@hidden Flip_A_Coin;
address@hidden
+
address@hidden@address@hidden of a parallel simulation of a physical system,
+with a separate generator of event probabilities in each task:}
address@hidden
address@hidden Ada.Numerics.Float_Random;
address@hidden Parallel_Simulation @address@hidden
+   @key[use] Ada.Numerics.Float_Random;
+   @key[task] @key[type] Worker @key[is]
+      @key[entry] Initialize_Generator (Initiator : @key[in] Integer);
+      ...
+   @key[end] Worker;
+   W : @key[array] (1 .. 10) @key[of] Worker;@Softpage
+   @key[task] @key[body] Worker @key[is]
+      G : Generator;
+      Probability_Of_Event : Uniformly_Distributed;
+   @address@hidden
+      @key[accept] Initialize_Generator (Initiator : @key[in] Integer) @key[do]
+         Reset (G, Initiator);
+      @key[end] Initialize_Generator;
+      @key[loop]
+         ...
+         Probability_Of_Event := Random(G);
+         ...
+      @key[end] @key[loop];
+   @key[end] Worker;@Softpage
address@hidden@Softpage
+   -- @RI{Initialize the generators in the Worker tasks to different states}
+   @key[for] I @key[in] W'Range @key[loop]
+      W(I).Initialize_Generator (I);
+   @key[end] @key[loop];
+   ... -- @RI{Wait for the Worker tasks to address@hidden
address@hidden Parallel_Simulation;
address@hidden
address@hidden
+
address@hidden
address@hidden on the last example:}
+Although each Worker task initializes its generator to a different state, those
+states will be the same in every execution of the program. The generator
+states can be initialized uniquely in each program execution by instantiating
+Ada.Numerics.Discrete_Random for the type Integer in the main procedure,
+resetting the generator obtained from that instance to a time-dependent state,
+and then using random integers obtained from that generator to initialize the
+generators in each Worker task.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00360-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] Type Generator in Numerics.Float_Random and in an
+  instance of Numerics.Discrete_Random is defined to need finalization. If the
+  restriction No_Nested_Finalization (see @RefSecNum{Tasking Restrictions})
+  applies to the partition, and Generator does not have a controlled part, it
+  will not be allowed in local objects in Ada 2005 whereas it would be allowed
+  in original Ada 95. Such code is not portable, as another Ada compiler may
+  have a controlled part in Generator, and thus would be illegal.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0050],ARef=[AI95-00089-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Made the passing of an 
incorrect
+  Image of a generator a bounded error, as it 
@Chg{Version=[3],New=[might],Old=[may]}
+  not be practical to check
+  for problems (if a generator consists of several related values).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0280-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Specified the implicit 
initial
+  value for (sub)type State. This was unspecified in Ada 95 and Ada 2005,
+  so a program depending on some other initial value is very unlikely
+  and certainly was not portable. An implementation can use default 
expressions,
+  aspect Default_Value, or aspect Default_Component_Value to keep the
+  representation of the type unchanged while meeting this new requirement.]}
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/pre_standard.mss 
b/packages/ada-ref-man/source_2012/pre_standard.mss
new file mode 100755
index 0000000..efab372
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pre_standard.mss
@@ -0,0 +1,497 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/pre_standard.mss,v $ }
address@hidden $Revision: 1.42 $ $Date: 2012/11/28 23:53:06 $ $Author: randy $ }
address@hidden(predefstandard, Root="ada.mss")
+
address@hidden: 2012/11/28 23:53:06 $}
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Package Standard}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} outlines
+the specification of the package Standard
+containing all predefined identifiers in the language.
address@hidden
+The corresponding package body is not specified by the language.
+
+The operators that are predefined for the types declared in the
+package Standard are given in comments since they are implicitly
+declared.
address@hidden,Sec=(pseudo-names of anonymous types)}
+Italics are used for pseudo-names of anonymous types (such
+as @i{root_real}) and for undefined information (such as
address@hidden).
address@hidden
+  All of the predefined operators are of convention Intrinsic.
address@hidden
+
address@hidden
+
address@hidden
address@hidden@;The library package Standard has the following declaration:
address@hidden names and characteristics of the numeric subtypes declared in
+the visible part of package Standard.}
address@hidden
address@hidden@key[package] Standard @key[is]
+   @key[pragma] Pure(Standard);
+
+   @key[type] @AdaTypeDefn{Boolean} @key[is] (False, True);
+
+
address@hidden   address@hidden The predefined relational operators for this 
type are as follows:}
+
address@hidden,Kind=[Revised],Ref=[8652/0028],ARef=[AI95-00145-01]}
+   -- @key[function] "="   (Left, Right : address@hidden'Base],Old=[]}) 
@key[return] Boolean;
+   -- @key[function] "/="  (Left, Right : address@hidden'Base],Old=[]}) 
@key[return] Boolean;
+   -- @key[function] "<"   (Left, Right : address@hidden'Base],Old=[]}) 
@key[return] Boolean;
+   -- @key[function] "<="  (Left, Right : address@hidden'Base],Old=[]}) 
@key[return] Boolean;
+   -- @key[function] ">"   (Left, Right : address@hidden'Base],Old=[]}) 
@key[return] Boolean;
+   -- @key[function] ">="  (Left, Right : address@hidden'Base],Old=[]}) 
@key[return] Boolean;
+
+
address@hidden   address@hidden The predefined logical operators and the 
predefined logical}
+   address@hidden negation operator are as follows:}
+
address@hidden,Kind=[Revised],Ref=[8652/0028],ARef=[AI95-00145-01]}
+   -- @key[function] "@key[and]" (Left, Right : address@hidden'Base],Old=[]}) 
@key[return] address@hidden'Base],Old=[]};
+   -- @key[function] "@key[or]"  (Left, Right : address@hidden'Base],Old=[]}) 
@key[return] address@hidden'Base],Old=[]};
+   -- @key[function] "@key[xor]" (Left, Right : address@hidden'Base],Old=[]}) 
@key[return] address@hidden'Base],Old=[]};
+
+
address@hidden,Kind=[Revised],Ref=[8652/0028],ARef=[AI95-00145-01]}
+   -- @key[function] "@key[not]" (Right : address@hidden'Base],Old=[]}) 
@key[return] address@hidden'Base],Old=[]};
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+   address@hidden The integer type root_integer @Chg{Version=[2],New=[and 
the],Old=[is predefined.]}}
+   address@hidden @Chg{Version=[2],New=[],Old=[The ]}corresponding universal 
type @Chg{Version=[2],New=[],Old=[is address@hidden,New=[ are 
predefined],Old=[]}.}
+
+
+   @key[type] @AdaTypeDefn{Integer} @key[is] @key{range} 
@RI{implementation-defined};
+
+
+   @key[subtype] @AdaSubtypeDefn{Name=[Natural],Of=[Integer]}  @key[is] 
Integer @key[range] 0 .. Integer'Last;
+   @key[subtype] @AdaSubtypeDefn{Name=[Positive],Of=[Integer]} @key[is] 
Integer @key[range] 1 .. Integer'Last;
+
+
address@hidden   address@hidden The predefined operators for type Integer are 
as follows:}
+
+   -- @key[function] "="  (Left, Right : Integer'Base) @key[return] Boolean;
+   -- @key[function] "/=" (Left, Right : Integer'Base) @key[return] Boolean;
+   -- @key[function] "<"  (Left, Right : Integer'Base) @key[return] Boolean;
+   -- @key[function] "<=" (Left, Right : Integer'Base) @key[return] Boolean;
+   -- @key[function] ">"  (Left, Right : Integer'Base) @key[return] Boolean;
+   -- @key[function] ">=" (Left, Right : Integer'Base) @key[return] Boolean;
+
+
+   -- @key[function] "+"   (Right : Integer'Base) @key[return] Integer'Base;
+   -- @key[function] "-"   (Right : Integer'Base) @key[return] Integer'Base;
+   -- @key[function] "@key[abs]" (Right : Integer'Base) @key[return] 
Integer'Base;
+
+
+   -- @key[function] "+"   (Left, Right : Integer'Base) @key[return] 
Integer'Base;
+   -- @key[function] "-"   (Left, Right : Integer'Base) @key[return] 
Integer'Base;
+   -- @key[function] "*"   (Left, Right : Integer'Base) @key[return] 
Integer'Base;
+   -- @key[function] "/"   (Left, Right : Integer'Base) @key[return] 
Integer'Base;
+   -- @key[function] "@key[rem]" (Left, Right : Integer'Base) @key[return] 
Integer'Base;
+   -- @key[function] "@key[mod]" (Left, Right : Integer'Base) @key[return] 
Integer'Base;
+
+
+   -- @key[function] "**"  (Left : Integer'Base; Right : Natural)
+   --                  @key[return] Integer'Base;
+
+
+   address@hidden The specification of each operator for the type}
+   address@hidden root_integer, or for any additional predefined integer}
+   address@hidden type, is obtained by replacing Integer by the name of the 
type}
+   address@hidden in the specification of the corresponding operator of the 
type}
+   address@hidden Integer. The right operand of the exponentiation operator}
+   address@hidden remains as subtype Natural.}
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+   address@hidden The floating point type root_real @Chg{Version=[2],New=[and 
the],Old=[is predefined.]}}
+   address@hidden @Chg{Version=[2],New=[],Old=[The ]}corresponding universal 
type @Chg{Version=[2],New=[],Old=[is address@hidden,New=[ are 
predefined],Old=[]}.}
+
+
+   @key[type] @AdaTypeDefn{Float} @key[is] @key{digits} 
@RI{implementation-defined};
+
+
address@hidden   address@hidden The predefined operators for this type are as 
follows:}
+
+   -- @key[function] "="   (Left, Right : Float) @key[return] Boolean;
+   -- @key[function] "/="  (Left, Right : Float) @key[return] Boolean;
+   -- @key[function] "<"   (Left, Right : Float) @key[return] Boolean;
+   -- @key[function] "<="  (Left, Right : Float) @key[return] Boolean;
+   -- @key[function] ">"   (Left, Right : Float) @key[return] Boolean;
+   -- @key[function] ">="  (Left, Right : Float) @key[return] Boolean;
+
+
+   -- @key[function] "+"   (Right : Float) @key[return] Float;
+   -- @key[function] "-"   (Right : Float) @key[return] Float;
+   -- @key[function] "@key[abs]" (Right : Float) @key[return] Float;
+
+
+   -- @key[function] "+"   (Left, Right : Float) @key[return] Float;
+   -- @key[function] "-"   (Left, Right : Float) @key[return] Float;
+   -- @key[function] "*"   (Left, Right : Float) @key[return] Float;
+   -- @key[function] "/"   (Left, Right : Float) @key[return] Float;
+
+
+   -- @key[function] "**"  (Left : Float; Right : Integer'Base) @key[return] 
Float;
+
+
+   address@hidden The specification of each operator for the type root_real, 
or for}
+   address@hidden any additional predefined floating point type, is obtained 
by}
+   address@hidden replacing Float by the name of the type in the specification 
of the}
+   address@hidden corresponding operator of the type Float.}
+
+
address@hidden   address@hidden In addition, the following operators are 
predefined for the root}
+   address@hidden numeric types:}
+
+   @key[function] "*" (Left : @RI{root_integer}; Right : @RI{root_real})
+     @key[return] @RI{root_real};
+
+
+   @key[function] "*" (Left : @RI{root_real};    Right : @RI{root_integer})
+     @key[return] @RI{root_real};
+
+
+   @key[function] "/" (Left : @RI{root_real};    Right : @RI{root_integer})
+     @key[return] @RI{root_real};
+
+
+   address@hidden The type universal_fixed is predefined.}
+   address@hidden The only multiplying operators defined between}
+   address@hidden fixed point types are}
+
+   @key[function] "*" (Left : @RI[universal_fixed]; Right : 
@RI[universal_fixed])
+     @key[return] @RI[universal_fixed];
+
+   @key[function] "/" (Left : @RI[universal_fixed]; Right : 
@RI[universal_fixed])
+     @key[return] @RI[universal_fixed];
+
address@hidden,Kind=[Added],ARef=[AI95-00230-01]}
address@hidden,Text=[   address@hidden The type universal_access is predefined.}
+   address@hidden The following equality operators are predefined:}]}
+
address@hidden,Kind=[Added],ARef=[AI95-00230-01]}
address@hidden,Text=[   @key[function] "="  (Left, Right: 
@RI[universal_access]) @key[return] Boolean;
+   @key[function] "/=" (Left, Right: @RI[universal_access]) @key[return] 
Boolean;]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00415-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0181-1],ARef=[AI05-0248-1]}
address@hidden()@tabset(P7, P14, P21, P28, P37, P44, P51, P58, P64)
address@hidden line}
+      address@hidden The declaration of type Character is based on the 
standard ISO 8859-1 character set.}
address@hidden line}
+      address@hidden There are no character literals corresponding to the 
positions for control characters.}
+      address@hidden They are indicated in italics in this definition. See 
@refsecnum[Character Types].}
address@hidden line]
+   @key[type] @AdaTypeDefn{Character} @key[is]
+     
(@RI[nul],@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden
 (16#00#) .. 7 (16#07#)}
+      
@RI[bs],@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden
 (16#08#) .. 15 (16#0F#)}
address@hidden line}
+      
@RI[dle],@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden
 (16#10#) .. 23 (16#17#)}
+      
@RI[can],@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden
 (16#18#) .. 31 (16#1F#)}
address@hidden line}
+      ' ',@\'!',@\'"',@\'#',@\'$',@\'%',@\'&',@\''',@address@hidden (16#20#) 
.. 39 (16#27#)}
+      '(',@\')',@\'*',@\'+',@\',',@\'-',@\'.',@\'/',@address@hidden (16#28#) 
.. 47 (16#2F#)}
address@hidden line}
+      '0',@\'1',@\'2',@\'3',@\'4',@\'5',@\'6',@\'7',@address@hidden (16#30#) 
.. 55 (16#37#)}
+      '8',@\'9',@\':',@\';',@\'<',@\'=',@\'>',@\'?',@address@hidden (16#38#) 
.. 63 (16#3F#)}
address@hidden line}
+      '@@',@\'A',@\'B',@\'C',@\'D',@\'E',@\'F',@\'G',@address@hidden (16#40#) 
.. 71 (16#47#)}
+      'H',@\'I',@\'J',@\'K',@\'L',@\'M',@\'N',@\'O',@address@hidden (16#48#) 
.. 79 (16#4F#)}
address@hidden line}
+      'P',@\'Q',@\'R',@\'S',@\'T',@\'U',@\'V',@\'W',@address@hidden (16#50#) 
.. 87 (16#57#)}
+      'X',@\'Y',@\'Z',@\'[',@\'\',@\']',@\'^',@\'_',@address@hidden (16#58#) 
.. 95 (16#5F#)}
address@hidden line}
+      '`',@\'a',@\'b',@\'c',@\'d',@\'e',@\'f',@\'g',@address@hidden (16#60#) 
.. 103 (16#67#)}
+      'h',@\'i',@\'j',@\'k',@\'l',@\'m',@\'n',@\'o',@address@hidden (16#68#) 
.. 111 (16#6F#)}
address@hidden line}
+      'p',@\'q',@\'r',@\'s',@\'t',@\'u',@\'v',@\'w',@address@hidden (16#70#) 
.. 119 (16#77#)}
+      'x',@\'y',@\'z',@\'{',@\'|',@\'}',@\'~',@address@hidden,@address@hidden 
(16#78#) .. 127 (16#7F#)}
address@hidden line}
+      
@RI[reserved_128],@address@hidden,@address@hidden,@address@hidden,@address@hidden@address@hidden
 (16#80#) .. 131 (16#83#)}
+      
@RI[reserved_132],@address@hidden,@address@hidden,@address@hidden,@address@hidden@address@hidden@RI{132
 (16#84#) .. 135 (16#87#)}
+      
@RI[hts],@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden
 (16#88#) .. 143 (16#8F#)}
address@hidden line}
+      
@RI[dcs],@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden,@address@hidden
 (16#90#) .. 151 (16#97#)}
+      
@RI[sos],@address@hidden,@address@hidden,@address@hidden,@address@hidden@address@hidden@RI{152
 (16#98#) .. 155 (16#9B#)}
+      
@RI[st],@address@hidden,@address@hidden,@address@hidden,@address@hidden@address@hidden@address@hidden
 (16#9C#) .. 159 (16#9F#)}
address@hidden line}
+      ' 
',@\'@latin1(161)',@\'@latin1(162)',@\'@latin1(163)',@\'@latin1(164)',@\'@latin1(165)',@\'@latin1(166)',@\'@latin1(167)',@address@hidden
 (16#A0#) .. 167 (16#A7#)}
+      
'@latin1(168)',@\'@latin1(169)',@\'@latin1(170)',@\'@latin1(171)',@Chg{Version=[3],address@hidden@address@hidden@address@hidden@RI{168
 (16#A8#) .. 171 (16#AB#)}
+      
@latin1(172)',@address@hidden,@\'@latin1(174)',@\'@latin1(175)',@address@hidden@address@hidden@RI{172
 (16#AC#) .. 175 
(16#AF#)}],address@hidden'@latin1(172)',@\'@latin1(173)',@\'@latin1(174)',@\'@latin1(175)',@address@hidden
 (16#A8#) .. 175 (16#AF#)}]}
address@hidden line}
+      
'@latin1(176)',@\'@latin1(177)',@\'@latin1(178)',@\'@latin1(179)',@\'@latin1(180)',@\'@latin1(181)',@\'@latin1(182)',@\'@latin1(183)',@address@hidden
 (16#B0#) .. 183 (16#B7#)}
+      
'@latin1(184)',@\'@latin1(185)',@\'@latin1(186)',@\'@latin1(187)',@\'@latin1(188)',@\'@latin1(189)',@\'@latin1(190)',@\'@latin1(191)',@address@hidden
 (16#B8#) .. 191 (16#BF#)}
address@hidden line}
+      
'@latin1(192)',@\'@latin1(193)',@\'@latin1(194)',@\'@latin1(195)',@\'@latin1(196)',@\'@latin1(197)',@\'@latin1(198)',@\'@latin1(199)',@address@hidden
 (16#C0#) .. 199 (16#C7#)}
+      
'@latin1(200)',@\'@latin1(201)',@\'@latin1(202)',@\'@latin1(203)',@\'@latin1(204)',@\'@latin1(205)',@\'@latin1(206)',@\'@latin1(207)',@address@hidden
 (16#C8#) .. 207 (16#CF#)}
address@hidden line}
+      
'@latin1(208)',@\'@latin1(209)',@\'@latin1(210)',@\'@latin1(211)',@\'@latin1(212)',@\'@latin1(213)',@\'@latin1(214)',@\'@latin1(215)',@address@hidden
 (16#D0#) .. 215 (16#D7#)}
+      
'@latin1(216)',@\'@latin1(217)',@\'@latin1(218)',@\'@latin1(219)',@\'@latin1(220)',@\'@latin1(221)',@\'@latin1(222)',@\'@latin1(223)',@address@hidden
 (16#D8#) .. 223 (16#DF#)}
address@hidden line}
+      
'@latin1(224)',@\'@latin1(225)',@\'@latin1(226)',@\'@latin1(227)',@\'@latin1(228)',@\'@latin1(229)',@\'@latin1(230)',@\'@latin1(231)',@address@hidden
 (16#E0#) .. 231 (16#E7#)}
+      
'@latin1(232)',@\'@latin1(233)',@\'@latin1(234)',@\'@latin1(235)',@\'@latin1(236)',@\'@latin1(237)',@\'@latin1(238)',@\'@latin1(239)',@address@hidden
 (16#E8#) .. 239 (16#EF#)}
address@hidden line}
+      
'@latin1(240)',@\'@latin1(241)',@\'@latin1(242)',@\'@latin1(243)',@\'@latin1(244)',@\'@latin1(245)',@\'@latin1(246)',@\'@latin1(247)',@address@hidden
 (16#F0#) .. 247 (16#F7#)}
+      
'@latin1(248)',@\'@latin1(249)',@\'@latin1(250)',@\'@latin1(251)',@\'@latin1(252)',@\'@latin1(253)',@\'@latin1(254)',@\'@latin1(255)'@Chg{Version=[2],New=[);],Old=[,@address@hidden
 (16#F8#) .. 255 (16#FF#)}
+
+
+   address@hidden The predefined operators for the type Character are the same 
as for}
+   address@hidden any enumeration type.}
address@hidden@;
+
address@hidden,Kind=[Added],address@hidden missing paragraph number here}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0266-1]}
address@hidden,New=[],address@hidden@;]}   address@hidden The declaration of 
type Wide_Character is based on the standard 
@Chg{Version=[2],New=[ISO/IEC],Old=[ISO]} 
address@hidden,New=[:@Chg{Version=[3],New=[2011],Old=[2003]}],Old=[]} BMP 
address@hidden,New=[],Old=[ set.]}}
+   address@hidden @Chg{Version=[2],New=[set. ],Old=[]}The first 256 positions 
have the same contents as type Character. See @refsecnum[Character types].}
address@hidden line]
+   @key[type] @AdaTypeDefn{Wide_Character} @key[is] (@RI[nul], @RI[soh] ... 
@address@hidden,New=[Hex_0000FFFE],Old=[FFFE]}], 
@address@hidden,New=[Hex_0000FFFF],Old=[FFFF]}]);
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0266-1]}
address@hidden,Text=[   address@hidden The declaration of type 
Wide_Wide_Character is based on the full]
+   address@hidden ISO/IEC 10646:@Chg{Version=[3],New=[2011],Old=[2003]} 
character set. The first 65536 positions have the]
+   address@hidden same contents as type Wide_Character. See 
@refsecnum[Character types].]
address@hidden line]
+   @key[type] @AdaTypeDefn{Wide_Wide_Character} @key[is] (@RI[nul], @RI[soh] 
... @RI[Hex_7FFFFFFE], @RI[Hex_7FFFFFFF]);
+   @key[for] Wide_Wide_Character'Size @key[use] 32;]}
+
address@hidden,address@hidden missing paragraph number here}
address@hidden,New=[],address@hidden@;]}   @key[package] @AdaPackDefn{ASCII} 
@key[is] ... @key[end] ASCII;  address@hidden; see @RefSecNum[ASCII]}
address@hidden, Sec=(package physically nested within the declaration of 
Standard)}
address@hidden line]
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   address@hidden Predefined string types:}
address@hidden line]
+   @key[type] @AdaTypeDefn{String} @key[is] @key[array](Positive @key[range] 
<>) @key[of] address@hidden,New=[
+      @key[with] Pack],Old=[;
+   @key[pragma] Pack(String)]};
+
address@hidden   address@hidden The predefined operators for this type are as 
follows:}
+
+   --     @key[function] "="  (Left, Right: String) @key[return] Boolean;
+   --     @key[function] "/=" (Left, Right: String) @key[return] 
Boolean;@Softpage
+   --     @key[function] "<"  (Left, Right: String) @key[return] Boolean;
+   --     @key[function] "<=" (Left, Right: String) @key[return] Boolean;
+   --     @key[function] ">"  (Left, Right: String) @key[return] Boolean;
+   --     @key[function] ">=" (Left, Right: String) @key[return] Boolean;
+
+
+   --     @key[function] "&" (Left: String;    Right: String)    @key[return] 
String;
+   --     @key[function] "&" (Left: Character; Right: String)    @key[return] 
String;
+   --     @key[function] "&" (Left: String;    Right: Character) @key[return] 
String;
+   --     @key[function] "&" (Left: Character; Right: Character) @key[return] 
String;
+
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+   @key[type] @AdaTypeDefn{Wide_String} @key[is] @key[array](Positive 
@key[range] <>) @key[of] address@hidden,New=[
+      @key[with] Pack],Old=[;
+   @key[pragma] Pack(Wide_String)]};
+
+   address@hidden The predefined operators for this type correspond to those 
for String.}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0229-1]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Wide_Wide_String} @key[is 
array] (Positive @key[range] <>)
+      @key[of] address@hidden,New=[
+         @key[with] Pack],Old=[;
+   @key[pragma] Pack (Wide_Wide_String)]};]}
+
address@hidden,Kind=[Added],ARef=[AI95-00285-01]}
address@hidden,Text=[   address@hidden The predefined operators for this type 
correspond to those for String.]]}
+
+
+   @key[type] @AdaTypeDefn{Duration} @key[is] @key[delta] 
@RI{implementation-defined} @key[range] @RI{implementation-defined};
+
+      address@hidden The predefined operators for the type Duration are the 
same as for}
+      address@hidden any fixed point type.}
+
+
address@hidden   address@hidden The predefined exceptions:}
+
+   @AdaExcDefn{Constraint_Error}: @key[exception];
+   @AdaExcDefn{Program_Error}   : @key[exception];
+   @AdaExcDefn{Storage_Error}   : @key[exception];
+   @AdaExcDefn{Tasking_Error}   : @key[exception];
+
address@hidden Standard;
address@hidden
+
+Standard has no private part.
address@hidden
+  This is important for portability. All library packages
+  are children of Standard, and if Standard had a private part then
+  it would be visible to all of them.
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
+In each of the types address@hidden,New=[,],Old=[ and]}
address@hidden,New=[, and Wide_Wide_Character],Old=[]},
+the character literals for the space character (position 32)
+and the non-breaking
+space character (position 160)
+correspond to different values. Unless
+indicated otherwise, each occurrence of
+the character literal
+' ' in this International Standard
+refers to the space character.
+Similarly, the character literals
+for hyphen (position 45)
+and soft hyphen (position 173) correspond to different values.
+Unless indicated otherwise, each occurrence of
+the character literal
+'@en@;' in this International Standard
+refers to the hyphen character.
address@hidden
+
address@hidden
address@hidden, Sec=(package_body of Standard)}
+Elaboration of the body of Standard has no effect.
address@hidden
+Note that the language does not define where
+this body appears in the environment @nt{declarative_part}
address@hidden see @RefSec{Program Structure and Compilation Issues}.
address@hidden
address@hidden
+
address@hidden
+ An implementation may provide additional predefined integer
+ types and additional predefined floating point types.
+  Not all of these types need have names.
address@hidden
+
+  An implementation may add representation items to package Standard, for
+  example to specify the internal codes of type Boolean,
+  or the Small of type Duration.
+
address@hidden
address@hidden
+
address@hidden
+If an implementation provides additional named predefined integer types,
+then the names should end with @lquotes@;address@hidden@; as in 
@lquotes@;address@hidden@;.
+If an implementation provides additional named predefined
+floating point types,
+then the names should end with @lquotes@;address@hidden@; as in 
@lquotes@;address@hidden@;.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If an implementation provides additional named predefined integer types,
+then the names should end with @lquotes@;address@hidden@;.
+If an implementation provides additional named predefined
+floating point types,
+then the names should end with @lquotes@;address@hidden@;.]}]}
address@hidden
+
address@hidden
+Certain aspects of the predefined entities cannot be completely
+described in the language itself. For example, although the
+enumeration type Boolean can be written showing the two enumeration
+literals False and True, the short-circuit control forms cannot be
+expressed in the language.
+
+As explained in @RefSec{Declarative Region}
+and @RefSec{The Compilation Process},
+the declarative region of the package Standard encloses every
+library unit and consequently the main subprogram;
+the declaration of every library unit is assumed to occur
+within this declarative region.
address@hidden
+are assumed to be ordered in such a way that there are no forward
+semantic dependences.
+However, as explained in @RefSec{Visibility}, the only library units that are
+visible within a given compilation unit are
+the library units named by all @nt{with_clause}s that
+apply to the given unit,
+and moreover, within the declarative region of a given library unit,
+that library unit itself.
+
+If all @nt{block_statement}s of a program are named, then the name
+of each program unit can always be written as an expanded name
+starting with Standard (unless Standard is itself hidden).
+The name of a library unit cannot be a homograph of a name (such as
+Integer) that is already declared in Standard.
+
+The exception Standard.Numeric_Error is defined in @RefSecNum{Numeric_Error}.
address@hidden
+The declaration of Natural needs to appear between the declaration of
+Integer and the (implicit) declaration of the "**" operator for Integer,
+because a formal parameter of "**" is of subtype Natural.
+This would be impossible in normal code, because the implicit
+declarations for a type occur immediately after the type declaration,
+with no possibility of intervening explicit declarations.
+But we're in Standard, and Standard is somewhat magic anyway.
+
+Using Natural as the subtype of the formal of "**" seems natural;
+it would be silly to have a textual rule about Constraint_Error being
+raised when there is a perfectly good subtype that means just that.
+Furthermore, by not using Integer for that formal, it helps remind the
+reader that the exponent remains Natural even when the left operand is
+replaced with the derivative of Integer.
+It doesn't logically imply that, but it's still useful as a reminder.
+
+In any case, declaring these general-purpose subtypes of Integer close
+to Integer seems more readable than declaring them much later.
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+Package Standard is declared to be pure.
address@hidden
+The introduction of the types Wide_Character and Wide_String is not
+an Ada 95 extension to Ada 83, since ISO WG9 has approved these as an
+authorized extension of the original Ada 83 standard that is part
+of that standard.
address@hidden
address@hidden
+
address@hidden
+Numeric_Error is made obsolescent.
+
+The declarations of Natural and Positive are moved to just after the
+declaration of Integer, so that "**" can refer to Natural without a
+forward reference.
+There's no real need to move Positive, too @em it just came along for
+the ride.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Types Wide_Wide_Character and Wide_Wide_String are new.]}
+  @begin{Discussion}
+    @ChgRef{Version=[2],Kind=[AddedNormal]}
+    @ChgAdded{Version=[2],Text=[The inconsistencies associated with these
+    types are documented in @RefSecNum{Character Types} and
+    @RefSecNum{String Types}.]}
+  @end{Discussion}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00230-01]}
+  @ChgAdded{Version=[2],Text=[Type @i<universal_access> and the equality
+  operations for it are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0028],ARef=[AI95-00145-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the parameter
+  type for the Boolean operators declared in Standard..]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0181-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Since soft_hyphen (position
+  173) is defined to be nongraphic, gave it a name.]}
+  @begin{Discussion}
+    @ChgRef{Version=[3],Kind=[AddedNormal]}
+    @ChgAdded{Version=[3],Text=[The inconsistencies associated with this
+    change are documented in @RefSecNum{Scalar Types}.]}
+  @end{Discussion}
address@hidden
diff --git a/packages/ada-ref-man/source_2012/pre_strings.mss 
b/packages/ada-ref-man/source_2012/pre_strings.mss
new file mode 100755
index 0000000..a0ab8e8
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/pre_strings.mss
@@ -0,0 +1,4052 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/pre_strings.mss,v $ }
address@hidden $Revision: 1.82 $ $Date: 2015/04/03 04:12:43 $ $Author: randy $ }
address@hidden(predefstrings, Root="ada.mss")
address@hidden: 2015/04/03 04:12:43 $}
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Handling}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause]}
+presents the specifications of the package Strings and
+several child packages, which provide facilities for dealing with
+ string data. Fixed-length,
+bounded-length, and unbounded-length strings are supported, for 
@Chg{Version=[2],New=[],Old=[both]}
address@hidden,New=[,],Old=[ and]} address@hidden,New=[,
+and Wide_Wide_String],Old=[]}.
+The string-handling subprograms include searches for pattern strings
+and for characters in program-specified sets,
+translation (via a character-to-character mapping), and transformation
+(replacing, inserting, overwriting, and deleting of substrings).
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden to Ada 83}
+This @Chg{Version=[3],New=[subclause],Old=[clause]}
+is new to Ada 95.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[Included Wide_Wide_String in this description;
+  the individual changes are documented as extensions as needed.]}
address@hidden
+
+
address@hidden Package Strings}
address@hidden
+The package Strings provides declarations
+common to the string handling packages.
address@hidden
+
address@hidden
address@hidden@;The library package Strings has the following declaration:
address@hidden
address@hidden,address@hidden Ada.Strings @key[is]
+   @key[pragma] Pure(Strings);
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
+   @AdaObjDefn{Space}      : @key[constant] Character      := ' ';
+   @AdaObjDefn{Wide_Space} : @key[constant] Wide_Character := ' 
';@Chg{Version=[2],New=[
+   @AdaObjDefn{Wide_Wide_Space} : @key[constant] Wide_Wide_Character := ' 
';],Old=[]}
+
+   @AdaExcDefn{Length_Error}, @AdaExcDefn{Pattern_Error}, 
@AdaExcDefn{Index_Error}, @AdaExcDefn{Translation_Error} : @key[exception];
+
+   @key[type] @AdaTypeDefn{Alignment}  @key[is] (Left, Right, Center);
+   @key[type] @AdaTypeDefn{Truncation} @key[is] (Left, Right, Error);
+   @key[type] @AdaTypeDefn{Membership} @key[is] (Inside, Outside);
+   @key[type] @AdaTypeDefn{Direction}  @key[is] (Forward, Backward);
+   @key[type] @AdaTypeDefn{Trim_End}   @key[is] (Left, Right, Both);
address@hidden Ada.Strings;
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  Constant Wide_Wide_Space is @Chg{Version=[3],New=[],Old=[newly ]}added
+  to Ada.Strings. If Ada.Strings is
+  referenced in a @nt{use_clause}, and an entity @i<E> with a
+  @nt{defining_identifier} of Wide_Wide_Space is defined in a package that is
+  also referenced in a @nt{use_clause}, the entity @i<E> may no longer be
+  use-visible, resulting in errors. This should be rare and is easily fixed if
+  it does occur.]}
address@hidden
+
+
+
address@hidden@Comment{Insert page break so printed Ada 95 w/ Corr RM looks 
better.}
address@hidden Package Strings.Maps}
address@hidden
+The package Strings.Maps defines the types, operations, and other
+entities needed for character sets and character-to-character mappings.
address@hidden
+
address@hidden
address@hidden@;The library package Strings.Maps has the following declaration:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00362-01]}
address@hidden,address@hidden Ada.Strings.Maps @key[is]
+   @key[pragma] @Chg{Version=[2],New=[Pure],Old=[Preelaborate]}(Maps);
+
address@hidden,Kind=[Revised],ARef=[AI95-00161-01]}
+   address@hidden Representation for a set of character values:}
+   @key[type] @AdaTypeDefn{Character_Set} @key[is] 
@key[private];@Chg{Version=[2],New=[
+   @key[pragma] Preelaborable_Initialization(Character_Set);],Old=[]}
+
+   @AdaObjDefn{Null_Set} : @key[constant] Character_Set;
+
+   @key[type] @AdaTypeDefn{Character_Range} @key[is]
+     @Key[record]
+        Low  : Character;
+        High : Character;
+     @key[end] @key[record];
+   -- @Examcom[Represents Character range Low..High]
+
+   @key[type] @AdaTypeDefn{Character_Ranges} @key[is] @key[array] (Positive 
@key[range] <>) @key[of] Character_Range;
+
+   @key[function] @AdaSubDefn{To_Set}    (Ranges : @key[in] 
Character_Ranges)@key[return] Character_Set;
+
+   @key[function] @AdaSubDefn{To_Set}    (Span   : @key[in] 
Character_Range)@key[return] Character_Set;
+
+   @key[function] @AdaSubDefn{To_Ranges} (Set    : @key[in] Character_Set)  
@key[return] Character_Ranges;
+
+   @key[function] "="   (Left, Right : @key[in] Character_Set) @key[return] 
Boolean;
+
+   @key[function] "@key[not]" (Right : @key[in] Character_Set)       
@key[return] Character_Set;
+   @key[function] "@key[and]" (Left, Right : @key[in] Character_Set) 
@key[return] Character_Set;
+   @key[function] "@key[or]"  (Left, Right : @key[in] Character_Set) 
@key[return] Character_Set;
+   @key[function] "@key[xor]" (Left, Right : @key[in] Character_Set) 
@key[return] Character_Set;
+   @key[function] "-"   (Left, Right : @key[in] Character_Set) @key[return] 
Character_Set;
+
+   @key[function] @AdaSubDefn{Is_In} (Element : @key[in] Character;
+                   Set     : @key[in] Character_Set)
+      @key[return] Boolean;
+
+   @key[function] @AdaSubDefn{Is_Subset} (Elements : @key[in] Character_Set;
+                       Set      : @key[in] Character_Set)
+      @key[return] Boolean;
+
+   @key[function] "<=" (Left  : @key[in] Character_Set;
+                  Right : @key[in] Character_Set)
+      @key[return] Boolean @key[renames] Is_Subset;
+
+
+   address@hidden Alternative representation for a set of character values:}
+   @key[subtype] @AdaSubtypeDefn{Name=[Character_Sequence],Of=[String]} 
@key[is] String;
+
+   @key[function] @AdaSubDefn{To_Set} (Sequence  : @key[in] 
Character_Sequence)@key[return] Character_Set;
+
+   @key[function] @AdaSubDefn{To_Set} (Singleton : @key[in] Character)     
@key[return] Character_Set;
+
+   @key[function] @AdaSubDefn{To_Sequence} (Set  : @key[in] Character_Set) 
@key[return] Character_Sequence;
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00161-01]}
+   address@hidden Representation for a character to character mapping:}
+   @key[type] @AdaTypeDefn{Character_Mapping} @key[is] 
@key[private];@Chg{Version=[2],New=[
+   @key[pragma] Preelaborable_Initialization(Character_Mapping);],Old=[]}
+
+   @key[function] @AdaSubDefn{Value} (Map     : @key[in] Character_Mapping;
+                   Element : @key[in] Character)
+      @key[return] Character;
+
+   @AdaObjDefn{Identity} : @key[constant] Character_Mapping;
+
+   @key[function] @AdaSubDefn{To_Mapping} (From, To : @key[in] 
Character_Sequence)
+      @key[return] Character_Mapping;
+
+   @key[function] @AdaSubDefn{To_Domain} (Map : @key[in] Character_Mapping)
+      @key[return] Character_Sequence;
+   @key[function] @AdaSubDefn{To_Range}  (Map : @key[in] Character_Mapping)
+      @key[return] Character_Sequence;
+
+   @key{type} @AdaTypeDefn{Character_Mapping_Function} @key{is}
+      @key{access} @key{function} (From : @key{in} Character) @key{return} 
Character;
+
address@hidden
+   ... -- @Examcom{not specified by the language}
address@hidden Ada.Strings.Maps;
address@hidden
+
+An object of type Character_Set represents a set of characters.
+
+Null_Set represents the set containing no characters.
+
+An object Obj of type Character_Range represents the set of characters
+in the range Obj.Low .. Obj.High.
+
+An object Obj of type Character_Ranges represents the
+union of the sets corresponding to Obj(I) for I in Obj'Range.
address@hidden
address@hidden@Keepnext
address@hidden To_Set (Ranges : @key[in] Character_Ranges) @key[return] 
Character_Set;
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+If Ranges'Length=0 then Null_Set is returned;
address@hidden,New=[,],Old=[]}
+the returned value represents the set corresponding to Ranges.
+
address@hidden@Keepnext
address@hidden To_Set (Span : @key[in] Character_Range) @key[return] 
Character_Set;
address@hidden
+
+The returned value represents the set containing each character in Span.
address@hidden@Keepnext
address@hidden To_Ranges (Set : @key[in] Character_Set) @key[return] 
Character_Ranges;
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+If Set = address@hidden,New=[,],Old=[]}
+then an empty Character_Ranges array is returned;
address@hidden,New=[,],Old=[]} the shortest array of contiguous
+ranges of Character values in Set, in increasing order of Low, is returned.
+
address@hidden@Keepnext
address@hidden "=" (Left, Right : @key[in] Character_Set) @key[return] Boolean;
address@hidden
address@hidden@;The function "=" returns True if Left and Right represent 
identical sets,
+and False otherwise.
address@hidden
+
address@hidden@;Each of the logical operators "@key[not]", "@key[and]", 
"@key[or]",
+and "@key[xor]" returns
+a Character_Set value that represents the set obtained by applying
+the corresponding operation to the set(s) represented by the parameter(s)
+of the operator.
+"@en"(Left, Right) is equivalent to "and"(Left, "not"(Right)).
address@hidden
+The set minus operator is provided for address@hidden
+
address@hidden
address@hidden@Keepnext
address@hidden Is_In (Element : @key[in] Character;
+                Set     : @key[in] Character_Set);
+   @key[return] Boolean;
address@hidden
address@hidden@;Is_In returns True if Element is in Set, and False otherwise.
+
address@hidden@Keepnext
address@hidden Is_Subset (Elements : @key[in] Character_Set;
+                    Set      : @key[in] Character_Set)
+   @key[return] Boolean;
address@hidden
address@hidden@;Is_Subset returns True if
+Elements is a subset of Set, and False otherwise.
+
address@hidden@Keepnext
address@hidden Character_Sequence @key[is] String;
address@hidden
address@hidden@;The Character_Sequence subtype is used to portray a set of 
character
+values and also to identify the domain and range of a character
+mapping.
address@hidden
+Although a named subtype is redundant @em the predefined type String
+could have been used for the parameter to To_Set and To_Mapping
+below @em the use of a differently named subtype identifies the intended
+purpose of the parameter.
address@hidden
+
address@hidden@Keepnext
address@hidden To_Set (Sequence  : @key[in] Character_Sequence) @key[return] 
Character_Set;@*
address@hidden To_Set (Singleton : @key[in] Character)          @key[return] 
Character_Set;
address@hidden
address@hidden@;Sequence portrays the set of character values that it explicitly
+contains (ignoring duplicates).
+Singleton portrays the set comprising a single Character.
+Each of the To_Set functions
+returns a Character_Set value that represents
+the set portrayed by Sequence or Singleton.
+
address@hidden@Keepnext
address@hidden To_Sequence (Set : @key[in] Character_Set) @key[return] 
Character_Sequence;
address@hidden
address@hidden@;The function To_Sequence returns a Character_Sequence value
+containing each of the characters in the set represented by Set, in
+ascending order with no duplicates.
+
address@hidden@Keepnext
address@hidden Character_Mapping @key[is] @key[private];
address@hidden
address@hidden@;An object of type Character_Mapping represents a
+Character-to-Character mapping.
+
address@hidden@Keepnext
address@hidden Value (Map     : @key[in] Character_Mapping;
+                Element : @key[in] Character)
+   @key[return] Character;
address@hidden
address@hidden@;The function Value returns the Character value to which Element 
maps
+with respect to the mapping represented by Map.
address@hidden
+
address@hidden, Sec=(a character to a pattern character)}
+A character C @i{matches} a pattern character P
+with respect to a given Character_Mapping value Map if
+Value(Map, C) = P.
address@hidden, Sec=(a string to a pattern string)}
+A string S @i{matches} a pattern string P with respect to a
+given Character_Mapping if their lengths are the same
+and if each character in S matches its corresponding character in
+the pattern string P.
address@hidden
+  In an earlier version of the string handling packages,
+  the definition of matching was symmetrical, namely
+  C matches P if Value(Map,C) = Value(Map,P).
+ However, applying the mapping
+  to the pattern was confusing according to some reviewers.
+  Furthermore, if the symmetrical version is needed, it can
+  be achieved by applying the mapping to the pattern (via translation) prior to
+  passing it as a parameter.
address@hidden
+
+String handling subprograms that deal with character mappings have
+parameters whose type is Character_Mapping.
address@hidden
address@hidden@Keepnext
+Identity : @key[constant] Character_Mapping;
address@hidden
+  @Trailing@;Identity maps each Character to itself.
+
address@hidden@Keepnext
address@hidden To_Mapping (From, To : @key[in] Character_Sequence)
+    @key[return] Character_Mapping;
address@hidden
+  @Trailing@;To_Mapping produces a Character_Mapping such that
+  each element of From maps to the corresponding element of To,
+  and each other character maps to itself.
+    If From'Length /= To'Length, or
+     if some character is repeated in From, then Translation_Error
+     is propagated.
+
address@hidden@Keepnext
address@hidden To_Domain (Map : @key[in] Character_Mapping) @key[return] 
Character_Sequence;
address@hidden
address@hidden@;To_Domain returns the shortest Character_Sequence value D such 
that
+each character not in D maps to itself, and such that
+the characters in D are in ascending order.
+The lower bound of D is 1.
+
address@hidden@Keepnext
address@hidden To_Range  (Map : @key[in] Character_Mapping) @key[return] 
Character_Sequence;
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0048],ARef=[AI95-00151-01]}
address@hidden@;To_Range returns the Character_Sequence value R,
address@hidden,Old=[with lower bound 1 and upper bound Map'Length,]}
+such that if D = To_Domain(Map)@Chg{New=[, then R has the same bounds as D,
+and],Old=[ then]} D(I) maps to R(I) for each I in D'Range.
address@hidden
+
+An object F of type Character_Mapping_Function maps a Character
+value C to the Character value address@hidden(C), which is said to
address@hidden C with respect to mapping function F.
address@hidden<match>,sec=<a character to a pattern character, with
+respect to a character mapping function>]
address@hidden
+
address@hidden
+Character_Mapping and Character_Mapping_Function
+are used both for character equivalence
+mappings in the search subprograms (such as for case insensitivity) and
+as transformational mappings in the Translate subprograms.
+
+To_Domain(Identity) and To_Range(Identity) each returns the null string.
address@hidden
+Package Strings.Maps is not pure, since it declares an
+access-to-subprogram type.
address@hidden
address@hidden
+
address@hidden
+To_Mapping("ABCD", "ZZAB") returns a Character_Mapping that maps 'A'
+and 'B' to 'Z', 'C' to 'A', 'D' to 'B', and each other Character to
+itself.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00161-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b[Amendment Correction:] Added @nt{pragma} Preelaborable_Initialization to
+  types Character_Set and Character_Mapping, so that they can be used
+  to declare default-initialized objects in preelaborated units.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00362-01]}
+  @ChgAdded{Version=[2],Text=[Strings.Maps is now Pure,
+  so it can be used in pure units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0048],ARef=[AI95-00151-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the definition 
of
+  the range of the result of To_Range, since the Ada 95 definition makes no
+  sense.]}
address@hidden
+
+
address@hidden String Handling}
address@hidden
+The language-defined package Strings.Fixed provides string-handling subprograms
+ for fixed-length strings;
+that is, for values of type Standard.String.
+Several of these subprograms are procedures that modify the contents of
+a String that is passed as an @key[out] or an @key[in] @key[out] parameter;
+ each has additional
+parameters to control the effect when the logical length of the result
+differs from the parameter's length.
+
+For each function that returns a String, the lower bound of the returned
+value is 1.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+Most operations that @Chg{Version=[2],New=[yield],Old=[yields]} a String
+are provided both as a
+function and as a procedure. The functional form is possibly a more aesthetic
+style but may introduce overhead due to extra copying or dynamic memory
+usage in some implementations. Thus a procedural form, with an @key[in]
address@hidden parameter so that all copying is done `in place', is also
address@hidden
+
+The basic model embodied in the package is that a fixed-length string
+comprises significant characters and possibly padding
+(with space characters)
+on either or both
+ends. When a shorter string is copied to a longer string, padding
+is inserted, and when a longer string is copied to a shorter one,
+padding is stripped. The Move procedure in Strings.Fixed, which takes a
+String as an @key[out] parameter, allows the programmer to control these
+effects. Similar control is provided by the string transformation
+procedures.
address@hidden
+
address@hidden
address@hidden@keepnext
address@hidden@;The library package Strings.Fixed has the following declaration:
address@hidden
address@hidden Ada.Strings.Maps;
address@hidden,address@hidden Ada.Strings.Fixed @key[is]
+   @key[pragma] Preelaborate(Fixed);
+
+
address@hidden "Copy" procedure for strings of possibly different lengths}
+
+   @key[procedure] @AdaSubDefn{Move} (Source  : @key[in]  String;
+                   Target  : @key[out] String;
+                   Drop    : @key[in]  Truncation := Error;
+                   Justify : @key[in]  Alignment  := Left;
+                   Pad     : @key[in]  Character  := Space);
+
+
address@hidden Search subprograms}
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Index} (Source  : @key[in] 
String;
+                   Pattern : @key[in] String;
+                   From    : @key[in] Positive;
+                   Going   : @key[in] Direction := Forward;
+                   Mapping : @key[in] Maps.Character_Mapping := Maps.Identity)
+      @key[return] Natural;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Index} (Source  : @key[in] 
String;
+                   Pattern : @key[in] String;
+                   From    : @key[in] Positive;
+                   Going   : @key[in] Direction := Forward;
+                   Mapping : @key[in] Maps.Character_Mapping_Function)
+      @key[return] Natural;]}
+
+   @key[function] @AdaSubDefn{Index} (Source   : @key[in] String;
+                   Pattern  : @key[in] String;
+                   Going    : @key[in] Direction := Forward;
+                   Mapping  : @key[in] Maps.Character_Mapping
+                                := Maps.Identity)
+      @key[return] Natural;
+
+   @key[function] @AdaSubDefn{Index} (Source   : @key[in] String;
+                   Pattern  : @key[in] String;
+                   Going    : @key[in] Direction := Forward;
+                   Mapping  : @key[in] Maps.Character_Mapping_Function)
+      @key[return] Natural;
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Index} (Source  : @key[in] 
String;
+                   Set     : @key[in] Maps.Character_Set;
+                   From    : @key[in] Positive;
+                   Test    : @key[in] Membership := Inside;
+                   Going   : @key[in] Direction := Forward)
+      @key[return] Natural;]}
+
+   @key[function] @AdaSubDefn{Index} (Source : @key[in] String;
+                   Set    : @key[in] Maps.Character_Set;
+                   Test   : @key[in] Membership := Inside;
+                   Going  : @key[in] Direction  := Forward)
+      @key[return] Natural;
+
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Index_Non_Blank} (Source : 
@key[in] String;
+                             From   : @key[in] Positive;
+                             Going  : @key[in] Direction := Forward)
+      @key[return] Natural;]}
+
+   @key[function] @AdaSubDefn{Index_Non_Blank} (Source : @key[in] String;
+                             Going  : @key[in] Direction := Forward)
+      @key[return] Natural;
+
+
+   @key[function] @AdaSubDefn{Count} (Source   : @key[in] String;
+                   Pattern  : @key[in] String;
+                   Mapping  : @key[in] Maps.Character_Mapping
+                                 := Maps.Identity)
+      @key[return] Natural;
+
+   @key[function] @AdaSubDefn{Count} (Source   : @key[in] String;
+                   Pattern  : @key[in] String;
+                   Mapping  : @key[in] Maps.Character_Mapping_Function)
+      @key[return] Natural;
+
+   @key[function] @AdaSubDefn{Count} (Source   : @key[in] String;
+                   Set      : @key[in] Maps.Character_Set)
+      @key[return] Natural;
+
+
address@hidden,Kind=[Added],ARef=[AI05-0031-1]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Find_Token} (Source : 
@key[in] String;
+                         Set    : @key[in] Maps.Character_Set;
+                         From   : @key[in] Positive;
+                         Test   : @key[in] Membership;
+                         First  : @key[out] Positive;
+                         Last   : @key[out] Natural);]}
+
+   @key[procedure] @AdaSubDefn{Find_Token} (Source : @key[in] String;
+                         Set    : @key[in] Maps.Character_Set;
+                         Test   : @key[in] Membership;
+                         First  : @key[out] Positive;
+                         Last   : @key[out] Natural);
+
+
address@hidden@;address@hidden String translation subprograms}
+
+   @key[function] @AdaSubDefn{Translate} (Source  : @key[in] String;
+                       Mapping : @key[in] Maps.Character_Mapping)
+      @key[return] String;
+
+   @key[procedure] @AdaSubDefn{Translate} (Source  : @key[in] @key[out] String;
+                        Mapping : @key[in] Maps.Character_Mapping);
+
+
+   @key[function] @AdaSubDefn{Translate} (Source  : @key[in] String;
+                       Mapping : @key[in] Maps.Character_Mapping_Function)
+      @key[return] String;
+
+   @key[procedure] @AdaSubDefn{Translate} (Source  : @key[in] @key[out] String;
+                        Mapping : @key[in] Maps.Character_Mapping_Function);
+
address@hidden@;address@hidden String transformation subprograms}
+
+   @key[function] @AdaSubDefn{Replace_Slice} (Source   : @key[in] String;
+                           Low      : @key[in] Positive;
+                           High     : @key[in] Natural;
+                           By       : @key[in] String)
+      @key[return] String;
+
+   @key[procedure] @AdaSubDefn{Replace_Slice} (Source   : @key[in] @key[out] 
String;
+                            Low      : @key[in] Positive;
+                            High     : @key[in] Natural;
+                            By       : @key[in] String;
+                            Drop     : @key[in] Truncation := Error;
+                            Justify  : @key[in] Alignment  := Left;
+                            Pad      : @key[in] Character  := Space);
+
+
+   @key[function] @AdaSubDefn{Insert} (Source   : @key[in] String;
+                    Before   : @key[in] Positive;
+                    New_Item : @key[in] String)
+      @key[return] String;
+
+   @key[procedure] @AdaSubDefn{Insert} (Source   : @key[in] @key[out] String;
+                     Before   : @key[in] Positive;
+                     New_Item : @key[in] String;
+                     Drop     : @key[in] Truncation := Error);
+
+
+   @key[function] @AdaSubDefn{Overwrite} (Source   : @key[in] String;
+                       Position : @key[in] Positive;
+                       New_Item : @key[in] String)
+      @key[return] String;
+
+   @key[procedure] @AdaSubDefn{Overwrite} (Source   : @key[in] @key[out] 
String;
+                        Position : @key[in] Positive;
+                        New_Item : @key[in] String;
+                        Drop     : @key[in] Truncation := Right);
+
+
+   @key[function] @AdaSubDefn{Delete} (Source  : @key[in] String;
+                    From    : @key[in] Positive;
+                    Through : @key[in] Natural)
+      @key[return] String;
+
+   @key[procedure] @AdaSubDefn{Delete} (Source  : @key[in] @key[out] String;
+                     From    : @key[in] Positive;
+                     Through : @key[in] Natural;
+                     Justify : @key[in] Alignment := Left;
+                     Pad     : @key[in] Character := Space);
+
+ address@hidden selector subprograms}
+   @key[function] @AdaSubDefn{Trim} (Source : @key[in] String;
+                  Side   : @key[in] Trim_End)
+      @key[return] String;
+
+   @key[procedure] @AdaSubDefn{Trim} (Source  : @key[in] @key[out] String;
+                   Side    : @key[in] Trim_End;
+                   Justify : @key[in] Alignment := Left;
+                   Pad     : @key[in] Character := Space);
+
+   @key[function] @AdaSubDefn{Trim} (Source : @key[in] String;
+                  Left   : @key[in] Maps.Character_Set;
+                  Right  : @key[in] Maps.Character_Set)
+      @key[return] String;
+
+   @key[procedure] @AdaSubDefn{Trim} (Source  : @key[in] @key[out] String;
+                   Left    : @key[in] Maps.Character_Set;
+                   Right   : @key[in] Maps.Character_Set;
+                   Justify : @key[in] Alignment := Strings.Left;
+                   Pad     : @key[in] Character := Space);
+
+
+   @key[function] @AdaSubDefn{Head} (Source : @key[in] String;
+                  Count  : @key[in] Natural;
+                  Pad    : @key[in] Character := Space)
+      @key[return] String;
+
+   @key[procedure] @AdaSubDefn{Head} (Source  : @key[in] @key[out] String;
+                   Count   : @key[in] Natural;
+                   Justify : @key[in] Alignment := Left;
+                   Pad     : @key[in] Character := Space);
+
+   @key[function] @AdaSubDefn{Tail} (Source : @key[in] String;
+                  Count  : @key[in] Natural;
+                  Pad    : @key[in] Character := Space)
+      @key[return] String;
+
+   @key[procedure] @AdaSubDefn{Tail} (Source  : @key[in] @key[out] String;
+                   Count   : @key[in] Natural;
+                   Justify : @key[in] Alignment := Left;
+                   Pad     : @key[in] Character := Space);
+
address@hidden@;address@hidden constructor functions}
+
+   @key[function] "*" (Left  : @key[in] Natural;
+                 Right : @key[in] Character) @key[return] String;
+
+   @key[function] "*" (Left  : @key[in] Natural;
+                 Right : @key[in] String) @key[return] String;
+
address@hidden Ada.Strings.Fixed;
address@hidden
+
+The effects of the above subprograms are as follows.
address@hidden
address@hidden@Keepnext
address@hidden Move (Source  : @key[in]  String;
+                Target  : @key[out] String;
+                Drop    : @key[in]  Truncation := Error;
+                Justify : @key[in]  Alignment  := Left;
+                Pad     : @key[in]  Character  := Space);
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+The Move procedure copies characters from Source to Target.
+If Source has the same length as Target, then the effect is
+to assign Source to Target.
+If Source is shorter than address@hidden,New=[,],Old=[]} then:
address@hidden
+If Justify=Left, then Source is copied into the first Source'Length
+ characters of Target.
+
+If Justify=Right, then Source is copied into the last Source'Length
+ characters of Target.
+
+If Justify=Center, then Source is copied into
+ the middle Source'Length characters of Target.
+In this case, if the difference in length between
+ Target and Source is odd, then the extra Pad character
+  is on the right.
+
+Pad is copied to each Target character not otherwise assigned.
address@hidden
+
+If Source is longer than Target, then the effect is based on
+Drop.
address@hidden
+If Drop=Left, then the rightmost Target'Length characters
+of Source are copied into Target.
+
+If Drop=Right, then the leftmost Target'Length characters
+of Source are copied into Target.
+
address@hidden@;If Drop=Error, then the effect depends on the value of the 
Justify
+parameter and also on whether any characters in Source other than
+Pad would fail to be copied:
address@hidden
+If Justify=Left, and if each of the rightmost Source'Length-Target'Length
+characters in Source is Pad, then the leftmost Target'Length characters
+of Source are copied to Target.
+
+If Justify=Right, and if each of the leftmost Source'Length-Target'Length
+characters in Source is Pad, then the rightmost Target'Length characters
+of Source are copied to Target.
+
address@hidden@;Otherwise, Length_Error is propagated.
address@hidden
address@hidden
address@hidden
+The Move procedure will work even if Source and Target
address@hidden
address@hidden
+The order of parameters (Source before Target)
+corresponds to the order in COBOL's MOVE address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden Index (Source  : @key[in] String;
+                Pattern : @key[in] String;
+                From    : @key[in] Positive;
+                Going   : @key[in] Direction := Forward;
+                Mapping : @key[in] Maps.Character_Mapping := Maps.Identity)
+   @key[return] Natural;@*
address@hidden Index (Source  : @key[in] String;
+                Pattern : @key[in] String;
+                From    : @key[in] Positive;
+                Going   : @key[in] Direction := Forward;
+                Mapping : @key[in] Maps.Character_Mapping_Function)
+   @key[return] Natural;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0056-1]}
address@hidden,Type=[Trailing],Text=[Each Index function searches, starting 
from From, for a slice of
+Source, with length Pattern'Length, that matches Pattern with respect to
+Mapping; the parameter Going indicates the direction of the lookup.
address@hidden,New=[If Source is the null string, Index returns 0;
+otherwise, if],Old=[If]}
+From is not in Source'Range, then Index_Error is propagated. If Going =
+Forward, then Index returns the smallest index I which is greater than or equal
+to From such that the slice of Source starting at I matches Pattern. If Going =
+Backward, then Index returns the largest index I such that the slice of Source
+starting at I matches Pattern and has an upper bound less than or equal to
+From. If there is no such slice, then 0 is returned. If Pattern is the null
+string, then Pattern_Error is propagated.]}
+
address@hidden
+   @ChgRef{Version=[2],Kind=[AddedNormal]}
+   @ChgAdded{Version=[2],Text=[There is no default parameter for From; the
+   default value would need to depend on other parameters (the bounds of Source
+   and the direction Going). It is better to use overloaded functions rather
+   than a special value to represent the default.]}
+
+   @ChgRef{Version=[2],Kind=[AddedNormal]}
+   @ChgAdded{Version=[2],Text=[There is no default value for the Mapping
+   parameter that is a Character_Mapping_Function; if there were, a call would
+   be ambiguous since there is also a default for the Mapping parameter that is
+   a Character_Mapping.]}
+
+   @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0056-1]}
+   @ChgAdded{Version=[3],Text=[The language does not define when the
+   Pattern_Error check is made. (That's because many common searching
+   implementations require a nonempty pattern) That means that the result for
+   a call like @f{Index ("", "")} could be 0 or could raise Pattern_Error.
+   Similarly, in the call @f{Index ("", "", From => 2)}, the language does not
+   define whether Pattern_Error or Index_Error is raised.]}
+
address@hidden
+
address@hidden@Keepnext
address@hidden Index (Source   : @key[in] String;
+                Pattern  : @key[in] String;
+                Going    : @key[in] Direction := Forward;
+                Mapping  : @key[in] Maps.Character_Mapping
+                              := Maps.Identity)
+   @key[return] Natural;@*
address@hidden Index (Source   : @key[in] String;
+                Pattern  : @key[in] String;
+                Going    : @key[in] Direction := Forward;
+                Mapping  : @key[in] Maps.Character_Mapping_Function)
+   @key[return] Natural;
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00301-01]}
address@hidden@ChgDeleted{Version=[2],Type=[Trailing],address@hidden to hold 
conditional format.}Can't have both.}
address@hidden,Type=[Leading],address@hidden to hold conditional format.}
address@hidden,New=[If Going = Forward, returns],
+Old=[Each Index function searches for a slice of Source, with length
+Pattern'Length, that matches Pattern
+with respect to Mapping;
+the parameter Going indicates the direction of the lookup.
+ If Going = Forward, then Index
+ returns the smallest index I such that
+    the slice of Source starting at I matches Pattern.
+  If Going = Backward, then Index
+ returns the largest index I such that
+    the slice of Source starting at I matches Pattern.
+  If there is no such slice, then 0 is returned.
+  If Pattern is the null string then Pattern_Error is propagated.]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[      Index (Source, Pattern, Source'First, Forward, 
Mapping);]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0264-1]}
address@hidden,Type=[Leading],address@hidden,New=[,],Old=[]} returns]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Type=[Trailing],Text=[      Index (Source, Pattern, Source'Last, 
Backward, Mapping);]}
address@hidden
address@hidden
+   @ChgRef{Version=[2],address@hidden up}
+   @ChgAdded{Version=[2],Text=[There is no default value for the Mapping
+   parameter that is a Character_Mapping_Function; if there were, a call would
+   be ambiguous since there is also a default for the Mapping parameter that is
+   a Character_Mapping.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden Index (Source  : @key[in] String;
+                Set     : @key[in] Maps.Character_Set;
+                From    : @key[in] Positive;
+                Test    : @key[in] Membership := Inside;
+                Going   : @key[in] Direction := Forward)
+   @key[return] Natural;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0056-1]}
address@hidden,Type=[Trailing],Text=[Index searches for the first or
+last occurrence of any of a set of characters (when Test=Inside), or any of the
+complement of a set of characters (when Test=Outside).
address@hidden,New=[If Source is the null string, Index returns 0;
+otherwise, if],Old=[If]} From is not in
+Source'Range, then Index_Error is propagated. Otherwise, it returns the
+smallest index I >= From (if Going=Forward) or the largest index I <= From (if
+Going=Backward) such that Source(I) satisfies the Test condition with respect
+to Set; it returns 0 if there is no such Character in Source.]}
+
address@hidden@Keepnext
address@hidden Index (Source : @key[in] String;
+                Set    : @key[in] Maps.Character_Set;
+                Test   : @key[in] Membership := Inside;
+                Going  : @key[in] Direction  := Forward)
+   @key[return] Natural;
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00301-01]}
address@hidden@ChgDeleted{Version=[2],Type=[Trailing],address@hidden to hold 
conditional format.}Can't have both.}
address@hidden,Type=[Leading],address@hidden to hold conditional format.}
address@hidden,New=[If Going = Forward, returns],
+Old=[Index searches for the first or last occurrence of any of a set of
+characters (when Test=Inside),
+or any of the complement of a set of characters (when Test=Outside).
+It returns the smallest index I (if Going=Forward) or the largest index I
+(if Going=Backward) such that
+Source(I) satisfies the Test condition with respect to Set;
+it returns 0 if there is no such Character in Source.]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[      Index (Source, Set, Source'First, Test, Forward);]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0264-1]}
address@hidden,Type=[Leading],address@hidden,New=[,],Old=[]} returns]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Type=[Trailing],Text=[      Index (Source, Set, Source'Last, 
Test, Backward);]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden Index_Non_Blank (Source : @key[in] String;
+                          From   : @key[in] Positive;
+                          Going  : @key[in] Direction := Forward)
+   @key[return] Natural;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Type=[Trailing],Text=[Returns Index (Source, Maps.To_Set(Space), 
From, Outside, Going);]}
+
address@hidden@Keepnext
address@hidden Index_Non_Blank (Source : @key[in] String;
+                          Going  : @key[in] Direction := Forward)
+   @key[return] Natural;
address@hidden
address@hidden@;Returns Index(Source, Maps.To_Set(Space), Outside, Going)
+
address@hidden@Keepnext
address@hidden Count (Source   : @key[in] String;
+                Pattern  : @key[in] String;
+                Mapping  : @key[in] Maps.Character_Mapping
+                             := Maps.Identity)
+   @key[return] Natural;@*
address@hidden Count (Source   : @key[in] String;
+                Pattern  : @key[in] String;
+                Mapping  : @key[in] Maps.Character_Mapping_Function)
+   @key[return] Natural;
address@hidden
address@hidden@;Returns the maximum number of nonoverlapping slices of Source 
that
+match Pattern with respect to Mapping.
+If Pattern is the null string then Pattern_Error is propagated.
address@hidden
+We say `maximum number' because it is possible to slice a source
+string in different ways yielding different numbers of matches. For
+example if Source is "ABABABA" and Pattern is "ABA", then Count yields
+2, although there is a partitioning of Source that yields just 1 match,
+for the middle slice. Saying `maximum number' is equivalent to saying
+that the pattern match starts either at the low index or the high index
+position.
address@hidden
+
address@hidden@Keepnext
address@hidden Count (Source   : @key[in] String;
+                Set      : @key[in] Maps.Character_Set)
+   @key[return] Natural;
address@hidden
address@hidden@;Returns the number of occurrences in Source of characters that
+are in Set.
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden Find_Token (Source : @key[in] String;
+                      Set    : @key[in] Maps.Character_Set;
+                      From   : @key[in] Positive;
+                      Test   : @key[in] Membership;
+                      First  : @key[out] Positive;
+                      Last   : @key[out] Natural);]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0031-1]}
address@hidden,Type=[Trailing],Text=[If Source is not the null string and
+From is not in Source'Range, then Index_Error is raised. Otherwise, First is 
set
+to the index of the first character in Source(From .. Source'Last) that
+satisfies the Test condition. Last is set to the largest index such that all
+characters in Source(First .. Last) satisfy the Test condition. If no 
characters
+in Source(From .. Source'Last) satisfy the Test condition, First is set to 
From,
+and Last is set to 0.]}
+
address@hidden@Keepnext
address@hidden Find_Token (Source : @key[in] String;
+                      Set    : @key[in] Maps.Character_Set;
+                      Test   : @key[in] Membership;
+                      First  : @key[out] Positive;
+                      Last   : @key[out] Natural);
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0049],ARef=[AI95-00128-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0031-1]}
address@hidden@;@Chg{Version=[3],New=[Equivalent to Find_Token (Source, Set,
+Source'First, Test, First, Last).],Old=[Find_Token returns in
+First and Last the indices of the beginning
+and end of the first slice of Source all of whose elements
+satisfy the Test condition, and such that the elements
+(if any) immediately before and after the slice do not
+satisfy the Test condition.
+If no such slice exists, then the value returned for Last is zero, and
+the value returned for First is Source'address@hidden; however, if
+Source'First is not in Positive then Constraint_Error
address@hidden,Sec=(raised by failure of run-time check)}
+is raised],Old=[]}.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0031-1]}
+  @ChgAdded{Version=[3],Text=[If Source'First is not in Positive, which can 
only
+  happen for an empty string, this will raise Constraint_Error.]}
address@hidden
+
address@hidden@Keepnext
address@hidden Translate (Source  : @key[in] String;
+                    Mapping : @key[in] Maps.Character_Mapping)
+   @key[return] String;@*
address@hidden Translate (Source  : @key[in] String;
+                    Mapping : @key[in] Maps.Character_Mapping_Function)
+   @key[return] String;
address@hidden
address@hidden@;Returns the string S whose length is Source'Length and such
+that S(I) is the character to which Mapping maps the corresponding
+element of Source, for I in 1..Source'Length.
+
address@hidden@Keepnext
address@hidden Translate (Source  : @key[in] @key[out] String;
+                     Mapping : @key[in] Maps.Character_Mapping);@*
address@hidden Translate (Source  : @key[in] @key[out] String;
+                     Mapping : @key[in] Maps.Character_Mapping_Function);
address@hidden
address@hidden@;Equivalent to Source := Translate(Source, Mapping).
+
address@hidden@Keepnext
address@hidden Replace_Slice (Source   : @key[in] String;
+                        Low      : @key[in] Positive;
+                        High     : @key[in] Natural;
+                        By       : @key[in] String)
+   @key[return] String;
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0049],ARef=[AI95-00128-01]}
address@hidden@Leading],address@hidden Low > Source'Last+1, or
+High < Source'address@hidden@;1, then Index_Error is propagated.
address@hidden:],Old=[, if High >= Low then the returned string
+comprises Source(Source'address@hidden@;1) & By & Source(High+1..Source'Last),
+and if High < Low then the returned string is
+Insert(Source, Before=>Low, New_Item=>By).]}
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0049],ARef=[AI95-00128-01]}
address@hidden,Text=[If High >= Low, then the returned string comprises
+Source(Source'address@hidden@;1) & By & Source(High+1..Source'Last), but with
+lower bound address@hidden
+
address@hidden,Kind=[Added],Ref=[8652/0049],ARef=[AI95-00128-01]}
address@hidden,Text=[If High < Low, then the returned string is
+Insert(Source, Before=>Low, New_Item=>By).]}
address@hidden
+
address@hidden@Keepnext
address@hidden Replace_Slice (Source   : @key[in] @key[out] String;
+                         Low      : @key[in] Positive;
+                         High     : @key[in] Natural;
+                         By       : @key[in] String;
+                         Drop     : @key[in] Truncation := Error;
+                         Justify  : @key[in] Alignment  := Left;
+                         Pad      : @key[in] Character  := Space);
address@hidden
address@hidden@;Equivalent to Move(Replace_Slice(Source, Low, High,
+By), Source, Drop, Justify, Pad).
+
address@hidden@Keepnext
address@hidden Insert (Source   : @key[in] String;
+                 Before   : @key[in] Positive;
+                 New_Item : @key[in] String)
+   @key[return] String;
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+Propagates Index_Error if Before is not in Source'First .. Source'Last+1;
address@hidden,New=[,],Old=[]}
+returns Source(Source'address@hidden@;1) & New_Item &
+Source(Before..Source'Last), but with lower bound 1.
+
+
address@hidden@Keepnext
address@hidden Insert (Source   : @key[in] @key[out] String;
+                  Before   : @key[in] Positive;
+                  New_Item : @key[in] String;
+                  Drop     : @key[in] Truncation := Error);
address@hidden
address@hidden@;Equivalent to Move(Insert(Source, Before, New_Item), Source, 
Drop).
+
address@hidden@Keepnext
address@hidden Overwrite (Source   : @key[in] String;
+                    Position : @key[in] Positive;
+                    New_Item : @key[in] String)
+   @key[return] String;
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+Propagates Index_Error if Position is not in Source'First .. Source'Last+1;
address@hidden,New=[,],Old=[]}
+returns the string obtained from Source by consecutively replacing
+characters starting at Position with corresponding characters from
+New_Item. If the end of Source is reached before the characters in
+New_Item are exhausted, the remaining characters from New_Item are
+appended to the string.
+
address@hidden@Keepnext
address@hidden Overwrite (Source   : @key[in] @key[out] String;
+                     Position : @key[in] Positive;
+                     New_Item : @key[in] String;
+                     Drop     : @key[in] Truncation := Right);
address@hidden
address@hidden@;Equivalent to Move(Overwrite(Source, Position,
+New_Item), Source, Drop).
+
address@hidden@Keepnext
address@hidden Delete (Source  : @key[in] String;
+                 From    : @key[in] Positive;
+                 Through : @key[in] Natural)
+   @key[return] String;
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0049],ARef=[AI95-00128-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden@;If From <= Through, the returned string is 
Replace_Slice(Source, From,
+Through, "")@Chg{Version=[3],New=[;],Old=[,]}
address@hidden,New=[,],Old=[]} it is address@hidden with lower
+bound 1],Old=[]}.
+
address@hidden@Keepnext
address@hidden Delete (Source  : @key[in] @key[out] String;
+                  From    : @key[in] Positive;
+                  Through : @key[in] Natural;
+                  Justify : @key[in] Alignment := Left;
+                  Pad     : @key[in] Character := Space);
address@hidden
address@hidden@;Equivalent to Move(Delete(Source, From, Through),
+Source, Justify => Justify, Pad => Pad).
+
address@hidden@Keepnext
address@hidden Trim (Source : @key[in] String;
+               Side   : @key[in] Trim_End)
+  @key[return] String;
address@hidden
address@hidden@;Returns the string obtained by removing from Source all leading
+Space characters (if Side = Left), all trailing Space characters
+(if Side = Right), or all leading and trailing Space characters
+(if Side = Both).
+
address@hidden@Keepnext
address@hidden Trim (Source  : @key[in] @key[out] String;
+                Side    : @key[in] Trim_End;
+                Justify : @key[in] Alignment := Left;
+                Pad     : @key[in] Character := Space);
address@hidden
address@hidden@;Equivalent to Move(Trim(Source, Side), Source, 
Justify=>Justify, Pad=>Pad).
+
address@hidden@Keepnext
address@hidden Trim (Source : @key[in] String;
+               Left   : @key[in] Maps.Character_Set;
+               Right  : @key[in] Maps.Character_Set)
+   @key[return] String;
address@hidden
address@hidden@;Returns the string obtained by removing from Source all leading
+characters in Left and all trailing characters in Right.
+
address@hidden@Keepnext
address@hidden Trim (Source  : @key[in] @key[out] String;
+                Left    : @key[in] Maps.Character_Set;
+                Right   : @key[in] Maps.Character_Set;
+                Justify : @key[in] Alignment := Strings.Left;
+                Pad     : @key[in] Character := Space);
address@hidden
address@hidden@;Equivalent to Move(Trim(Source, Left, Right), Source,
+Justify => Justify, Pad=>Pad).
+
address@hidden@Keepnext
address@hidden Head (Source : @key[in] String;
+               Count  : @key[in] Natural;
+               Pad    : @key[in] Character := Space)
+   @key[return] String;
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+Returns a string of length Count. If Count <= Source'Length, the
+string comprises the first Count characters of Source.
address@hidden,New=[,],Old=[]} its contents
+are Source concatenated with address@hidden@;Source'Length Pad characters.
+
address@hidden@Keepnext
address@hidden Head (Source  : @key[in] @key[out] String;
+                Count   : @key[in] Natural;
+                Justify : @key[in] Alignment := Left;
+                Pad     : @key[in] Character := Space);
address@hidden
address@hidden@;Equivalent to Move(Head(Source, Count, Pad), Source, 
Drop=>Error,
+Justify=>Justify, Pad=>Pad).
+
address@hidden@Keepnext
address@hidden Tail (Source : @key[in] String;
+               Count  : @key[in] Natural;
+               Pad    : @key[in] Character := Space)
+   @key[return] String;
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+Returns a string of length Count. If Count <= Source'Length, the
+string comprises the last Count characters of Source.
address@hidden,New=[,],Old=[]} its contents
+are Count-Source'Length Pad characters concatenated with Source.
+
address@hidden@Keepnext
address@hidden Tail (Source  : @key[in] @key[out] String;
+                Count   : @key[in] Natural;
+                Justify : @key[in] Alignment := Left;
+                Pad     : @key[in] Character := Space);
address@hidden
address@hidden@;Equivalent to Move(Tail(Source, Count, Pad), Source, 
Drop=>Error,
+Justify=>Justify, Pad=>Pad).
+
address@hidden@Keepnext
address@hidden "*" (Left  : @key[in] Natural;
+              Right : @key[in] Character) @key[return] String;@*
address@hidden "*" (Left  : @key[in] Natural;
+              Right : @key[in] String) @key[return] String;
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0049],ARef=[AI95-00128-01]}
+These functions replicate a character or string a specified number
+of times. The first function returns a string whose length is Left and each
+of whose elements is Right. The second function returns a string whose
+length is Left*Right'Length and whose value is the null
+string if Left = 0 and @Chg{New=[otherwise ],Old=[]}is
+(address@hidden@;1)*Right & Right @Chg{New=[with lower bound 
1],Old=[otherwise]}.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
+In the Index and Count functions taking Pattern and Mapping parameters,
+the actual String parameter passed to Pattern should comprise characters
+occurring as target characters of the mapping.
address@hidden,New=[,],Old=[]} the pattern will not match.
+
+In the Insert subprograms, inserting at the end of a string is obtained
+by passing Source'Last+1 as the Before parameter.
+
address@hidden,Sec=(raised by failure of run-time check)}
+If a null Character_Mapping_Function is passed to any of the
+string handling subprograms, Constraint_Error is propagated.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00301-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  Overloaded versions of Index and Index_Non_Blank are
+  @Chg{Version=[3],New=[],Old=[newly ]}added to
+  Strings.Fixed. If Strings.Fixed is referenced in a @nt{use_clause}, and an
+  entity @i<E> with a @nt{defining_identifier} of Index or Index_Non_Blank is
+  defined in a package that is also referenced in a @nt{use_clause}, the entity
+  @i<E> may no longer be use-visible, resulting in errors. This should be rare
+  and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0049],ARef=[AI95-00128-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that Find_Token
+  may raise Constraint_Error if Source'First is not in Positive (which is
+  only possible for a null string).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0049],ARef=[AI95-00128-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that 
Replace_Slice,
+  Delete, and "*" always return a string with lower bound 1.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0031-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  An overloaded version of Find_Token is added to
+  Strings.Fixed. If Strings.Fixed is referenced in a @nt{use_clause}, and an
+  entity @i<E> with a @nt{defining_identifier} of Find_Token is
+  defined in a package that is also referenced in a @nt{use_clause}, the entity
+  @i<E> may no longer be use-visible, resulting in errors. This should be rare
+  and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0056-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified that Index
+  never raises Index_Error if the source string is null.]}
address@hidden
+
+
address@hidden String Handling}
address@hidden
+The language-defined package Strings.Bounded provides a generic package
+each of whose instances yields a private type Bounded_String and a
+set of operations. An object of a particular Bounded_String type
+represents a String whose low bound is 1 and whose length
+can vary conceptually
+between 0 and a maximum size established at the
+generic instantiation.
+The subprograms for fixed-length string handling
+are either overloaded directly for Bounded_String, or are modified as
+needed to reflect the variability in length. Additionally, since the
+Bounded_String type is private, appropriate constructor and selector
+operations are provided.
address@hidden
+Strings.Bounded declares an inner generic package, versus itself
+being directly a generic child of Strings, in order to retain
+compatibility with a version of the string-handling packages that
+is generic with respect to the character and string address@hidden
address@hidden
+The bound of a bounded-length string is specified as a parameter
+to a generic, versus as the value for a discriminant, because of the
+inappropriateness of assignment and equality of discriminated types for
+the copying and comparison of bounded address@hidden
address@hidden
+
address@hidden
address@hidden@Keepnext@;The library package Strings.Bounded has the following 
declaration:
address@hidden
address@hidden Ada.Strings.Maps;
address@hidden,address@hidden Ada.Strings.Bounded @key[is]
+   @key[pragma] Preelaborate(Bounded);
+
+
+   @key[generic]
+      Max   : Positive;    address@hidden Maximum length of a Bounded_String}
+   @key[package] @AdaPackDefn{Generic_Bounded_Length} @key[is]
+
+      @AdaObjDefn{Max_Length} : @key[constant] Positive := Max;
+
+      @key[type] @AdaTypeDefn{Bounded_String} @key[is] @key[private];
+
+      @AdaObjDefn{Null_Bounded_String} : @key[constant] Bounded_String;
+
+      @key[subtype] @AdaSubtypeDefn{Name=[Length_Range],Of=[Natural]} @key[is] 
Natural @key[range] 0 .. Max_Length;
+
+      @key[function] @AdaSubDefn{Length} (Source : @key[in] Bounded_String) 
@key[return] Length_Range;
+
+
+   address@hidden Conversion, Concatenation, and Selection functions}
+
+      @key[function] @AdaSubDefn{To_Bounded_String} (Source : @key[in] String;
+                                  Drop   : @key[in] Truncation := Error)
+         @key[return] Bounded_String;
+
+      @key[function] @AdaSubDefn{To_String} (Source : @key[in] Bounded_String) 
@key[return] String;
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[      @key[procedure] @AdaSubDefn{Set_Bounded_String}
+         (Target :    @key[out] Bounded_String;
+          Source : @key[in]     String;
+          Drop   : @key[in]     Truncation := Error);]}
+
+      @key[function] @AdaSubDefn{Append} (Left, Right : @key[in] 
Bounded_String;
+                       Drop        : @key[in] Truncation  := Error)
+         @key[return] Bounded_String;
+
+      @key[function] @AdaSubDefn{Append} (Left  : @key[in] Bounded_String;
+                       Right : @key[in] String;
+                       Drop  : @key[in] Truncation := Error)
+         @key[return] Bounded_String;
+
+      @key[function] @AdaSubDefn{Append} (Left  : @key[in] String;
+                       Right : @key[in] Bounded_String;
+                       Drop  : @key[in] Truncation := Error)
+         @key[return] Bounded_String;
+
+      @key[function] @AdaSubDefn{Append} (Left  : @key[in] Bounded_String;
+                       Right : @key[in] Character;
+                       Drop  : @key[in] Truncation := Error)
+         @key[return] Bounded_String;
+
+      @key[function] @AdaSubDefn{Append} (Left  : @key[in] Character;
+                       Right : @key[in] Bounded_String;
+                       Drop  : @key[in] Truncation := Error)
+         @key[return] Bounded_String;
+
+      @key[procedure] @AdaSubDefn{Append} (Source   : @key[in out] 
Bounded_String;
+                        New_Item : @key[in] Bounded_String;
+                        Drop     : @key[in] Truncation  := Error);
+
+      @key[procedure] @AdaSubDefn{Append} (Source   : @key[in out] 
Bounded_String;
+                        New_Item : @key[in] String;
+                        Drop     : @key[in] Truncation  := Error);
+
+      @key[procedure] @AdaSubDefn{Append} (Source   : @key[in out] 
Bounded_String;
+                        New_Item : @key[in] Character;
+                        Drop     : @key[in] Truncation  := Error);
+
+      @key[function] "&" (Left, Right : @key[in] Bounded_String)
+         @key[return] Bounded_String;
+
+      @key[function] "&" (Left : @key[in] Bounded_String; Right : @key[in] 
String)
+         @key[return] Bounded_String;
+
+      @key[function] "&" (Left : @key[in] String; Right : @key[in] 
Bounded_String)
+         @key[return] Bounded_String;
+
+      @key[function] "&" (Left : @key[in] Bounded_String; Right : @key[in] 
Character)
+         @key[return] Bounded_String;
+
+      @key[function] "&" (Left : @key[in] Character; Right : @key[in] 
Bounded_String)
+         @key[return] Bounded_String;
+
+
+      @key[function] @AdaSubDefn{Element} (Source : @key[in] Bounded_String;
+                        Index  : @key[in] Positive)
+         @key[return] Character;
+
+      @key[procedure] @AdaSubDefn{Replace_Element} (Source : @key[in] 
@key[out] Bounded_String;
+                                 Index  : @key[in] Positive;
+                                 By     : @key[in] Character);
+
+
+      @key[function] @AdaSubDefn{Slice} (Source : @key[in] Bounded_String;
+                      Low    : @key[in] Positive;
+                      High   : @key[in] Natural)
+         @key[return] String;
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[      @key[function] @AdaSubDefn{Bounded_Slice}
+         (Source : @key[in] Bounded_String;
+          Low    : @key[in] Positive;
+          High   : @key[in] Natural)
+             @key[return] Bounded_String;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[      @key[procedure] @AdaSubDefn{Bounded_Slice}
+         (Source : @key[in]     Bounded_String;
+          Target :    @key[out] Bounded_String;
+          Low    : @key[in]     Positive;
+          High   : @key[in]     Natural);]}
+
+      @key[function] "="  (Left, Right : @key[in] Bounded_String) @key[return] 
Boolean;
+      @key[function] "="  (Left : @key[in] Bounded_String; Right : @key[in] 
String)
+        @key[return] Boolean;
+
+      @key[function] "="  (Left : @key[in] String; Right : @key[in] 
Bounded_String)
+        @key[return] Boolean;
+
+
+      @key[function] "<"  (Left, Right : @key[in] Bounded_String) @key[return] 
Boolean;
+
+      @key[function] "<"  (Left : @key[in] Bounded_String; Right : @key[in] 
String)
+        @key[return] Boolean;
+
+      @key[function] "<"  (Left : @key[in] String; Right : @key[in] 
Bounded_String)
+        @key[return] Boolean;
+
+      @key[function] "<=" (Left, Right : @key[in] Bounded_String) @key[return] 
Boolean;
+
+      @key[function] "<="  (Left : @key[in] Bounded_String; Right : @key[in] 
String)
+        @key[return] Boolean;
+
+      @key[function] "<="  (Left : @key[in] String; Right : @key[in] 
Bounded_String)
+        @key[return] Boolean;
+
+      @key[function] ">"  (Left, Right : @key[in] Bounded_String) @key[return] 
Boolean;
+
+      @key[function] ">"  (Left : @key[in] Bounded_String; Right : @key[in] 
String)
+        @key[return] Boolean;
+
+      @key[function] ">"  (Left : @key[in] String; Right : @key[in] 
Bounded_String)
+        @key[return] Boolean;
+
+      @key[function] ">=" (Left, Right : @key[in] Bounded_String) @key[return] 
Boolean;
+
+      @key[function] ">="  (Left : @key[in] Bounded_String; Right : @key[in] 
String)
+        @key[return] Boolean;
+
+      @key[function] ">="  (Left : @key[in] String; Right : @key[in] 
Bounded_String)
+        @key[return] Boolean;
+
address@hidden,Kind=[Revised],ARef=[AI95-00301-01]}
+   address@hidden Search @Chg{Version=[2],New=[subprograms],Old=[functions]}}
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[      @key[function] @AdaSubDefn{Index} (Source  : 
@key[in] Bounded_String;
+                      Pattern : @key[in] String;
+                      From    : @key[in] Positive;
+                      Going   : @key[in] Direction := Forward;
+                      Mapping : @key[in] Maps.Character_Mapping := 
Maps.Identity)
+         @key[return] Natural;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[      @key[function] @AdaSubDefn{Index} (Source  : 
@key[in] Bounded_String;
+                      Pattern : @key[in] String;
+                      From    : @key[in] Positive;
+                      Going   : @key[in] Direction := Forward;
+                      Mapping : @key[in] Maps.Character_Mapping_Function)
+         @key[return] Natural;]}
+
+      @key[function] @AdaSubDefn{Index} (Source   : @key[in] Bounded_String;
+                      Pattern  : @key[in] String;
+                      Going    : @key[in] Direction := Forward;
+                      Mapping  : @key[in] Maps.Character_Mapping
+                                 := Maps.Identity)
+         @key[return] Natural;
+
+      @key[function] @AdaSubDefn{Index} (Source   : @key[in] Bounded_String;
+                      Pattern  : @key[in] String;
+                      Going    : @key[in] Direction := Forward;
+                      Mapping  : @key[in] Maps.Character_Mapping_Function)
+         @key[return] Natural;
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[      @key[function] @AdaSubDefn{Index} (Source  : 
@key[in] Bounded_String;
+                      Set     : @key[in] Maps.Character_Set;
+                      From    : @key[in] Positive;
+                      Test    : @key[in] Membership := Inside;
+                      Going   : @key[in] Direction := Forward)
+         @key[return] Natural;]}
+
+      @key[function] @AdaSubDefn{Index} (Source : @key[in] Bounded_String;
+                      Set    : @key[in] Maps.Character_Set;
+                      Test   : @key[in] Membership := Inside;
+                      Going  : @key[in] Direction  := Forward)
+         @key[return] Natural;
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[      @key[function] @AdaSubDefn{Index_Non_Blank} (Source 
: @key[in] Bounded_String;
+                                From   : @key[in] Positive;
+                                Going  : @key[in] Direction := Forward)
+         @key[return] Natural;]}
+
+      @key[function] @AdaSubDefn{Index_Non_Blank} (Source : @key[in] 
Bounded_String;
+                                Going  : @key[in] Direction := Forward)
+         @key[return] Natural;
+
+
+      @key[function] @AdaSubDefn{Count} (Source   : @key[in] Bounded_String;
+                      Pattern  : @key[in] String;
+                      Mapping  : @key[in] Maps.Character_Mapping
+                                   := Maps.Identity)
+         @key[return] Natural;
+
+      @key[function] @AdaSubDefn{Count} (Source   : @key[in] Bounded_String;
+                      Pattern  : @key[in] String;
+                      Mapping  : @key[in] Maps.Character_Mapping_Function)
+         @key[return] Natural;
+
+      @key[function] @AdaSubDefn{Count} (Source   : @key[in] Bounded_String;
+                      Set      : @key[in] Maps.Character_Set)
+         @key[return] Natural;
+
+
address@hidden,Kind=[Added],ARef=[AI05-0031-1]}
address@hidden,Text=[      @key[procedure] @AdaSubDefn{Find_Token} (Source : 
@key[in] Bounded_String;
+                            Set    : @key[in] Maps.Character_Set;
+                            From   : @key[in] Positive;
+                            Test   : @key[in] Membership;
+                            First  : @key[out] Positive;
+                            Last   : @key[out] Natural);]}
+
+      @key[procedure] @AdaSubDefn{Find_Token} (Source : @key[in] 
Bounded_String;
+                            Set    : @key[in] Maps.Character_Set;
+                            Test   : @key[in] Membership;
+                            First  : @key[out] Positive;
+                            Last   : @key[out] Natural);
+
address@hidden@;   address@hidden String translation subprograms}
+
+      @key[function] @AdaSubDefn{Translate} (Source  : @key[in] Bounded_String;
+                          Mapping : @key[in] Maps.Character_Mapping)
+         @key[return] Bounded_String;
+
+      @key[procedure] @AdaSubDefn{Translate} (Source  : @key[in] @key[out] 
Bounded_String;
+                           Mapping : @key[in] Maps.Character_Mapping);
+
+
+      @key[function] @AdaSubDefn{Translate} (Source  : @key[in] Bounded_String;
+                          Mapping : @key[in] Maps.Character_Mapping_Function)
+         @key[return] Bounded_String;
+
+      @key[procedure] @AdaSubDefn{Translate} (Source  : @key[in] @key[out] 
Bounded_String;
+                           Mapping : @key[in] Maps.Character_Mapping_Function);
+
address@hidden@;   address@hidden String transformation subprograms}
+
+      @key[function] @AdaSubDefn{Replace_Slice} (Source   : @key[in] 
Bounded_String;
+                              Low      : @key[in] Positive;
+                              High     : @key[in] Natural;
+                              By       : @key[in] String;
+                              Drop     : @key[in] Truncation := Error)
+         @key[return] Bounded_String;
+
+
+      @key[procedure] @AdaSubDefn{Replace_Slice} (Source   : @key[in] 
@key[out] Bounded_String;
+                               Low      : @key[in] Positive;
+                               High     : @key[in] Natural;
+                               By       : @key[in] String;
+                               Drop     : @key[in] Truncation := Error);
+
+
+      @key[function] @AdaSubDefn{Insert} (Source   : @key[in] Bounded_String;
+                       Before   : @key[in] Positive;
+                       New_Item : @key[in] String;
+                       Drop     : @key[in] Truncation := Error)
+         @key[return] Bounded_String;
+
+      @key[procedure] @AdaSubDefn{Insert} (Source   : @key[in] @key[out] 
Bounded_String;
+                        Before   : @key[in] Positive;
+                        New_Item : @key[in] String;
+                        Drop     : @key[in] Truncation := Error);
+
+
+      @key[function] @AdaSubDefn{Overwrite} (Source    : @key[in] 
Bounded_String;
+                          Position  : @key[in] Positive;
+                          New_Item  : @key[in] String;
+                          Drop      : @key[in] Truncation := Error)
+         @key[return] Bounded_String;
+
+      @key[procedure] @AdaSubDefn{Overwrite} (Source    : @key[in] @key[out] 
Bounded_String;
+                           Position  : @key[in] Positive;
+                           New_Item  : @key[in] String;
+                           Drop      : @key[in] Truncation := Error);
+
+      @key[function] @AdaSubDefn{Delete} (Source  : @key[in] Bounded_String;
+                       From    : @key[in] Positive;
+                       Through : @key[in] Natural)
+         @key[return] Bounded_String;
+
+      @key[procedure] @AdaSubDefn{Delete} (Source  : @key[in] @key[out] 
Bounded_String;
+                        From    : @key[in] Positive;
+                        Through : @key[in] Natural);
+
+   address@hidden selector subprograms}
+
+      @key[function] @AdaSubDefn{Trim} (Source : @key[in] Bounded_String;
+                     Side   : @key[in] Trim_End)
+         @key[return] Bounded_String;
+      @key[procedure] @AdaSubDefn{Trim} (Source : @key[in] @key[out] 
Bounded_String;
+                      Side   : @key[in] Trim_End);
+
+      @key[function] @AdaSubDefn{Trim} (Source : @key[in] Bounded_String;
+                     Left   : @key[in] Maps.Character_Set;
+                     Right  : @key[in] Maps.Character_Set)
+         @key[return] Bounded_String;
+
+      @key[procedure] @AdaSubDefn{Trim} (Source : @key[in] @key[out] 
Bounded_String;
+                      Left   : @key[in] Maps.Character_Set;
+                      Right  : @key[in] Maps.Character_Set);
+
+      @key[function] @AdaSubDefn{Head} (Source : @key[in] Bounded_String;
+                     Count  : @key[in] Natural;
+                     Pad    : @key[in] Character  := Space;
+                     Drop   : @key[in] Truncation := Error)
+         @key[return] Bounded_String;
+
+      @key[procedure] @AdaSubDefn{Head} (Source : @key[in] @key[out] 
Bounded_String;
+                      Count  : @key[in] Natural;
+                      Pad    : @key[in] Character  := Space;
+                      Drop   : @key[in] Truncation := Error);
+
+      @key[function] @AdaSubDefn{Tail} (Source : @key[in] Bounded_String;
+                     Count  : @key[in] Natural;
+                     Pad    : @key[in] Character  := Space;
+                     Drop   : @key[in] Truncation := Error)
+         @key[return] Bounded_String;
+
+      @key[procedure] @AdaSubDefn{Tail} (Source : @key[in] @key[out] 
Bounded_String;
+                      Count  : @key[in] Natural;
+                      Pad    : @key[in] Character  := Space;
+                      Drop   : @key[in] Truncation := Error);
+
+   address@hidden constructor subprograms}
+
+      @key[function] "*" (Left  : @key[in] Natural;
+                    Right : @key[in] Character)
+         @key[return] Bounded_String;
+
+      @key[function] "*" (Left  : @key[in] Natural;
+                    Right : @key[in] String)
+         @key[return] Bounded_String;
+
+      @key[function] "*" (Left  : @key[in] Natural;
+                    Right : @key[in] Bounded_String)
+         @key[return] Bounded_String;
+
+
+      @key[function] @AdaSubDefn{Replicate} (Count : @key[in] Natural;
+                          Item  : @key[in] Character;
+                          Drop  : @key[in] Truncation := Error)
+         @key[return] Bounded_String;
+
+      @key[function] @AdaSubDefn{Replicate} (Count : @key[in] Natural;
+                          Item  : @key[in] String;
+                          Drop  : @key[in] Truncation := Error)
+         @key[return] Bounded_String;
+
+      @key[function] @AdaSubDefn{Replicate} (Count : @key[in] Natural;
+                          Item  : @key[in] Bounded_String;
+                          Drop  : @key[in] Truncation := Error)
+         @key[return] Bounded_String;
+
+   @key[private]
+       ... -- @Examcom{not specified by the language}
+   @key[end] Generic_Bounded_Length;
+
address@hidden Ada.Strings.Bounded;
address@hidden
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0097],ARef=[AI95-00115-01]}
address@hidden,Kind=[DeletedAdded],ARef=[AI95-00344-01]}
address@hidden,address@hidden,New=[Bounded_String cannot be
+implemented as a (directly) controlled type,
+as Ada.Strings.Bounded.Generic_Bounded_Length can be instantiated at any
+nesting depth. Bounded_String could have
+a component of a controlled type, as long as that type is declared in some
+other (nongeneric) package (including directly in 
Ada.Strings.Bounded).],Old=[]}]}
address@hidden allows controlled types to be declared at
+any nesting depth, so this note is obsolete.}
+
address@hidden
+
+Null_Bounded_String represents the null string.
+If an object of type Bounded_String is not otherwise initialized, it
+will be initialized to the same value as Null_Bounded_String.
address@hidden
address@hidden@Keepnext
address@hidden Length (Source : @key[in] Bounded_String) @key[return] 
Length_Range;
address@hidden
address@hidden@;The Length function returns the length of the string 
represented by
+Source.
+
address@hidden@Keepnext
address@hidden To_Bounded_String (Source : @key[in] String;
+                            Drop   : @key[in] Truncation := Error)
+   @key[return] Bounded_String;
address@hidden
address@hidden@ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0264-1]}
+If Source'Length <= address@hidden,New=[,],Old=[]} then
+this function
+returns a Bounded_String that represents Source.
address@hidden,New=[,],Old=[]}
+the effect depends on the value of Drop:
address@hidden
+If Drop=Left, then
+the result is a Bounded_String that represents the string comprising
+the rightmost Max_Length characters of Source.
+
+ If Drop=Right, then
+the result is a Bounded_String that represents the string comprising
+the leftmost Max_Length characters of Source.
+
address@hidden@;If Drop=Error, then Strings.Length_Error is propagated.
address@hidden
+
address@hidden@Keepnext
address@hidden To_String (Source : @key[in] Bounded_String) @key[return] String;
address@hidden
address@hidden@;To_String returns the String value with lower bound 1 
represented by
+Source. If B is a Bounded_String, then B = To_Bounded_String(To_String(B)).
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Set_Bounded_String
+   (Target :    @key[out] Bounded_String;
+    Source : @key[in]     String;
+    Drop   : @key[in]     Truncation := Error);]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Type=[Trailing],Text=[Equivalent to Target := To_Bounded_String 
(Source, Drop);]}
+
address@hidden
+
+Each of the Append functions returns a Bounded_String obtained by concatenating
+the string or character given or represented by one of the parameters,
+with the string or character given or represented by the other parameter,
+and applying To_Bounded_String to the concatenation result string,
+with Drop as provided to the Append function.
+
+Each of the procedures Append(Source, New_Item, Drop) has the same
+effect as the corresponding assignment Source :=
+Append(Source, New_Item, Drop).
+
+Each of the "&" functions has the same effect as the corresponding
+Append function, with Error as the Drop parameter.
address@hidden
address@hidden@Keepnext
address@hidden Element (Source : @key[in] Bounded_String;
+                  Index  : @key[in] Positive)
+   @key[return] Character;
address@hidden
address@hidden@;Returns the character at position Index in the string 
represented
+by Source; propagates Index_Error if Index > Length(Source).
+
address@hidden@Keepnext
address@hidden Replace_Element (Source : @key[in] @key[out] Bounded_String;
+                           Index  : @key[in] Positive;
+                           By     : @key[in] Character);
address@hidden
address@hidden@;Updates Source such that the character at position Index in the
+string represented by Source is By;
+propagates Index_Error if Index > Length(Source).
+
address@hidden@Keepnext
address@hidden Slice (Source : @key[in] Bounded_String;
+                Low    : @key[in] Positive;
+                High   : @key[in] Natural)
+   @key[return] String;
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0049],ARef=[AI95-00128-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00238-01]}
address@hidden@;Returns the slice at positions Low through High in the string
+represented by Source; propagates Index_Error if
+Low > Length(Source)address@hidden or High > Length(Source)],address@hidden,
+New=[ The bounds of the returned string are Low and High.],Old=[]}.
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Bounded_Slice
+   (Source : @key[in] Bounded_String;
+    Low    : @key[in] Positive;
+    High   : @key[in] Natural)
+       @key[return] Bounded_String;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Type=[Trailing],Text=[Returns the slice at positions Low
+through High in the string represented by Source as a bounded string;
+propagates Index_Error if Low > Length(Source)+1 or High > Length(Source).]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,KeepNext=[T],address@hidden Bounded_Slice
+   (Source : @key[in]     Bounded_String;
+    Target :    @key[out] Bounded_String;
+    Low    : @key[in]     Positive;
+    High   : @key[in]     Natural);]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Type=[Trailing],Text=[Equivalent to Target := Bounded_Slice 
(Source, Low, High);]}
+
address@hidden
+
+Each of the functions "=", "<", ">", "<=", and ">="
+returns the same result as the corresponding String
+operation applied to the String values given or represented by
+the two parameters.
+
+Each of the search subprograms (Index, Index_Non_Blank,
+Count, Find_Token) has the
+same effect as the corresponding subprogram in Strings.Fixed applied
+to the string represented by the Bounded_String parameter.
+
+Each of the Translate subprograms, when applied to a Bounded_String, has
+an analogous effect to the corresponding subprogram in Strings.Fixed.
+For the Translate function,
+the translation is applied to the string represented by the Bounded_String
+parameter, and the result is converted (via To_Bounded_String) to a
+Bounded_String.
+For the Translate procedure, the string represented by the Bounded_String
+parameter after the translation is given by the Translate function for
+fixed-length strings applied to the string represented by the
+original value of the parameter.
+
address@hidden,Kind=[Revised],Ref=[8652/0049],ARef=[AI95-00128-01]}
+Each of the transformation subprograms (Replace_Slice, Insert,
+Overwrite, Delete), selector subprograms (Trim, Head, Tail),
+and constructor functions ("*") has an effect based on its
+corresponding subprogram in Strings.Fixed, and Replicate is based on
+Fixed."*". @Chg{New=[In the case of a function],
+Old=[For each of these subprograms]}, the corresponding
+fixed-length string subprogram is applied to the string represented by
+the Bounded_String parameter. To_Bounded_String is applied the result
+string, with Drop (or Error in the case of Generic_Bounded_Length."*")
+determining the effect when the string length exceeds Max_Length.
address@hidden the case of a procedure, the corresponding function in
address@hidden@address@hidden@!Length is applied, with the result
+assigned into the Source parameter.],Old=[]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+The "/=" operations between Bounded_String and String, and between String
+and Bounded_String, are automatically defined based on the @Chg{Version=[2],
+New=[corresponding],Old=[corrsponding]}
+"=" operations.
address@hidden
address@hidden
+
address@hidden
+Bounded string objects should not be implemented by implicit
+pointers and dynamic allocation.
address@hidden,Kind=[Added],address@hidden,
+Text=[Bounded string objects should not be implemented by implicit
+pointers and dynamic allocation.]}]}
address@hidden
address@hidden@;The following is a possible implementation of the private part
+of the package:
address@hidden
address@hidden Bounded_String_Internals (Length : Length_Range := 0) @key[is]
+   @key[record]
+      Data : String(1..Length);
+   @key[end] @key[record];
+
address@hidden Bounded_String @key[is]
+   @key[record]
+      Data : Bounded_String_Internals;  address@hidden Unconstrained}
+   @key[end] @key[record];
+
+Null_Bounded_String : @key[constant] Bounded_String :=
+   (Data => (Length => 0,
+             Data   => (1..0 => ' ')));
address@hidden
address@hidden
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00238-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @B[Amendment Correction:] The bounds of the string returned from
+  Slice are now defined. This is technically an inconsistency; if a program
+  depended on some other lower bound for the string returned from Slice,
+  it could fail when compiled with Ada 2005. Such code is not portable even
+  between Ada 95 implementations, so it should be very rare.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00301-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  Procedure Set_Bounded_String, two Bounded_Slice subprograms, and overloaded
+  versions of Index and Index_Non_Blank are
+  @Chg{Version=[3],New=[],Old=[newly ]}added to
+  Strings.Bounded.Generic_Bounded_Length. If an instance of 
Generic_Bounded_Length is
+  referenced in a @nt{use_clause}, and an entity @i<E> with the
+  @nt{defining_identifier} as a new entity in Generic_Bounded_Length is 
defined in a
+  package that is also referenced in a @nt{use_clause}, the entity @i<E> may no
+  longer be use-visible, resulting in errors. This should be rare and is easily
+  fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0049],ARef=[AI95-00128-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the conditions 
for
+  which Slice raises Index_Error.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0049],ARef=[AI95-00128-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified the meaning of
+  transformation, selector, and constructor subprograms by describing the
+  effects of procedures and functions separately.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0031-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  An overloaded version of Find_Token is added to
+  Strings.Bounded.Generic_Bounded_Length. If an instance of 
Generic_Bounded_Length is
+  referenced in a @nt{use_clause}, and an
+  entity @i<E> with a @nt{defining_identifier} of Find_Token is
+  defined in a package that is also referenced in a @nt{use_clause}, the entity
+  @i<E> may no longer be use-visible, resulting in errors. This should be rare
+  and is easily fixed if it does occur.]}
address@hidden
+
+
+
address@hidden String Handling}
address@hidden
+The language-defined package Strings.Unbounded provides a
+ private type Unbounded_String and a
+set of operations. An object of type Unbounded_String represents a String
+whose low bound is 1 and whose length
+can vary conceptually between 0 and Natural'Last.
+The subprograms for fixed-length string handling
+are either overloaded directly for Unbounded_String, or are modified as
+needed to reflect the flexibility in length. Since the
+Unbounded_String type is private, relevant constructor and selector
+operations are provided.
address@hidden
+The transformation operations for fixed- and bounded-length strings that
+are not necessarily length preserving are supplied for Unbounded_String
+as procedures as well as functions.
+This allows an implementation to do an initial allocation for
+an unbounded string and to avoid further allocations as long
+as the length does not exceed the allocated length.
address@hidden
address@hidden
+
address@hidden
address@hidden@;The library package Strings.Unbounded has the following 
declaration:
address@hidden
address@hidden Ada.Strings.Maps;
address@hidden,address@hidden Ada.Strings.Unbounded @key[is]
+   @key[pragma] Preelaborate(Unbounded);
+
address@hidden,Kind=[Revised],ARef=[AI95-00161-01]}
+   @key[type] @AdaTypeDefn{Unbounded_String} @key[is] 
@key[private];@Chg{Version=[2],New=[
+   @key[pragma] Preelaborable_Initialization(Unbounded_String);],Old=[]}
+
+   @AdaObjDefn{Null_Unbounded_String} : @key[constant] Unbounded_String;
+
+   @key[function] @AdaSubDefn{Length} (Source : @key[in] Unbounded_String) 
@key[return] Natural;
+
+   @key[type] @AdaTypeDefn{String_Access} @key[is] @key[access] @key[all] 
String;
+   @key[procedure] @AdaSubDefn{Free} (X : @key[in] @key[out] String_Access);
+
address@hidden Conversion, Concatenation, and Selection functions}
+
+   @key[function] @AdaSubDefn{To_Unbounded_String} (Source : @key[in] String)
+      @key[return] Unbounded_String;
+
+   @key[function] @AdaSubDefn{To_Unbounded_String} (Length : @key[in] Natural)
+      @key[return] Unbounded_String;
+
+   @key[function] @AdaSubDefn{To_String} (Source : @key[in] Unbounded_String) 
@key[return] String;
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Set_Unbounded_String}
+     (Target :    @key[out] Unbounded_String;
+      Source : @key[in]     String);]}
+
+   @key[procedure] @AdaSubDefn{Append} (Source   : @key[in out] 
Unbounded_String;
+                     New_Item : @key[in] Unbounded_String);
+
+   @key[procedure] @AdaSubDefn{Append} (Source   : @key[in out] 
Unbounded_String;
+                     New_Item : @key[in] String);
+
+   @key[procedure] @AdaSubDefn{Append} (Source   : @key[in out] 
Unbounded_String;
+                     New_Item : @key[in] Character);
+
+   @key[function] "&" (Left, Right : @key[in] Unbounded_String)
+      @key[return] Unbounded_String;
+
+   @key[function] "&" (Left : @key[in] Unbounded_String; Right : @key[in] 
String)
+      @key[return] Unbounded_String;
+
+   @key[function] "&" (Left : @key[in] String; Right : @key[in] 
Unbounded_String)
+      @key[return] Unbounded_String;
+
+   @key[function] "&" (Left : @key[in] Unbounded_String; Right : @key[in] 
Character)
+      @key[return] Unbounded_String;
+
+   @key[function] "&" (Left : @key[in] Character; Right : @key[in] 
Unbounded_String)
+      @key[return] Unbounded_String;
+
+
+   @key[function] @AdaSubDefn{Element} (Source : @key[in] Unbounded_String;
+                     Index  : @key[in] Positive)
+      @key[return] Character;
+
+   @key[procedure] @AdaSubDefn{Replace_Element} (Source : @key[in] @key[out] 
Unbounded_String;
+                              Index  : @key[in] Positive;
+                              By     : @key[in] Character);
+
+
+   @key[function] @AdaSubDefn{Slice} (Source : @key[in] Unbounded_String;
+                   Low    : @key[in] Positive;
+                   High   : @key[in] Natural)
+      @key[return] String;
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Unbounded_Slice}
+      (Source : @key[in] Unbounded_String;
+       Low    : @key[in] Positive;
+       High   : @key[in] Natural)
+          @key[return] Unbounded_String;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Unbounded_Slice}
+      (Source : @key[in]     Unbounded_String;
+       Target :    @key[out] Unbounded_String;
+       Low    : @key[in]     Positive;
+       High   : @key[in]     Natural);]}
+
+   @key[function] "="  (Left, Right : @key[in] Unbounded_String) @key[return] 
Boolean;
+
+   @key[function] "="  (Left : @key[in] Unbounded_String; Right : @key[in] 
String)
+     @key[return] Boolean;
+
+   @key[function] "="  (Left : @key[in] String; Right : @key[in] 
Unbounded_String)
+     @key[return] Boolean;
+
+   @key[function] "<"  (Left, Right : @key[in] Unbounded_String) @key[return] 
Boolean;
+
+   @key[function] "<"  (Left : @key[in] Unbounded_String; Right : @key[in] 
String)
+     @key[return] Boolean;
+
+   @key[function] "<"  (Left : @key[in] String; Right : @key[in] 
Unbounded_String)
+     @key[return] Boolean;
+
+   @key[function] "<=" (Left, Right : @key[in] Unbounded_String) @key[return] 
Boolean;
+
+   @key[function] "<="  (Left : @key[in] Unbounded_String; Right : @key[in] 
String)
+     @key[return] Boolean;
+
+   @key[function] "<="  (Left : @key[in] String; Right : @key[in] 
Unbounded_String)
+     @key[return] Boolean;
+
+   @key[function] ">"  (Left, Right : @key[in] Unbounded_String) @key[return] 
Boolean;
+
+   @key[function] ">"  (Left : @key[in] Unbounded_String; Right : @key[in] 
String)
+     @key[return] Boolean;
+
+   @key[function] ">"  (Left : @key[in] String; Right : @key[in] 
Unbounded_String)
+     @key[return] Boolean;
+
+   @key[function] ">=" (Left, Right : @key[in] Unbounded_String) @key[return] 
Boolean;
+
+   @key[function] ">="  (Left : @key[in] Unbounded_String; Right : @key[in] 
String)
+     @key[return] Boolean;
+
+   @key[function] ">="  (Left : @key[in] String; Right : @key[in] 
Unbounded_String)
+     @key[return] Boolean;
+
+
address@hidden Search subprograms}
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Index} (Source  : @key[in] 
Unbounded_String;
+                   Pattern : @key[in] String;
+                   From    : @key[in] Positive;
+                   Going   : @key[in] Direction := Forward;
+                   Mapping : @key[in] Maps.Character_Mapping := Maps.Identity)
+      @key[return] Natural;]}
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Index} (Source  : @key[in] 
Unbounded_String;
+                   Pattern : @key[in] String;
+                   From    : @key[in] Positive;
+                   Going   : @key[in] Direction := Forward;
+                   Mapping : @key[in] Maps.Character_Mapping_Function)
+      @key[return] Natural;]}
+
+   @key[function] @AdaSubDefn{Index} (Source   : @key[in] Unbounded_String;
+                   Pattern  : @key[in] String;
+                   Going    : @key[in] Direction := Forward;
+                   Mapping  : @key[in] Maps.Character_Mapping
+                                := Maps.Identity)
+      @key[return] Natural;
+
+   @key[function] @AdaSubDefn{Index} (Source   : @key[in] Unbounded_String;
+                   Pattern  : @key[in] String;
+                   Going    : @key[in] Direction := Forward;
+                   Mapping  : @key[in] Maps.Character_Mapping_Function)
+      @key[return] Natural;
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Index} (Source  : @key[in] 
Unbounded_String;
+                   Set     : @key[in] Maps.Character_Set;
+                   From    : @key[in] Positive;
+                   Test    : @key[in] Membership := Inside;
+                   Going    : @key[in] Direction := Forward)
+      @key[return] Natural;]}
+
+   @key[function] @AdaSubDefn{Index} (Source : @key[in] Unbounded_String;
+                   Set    : @key[in] Maps.Character_Set;
+                   Test   : @key[in] Membership := Inside;
+                   Going  : @key[in] Direction  := Forward) @key[return] 
Natural;
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Index_Non_Blank} (Source : 
@key[in] Unbounded_String;
+                             From   : @key[in] Positive;
+                             Going  : @key[in] Direction := Forward)
+      @key[return] Natural;]}
+
+   @key[function] @AdaSubDefn{Index_Non_Blank} (Source : @key[in] 
Unbounded_String;
+                             Going  : @key[in] Direction := Forward)
+      @key[return] Natural;
+
+
+   @key[function] @AdaSubDefn{Count} (Source   : @key[in] Unbounded_String;
+                   Pattern  : @key[in] String;
+                   Mapping  : @key[in] Maps.Character_Mapping
+                                := Maps.Identity)
+      @key[return] Natural;
+
+   @key[function] @AdaSubDefn{Count} (Source   : @key[in] Unbounded_String;
+                   Pattern  : @key[in] String;
+                   Mapping  : @key[in] Maps.Character_Mapping_Function)
+      @key[return] Natural;
+
+   @key[function] @AdaSubDefn{Count} (Source   : @key[in] Unbounded_String;
+                   Set      : @key[in] Maps.Character_Set)
+      @key[return] Natural;
+
+
address@hidden,Kind=[Added],ARef=[AI05-0031-1]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Find_Token} (Source : 
@key[in] Unbounded_String;
+                         Set    : @key[in] Maps.Character_Set;
+                         From   : @key[in] Positive;
+                         Test   : @key[in] Membership;
+                         First  : @key[out] Positive;
+                         Last   : @key[out] Natural);]}
+
+   @key[procedure] @AdaSubDefn{Find_Token} (Source : @key[in] Unbounded_String;
+                         Set    : @key[in] Maps.Character_Set;
+                         Test   : @key[in] Membership;
+                         First  : @key[out] Positive;
+                         Last   : @key[out] Natural);
+
+
address@hidden@;address@hidden String translation subprograms}
+
+   @key[function] @AdaSubDefn{Translate} (Source  : @key[in] Unbounded_String;
+                       Mapping : @key[in] Maps.Character_Mapping)
+      @key[return] Unbounded_String;
+
+   @key[procedure] @AdaSubDefn{Translate} (Source  : @key[in] @key[out] 
Unbounded_String;
+                        Mapping : @key[in] Maps.Character_Mapping);
+
+   @key[function] @AdaSubDefn{Translate} (Source  : @key[in] Unbounded_String;
+                       Mapping : @key[in] Maps.Character_Mapping_Function)
+      @key[return] Unbounded_String;
+
+   @key[procedure] @AdaSubDefn{Translate} (Source  : @key[in] @key[out] 
Unbounded_String;
+                        Mapping : @key[in] Maps.Character_Mapping_Function);
+
address@hidden@;address@hidden String transformation subprograms}
+
+   @key[function] @AdaSubDefn{Replace_Slice} (Source   : @key[in] 
Unbounded_String;
+                           Low      : @key[in] Positive;
+                           High     : @key[in] Natural;
+                           By       : @key[in] String)
+      @key[return] Unbounded_String;
+
+   @key[procedure] @AdaSubDefn{Replace_Slice} (Source   : @key[in] @key[out] 
Unbounded_String;
+                            Low      : @key[in] Positive;
+                            High     : @key[in] Natural;
+                            By       : @key[in] String);
+
+   @key[function] @AdaSubDefn{Insert} (Source   : @key[in] Unbounded_String;
+                    Before   : @key[in] Positive;
+                    New_Item : @key[in] String)
+      @key[return] Unbounded_String;
+
+   @key[procedure] @AdaSubDefn{Insert} (Source   : @key[in] @key[out] 
Unbounded_String;
+                     Before   : @key[in] Positive;
+                     New_Item : @key[in] String);
+
+   @key[function] @AdaSubDefn{Overwrite} (Source    : @key[in] 
Unbounded_String;
+                       Position  : @key[in] Positive;
+                       New_Item  : @key[in] String)
+      @key[return] Unbounded_String;
+
+   @key[procedure] @AdaSubDefn{Overwrite} (Source    : @key[in] @key[out] 
Unbounded_String;
+                        Position  : @key[in] Positive;
+                        New_Item  : @key[in] String);
+
+   @key[function] @AdaSubDefn{Delete} (Source  : @key[in] Unbounded_String;
+                    From    : @key[in] Positive;
+                    Through : @key[in] Natural)
+      @key[return] Unbounded_String;
+
+   @key[procedure] @AdaSubDefn{Delete} (Source  : @key[in] @key[out] 
Unbounded_String;
+                     From    : @key[in] Positive;
+                     Through : @key[in] Natural);
+
+   @key[function] @AdaSubDefn{Trim} (Source : @key[in] Unbounded_String;
+                  Side   : @key[in] Trim_End)
+      @key[return] Unbounded_String;
+
+   @key[procedure] @AdaSubDefn{Trim} (Source : @key[in] @key[out] 
Unbounded_String;
+                   Side   : @key[in] Trim_End);
+
+   @key[function] @AdaSubDefn{Trim} (Source : @key[in] Unbounded_String;
+                  Left   : @key[in] Maps.Character_Set;
+                  Right  : @key[in] Maps.Character_Set)
+      @key[return] Unbounded_String;
+
+   @key[procedure] @AdaSubDefn{Trim} (Source : @key[in] @key[out] 
Unbounded_String;
+                   Left   : @key[in] Maps.Character_Set;
+                   Right  : @key[in] Maps.Character_Set);
+
+
+   @key[function] @AdaSubDefn{Head} (Source : @key[in] Unbounded_String;
+                  Count  : @key[in] Natural;
+                  Pad    : @key[in] Character := Space)
+      @key[return] Unbounded_String;
+
+   @key[procedure] @AdaSubDefn{Head} (Source : @key[in] @key[out] 
Unbounded_String;
+                   Count  : @key[in] Natural;
+                   Pad    : @key[in] Character := Space);
+
+   @key[function] @AdaSubDefn{Tail} (Source : @key[in] Unbounded_String;
+                  Count  : @key[in] Natural;
+                  Pad    : @key[in] Character := Space)
+      @key[return] Unbounded_String;
+
+   @key[procedure] @AdaSubDefn{Tail} (Source : @key[in] @key[out] 
Unbounded_String;
+                   Count  : @key[in] Natural;
+                   Pad    : @key[in] Character := Space);
+
+   @key[function] "*" (Left  : @key[in] Natural;
+                 Right : @key[in] Character)
+      @key[return] Unbounded_String;
+
+   @key[function] "*" (Left  : @key[in] Natural;
+                 Right : @key[in] String)
+      @key[return] Unbounded_String;
+
+   @key[function] "*" (Left  : @key[in] Natural;
+                 Right : @key[in] Unbounded_String)
+      @key[return] Unbounded_String;
+
address@hidden
+   ... -- @Examcom{not specified by the language}
address@hidden Ada.Strings.Unbounded;
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00360-01]}
address@hidden,Text=[The type Unbounded_String
+needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization}).]}
+
+Null_Unbounded_String represents the null String.
+If an object of type Unbounded_String is not otherwise initialized, it
+will be initialized to the same value as Null_Unbounded_String.
+
+The function Length returns the length of the String represented by Source.
+
+The type String_Access provides a (nonprivate) access type for explicit
+processing of unbounded-length strings. The procedure Free performs
+an unchecked deallocation of an object of type String_Access.
+
+The function To_Unbounded_String(Source : in String)
+returns an Unbounded_String that represents Source.
+The function To_Unbounded_String(Length : in Natural)
+returns an Unbounded_String that represents an uninitialized String
+whose length is Length.
+
address@hidden@;The function To_String returns the String with lower bound 1
+represented by Source. To_String and To_Unbounded_String are related as 
follows:
address@hidden
+If S is a String, then To_String(To_Unbounded_String(S)) = S.
+
+If U is an Unbounded_String, then To_Unbounded_String(To_String(U)) = U.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[The procedure Set_Unbounded_String sets Target to an 
Unbounded_String that
+represents Source.]}
+
+For each of the Append procedures,
+the resulting string represented by the Source parameter is given
+by the concatenation of the original value of Source and the value
+of New_Item.
+
+Each of the "&" functions returns an Unbounded_String obtained by concatenating
+the string or character given or represented by one of the parameters,
+with the string or character given or represented by the other parameter,
+and applying To_Unbounded_String to the concatenation result string.
+
+The Element, Replace_Element, and Slice subprograms have the same effect
+as the corresponding bounded-length string subprograms.
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0262-1]}
address@hidden,Text=[The function Unbounded_Slice returns the slice at
+positions Low through High in the string represented by Source as an
+Unbounded_String. The procedure Unbounded_Slice sets Target to the
+Unbounded_String representing the slice at positions Low through High in the
+string represented by Source. Both
address@hidden,New=[subprograms],Old=[routines]} propagate Index_Error
+if Low > Length(Source)+1 or High > Length(Source).]}
+
+Each of the functions "=", "<", ">", "<=", and ">="
+returns the same result as the corresponding String
+operation applied to the String values given or represented by Left and Right.
+
+Each of the search subprograms (Index, Index_Non_Blank, Count, Find_Token)
+has the same effect as the corresponding subprogram in Strings.Fixed applied
+to the string represented by the Unbounded_String parameter.
+
+The Translate function has
+an analogous effect to the corresponding subprogram in Strings.Fixed.
+The translation is applied to the string represented by the Unbounded_String
+parameter, and the result is converted (via To_Unbounded_String) to an
+Unbounded_String.
+
+Each of the transformation functions (Replace_Slice, Insert, Overwrite,
+Delete), selector functions (Trim, Head, Tail), and constructor functions
+("*") is likewise analogous to its corresponding
+subprogram in Strings.Fixed. For each of the subprograms,
+the corresponding fixed-length string subprogram is applied to the string
+represented by the Unbounded_String parameter, and
+To_Unbounded_String is applied the result string.
+
+For each of the procedures Translate,
+Replace_Slice, Insert, Overwrite, Delete,
+Trim, Head, and Tail, the resulting string represented by the Source parameter
+is given by the corresponding function for fixed-length strings applied to
+the string represented by Source's original value.
address@hidden
+
address@hidden
+No storage associated
+with an Unbounded_String object shall be
+lost upon assignment or scope exit.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00301-01]}
+A sample implementation of the private part of
+the package and several of the subprograms appears in the @Chg{Version=[2],
+New=[Ada 95 ],Old=[]}Rationale.
+
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00360-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] Type Unbounded_String is defined to need
+  finalization. If the restriction No_Nested_Finalization (see
+  @RefSecNum{Tasking Restrictions}) applies to the partition, and
+  Unbounded_String does not have a controlled part, it will not be allowed in
+  local objects in Ada 2005 whereas it would be allowed in original Ada 95.
+  Such code is not portable, as most Ada compilers have a controlled part in
+  Unbounded_String, and thus would be illegal.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00301-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[Procedure Set_Unbounded_String,
+  two Unbounded_Slice subprograms, and overloaded
+  versions of Index and Index_Non_Blank are
+  @Chg{Version=[3],New=[],Old=[newly ]}added to Strings.Unbounded.
+  If Strings.Unbounded is
+  referenced in a @nt{use_clause}, and an entity @i<E> with the same
+  @nt{defining_identifier} as a new entity in Strings.Unbounded is defined in a
+  package that is also referenced in a @nt{use_clause}, the entity @i<E> may no
+  longer be use-visible, resulting in errors. This should be rare and is easily
+  fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00161-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b[Amendment Correction:] Added a @nt{pragma} Preelaborable_Initialization to
+  type Unbounded_String, so that it can be used to declare default-initialized
+  objects in preelaborated units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0031-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  An overloaded version of Find_Token is added to
+  Strings.Unbounded. If Strings.Unbounded is referenced in a @nt{use_clause},
+  and an entity @i<E> with a @nt{defining_identifier} of Find_Token is
+  defined in a package that is also referenced in a @nt{use_clause}, the entity
+  @i<E> may no longer be use-visible, resulting in errors. This should be rare
+  and is easily fixed if it does occur.]}
address@hidden
+
+
address@hidden Sets and Mappings}
+
address@hidden
+
+The language-defined package Strings.Maps.Constants declares
+Character_Set
+and Character_Mapping
+constants corresponding to classification and conversion functions
+in package Characters.Handling.
address@hidden
+The Constants package is a child of Strings.Maps since it needs
+visibility of the private part of Strings.Maps in order to
+initialize the constants
+in a preelaborable way (i.e. via aggregates versus function calls).
address@hidden
+
address@hidden
+
address@hidden
address@hidden@;The library package Strings.Maps.Constants has the following 
declaration:
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00362-01]}
address@hidden,address@hidden Ada.Strings.Maps.Constants @key[is]
+   @key[pragma] @Chg{Version=[2],New=[Pure],Old=[Preelaborate]}(Constants);
+
+   @AdaObjDefn{Control_Set}           : @key[constant] Character_Set;
+   @AdaObjDefn{Graphic_Set}           : @key[constant] Character_Set;
+   @AdaObjDefn{Letter_Set}            : @key[constant] Character_Set;
+   @AdaObjDefn{Lower_Set}             : @key[constant] Character_Set;
+   @AdaObjDefn{Upper_Set}             : @key[constant] Character_Set;
+   @AdaObjDefn{Basic_Set}             : @key[constant] Character_Set;
+   @AdaObjDefn{Decimal_Digit_Set}     : @key[constant] Character_Set;
+   @AdaObjDefn{Hexadecimal_Digit_Set} : @key[constant] Character_Set;
+   @AdaObjDefn{Alphanumeric_Set}      : @key[constant] Character_Set;
+   @AdaObjDefn{Special_Set}           : @key[constant] Character_Set;
+   @AdaObjDefn{ISO_646_Set}           : @key[constant] Character_Set;
+
+   @AdaObjDefn{Lower_Case_Map}        : @key[constant] Character_Mapping;
+     address@hidden to lower case for letters, else identity}
+   @AdaObjDefn{Upper_Case_Map}        : @key[constant] Character_Mapping;
+     address@hidden to upper case for letters, else identity}
+   @AdaObjDefn{Basic_Map}             : @key[constant] Character_Mapping;
+     address@hidden to basic letter for letters, else identity}
+
address@hidden
+   ... -- @Examcom{not specified by the language}
address@hidden Ada.Strings.Maps.Constants;
address@hidden
+
+
+Each of these constants represents a correspondingly named
+set of characters or
+character mapping in Characters.Handling
+(see @refsecnum(The Package Characters.Handling)).
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0114-1]}
address@hidden,Text=[There are certain characters which are defined to be
+lower case letters by ISO 10646 and are therefore allowed in identifiers, but
+are not considered lower case letters by Ada.Strings.Maps.Constants.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This is to maintain runtime compatibility with 
the
+  Ada 95 definitions of these constants; existing correct programs could break 
if
+  the definitions were changed in a way the programs did not anticipate.]}
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00362-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Strings.Maps.Constants is now Pure,
+  so it can be used in pure units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0114-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added a note to clarify 
that
+  these constants don't have any relationship to the characters allowed in
+  identifiers.]}
address@hidden
+
+
address@hidden Handling}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0286-1]}
+Facilities for handling strings of Wide_Character elements are
+found in the packages address@hidden, address@hidden,
address@hidden@!Bounded, address@hidden@!Unbounded,
+and address@hidden@address@hidden@Chg{Version=[2],New=[, and in the
address@hidden,New=[library ],Old=[]}functions address@hidden,
address@hidden@!Wide_Hash,
address@hidden@!Wide_Hash,@Chg{Version=[3],New=[],Old=[ and]}
address@hidden@address@hidden,New=[,
address@hidden@address@hidden@!Insensitive,
address@hidden@address@hidden@address@hidden,
address@hidden@address@hidden@address@hidden,
address@hidden@address@hidden@address@hidden,
address@hidden@address@hidden@!Insensitive,
address@hidden@address@hidden@address@hidden,
address@hidden@address@hidden@address@hidden, and
address@hidden@address@hidden@address@hidden,Old=[]}],Old=[]}.
+They provide the same string-handling operations
+as the corresponding address@hidden,New=[ and functions],Old=[]}
+for strings of Character elements.
address@hidden,address@hidden
address@hidden,address@hidden
address@hidden,address@hidden
address@hidden,address@hidden
address@hidden@!Fixed],address@hidden
address@hidden@!Bounded],address@hidden
address@hidden@!Unbounded],address@hidden
address@hidden,address@hidden,address@hidden
address@hidden@!Fixed],address@hidden
address@hidden@!Bounded],address@hidden
address@hidden@!Unbounded],address@hidden
address@hidden,address@hidden
address@hidden@!Fixed],address@hidden
address@hidden@!Bounded],address@hidden
address@hidden@!Unbounded],address@hidden,Old=[]}
address@hidden@!Maps],address@hidden
address@hidden
+
address@hidden
+The package Strings.Wide_Maps has the following declaration.
address@hidden
address@hidden,address@hidden@key[package] Ada.Strings.Wide_Maps @key[is]
+   @key[pragma] Preelaborate(Wide_Maps);
+
address@hidden,Kind=[Revised],ARef=[AI95-00161-01]}
+   address@hidden Representation for a set of Wide_Character values:}
+   @key[type] @AdaTypeDefn{Wide_Character_Set} @key[is] 
@key[private];@Chg{Version=[2],New=[
+   @key[pragma] Preelaborable_Initialization(Wide_Character_Set);],Old=[]}
+
+   @AdaObjDefn{Null_Set} : @key[constant] Wide_Character_Set;
+
+   @key[type] @AdaTypeDefn{Wide_Character_Range} @key[is]
+     @key[record]
+         Low  : Wide_Character;
+         High : Wide_Character;
+     @key[end] @key[record];
+   -- @Examcom{Represents Wide_Character range Low..High}
+
+   @key[type] @AdaTypeDefn{Wide_Character_Ranges} @key[is] @key[array] 
(Positive @key[range] <>)
+      @key[of] Wide_Character_Range;
+
+   @key[function] @AdaSubDefn{To_Set}    (Ranges : @key[in] 
Wide_Character_Ranges)
+      @key[return] Wide_Character_Set;
+
+   @key[function] @AdaSubDefn{To_Set}    (Span   : @key[in] 
Wide_Character_Range)
+      @key[return] Wide_Character_Set;
+
+   @key[function] @AdaSubDefn{To_Ranges} (Set    : @key[in] Wide_Character_Set)
+      @key[return] Wide_Character_Ranges;
+
+   @key[function] "="   (Left, Right : @key[in] Wide_Character_Set) 
@key[return] Boolean;
+
+   @key[function] "@key[not]" (Right : @key[in] Wide_Character_Set)
+      @key[return] Wide_Character_Set;
+   @key[function] "@key[and]" (Left, Right : @key[in] Wide_Character_Set)
+      @key[return] Wide_Character_Set;
+   @key[function] "@key[or]"  (Left, Right : @key[in] Wide_Character_Set)
+      @key[return] Wide_Character_Set;
+   @key[function] "@key[xor]" (Left, Right : @key[in] Wide_Character_Set)
+      @key[return] Wide_Character_Set;
+   @key[function] "-"   (Left, Right : @key[in] Wide_Character_Set)
+      @key[return] Wide_Character_Set;
+
+   @key[function] @AdaSubDefn{Is_In} (Element : @key[in] Wide_Character;
+                   Set     : @key[in] Wide_Character_Set)
+      @key[return] Boolean;
+
+   @key[function] @AdaSubDefn{Is_Subset} (Elements : @key[in] 
Wide_Character_Set;
+                       Set      : @key[in] Wide_Character_Set)
+      @key[return] Boolean;
+
+   @key[function] "<=" (Left  : @key[in] Wide_Character_Set;
+                  Right : @key[in] Wide_Character_Set)
+      @key[return] Boolean @key[renames] Is_Subset;
+
+
+   address@hidden Alternative representation for a set of Wide_Character 
values:}
+   @key[subtype] 
@AdaSubtypeDefn{Name=[Wide_Character_Sequence],Of=[Wide_String]} @key[is] 
Wide_String;
+
+   @key[function] @AdaSubDefn{To_Set} (Sequence  : @key[in] 
Wide_Character_Sequence)
+      @key[return] Wide_Character_Set;
+
+   @key[function] @AdaSubDefn{To_Set} (Singleton : @key[in] Wide_Character)
+      @key[return] Wide_Character_Set;
+
+   @key[function] @AdaSubDefn{To_Sequence} (Set  : @key[in] Wide_Character_Set)
+      @key[return] Wide_Character_Sequence;
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00161-01]}
+   address@hidden Representation for a Wide_Character to Wide_Character 
mapping:}
+   @key[type] @AdaTypeDefn{Wide_Character_Mapping} @key[is] 
@key[private];@Chg{Version=[2],New=[
+   @key[pragma] Preelaborable_Initialization(Wide_Character_Mapping);],Old=[]}
+
+   @key[function] @AdaSubDefn{Value} (Map     : @key[in] 
Wide_Character_Mapping;
+                   Element : @key[in] Wide_Character)
+      @key[return] Wide_Character;
+
+   @AdaObjDefn{Identity} : @key[constant] Wide_Character_Mapping;
+
+   @key[function] @AdaSubDefn{To_Mapping} (From, To : @key[in] 
Wide_Character_Sequence)
+      @key[return] Wide_Character_Mapping;
+
+   @key[function] @AdaSubDefn{To_Domain} (Map : @key[in] 
Wide_Character_Mapping)
+      @key[return] Wide_Character_Sequence;
+
+   @key[function] @AdaSubDefn{To_Range}  (Map : @key[in] 
Wide_Character_Mapping)
+      @key[return] Wide_Character_Sequence;
+
+
+   @key{type} @AdaTypeDefn{Wide_Character_Mapping_Function} @key{is}
+      @key{access} @key{function} (From : @key{in} Wide_Character) 
@key{return} Wide_Character;
+
address@hidden
+   ... -- @Examcom{not specified by the language}
address@hidden Ada.Strings.Wide_Maps;
address@hidden
+
+The context clause for each of the packages Strings.Wide_Fixed,
+Strings.Wide_Bounded, and Strings.Wide_Unbounded
+identifies Strings.Wide_Maps instead of Strings.Maps.
+
address@hidden,Kind=[Added],ARef=[AI05-0223-1]}
address@hidden,Text=[Types Wide_Character_Set and Wide_Character_Mapping
+need finalization.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00302-03]}
address@hidden,Kind=[Revised],ARef=[AI05-0286-1]}
address@hidden@;For each of the packages Strings.Fixed, Strings.Bounded,
+Strings.Unbounded, and address@hidden,New=[, and
+for @Chg{Version=[3],New=[library ],Old=[]}functions
+Strings.Hash, Strings.Fixed.Hash, Strings.Bounded.Hash,
address@hidden,New=[],Old=[and address@hidden,
address@hidden,address@hidden@address@hidden,
address@hidden@address@hidden,
address@hidden@address@hidden,
address@hidden@address@hidden,
address@hidden@address@hidden,
address@hidden@address@hidden,
address@hidden@address@hidden, and
address@hidden@address@hidden, ],Old=[]}],Old=[]}the
+corresponding wide string
+package @Chg{Version=[3],New=[or function ],Old=[]}has
+the same contents except that
address@hidden
+Wide_Space replaces Space
+
+Wide_Character replaces Character
+
+Wide_String replaces String
+
+Wide_Character_Set replaces Character_Set
+
+Wide_Character_Mapping replaces Character_Mapping
+
+Wide_Character_Mapping_Function replaces Character_Mapping_Function
+
+Wide_Maps replaces Maps
+
+Bounded_Wide_String replaces Bounded_String
+
+Null_Bounded_Wide_String replaces Null_Bounded_String
+
+To_Bounded_Wide_String replaces To_Bounded_String
+
+To_Wide_String replaces To_String
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[Set_Bounded_Wide_String replaces Set_Bounded_String]}
+
+Unbounded_Wide_String replaces Unbounded_String
+
+Null_Unbounded_Wide_String replaces Null_Unbounded_String
+
+Wide_String_Access replaces String_Access
+
+To_Unbounded_Wide_String replaces To_Unbounded_String
+
address@hidden,Kind=[Added],ARef=[AI95-00301-01]}
address@hidden,Text=[Set_Unbounded_Wide_String replaces Set_Unbounded_String]}
+
address@hidden
+
address@hidden@keepnext@;The following additional declaration is present in
+Strings.Wide_Maps.Wide_Constants:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden : @key[constant] Wide_Maps.Wide_Character_Set;
address@hidden each Wide_Character value WC such address@hidden,New=[
+--],address@hidden@Chg{Version=[2],New=[Conversions.],Old=[]}Is_Character(WC) 
is True}
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00395-01]}
address@hidden,Text=[Each Wide_Character_Set constant in the package
+Strings.Wide_Maps.Wide_Constants contains no values outside the Character
+portion of Wide_Character. Similarly, each Wide_Character_Mapping constant in
+this package is the identity mapping when applied to any element outside the
+Character portion of Wide_Character.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00362-01]}
address@hidden,address@hidden Pure is replaced by
address@hidden Preelaborate in Strings.Wide_Maps.Wide_Constants.]}
+
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+If a null Wide_Character_Mapping_Function is passed to any of the
+Wide_String handling subprograms, Constraint_Error is propagated.
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00395-01]}
address@hidden,Text=[Each Wide_Character_Set constant in the package
+Strings.Wide_Maps.Wide_Constants contains no values outside the Character
+portion of Wide_Character. Similarly, each Wide_Character_Mapping
+constant in this package is the identity mapping when applied to
+any element outside the Character portion of Wide_Character.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00301-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  Various new operations are added to Strings.Wide_Fixed, Strings.Wide_Bounded,
+  and Strings.Wide_Unbounded. If one of these packages is referenced in a
+  @nt{use_clause}, and an entity @i<E> with the same @nt{defining_identifier}
+  as a new entity is defined in a package that is also referenced in a
+  @nt{use_clause}, the entity @i<E> may no longer be use-visible, resulting in
+  errors. This should be rare and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00161-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b[Amendment Correction:] Added @nt{pragma} Preelaborable_Initialization to
+  types Wide_Character_Set and Wide_Character_Mapping, so that they can be
+  used to declare default-initialized objects in preelaborated units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[Corrected the description of Character_Set.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],Text=[Added wide versions of Strings.Hash and
+  Strings.Unbounded.Hash.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00362-01]}
+  @ChgAdded{Version=[2],Text=[Added wording so that
+  Strings.Wide_Maps.Wide_Constants does not change to Pure.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00395-01]}
+  @ChgAdded{Version=[2],Text=[The second Note is now normative text, since
+  there is no way to derive it from the other rules. It's a little
+  weird given the use of Unicode character classifications in Ada 2005;
+  but changing it would be inconsistent with Ada 95 and a one-to-one
+  mapping isn't necessarily correct anyway.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0286-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The case insenstive library functions
+  (address@hidden@address@hidden,
+  address@hidden@address@hidden@!Insensitive,
+  address@hidden@address@hidden@!Insensitive,
+  address@hidden@address@hidden@!Insensitive,
+  address@hidden@address@hidden,
+  address@hidden@address@hidden@!Insensitive,
+  address@hidden@address@hidden@!Insensitive, and
+  address@hidden@address@hidden@!Insensitive)
+  are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0223-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction>: Identified 
Wide_Character_Set
+  and Wide_Character_Mapping as needing finalization. It is likely that they
+  are implemented with a controlled type, so this change is unlikely to make
+  any difference in practice.]}
address@hidden
+
+
address@hidden,Name=[Wide_Wide_String Handling]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0286-1]}
address@hidden,Text=[Facilities for handling strings of
+Wide_Wide_Character elements are found in
+the packages address@hidden@!Maps, address@hidden@!Fixed,
address@hidden@!Bounded, address@hidden@!Unbounded, and
address@hidden@address@hidden@!Constants, and in the
address@hidden,New=[library ],Old=[]}functions address@hidden@!Hash,
address@hidden@address@hidden@!Hash,
address@hidden@address@hidden@address@hidden,@Chg{Version=[3],New=[],Old=[ and]}
address@hidden@address@hidden@address@hidden@Chg{Version=[3],New=[,
address@hidden@address@hidden@!Insensitive,
address@hidden@address@hidden@address@hidden,
address@hidden@address@hidden@address@hidden,
address@hidden@address@hidden@address@hidden,
address@hidden@address@hidden@!Insensitive,
address@hidden@address@hidden@address@hidden,
address@hidden@address@hidden@address@hidden, and
address@hidden@address@hidden@address@hidden,Old=[]}.
+They provide the same
+string-handling operations as the corresponding packages and functions
+for strings of Character elements.
address@hidden,Child=[Wide_Wide_Fixed]}
address@hidden,Child=[Wide_Wide_Bounded]}
address@hidden,Child=[Wide_Wide_Unbounded]}
address@hidden,address@hidden
address@hidden@!Fixed],address@hidden
address@hidden@!Bounded],address@hidden
address@hidden@!Unbounded],address@hidden
address@hidden,address@hidden,address@hidden
address@hidden@!Fixed],address@hidden
address@hidden@!Bounded],address@hidden
address@hidden@!Unbounded],address@hidden
address@hidden,address@hidden
address@hidden@!Fixed],address@hidden
address@hidden@!Bounded],address@hidden
address@hidden@!Unbounded],address@hidden,Old=[]}
address@hidden@!Maps],address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,Type=[Leading],Text=[The library package Strings.Wide_Wide_Maps 
has the following declaration.]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<package> Ada.Strings.Wide_Wide_Maps 
@key<is>@ChildUnit{Parent=[Ada.Strings],Child=[Wide_Wide_Maps]}
+   @key<pragma> Preelaborate(Wide_Wide_Maps);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @Examcom[Representation for a set of 
Wide_Wide_Character values:]
+   @key<type> @AdaTypeDefn{Wide_Wide_Character_Set} @key<is private>;
+   @key<pragma> Preelaborable_Initialization(Wide_Wide_Character_Set);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{Null_Set} : @key<constant> 
Wide_Wide_Character_Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<type> @AdaTypeDefn{Wide_Wide_Character_Range} 
@key<is>
+      @key<record>
+         Low  : Wide_Wide_Character;
+         High : Wide_Wide_Character;
+      @key<end record>;
+   -- @Examcom[Represents Wide_Wide_Character range Low..High]]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<type> @AdaTypeDefn{Wide_Wide_Character_Ranges} 
@key<is array> (Positive @key<range> <>)
+         @key<of> Wide_Wide_Character_Range;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{To_Set} (Ranges : @key<in> 
Wide_Wide_Character_Ranges)
+         @key<return> Wide_Wide_Character_Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{To_Set} (Span : @key<in> 
Wide_Wide_Character_Range)
+         @key<return> Wide_Wide_Character_Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{To_Ranges} (Set : @key<in> 
Wide_Wide_Character_Set)
+         @key<return> Wide_Wide_Character_Ranges;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> "=" (Left, Right : @key<in> 
Wide_Wide_Character_Set) @key<return> Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> "@key<not>" (Right : @key<in> 
Wide_Wide_Character_Set)
+         @key<return> Wide_Wide_Character_Set;
+   @key<function> "@key<and>" (Left, Right : @key<in> Wide_Wide_Character_Set)
+         @key<return> Wide_Wide_Character_Set;
+   @key<function> "@key<or>" (Left, Right : @key<in> Wide_Wide_Character_Set)
+         @key<return> Wide_Wide_Character_Set;
+   @key<function> "@key<xor>" (Left, Right : @key<in> Wide_Wide_Character_Set)
+         @key<return> Wide_Wide_Character_Set;
+   @key<function> "-" (Left, Right : @key<in> Wide_Wide_Character_Set)
+         @key<return> Wide_Wide_Character_Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Is_In} (Element : @key<in> 
Wide_Wide_Character;
+                   Set     : @key<in> Wide_Wide_Character_Set)
+         @key<return> Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Is_Subset} (Elements : 
@key<in> Wide_Wide_Character_Set;
+                       Set      : @key<in> Wide_Wide_Character_Set)
+         @key<return> Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> "<=" (Left  : @key<in> 
Wide_Wide_Character_Set;
+                  Right : @key<in> Wide_Wide_Character_Set)
+         @key<return> Boolean @key<renames> Is_Subset;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @Examcom[Alternative representation for a set of 
Wide_Wide_Character values:]
+   @key<subtype> 
@AdaSubtypeDefn{Name=[Wide_Wide_Character_Sequence],Of=[Wide_Wide_String]} 
@key<is> Wide_Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{To_Set} (Sequence : @key<in> 
Wide_Wide_Character_Sequence)
+         @key<return> Wide_Wide_Character_Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{To_Set} (Singleton : 
@key<in> Wide_Wide_Character)
+         @key<return> Wide_Wide_Character_Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{To_Sequence} (Set : @key<in> 
Wide_Wide_Character_Set)
+         @key<return> Wide_Wide_Character_Sequence;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @Examcom[Representation for a Wide_Wide_Character to 
Wide_Wide_Character]
+   -- @Examcom[mapping:]
+   @key<type> @AdaTypeDefn{Wide_Wide_Character_Mapping} @key<is private>;
+   @key<pragma> Preelaborable_Initialization(Wide_Wide_Character_Mapping);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{Value} (Map     : @key<in> 
Wide_Wide_Character_Mapping;
+                   Element : @key<in> Wide_Wide_Character)
+         @key<return> Wide_Wide_Character;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{Identity} : @key<constant> 
Wide_Wide_Character_Mapping;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{To_Mapping} (From, To : 
@key<in> Wide_Wide_Character_Sequence)
+         @key<return> Wide_Wide_Character_Mapping;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{To_Domain} (Map : @key<in> 
Wide_Wide_Character_Mapping)
+         @key<return> Wide_Wide_Character_Sequence;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<function> @AdaSubDefn{To_Range} (Map : @key<in> 
Wide_Wide_Character_Mapping)
+         @key<return> Wide_Wide_Character_Sequence;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<type> 
@AdaTypeDefn{Wide_Wide_Character_Mapping_Function} @key<is>
+         @key<access function> (From : @key<in> Wide_Wide_Character)
+         @key<return> Wide_Wide_Character;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<private>
+   ... -- @Examcom[not specified by the language]
address@hidden<end> Ada.Strings.Wide_Wide_Maps;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,address@hidden@!Maps],address@hidden
+The context clause for each of the packages Strings.Wide_Wide_Fixed,
+Strings.Wide_Wide_Bounded, and Strings.Wide_Wide_Unbounded identifies
+Strings.Wide_Wide_Maps instead of Strings.Maps.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0223-1]}
address@hidden,Text=[Types Wide_Wide_Character_Set and
+Wide_Wide_Character_Mapping need finalization.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0286-1]}
address@hidden,Type=[Leading],Text=[For each of the packages
address@hidden, address@hidden, address@hidden, and address@hidden,
+and for @Chg{Version=[3],New=[library ],Old=[]}functions
address@hidden, address@hidden, address@hidden,
address@hidden,New=[],Old=[and address@hidden,
address@hidden,address@hidden@address@hidden,
address@hidden@address@hidden,
address@hidden@address@hidden,
address@hidden@address@hidden,
address@hidden@address@hidden,
address@hidden@address@hidden,
address@hidden@address@hidden, and
address@hidden@address@hidden,
+],Old=[]}the corresponding wide wide string package or function has the same
+contents except that]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Wide_Wide_Space replaces Space]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Wide_Wide_Character replaces Character]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Wide_Wide_String replaces String]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Wide_Wide_Character_Set replaces Character_Set]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Wide_Wide_Character_Mapping replaces Character_Mapping]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Wide_Wide_Character_Mapping_Function replaces 
Character_Mapping_Function]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Wide_Wide_Maps replaces Maps]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Bounded_Wide_Wide_String replaces Bounded_String]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Null_Bounded_Wide_Wide_String replaces 
Null_Bounded_String]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[To_Bounded_Wide_Wide_String replaces To_Bounded_String]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[To_Wide_Wide_String replaces To_String]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00301-01]}
address@hidden,Text=[Set_Bounded_Wide_Wide_String replaces Set_Bounded_String]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Unbounded_Wide_Wide_String replaces Unbounded_String]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Null_Unbounded_Wide_Wide_String replaces 
Null_Unbounded_String]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Wide_Wide_String_Access replaces String_Access]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[To_Unbounded_Wide_Wide_String replaces 
To_Unbounded_String]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00301-01]}
address@hidden,Text=[Set_Unbounded_Wide_Wide_String replaces 
Set_Unbounded_String]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The following
+additional declarations are present in
+Strings.Wide_Wide_Maps.Wide_Wide_Constants:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden : @key<constant> 
Wide_Wide_Maps.Wide_Wide_Character_Set;
+-- @Examcom[Contains each Wide_Wide_Character value WWC such that]
+-- @Examcom[Characters.Conversions.Is_Character(WWC) is True]
address@hidden : @key<constant> Wide_Wide_Maps.Wide_Wide_Character_Set;
+-- @Examcom[Contains each Wide_Wide_Character value WWC such that]
+-- @Examcom[Characters.Conversions.Is_Wide_Character(WWC) is True]]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,Text=[Each Wide_Wide_Character_Set constant in the package
address@hidden@address@hidden@!Constants contains no values outside the 
Character
+portion of address@hidden Similarly, each address@hidden@!Mapping constant in
+this package is the identity mapping when applied to any element outside the
+Character portion of Wide_Wide_Character.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00395-01]}
address@hidden,address@hidden Pure is replaced by
address@hidden Preelaborate in Strings.Wide_Wide_Maps.Wide_Wide_Constants.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00285-01]}
address@hidden,address@hidden,Sec=(raised by failure of run-time check)}
+If a null Wide_Wide_Character_Mapping_Function is passed to any of the
+Wide_Wide_String handling subprograms, Constraint_Error is propagated.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01],ARef=[AI95-00395-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The double-wide string-handling packages (Strings.Wide_Wide_Maps,
+  Strings.Wide_Wide_Fixed, Strings.Wide_Wide_Bounded,
+  Strings.Wide_Wide_Unbounded, and Strings.Wide_Wide_Maps.Wide_Wide_Constants),
+  and functions Strings.Wide_Wide_Hash and
+  Strings.Wide_Wide_Unbounded.Wide_Wide_Hash are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0286-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The case insenstive library functions
+  (address@hidden@address@hidden,
+  address@hidden@address@hidden@!Insensitive,
+  address@hidden@address@hidden@!Insensitive,
+  address@hidden@address@hidden@!Insensitive,
+  address@hidden@address@hidden,
+  address@hidden@address@hidden@!Insensitive,
+  address@hidden@address@hidden@!Insensitive, and
+  address@hidden@address@hidden@!Insensitive)
+  are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0223-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction>: Identified 
Wide_Wide_Character_Set
+  and Wide_Wide_Character_Mapping as needing finalization. It is likely that
+  they are implemented with a controlled type, so this change is unlikely to
+  make any difference in practice.]}
address@hidden
+
+
+
+
address@hidden,Name=[String Hashing]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library
+function Strings.Hash has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0298-1]}
address@hidden,address@hidden<with> Ada.Containers;
address@hidden<function> Ada.Strings.Hash (Key : String) @key<return> 
Containers.Hash_Type;@SubChildUnit{Parent=[Ada.Strings],Child=[Hash]}
address@hidden<pragma> 
Pure(@Chg{Version=[3],New=[Ada.Strings.Hash],Old=[Hash]});]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns an implementation-defined
+value which is a function of the value of Key. If @i<A> and @i<B> are strings
+such that @i<A> equals @i<B>, Hash(@i<A>) equals Hash(@i<B>).]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The values returned by Strings.Hash.]}]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library
+function Strings.Fixed.Hash has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0298-1]}
address@hidden,address@hidden<with> Ada.Containers, Ada.Strings.Hash;
address@hidden<function> Ada.Strings.Fixed.Hash (Key : String) @key<return> 
Containers.Hash_Type
+   @key<renames> Ada.Strings.Hash;@Chg{Version=[3],New=[],Old=[
address@hidden<pragma> Pure(Hash);]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+function Strings.Bounded.Hash has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0298-1]}
address@hidden,address@hidden<with> Ada.Containers;
address@hidden<generic>@SubChildUnit{Parent=[Ada.Strings.Bounded],Child=[Hash]}
+   @key<with package> Bounded @key<is>
+      @key<new> Ada.Strings.Bounded.Generic_Bounded_Length (<>);
address@hidden<function> Ada.Strings.Bounded.Hash (Key : Bounded.Bounded_String)
+   @key<return> Containers.Hash_Type;
address@hidden<pragma> 
Preelaborate(@Chg{Version=[3],New=[Ada.Strings.Bounded.Hash],Old=[Hash]});]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0001-1]}
address@hidden,Type=[Trailing],address@hidden,New=[Equivalent to],
+Old=[Strings.Bounded.Hash is
+equivalent to the function call]} Strings.Hash (Bounded.To_String (Key));]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library
+function Strings.Unbounded.Hash has the following declaration:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0298-1]}
address@hidden,address@hidden<with> Ada.Containers;
address@hidden<function> Ada.Strings.Unbounded.Hash (Key : 
Unbounded_String)@SubChildUnit{Parent=[Ada.Strings.Unbounded],Child=[Hash]}
+   @key<return> Containers.Hash_Type;
address@hidden<pragma> 
Preelaborate(@Chg{Version=[3],New=[Ada.Strings.Unbounded.Hash],Old=[Hash]});]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0001-1]}
address@hidden,Type=[Trailing],address@hidden,New=[Equivalent to],
+Old=[Strings.Unbounded.Hash is
+equivalent to the function call]}
+Strings.Hash (To_String (Key));]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0298-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library function
+Strings.Hash_Case_Insensitive has the following declaration:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden<with> Ada.Containers;
address@hidden<function> Ada.Strings.Hash_Case_Insensitive (Key : 
String)@SubChildUnit{Parent=[Ada.Strings],Child=[Hash_Case_Insensitive]}
+   @key<return> Containers.Hash_Type;
address@hidden<pragma> Pure(Ada.Strings.Hash_Case_Insensitive);]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Type=[Trailing],Text=[Returns an implementation-defined
+value which is a function of the value of Key, converted to lower case. If
+A and B are strings such that Strings.Equal_Case_Insensitive (A, B) (see
address@hidden Comparison}) is
+True, then Hash_Case_Insensitive(A) equals Hash_Case_Insensitive(B).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0298-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library function
+Strings.Fixed.Hash_Case_Insensitive has the following declaration:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden<with> Ada.Containers, 
Ada.Strings.Hash_Case_Insensitive;
address@hidden Ada.Strings.Fixed.Hash_Case_Insensitive (Key : 
String)@SubChildUnit{Parent=[Ada.Strings.Fixed],Child=[Hash_Case_Insensitive]}
+   @key[return] Containers.Hash_Type @key[renames] 
Ada.Strings.Hash_Case_Insensitive;]}
address@hidden
+
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0298-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+function Strings.Bounded.Hash_Case_Insensitive has the following declaration:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden<with> Ada.Containers;
address@hidden
+   @key[with package] Bounded @key[is]
+      @key[new] Ada.Strings.Bounded.Generic_Bounded_Length (<>);
address@hidden address@hidden,Child=[Hash_Case_Insensitive]}
+   (Key : Bounded.Bounded_String) @key[return] Containers.Hash_Type;
address@hidden Preelaborate(Ada.Strings.Bounded.Hash_Case_Insensitive);]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Type=[Trailing],Text=[Equivalent to
+Strings.Hash_Case_Insensitive (Bounded.To_String (Key));]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0001-1],ARef=[AI05-0298-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library function
+Strings.Unbounded.Hash_Case_Insensitive has the following declaration:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden<with> Ada.Containers;
address@hidden address@hidden,Child=[Hash_Case_Insensitive]}
+   (Key : Unbounded_String) @key[return] Containers.Hash_Type;
address@hidden Preelaborate(Ada.Strings.Unbounded.Hash_Case_Insensitive);]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Type=[Trailing],Text=[Equivalent to
+Strings.Hash_Case_Insensitive (To_String (Key));]}
address@hidden
+
address@hidden
+
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00302-03]}
address@hidden,Text=[The Hash functions should be good hash
+functions, returning a wide spread of values for different string values. It
+should be unlikely for similar strings to return the same value.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Strings.Hash should be good a hash
+function, returning a wide spread of values for different string values,
+and similar strings should rarely return the same value.]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The other functions are defined in terms of
+  Strings.Hash, so they don't need separate advice in the Annex.]}
address@hidden
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00302-03]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The Strings.Hash, Strings.Fixed.Hash, Strings.Bounded.Hash, and
+  Strings.Unbounded.Hash functions are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The Strings.Hash_Case_Insensitive, Strings.Fixed.Hash_Case_Insensitive,
+  Strings.Bounded.Hash_Case_Insensitive, and
+  Strings.Unbounded.Hash_Case_Insensitive functions are new.]}
address@hidden
+
+
address@hidden,Name=[String Comparison]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0286-1],ARef=[AI05-0298-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library function
+Strings.Equal_Case_Insensitive has the following declaration:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Strings.Equal_Case_Insensitive (Left, Right : 
String)@SubChildUnit{Parent=[Ada.Strings],Child=[Equal_Case_Insensitive]}
+   @key[return] Boolean;
address@hidden Pure(Ada.Strings.Equal_Case_Insensitive);]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns True if the strings consist
+of the same sequence of characters after applying locale-independent simple 
case
+folding, as defined by documents referenced in the note in Clause 1 of ISO/IEC
+10646:2011. Otherwise, returns False. This function uses the same method as is
+used to determine whether two identifiers are the same.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0286-1]}
+  @ChgAdded{Version=[3],Text=[For String, this is equivalent to converting to
+  lower case and comparing. Not so for other string types. For Wide_Strings and
+  Wide_Wide_Strings, note that this result is a more accurate comparison than
+  converting the strings to lower case and comparing the results; it is 
possible
+  that the lower case conversions are the same but this routine will report the
+  strings as different. Additionally, Unicode says that the result of this
+  function will never change for strings made up solely of defined code points;
+  there is no such guarantee for case conversion to lower case.]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0248-1],ARef=[AI05-0298-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library function
+Strings.Fixed.Equal_Case_Insensitive has the following declaration:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Strings.Equal_Case_Insensitive;
address@hidden address@hidden,Child=[Equal_Case_Insensitive]}
+   (Left, Right : String) @key[return] Boolean
+      @key[renames] Ada.Strings.Equal_Case_Insensitive;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0248-1],ARef=[AI05-0298-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+function Strings.Bounded.Equal_Case_Insensitive has the following 
declaration:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key[with package] Bounded @key[is]
+      @key[new] Ada.Strings.Bounded.Generic_Bounded_Length (<>);
address@hidden address@hidden,Child=[Equal_Case_Insensitive]}
+   (Left, Right : Bounded.Bounded_String) @key[return] Boolean;
address@hidden Preelaborate(Ada.Strings.Bounded.Equal_Case_Insensitive);]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Equivalent to
+Strings.Equal_Case_Insensitive (Bounded.To_String (Left), Bounded.To_String 
(Right));]}
address@hidden
+
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0248-1],ARef=[AI05-0298-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library function
+Strings.Unbounded.Equal_Case_Insensitive has the following declaration:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden address@hidden,Child=[Equal_Case_Insensitive]}
+   (Left, Right : Unbounded_String) @key[return] Boolean;
address@hidden Preelaborate(Ada.Strings.Unbounded.Equal_Case_Insensitive);]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Equivalent to
+Strings.Equal_Case_Insensitive (To_String (Left), To_String (Right));]}
address@hidden
+
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0298-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library function
+Strings.Less_Case_Insensitive has the following declaration:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Strings.Less_Case_Insensitive (Left, Right : 
String)@SubChildUnit{Parent=[Ada.Strings],Child=[Less_Case_Insensitive]}
+   @key[return] Boolean;
address@hidden Pure(Ada.Strings.Less_Case_Insensitive);]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Performs a lexicographic comparison
+of strings Left and Right, converted to lower case.]}
address@hidden
+
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0248-1],ARef=[AI05-0298-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library function
+Strings.Fixed.Less_Case_Insensitive has the following declaration:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Strings.Less_Case_Insensitive;
address@hidden address@hidden,Child=[Less_Case_Insensitive]}
+   (Left, Right : String) @key[return] Boolean
+      @key[renames] Ada.Strings.Less_Case_Insensitive;]}
address@hidden
+
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0248-1],ARef=[AI05-0298-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The generic library
+function Strings.Bounded.Less_Case_Insensitive has the following declaration:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   @key[with package] Bounded @key[is]
+      @key[new] Ada.Strings.Bounded.Generic_Bounded_Length (<>);
address@hidden address@hidden,Child=[Less_Case_Insensitive]}
+  (Left, Right : Bounded.Bounded_String) @key[return] Boolean;
address@hidden Preelaborate(Ada.Strings.Bounded.Less_Case_Insensitive);]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Equivalent to
+Strings.Less_Case_Insensitive (Bounded.To_String (Left), Bounded.To_String 
(Right));]}
address@hidden
+
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0248-1],ARef=[AI05-0298-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The library function
+Strings.Unbounded.Less_Case_Insensitive has the following declaration:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden address@hidden,Child=[Less_Case_Insensitive]}
+  (Left, Right : Unbounded_String) @key[return] Boolean;
address@hidden Preelaborate(Ada.Strings.Unbounded.Less_Case_Insensitive);]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Equivalent to
+Strings.Less_Case_Insensitive (To_String (Left), To_String (Right));]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0001-1],ARef=[AI05-0286-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The Strings.Equal_Case_Insensitive, Strings.Fixed.Equal_Case_Insensitive,
+  Strings.Bounded.Equal_Case_Insensitive,
+  Strings.Unbounded.Equal_Case_Insensitive,
+  Strings.Less_Case_Insensitive, Strings.Fixed.Less_Case_Insensitive,
+  Strings.Bounded.Less_Case_Insensitive,
+  Strings.Unbounded.Less_Case_Insensitive functions are new.]}
address@hidden
+
+
address@hidden,Name=[String Encoding]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Text=[Facilities for encoding, decoding, and converting strings 
in various character
+encoding schemes are provided by packages address@hidden,
address@hidden@!Conversions, address@hidden@!Strings,
address@hidden@!Wide_Strings, and
address@hidden@!Wide_Wide_Strings.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Type=[Leading],Text=[The encoding library packages have
+the following declarations:]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,address@hidden,address@hidden Ada.Strings.UTF_Encoding @key[is]
+   @key[pragma] Pure (UTF_Encoding);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @Examcom[Declarations common to the string encoding 
packages]
+   @key[type] @AdaTypeDefn{Encoding_Scheme} @key[is] (UTF_8, UTF_16BE, 
UTF_16LE);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[subtype] 
@AdaSubtypeDefn{Name=[UTF_String],Of=[String]} @key[is] String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[subtype] 
@AdaSubtypeDefn{Name=[UTF_8_String],Of=[String]} @key[is] String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[subtype] 
@AdaSubtypeDefn{Name=[UTF_16_Wide_String],Of=[Wide_String]} @key[is] 
Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaExcDefn{Encoding_Error} : @key[exception];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{BOM_8}    : @key[constant] UTF_8_String :=
+                Character'Val(16#EF#) &
+                Character'Val(16#BB#) &
+                Character'Val(16#BF#);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{BOM_16BE} : @key[constant] UTF_String :=
+                Character'Val(16#FE#) &
+                Character'Val(16#FF#);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{BOM_16LE} : @key[constant] UTF_String :=
+                Character'Val(16#FF#) &
+                Character'Val(16#FE#);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{BOM_16}   : @key[constant] 
UTF_16_Wide_String :=
+               (1 => Wide_Character'Val(16#FEFF#));]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Encoding} (Item    : 
UTF_String;
+                      Default : Encoding_Scheme := UTF_8)
+      @key[return] Encoding_Scheme;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Strings.UTF_Encoding;]}
+
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,address@hidden,address@hidden 
Ada.Strings.UTF_Encoding.Conversions @key[is]
+   @key[pragma] Pure (Conversions);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @Examcom{Conversions between various encoding 
schemes}
+   @key[function] @AdaSubDefn{Convert} (Item          : UTF_String;
+                     Input_Scheme  : Encoding_Scheme;
+                     Output_Scheme : Encoding_Scheme;
+                     Output_BOM    : Boolean := False) @key[return] 
UTF_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Convert} (Item          : 
UTF_String;
+                     Input_Scheme  : Encoding_Scheme;
+                     Output_BOM    : Boolean := False)
+      @key[return] UTF_16_Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Convert} (Item          : 
UTF_8_String;
+                     Output_BOM    : Boolean := False)
+      @key[return] UTF_16_Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Convert} (Item          : 
UTF_16_Wide_String;
+                     Output_Scheme : Encoding_Scheme;
+                     Output_BOM    : Boolean := False) @key[return] 
UTF_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Convert} (Item          : 
UTF_16_Wide_String;
+                     Output_BOM    : Boolean := False) @key[return] 
UTF_8_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Strings.UTF_Encoding.Conversions;]}
+
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,address@hidden,address@hidden Ada.Strings.UTF_Encoding.Strings 
@key[is]
+   @key[pragma] Pure (Strings);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @Examcom{Encoding / decoding between String and 
various encoding schemes}
+   @key[function] @AdaSubDefn{Encode} (Item          : String;
+                    Output_Scheme : Encoding_Scheme;
+                    Output_BOM    : Boolean  := False) @key[return] 
UTF_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Encode} (Item       : String;
+                    Output_BOM : Boolean  := False) @key[return] 
UTF_8_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Encode} (Item       : String;
+                    Output_BOM : Boolean  := False)
+      @key[return] UTF_16_Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Decode} (Item         : 
UTF_String;
+                    Input_Scheme : Encoding_Scheme) @key[return] String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Decode} (Item : 
UTF_8_String) @key[return] String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Decode} (Item : 
UTF_16_Wide_String) @key[return] String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Strings.UTF_Encoding.Strings;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,address@hidden,address@hidden 
Ada.Strings.UTF_Encoding.Wide_Strings @key[is]
+   @key[pragma] Pure (Wide_Strings);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @Examcom{Encoding / decoding between Wide_String and 
various encoding schemes}
+   @key[function] @AdaSubDefn{Encode} (Item          : Wide_String;
+                    Output_Scheme : Encoding_Scheme;
+                    Output_BOM    : Boolean  := False) @key[return] 
UTF_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Encode} (Item       : 
Wide_String;
+                    Output_BOM : Boolean  := False) @key[return] 
UTF_8_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Encode} (Item       : 
Wide_String;
+                    Output_BOM : Boolean  := False)
+      @key[return] UTF_16_Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Decode} (Item         : 
UTF_String;
+                    Input_Scheme : Encoding_Scheme) @key[return] Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Decode} (Item : 
UTF_8_String) @key[return] Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Decode} (Item : 
UTF_16_Wide_String) @key[return] Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Strings.UTF_Encoding.Wide_Strings;]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,address@hidden,address@hidden 
Ada.Strings.UTF_Encoding.Wide_Wide_Strings @key[is]
+   @key[pragma] Pure (Wide_Wide_Strings);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   -- @Examcom{Encoding / decoding between 
Wide_Wide_String and various encoding schemes}
+   @key[function] @AdaSubDefn{Encode} (Item          : Wide_Wide_String;
+                    Output_Scheme : Encoding_Scheme;
+                    Output_BOM    : Boolean  := False) @key[return] 
UTF_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Encode} (Item       : 
Wide_Wide_String;
+                    Output_BOM : Boolean  := False) @key[return] 
UTF_8_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Encode} (Item       : 
Wide_Wide_String;
+                    Output_BOM : Boolean  := False)
+      @key[return] UTF_16_Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Decode} (Item         : 
UTF_String;
+                    Input_Scheme : Encoding_Scheme) @key[return] 
Wide_Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Decode} (Item : 
UTF_8_String) @key[return] Wide_Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Decode} (Item : 
UTF_16_Wide_String) @key[return] Wide_Wide_String;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Strings.UTF_Encoding.Wide_Wide_Strings;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2],ARef=[AI05-0262-1]}
address@hidden,Text=[The type Encoding_Scheme defines encoding schemes.
+UTF_8 corresponds to the UTF-8 encoding scheme defined by Annex D of ISO/IEC
+10646. UTF_16BE corresponds to the UTF-16 encoding scheme defined by Annex C of
+ISO/IEC 10646 in 8 bit, big-endian order; and UTF_16LE corresponds to the
+UTF-16 encoding scheme in 8 bit, little-endian
address@hidden address@hidden address@hidden@Defn{UTF-16}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Text=[The subtype UTF_String is used to represent a String
+of 8-bit values containing a sequence of values encoded in one of three ways
+(UTF-8, UTF-16BE, or UTF-16LE). The subtype UTF_8_String is used to represent a
+String of 8-bit values containing a sequence of values encoded in UTF-8. The
+subtype UTF_16_Wide_String is used to represent a Wide_String of 16-bit values
+containing a sequence of values encoded in UTF-16.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2],ARef=[AI05-0262-1]}
address@hidden,Text=[The BOM_8, BOM_16BE, BOM_16LE, and BOM_16 constants
+correspond to values used at the start of a string to indicate the encoding.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0262-1],ARef=[AI05-0269-1]}
address@hidden,Text=[Each of the Encode functions takes a String,
+Wide_String, or Wide_Wide_String Item parameter that is assumed to be an array
+of unencoded characters. Each of the Convert functions takes a UTF_String,
+UTF_8_String, or UTF_16_String Item parameter that is assumed to
+contain characters whose position values correspond to a valid encoding 
sequence
+according to the encoding scheme required by the function or specified by its
+Input_Scheme parameter.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2],ARef=[AI05-0262-1],ARef=[AI05-0269-1]}
address@hidden,Text=[Each of the Convert and Encode functions returns
+a UTF_String, UTF_8_String, or UTF_16_String value whose characters have 
position values
+that correspond to the encoding of the Item parameter according to the
+encoding scheme required by the function or specified by its Output_Scheme
+parameter. For UTF_8, no overlong encoding is returned. A BOM is included
+at the start of the returned string if the Output_BOM parameter is set to
+True. The lower bound of the returned string is 1.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2],ARef=[AI05-0262-1]}
address@hidden,Text=[Each of the Decode functions takes a UTF_String,
+UTF_8_String, or UTF_16_String Item parameter which is assumed to
+contain characters whose position values correspond to a valid encoding 
sequence
+according to the encoding scheme required by the function or specified by its
+Input_Scheme parameter, and returns the corresponding String, Wide_String, or
+Wide_Wide_String value. The lower bound of the returned string is 1.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2],ARef=[AI05-0262-1]}
address@hidden,Text=[For each of the Convert and Decode functions, an
+initial BOM in the input that matches the expected encoding scheme is ignored,
+and a different initial BOM causes Encoding_Error to be propagated.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Type=[Leading],Text=[The exception Encoding_Error is also 
propagated in the following
+situations:]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0088-1]}
+  @ChgAdded{Version=[3],Text=[By a @Chg{Version=[4],New=[Convert or
+    ],Old=[]}Decode function when a UTF encoded
+    string contains an invalid encoding sequence.]}
+
+  @begin{Honest}
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0088-1]}
+  @ChgAdded{Version=[4],Text=[An overlong encoding is not invalid for the
+    purposes of this check, and this does not depend on the character set
+    version in use. Some recent character set standards declare overlong
+    encodings to be invalid; it would be unnecessary and unfriendly to users
+    for Convert or Decode to raise an exception for an overlong encoding.]}
+  @end{Honest}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0088-1]}
+  @ChgAdded{Version=[3],Text=[By a @Chg{Version=[4],New=[Convert or
+    ],Old=[]}Decode function when the expected encoding is
+    UTF-16BE or UTF-16LE and the input string has an odd length.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Text=[By a Decode function yielding a String when
+    the decoding of a sequence results in a code point whose value exceeds
+    16#FF#.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[By a Decode function yielding a Wide_String when
+    the decoding of a sequence results in a code point whose value exceeds
+    16#FFFF#.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0262-1]}
+  @ChgAdded{Version=[3],Text=[By an Encode function taking a Wide_String as
+    input when an invalid character appears in the input. In particular, the
+    characters whose position is in the range 16#D800# .. 16#DFFF# are invalid
+    because they conflict with UTF-16 surrogate encodings, and the characters
+    whose position is 16#FFFE# or 16#FFFF# are also invalid because they
+    conflict with BOM codes.]}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Encoding (Item    : UTF_String;
+                   Default : Encoding_Scheme := UTF_8)
+   @key[return] Encoding_Scheme;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2],ARef=[AI05-0269-1]}
address@hidden,Type=[Trailing],Text=[Inspects a UTF_String value to
+determine whether it starts with a BOM for UTF-8, UTF-16BE, or UTF_16LE. If so,
+returns the scheme corresponding to the BOM; otherwise, returns the value of
+Default.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Convert (Item          : UTF_String;
+                  Input_Scheme  : Encoding_Scheme;
+                  Output_Scheme : Encoding_Scheme;
+                  Output_BOM    : Boolean := False) @key[return] UTF_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+(originally encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by
+Input_Scheme) encoded in one of these three schemes as
+specified by Output_Scheme.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Convert (Item          : UTF_String;
+                  Input_Scheme  : Encoding_Scheme;
+                  Output_BOM    : Boolean := False)
+   @key[return] UTF_16_Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+(originally encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by
+Input_Scheme) encoded in UTF-16.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Convert (Item          : 
UTF_8_String;
+                  Output_BOM    : Boolean := False)
+   @key[return] UTF_16_Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+(originally encoded in UTF-8) encoded in UTF-16.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Convert (Item          : 
UTF_16_Wide_String;
+                  Output_Scheme : Encoding_Scheme;
+                  Output_BOM    : Boolean := False) @key[return] UTF_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+(originally encoded in UTF-16) encoded in UTF-8,
+UTF-16LE, or UTF-16BE as specified by Output_Scheme.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Convert (Item          : 
UTF_16_Wide_String;
+                  Output_BOM    : Boolean := False) @key[return] 
UTF_8_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+(originally encoded in UTF-16) encoded in UTF-8.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Encode (Item          : String;
+                 Output_Scheme : Encoding_Scheme;
+                 Output_BOM    : Boolean  := False) @key[return] UTF_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0262-1]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+encoded in UTF-8, UTF-16LE, or UTF-16BE as specified
+by Output_Scheme.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Encode (Item       : String;
+                 Output_BOM : Boolean  := False) @key[return] UTF_8_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+encoded in UTF-8.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Encode (Item       : String;
+                 Output_BOM : Boolean  := False) @key[return] 
UTF_16_Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+encoded in UTF_16.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Decode (Item         : UTF_String;
+                 Input_Scheme : Encoding_Scheme) @key[return] String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the result of decoding Item,
+which is encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by 
Input_Scheme.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Decode (Item : UTF_8_String) 
@key[return] String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the result of decoding Item,
+which is encoded in UTF-8.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Decode (Item : UTF_16_Wide_String) 
@key[return] String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the result of decoding Item,
+which is encoded in UTF-16.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Encode (Item          : Wide_String;
+                 Output_Scheme : Encoding_Scheme;
+                 Output_BOM    : Boolean  := False) @key[return] UTF_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0262-1]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+encoded in UTF-8, UTF-16LE, or UTF-16BE as specified
+by Output_Scheme.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Encode (Item       : Wide_String;
+                 Output_BOM : Boolean  := False) @key[return] UTF_8_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+encoded in UTF-8.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Encode (Item       : Wide_String;
+                 Output_BOM : Boolean  := False) @key[return] 
UTF_16_Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+encoded in UTF_16.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Decode (Item         : UTF_String;
+                 Input_Scheme : Encoding_Scheme) @key[return] Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the result of decoding Item,
+which is encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by 
Input_Scheme.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Decode (Item : UTF_8_String) 
@key[return] Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the result of decoding Item, which 
is encoded in UTF-8.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Decode (Item : UTF_16_Wide_String) 
@key[return] Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the result of decoding Item,
+which is encoded in UTF-16.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Encode (Item          : 
Wide_Wide_String;
+                 Output_Scheme : Encoding_Scheme;
+                 Output_BOM    : Boolean  := False) @key[return] UTF_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0262-1]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by Output_Scheme.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Encode (Item       : 
Wide_Wide_String;
+                 Output_BOM : Boolean  := False) @key[return] UTF_8_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+encoded in UTF-8.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Encode (Item       : 
Wide_Wide_String;
+                 Output_BOM : Boolean  := False) @key[return] 
UTF_16_Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the value of Item
+encoded in UTF_16.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Decode (Item         : UTF_String;
+                 Input_Scheme : Encoding_Scheme) @key[return] 
Wide_Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the result of decoding Item,
+which is encoded in UTF-8, UTF-16LE, or UTF-16BE as specified by 
Input_Scheme.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Decode (Item : UTF_8_String) 
@key[return] Wide_Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the result of decoding Item,
+which is encoded in UTF-8.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Keepnext=[T],address@hidden Decode (Item : UTF_16_Wide_String) 
@key[return] Wide_Wide_String;]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Trailing],Text=[Returns the result of decoding Item,
+which is encoded in UTF-16.]}
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Text=[If an implementation supports other encoding
+schemes, another similar child of Ada.Strings should be defined.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[If an implementation supports other string encoding
+schemes, a child of Ada.Strings similar to UTF_Encoding should be defined.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0137-2]}
address@hidden,Text=[A BOM (Byte-Order Mark, code position 16#FEFF#) can
+be included in a file or other entity to indicate the encoding; it is skipped
+when decoding. Typically, only the first line of a file or other entity 
contains
+a BOM. When decoding, the Encoding function can be called on the first line to
+determine the encoding; this encoding will then be used in subsequent calls to
+Decode to convert all of the lines to an internal format.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0137-2]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The packages Strings.UTF_Encoding, Strings.UTF_Encoding.Conversions,
+  Strings.UTF_Encoding.Strings, Strings.UTF_Encoding.Wide_Strings,
+  and Strings.UTF_Encoding.Wide_Wide_Strings are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0088-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Fixed the omission that 
Convert
+  routines make the same checks on input as Decode routines.]}
address@hidden
+
+
diff --git a/packages/ada-ref-man/source_2012/real_attribs.mss 
b/packages/ada-ref-man/source_2012/real_attribs.mss
new file mode 100755
index 0000000..5ea1e96
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/real_attribs.mss
@@ -0,0 +1,732 @@
address@hidden(realattribs, Root="ada.mss")
+
address@hidden: 2011/09/29 06:37:25 $}
+
address@hidden: e:\\cvsroot/ARM/Source/real_attribs.mss,v $}
address@hidden: 1.27 $}
+
address@hidden of Floating Point Types}
+
address@hidden
address@hidden@Defn2{Term=[representation-oriented attributes],
+               Sec=[of a floating point subtype]}
+The following @i{representation-oriented attributes} are defined for
address@hidden subtype S of a floating point type @i{T}}.
address@hidden
address@hidden<S>, AttrName=<Machine_Radix>,
+  Text=[Yields the radix of the hardware
+   representation of the type @i{T}. The value of this attribute is of
+   the type @i{universal_integer}.]}
address@hidden
+
address@hidden form}
+The values of other representation-oriented attributes of a floating point
+subtype, and of the @lquotes@;primitive address@hidden@; attributes of a 
floating point
+subtype described later, are defined in terms of a particular representation
+of nonzero values called the @i{canonical form}.
+The canonical form (for the type @i{T}) is the address@hidden
+@ @ @ @ @PorM @RI{mantissa} @Times 
@address@hidden'address@hidden@address@hidden
+where
address@hidden
+   @i{mantissa} is a fraction in the number base @i{T}'Machine_Radix,
+   the first digit of which is nonzero, and
+
+   @i{exponent} is an integer.
address@hidden
address@hidden
address@hidden<S>, AttrName=<Machine_Mantissa>,
+  Text=[Yields the largest value of @RI{p} such that every value expressible
+   in the canonical form (for the type @i{T}), having a @RI{p}-digit
+   @i{mantissa} and an @i{exponent} between @i{T}'Machine_Emin and
+   @i{T}'Machine_Emax, is a machine number (see @RefSecNum{Floating Point 
Types})
+   of the type @i{T}. This attribute yields a value of the type
+   @i{universal_integer}.]}
address@hidden
+   Values of a type held in an extended register are, in general, not machine
+   numbers of the type, since they cannot be expressed in the canonical form
+   with a sufficiently short @i{mantissa}.
address@hidden
+
address@hidden<S>, AttrName=<Machine_Emin>,
+  Text=[Yields the smallest (most negative) value of @i{exponent} such
+   that every value expressible in the canonical form (for the type @i{T}),
+   having a @i{mantissa} of @i{T}'Machine_Mantissa digits, is a machine number
+   (see @RefSecNum{Floating Point Types}) of the type
+   @i{T}.
+   This attribute yields
+   a value of the type @i{universal_integer}.]}
+
address@hidden<S>, AttrName=<Machine_Emax>,
+  Text=[Yields the largest (most positive) value of @i{exponent} such that
+   every value expressible in the canonical form (for the type @i{T}), having
+   a @i{mantissa} of @i{T}'Machine_Mantissa digits, is a machine number
+   (see @RefSecNum{Floating Point Types}) of the type @i{T}. This attribute
+   yields a value of the type @i{universal_integer}.]}
address@hidden
+
+  Note that the above definitions do not determine unique values for the
+  representation-oriented attributes of floating point types.
+  The implementation may choose any set of values that collectively
+  satisfies the definitions.
+
address@hidden
+
address@hidden<S>, AttrName=<Denorm>,
+  Text=[Yields the value True if every value expressible in the address@hidden
+   @ @ @ @ @PorM @RI{mantissa} @Times 
@address@hidden'address@hidden@address@hidden'address@hidden
+   where @i{mantissa} is a nonzero @i{T}'Machine_Mantissa-digit fraction in the
+   number base @i{T}'Machine_Radix, the first digit of which is zero,
+   is a machine number (see @RefSecNum{Floating Point Types}) of the type
+   @i{T}; yields the value False otherwise.
+   The value
+   of this attribute is of the predefined type Boolean.]}
address@hidden
+
address@hidden number}
+The values described by the formula in the definition of S'Denorm are called
address@hidden numbers}.
address@hidden number}
+A nonzero machine number that is not a denormalized number is a
address@hidden number}.
address@hidden in canonical form}
address@hidden representation}
+A normalized number @RI{x} of a given type @i{T} is said to be
address@hidden in canonical form} when it is expressed in the
+canonical form (for the type @i{T}) with a @i{mantissa}
+having @i{T}'Machine_Mantissa digits;
+the resulting form is the @i{canonical-form representation} of @RI{x}.
address@hidden
+   The intent is that S'Denorm be True when such denormalized numbers exist
+   and are generated in the circumstances defined by IEC 559:1989,
+   though the latter requirement is not formalized here.
address@hidden
address@hidden
address@hidden<S>, AttrName=<Machine_Rounds>,
+  Text=[Yields the value True if rounding is performed on inexact
+   results of every predefined operation that yields a result of the
+   type @i{T}; yields the value False otherwise.
+   The value
+   of this attribute is of the predefined type Boolean.]}
address@hidden
+   @Leading@;It is difficult to be more precise about what it means to round
+   the result of a predefined operation. If the implementation does not use
+   extended registers, so that every arithmetic result is necessarily a machine
+   number, then rounding seems to imply two things:
+   @begin{Itemize}
+      S'Model_Mantissa = S'Machine_Mantissa, so that operand preperturbation
+      never occurs;
+
+      when the exact mathematical result is not a machine number, the result of
+      a predefined operation must be the nearer of the two adjacent machine
+      numbers.
+   @end{Itemize}
+
+   Technically, this attribute should yield False when extended registers are
+   used, since a few computed results will cross over the half-way point as
+   a result of double rounding, if and when a value held in an extended
+   register has to be reduced in precision to that of the machine numbers. It
+   does not seem desirable to preclude the use of extended registers when
+   S'Machine_Rounds could otherwise be True.
address@hidden
+
address@hidden<S>, AttrName=<Machine_Overflows>,
+  Text=[Yields the value True if overflow and
+   divide-by-zero are detected and
+   reported by raising Constraint_Error for every predefined operation that
+   yields a result of the type @i{T};
+   yields the value False otherwise.
+   The value of this
+   attribute is of the predefined type Boolean.]}
+
address@hidden<S>, AttrName=<Signed_Zeros>,
+  Text=[Yields the value True if the hardware representation for the
+   type @i{T} has the capability of representing both positively and negatively
+   signed zeros, these being generated and used by the predefined operations of
+   the type @i{T} as specified in IEC 559:1989; yields the value False
+   otherwise.
+   The value of this attribute
+   is of the predefined type Boolean.]}
address@hidden
+
address@hidden@Defn{normalized exponent}
+For every value @RI{x} of a floating point type @i{T}, the
address@hidden exponent} of @RI{x} is defined as follows:
address@hidden
+   the normalized exponent of zero is (by convention) zero;
+
+   for nonzero @RI{x}, the normalized exponent of @RI{x} is the unique
+   integer @RI{k} such that
+   @address@hidden'address@hidden@address@hidden@;1} @leq @address@hidden @Lt
+   @address@hidden'address@hidden@RI{k}}.
address@hidden
address@hidden
+   The normalized exponent of a normalized number @RI{x} is the value
+   of @i{exponent} in the canonical-form representation of @RI{x}.
+
+   The normalized exponent of a denormalized number is less than the value of
+   @i{T}'Machine_Emin.
address@hidden
+
address@hidden
address@hidden@Defn{primitive function}
+The following @i{primitive function attributes} are defined for any subtype
+S of a floating point type @i{T}.
address@hidden
address@hidden(Description)
address@hidden<S>, AttrName=<Exponent>,
+  Text=[S'Exponent denotes a function with the following
+   specification:
address@hidden(DescExample)
address@hidden(function) S'Exponent (@RI(X) : @RI(T))
+  @key(return) @RI(universal_integer)
address@hidden(DescExample)
+
+   @NoPrefix@;The function yields the normalized exponent of @i{X}.]}
+
address@hidden<S>, AttrName=<Fraction>,
+  Text=[S'Fraction denotes a function with the following
+   specification:
address@hidden(DescExample)
address@hidden(function) S'Fraction (@RI(X) : @RI(T))
+  @key(return) @RI(T)
address@hidden(DescExample)
+
+   @NoPrefix@;The function yields the value @RI(X) @Times 
@RI(T)@R('Machine_Radix)@+(@address@hidden(k)), where
+   @RI(k) is the normalized exponent of @i(X). A zero address@hidden(, which
+   can only occur when @i(X) is zero,) has the sign of @i(X).]}
address@hidden
+   Informally, when @i{X} is a normalized number, the result is the value
+   obtained by replacing the @i{exponent} by zero in the canonical-form
+   representation of @i{X}.
address@hidden
address@hidden
+   Except when @i{X} is zero, the magnitude of the result is
+   greater than or equal to the reciprocal of @i{T}'Machine_Radix and less than
+   one; consequently, the result is always a normalized number, even when @i{X}
+   is a denormalized number.
address@hidden
address@hidden
+   When @i{X} is a denormalized number, the result is the value obtained by
+   replacing the @i{exponent} by zero in the canonical-form representation of
+   the result of scaling @i{X} up sufficiently to normalize it.
address@hidden
+
address@hidden<S>, AttrName=<Compose>,
+  Text=[S'Compose denotes a function with the following
+   specification:
address@hidden
address@hidden(function) S'Compose (@RI{Fraction} : @RI{T};
+                    @RI{Exponent} : @RI{universal_integer})
+  @key(return) @RI{T}
address@hidden
+
+   @NoPrefix@;@Defn2{Term=(Constraint_Error),Sec=(raised by failure of 
run-time check)}
+   Let @RI{v} be the value @RI{Fraction} @Times
+   @address@hidden('Machine_Radix)@address@hidden@address@hidden,
+   where @RI{k} is the normalized exponent of @i{Fraction}.
+   If @RI{v} is a machine number of the type @i{T}, or if
+   @address@hidden @geq @address@hidden('Model_Small), the function yields 
@RI{v};
+   otherwise,
+   it yields either one of the machine numbers of the type @i{T} adjacent to
+   @RI{v}.
+   @IndexCheck{Range_Check}Constraint_Error is optionally raised if
+   @RI{v} is outside the base range of S.
+   A zero result has the sign of @i{Fraction} when S'Signed_Zeros is True.]}
address@hidden
+   Informally, when @i{Fraction} and @RI{v} are both normalized numbers, the
+   result is the value obtained by replacing the @i{exponent} by @i{Exponent}
+   in the canonical-form representation of @i{Fraction}.
address@hidden
address@hidden
+   If @i{Exponent} is less than @i{T}'Machine_Emin and
+   @i{Fraction} is nonzero, the result is either zero, @i{T}'Model_Small, or
+   (if @i{T}'Denorm is True) a denormalized number.
address@hidden
+
address@hidden<S>, AttrName=<Scaling>,
+  Text=[S'Scaling denotes a function with the following
+   specification:
address@hidden
address@hidden(function) S'Scaling (@RI{X} : @RI{T};
+                    @RI{Adjustment} : @RI{universal_integer})
+  @key(return) @RI{T}
address@hidden
+
+   @address@hidden(Constraint_Error),Sec=(raised by failure of run-time check)}
+   Let @RI{v} be the value @RI{X} @Times 
@address@hidden('Machine_Radix)@address@hidden
+   If @RI{v} is a machine number of the type @i{T}, or if
+   @address@hidden @geq @address@hidden('Model_Small), the function yields 
@RI{v};
+   otherwise,
+   it yields either one of the machine numbers of the type @i{T} adjacent to
+   @RI{v}.
address@hidden is optionally raised if
address@hidden is outside the base range of S.
+   A zero result has the sign of @i{X} when S'Signed_Zeros is True.]}
address@hidden
+   Informally, when @i{X} and @RI{v} are both normalized numbers, the result
+   is the value obtained by increasing the @i{exponent} by @i{Adjustment} in 
the
+   canonical-form representation of @i{X}.
address@hidden
address@hidden
+   If @i{Adjustment} is sufficiently small (i.e., sufficiently negative), the
+   result is
+   either zero, @i{T}'Model_Small, or (if @i{T}'Denorm is True) a denormalized
+   number.
address@hidden
+
address@hidden<S>, AttrName=<Floor>,
+  Text=[S'Floor denotes a function with the following
+   specification:
address@hidden
address@hidden(function) S'Floor (@RI{X} : @RI{T})
+  @key(return) @RI{T}
address@hidden
+
+   @NoPrefix@;The function yields the value @address@hidden,
+   i.e., the largest (most positive) integral value less than or equal to
+   @i{X}.
+   When @i{X} is zero, the
+   result has the sign of @i{X}; a zero result otherwise has a positive
+   sign.]}
+
address@hidden<S>, AttrName=<Ceiling>,
+  Text=[S'Ceiling denotes a function with the following
+   specification:
address@hidden
address@hidden(function) S'Ceiling (@RI{X} : @RI{T})
+  @key(return) @RI{T}
address@hidden
+
+   @NoPrefix@;The function yields the value @address@hidden,
+   i.e., the smallest (most negative) integral value greater than or equal to
+   @i{X}.
+   When @i{X} is zero, the
+   result has the sign of @i{X}; a zero result otherwise has a negative sign
+   when S'Signed_Zeros is True.]}
+
address@hidden<S>, AttrName=<Rounding>,
+  Text=[S'Rounding denotes a function with the following
+   specification:
address@hidden
address@hidden(function) S'Rounding (@RI{X} : @RI{T})
+  @key(return) @RI{T}
address@hidden
+
+   @NoPrefix@;The function yields the integral value nearest to @i{X},
+   rounding away from zero if @i{X} lies exactly halfway between two integers.
+   A zero result has the sign of @i{X} when S'Signed_Zeros is True.]}
+
address@hidden<S>, AttrName=<Unbiased_Rounding>,
+  Text=[S'Unbiased_Rounding denotes a function with
+   the following specification:
address@hidden
address@hidden(function) S'Unbiased_Rounding (@RI{X} : @RI{T})
+  @key(return) @RI{T}
address@hidden
+
+   @NoPrefix@;The function yields the integral value nearest to @i{X},
+   rounding toward the even integer if @i{X} lies exactly halfway between
+   two integers. A zero result has the sign of @i{X} when S'Signed_Zeros is
+   True.]}
+
address@hidden,Kind=[Added],ChginAnnex=[T],
+  Leading=<T>, Prefix=<S>, AttrName=<Machine_Rounding>, ARef=[AI95-00267-01],
+  address@hidden,New=[S'Machine_Rounding denotes a function
+     with the following specification:],Old=[]}
address@hidden(Descexample)
address@hidden,Kind=[Added]}
address@hidden,address@hidden(function) S'Machine_Rounding (@RI{X} : @RI{T})
+  @key(return) @RI{T}]}
address@hidden(Descexample)
+
+   @ChgRef{Version=[2],Kind=[Added]}
+   @ChgAdded{Version=[2],NoPrefix=[T],Text=[The function yields the
+   integral value nearest to @i{X}. If @i{X} lies exactly halfway between two
+   integers, one of those integers is returned, but which of them is returned
+   is unspecified. A zero result has the sign of @i{X} when S'Signed_Zeros is
+   True. This function provides access to the rounding behavior which is most
+   efficient on the target address@hidden
+
+   @begin{Discussion}
+     @ChgRef{Version=[2],Kind=[Added]}
+     @ChgAdded{Version=[2],Text=[We leave the rounding unspecified, so that
+     users cannot depend on a particular rounding. This attribute is intended
+     for use in cases where the particular rounding chosen is irrelevant. If
+     there is a need to know which way values halfway between two integers are
+     rounded, one of the other rounding attributes should be used.]}
+   @end{Discussion}
+
address@hidden<S>, AttrName=<Truncation>,
+  Text=[S'Truncation denotes a function with the following
+   specification:
address@hidden
address@hidden(function) S'Truncation (@RI{X} : @RI{T})
+  @key(return) @RI{T}
address@hidden
+
+   @NoPrefix@;The function yields the value @address@hidden when @i{X} is 
negative,
+   and @address@hidden otherwise. A zero result has the sign of @i{X} when
+   S'Signed_Zeros is True.]}
+
address@hidden<S>, AttrName=<Remainder>,
+  Text=[S'Remainder denotes a function with the following
+   specification:
address@hidden
address@hidden(function) S'Remainder (@RI{X}, @RI{Y} : @RI{T})
+  @key(return) @RI{T}
address@hidden
+
+   @address@hidden(Constraint_Error),Sec=(raised by failure of run-time check)}
+   For nonzero @i{Y}, let @RI{v} be the value
+   @RI{X} @en @RI{n} @Times @RI{Y}, where @RI{n} is the integer nearest to
+   the exact value of @RI{X}/@RI{Y}; if @address@hidden @en @RI{X}/@RI{Y}} = 
1/2,
+   then @RI(n) is chosen to be even. If @RI{v} is a machine number of
+   the type @i{T}, the function yields @RI{v}; otherwise, it yields zero.
address@hidden is raised if @i{Y} is zero.
+   A zero result has the sign of @i{X} when S'Signed_Zeros is True.]}
address@hidden
+   The magnitude of the result is less than or equal to one-half the magnitude
+   of @i{Y}.
address@hidden
address@hidden
+   Given machine numbers @i{X} and @i{Y} of the type @i{T}, @RI{v} is
+   necessarily a machine number of the type @i{T}, except when @i{Y} is in the
+   neighborhood of zero, @i{X} is sufficiently close to a multiple of @i{Y},
+   and @i{T}'Denorm is False.
address@hidden
+
address@hidden<S>, AttrName=<Adjacent>,
+  Text=[S'Adjacent denotes a function with the following
+   specification:
address@hidden
address@hidden(function) S'Adjacent (@RI{X}, @RI{Towards} : @RI{T})
+  @key(return) @RI{T}
address@hidden
+
+   @NoPrefix@;@Defn2{Term=(Constraint_Error),Sec=(raised by failure of 
run-time check)}
+   If @RI{Towards} = @RI{X}, the function yields @i{X}; otherwise, it
+   yields the machine number of the type @i{T} adjacent to @i{X} in the
+   direction of @i{Towards}, if that machine number exists.
+   @IndexCheck{Range_Check}If the result would
+   be outside the base range of S, Constraint_Error is raised.
+   When @i{T}'Signed_Zeros is True, a zero result has the sign of @i{X}.
+   When @i{Towards} is zero, its sign has no bearing on the result.]}
address@hidden
+   The value of S'Adjacent(0.0, 1.0) is the smallest normalized positive number
+   of the type @i{T} when @i{T}'Denorm is False and the smallest denormalized
+   positive number of the type @i{T} when @i{T}'Denorm is True.
address@hidden
+
address@hidden<S>, AttrName=<Copy_Sign>,
+  Text=[S'Copy_Sign denotes a function with the following specification:
address@hidden
address@hidden(function) S'Copy_Sign (@RI{Value}, @RI{Sign} : @RI{T})
+  @key(return) @RI{T}
address@hidden
+
+   @address@hidden(Constraint_Error),Sec=(raised by failure of run-time check)}
+   If the value of @i{Value} is nonzero, the function yields a result whose
+   magnitude is that of @i{Value} and whose sign is that of @i{Sign};
+   otherwise, it yields the value zero.
address@hidden is optionally raised if the result
+is outside the base range of S.
+   A zero result has the sign of @i{Sign} when S'Signed_Zeros is True.]}
address@hidden
+   S'Copy_Sign is provided for convenience in restoring the sign to a quantity
+   from which it has been temporarily removed, or to a related quantity. When
+   S'Signed_Zeros is True, it is also instrumental in determining the sign
+   of a zero quantity, when required. (Because negative and positive zeros
+   compare equal in systems conforming to IEC 559:1989, a negative zero does
+   @i{not} appear to be negative when compared to zero.) The sign
+   determination is accomplished by transferring the sign of the zero quantity
+   to a nonzero quantity and then testing for a negative result.
address@hidden
+
address@hidden<S>, AttrName=<Leading_Part>,
+  Text=[S'Leading_Part denotes a function with the following specification:
address@hidden
address@hidden(function) S'Leading_Part (@RI{X} : @RI{T};
+                         @RI{Radix_Digits} : @RI{universal_integer})
+  @key(return) @RI{T}
address@hidden
+
+   @NoPrefix@;Let @RI{v} be the value 
@address@hidden('Machine_Radix)@address@hidden@address@hidden,
+   where @RI{k} is the normalized exponent of @i{X}. The function yields
+   the value
+   @begin{Itemize}
+      @address@hidden/@RI{v}} @Times @RI{v},
+      when @i{X} is nonnegative and @i{Radix_Digits} is positive;
+
+      @address@hidden/@RI{v}} @Times @RI{v},
+      when @i{X} is negative and @i{Radix_Digits} is positive.
+   @end{Itemize}
+
+   @address@hidden(Constraint_Error),Sec=(raised by failure of run-time check)}
+   @IndexCheck{Range_Check}Constraint_Error is raised when @i{Radix_Digits}
+   is zero or negative.
+   A zero address@hidden, which can only occur when @i{X} is zero,} has the
+   sign of @i{X}.]}
address@hidden
+   Informally, if @i{X} is nonzero, the result is the value
+   obtained by retaining only the specified number of (leading) significant
+   digits of @i{X} (in the machine radix), setting all other digits to zero.
address@hidden
address@hidden
+   The result can be obtained by first scaling @i{X} up, if necessary to
+   normalize it, then masking the mantissa so as to retain only the specified
+   number of leading digits, then scaling the result back down if @i{X} was
+   scaled up.
address@hidden
+
address@hidden<S>, AttrName=<Machine>,
+  Text=[S'Machine denotes a function with the following specification:
address@hidden
address@hidden(function) S'Machine (@RI{X} : @RI{T})
+  @key(return) @RI{T}
address@hidden
+
+   @address@hidden(Constraint_Error),Sec=(raised by failure of run-time check)}
+   If @i{X} is a machine number of the type @i{T}, the function yields @i{X};
+   otherwise, it yields the value obtained by rounding or truncating @i{X} to
+   either one of the adjacent machine numbers of the type @i(T).
address@hidden is raised if rounding or
+truncating @i{X} to the precision
+   of the machine numbers results in a value outside the base range of S.
+   A zero result has the sign of @i{X} when S'Signed_Zeros is True.]}
address@hidden
+   @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+   All of the primitive function attributes except Rounding and Machine
+   correspond to subprograms in the Generic_Primitive_Functions
+   generic package @Chg{Version=[3],New=[that was ],Old=[]}proposed
+   as a separate ISO standard (ISO/IEC DIS 11729) for
+   Ada 83. The Scaling, Unbiased_Rounding, and Truncation attributes
+   correspond to the Scale, Round, and Truncate functions, respectively, in
+   Generic_Primitive_Functions. The Rounding attribute rounds away from zero;
+   this functionality was not provided in Generic_Primitive_Functions. The
+   name Round was not available for either of the primitive function attributes
+   that perform rounding, since an attribute of that name is used for a
+   different purpose for decimal fixed point types. Likewise, the name Scale
+   was not available, since an attribute of that name is also used for a
+   different purpose for decimal fixed point types. The functionality of the
+   Machine attribute was also not provided in Generic_Primitive_Functions. The
+   functionality of the Decompose procedure of Generic_Primitive_Functions is
+   only provided in the form of the separate attributes Exponent and Fraction.
+   The functionality of the Successor and Predecessor functions of
+   Generic_Primitive_Functions is provided by the extension of the existing
+   Succ and Pred attributes.
address@hidden
address@hidden
+   The primitive function attributes may be implemented either with appropriate
+   floating point arithmetic operations or with integer and logical operations
+   that act on parts of the representation directly. The latter is strongly
+   encouraged when it is more efficient than the former; it is mandatory when
+   the former cannot deliver the required accuracy due to limitations of the
+   implementation's arithmetic operations.
address@hidden
address@hidden(Description)
+
address@hidden
address@hidden@Defn2{Term=[model-oriented attributes],
+                Sec=[of a floating point subtype]}
+The following @i{model-oriented attributes} are defined for any subtype S of
+a floating point type @i{T}.
address@hidden
address@hidden
address@hidden<S>, AttrName=<Model_Mantissa>,
+  Text=[If the Numerics Annex is not supported,
+   this attribute yields an implementation defined value that is
+   greater than or equal to
+   @address@hidden @Times @Log(10) / @Log(@RI{T}'@R{Machine_Radix})} + 1, where
+   @RI{d} is the requested decimal precision of @i{T},
+   and less than or equal to the value of
+   @i{T}'Machine_Mantissa.
+   See @RefSecNum{Model-Oriented Attributes of Floating Point Types}
+   for further requirements
+   that apply to implementations supporting the Numerics
+   Annex.
+   The value of this attribute is of the type
+   @i{universal_integer}.]}
+
address@hidden<S>, AttrName=<Model_Emin>,
+  Text=[If the Numerics Annex is not supported,
+  this attribute yields an implementation defined value
+  that is greater than or equal to the value
+  of @i{T}'Machine_Emin.
+  See @RefSecNum{Model-Oriented Attributes of Floating Point Types}
+  for further requirements
+  that apply to implementations supporting the Numerics
+  Annex.
+  The value of this attribute is of the type
+  @i{universal_integer}.]}
+
address@hidden<S>, AttrName=<Model_Epsilon>,
+  Text=[Yields the value
+   @address@hidden('Machine_Radix)@+{1 @en @address@hidden('Model_Mantissa)}. 
The value of this
+   attribute is of the type @i{universal_real}.]}
address@hidden
+   In most implementations, this attribute yields the absolute value of the
+   difference between one and the smallest machine number of the type @i{T}
+   above one which, when added to one, yields a machine number different from
+   one. Further discussion can be found in
+   @RefSecNum{Model-Oriented Attributes of Floating Point Types}.
address@hidden
+
address@hidden<S>, AttrName=<Model_Small>,
+  Text=[Yields the value
+   @address@hidden('Machine_Radix)@address@hidden@R('Model_Emin) @en 1}. The 
value of this
+   attribute is of the type @i{universal_real}.]}
address@hidden
+   In most implementations, this attribute yields the
+   smallest positive normalized number of the type @i{T},
+   i.e. the number corresponding to the positive underflow
+   threshold. In some implementations employing a radix-complement
+   representation for the type @i{T}, the positive underflow threshold is
+   closer to zero than is the negative underflow threshold, with the
+   consequence that the smallest positive normalized number does not coincide 
with
+   the positive underflow threshold (i.e., it exceeds the latter). Further
+   discussion can be found in
+   @RefSecNum{Model-Oriented Attributes of Floating Point Types}.
address@hidden
+
address@hidden<S>, AttrName=<Model>,
+  Text=[S'Model denotes a function with the following specification:
address@hidden
address@hidden(function) S'Model (@RI{X} : @RI{T})
+  @key(return) @RI{T}
address@hidden
+
+   @NoPrefix@;If the Numerics Annex is not supported,
+   the meaning of this attribute is implementation
+   defined;
+   see @RefSecNum{Model-Oriented Attributes of Floating Point Types}
+   for the definition that applies to implementations supporting
+   the Numerics Annex.]}
+
address@hidden<S>, AttrName=<Safe_First>,
+  Text=[Yields the lower bound of the safe range
+  (see @RefSecNum{Floating Point Types}) of the type @i{T}.
+  If the Numerics Annex is not supported, the value
+  of this attribute is implementation defined;
+  see @RefSecNum{Model-Oriented Attributes of Floating Point Types}
+  for the definition that applies to
+  implementations supporting the Numerics Annex. The value of this attribute
+  is of the type @i{universal_real}.]}
+
address@hidden<S>, AttrName=<Safe_Last>,
+  Text=[Yields the upper bound of the safe range
+  (see @RefSecNum{Floating Point Types}) of the type @i{T}.
+  If the Numerics Annex is not supported, the value
+  of this attribute is implementation defined;
+  see @RefSecNum{Model-Oriented Attributes of Floating Point Types}
+  for the definition that applies to
+  implementations supporting the Numerics Annex. The value of this attribute
+  is of the type @i{universal_real}.]}
address@hidden
+   A predefined floating point arithmetic operation that yields a value in the
+   safe range of its result type is guaranteed not to overflow.
address@hidden
address@hidden
+
+An exception is made for exponentiation by a negative exponent in
address@hidden Precedence Operators}.
+
address@hidden
address@hidden values of the Model_Mantissa, Model_Emin, Model_Epsilon,
+Model, Safe_First, and Safe_Last attributes, if the Numerics
+Annex is not supported.}
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden with Ada 83}
+The Epsilon and Mantissa attributes of floating point types are removed
+from the language and replaced by Model_Epsilon and
+Model_Mantissa, which may have different values (as a result of changes in the
+definition of model numbers); the replacement of one set of attributes by
+another is intended to convert what would be an inconsistent change into an
+incompatible change.
+
+The Emax, Small, Large, Safe_Emax, Safe_Small, and Safe_Large attributes of
+floating point types are removed from the language. Small and Safe_Small are
+collectively replaced by Model_Small, which is functionally equivalent to
+Safe_Small, though it may have a slightly different value. The others are
+collectively replaced by Safe_First and Safe_Last. Safe_Last is functionally
+equivalent to Safe_Large, though it may have a different value; Safe_First is
+comparable to the negation of Safe_Large but may differ slightly from it as
+well as from the negation of Safe_Last. Emax and Safe_Emax had relatively few
+uses in Ada 83; T'Safe_Emax can be computed in the revised language as
+Integer'Min(T'Exponent(T'Safe_First), T'Exponent(T'Safe_Last)).
+
+Implementations are encouraged to eliminate the incompatibilities discussed
+here by retaining the old attributes, during a transition period,
+in the form of implementation-defined attributes with their former values.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The Model_Emin attribute is new. It is conceptually similar to the negation of
+Safe_Emax attribute of Ada 83, adjusted for the fact that the model numbers now
+have the hardware radix. It is a fundamental determinant, along with
+Model_Mantissa, of the set of model numbers of a type
+(see @RefSecNum{Model of Floating Point Arithmetic}).
+
+The Denorm and Signed_Zeros attributes are new, as are all of the
+primitive function attributes.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00388-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The Machine_Rounding attribute is new.]}
address@hidden
+
+
address@hidden of Fixed Point Types}
+
address@hidden
address@hidden@Defn2{Term=[representation-oriented attributes],
+                Sec=[of a fixed point subtype]}
+The following @i{representation-oriented} attributes are defined for
address@hidden subtype S of a fixed point type @i{T}}.
address@hidden
address@hidden<S>, AttrName=<Machine_Radix>,
+  Text=[Yields the radix of the hardware representation of the type
+   @i{T}. The value of this attribute is of the type @i{universal_integer}.]}
+
address@hidden<S>, AttrName=<Machine_Rounds>,
+  Text=[Yields the value True if rounding is performed on inexact
+   results of every predefined operation that yields a result of the
+   type @i{T}; yields the value False otherwise.
+   The value
+   of this attribute is of the predefined type Boolean.]}
+
address@hidden<S>, AttrName=<Machine_Overflows>,
+  Text=[Yields the value True if overflow and divide-by-zero are detected and
+   reported by raising Constraint_Error for every predefined operation that
+   yields a result of the type @i{T};
+   yields the value False otherwise.
+   The value of
+   this attribute is of the predefined type Boolean.]}
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden with Ada 83}
+The Mantissa, Large, Safe_Small, and Safe_Large attributes of fixed
+point types are removed from the language.
+
+Implementations are encouraged to eliminate the resulting incompatibility by
+retaining these attributes, during a transition period,
+in the form of implementation-defined attributes with their former values.
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The Machine_Radix attribute
+is now allowed for fixed point types. It is
+also specifiable in an attribute definition clause
+(see @RefSecNum{Machine_Radix Attribute Definition Clause}).
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/rm.msm 
b/packages/ada-ref-man/source_2012/rm.msm
new file mode 100755
index 0000000..997d03c
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/rm.msm
@@ -0,0 +1,107 @@
address@hidden file for the RM (public versions)}
+
address@hidden properties}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden,Text=[Ada Reference address@hidden title for all versions}
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden
address@hidden@Comment{For Ada 95 and 2005, use "section" instead}
+
address@hidden properties}
address@hidden @Comment{One large file allows Word to make a TOC}
address@hidden,Text=[ISO/IEC 8652:1995(E)]}
address@hidden,Text=[ISO/IEC 8652:1995(E) with COR.1:2001]}
address@hidden: address@hidden,Text=[ISO/IEC 8652:2007(E) Ed. 3]}
address@hidden: @RTFHeaderPrefix{Version=[2],Text=[Consolidated Ada Reference 
Manual - 2005 Edition]}}
address@hidden: address@hidden,Text=[ISO/IEC 8652:2012(E)]}
address@hidden: @RTFHeaderPrefix{Version=[3],Text=[Ada Reference Manual - 2012 
Edition]}}
address@hidden: address@hidden,Text=[ISO/IEC 8652:2012(E) with COR.1:2016]}
address@hidden,Text=[ISO/IEC 8652:202x(E)]}
address@hidden,UseClauseName=[T],address@hidden style footers}
address@hidden
address@hidden,SansSerif=[Arial]}
address@hidden,Text=[Original Text]}
address@hidden,Text=[Technical Corrigendum 1]}
address@hidden,Text=[Amendment 1]}
address@hidden,Text=[Ada 2012]}
address@hidden,Text=[Ada 2012 Corrigendum 1]}
address@hidden,Text=[Ada 202x]}
+
address@hidden properties}
address@hidden small files are used, thus no @SingleHTMLOutputFile command}
address@hidden,address@hidden "4Comp" for the Consolidated AARM}
address@hidden,SrchName=[RM-SRCH.html],IndexName=[],
+   UseButtons=[T],OnTop=[T],OnBottom=[T]}
address@hidden let the program link to the index}
address@hidden
address@hidden<DIV><SPAN Style="font-size:200%; color: rgb(0,0,153)"><B>Ada 
Reference Manual</B></SPAN> &mdash; <A HREF="RM-TTL.html"><B>Legal 
Information</B></A></DIV>}
address@hidden<DIV Style="margin-top:0.0em"><IMG SRC="AE_logo.gif" height=100 
width=113 align=right ALT="Ada-Europe">
+<SPAN Style="vertical-align: middle; font-size:120%">Ada 2005 and 2012 
Editions sponsored in part by <SPAN Style="font-size: 125%"><A 
HREF="http://www.ada-europe.org/";><B>Ada-Europe</B></A></SPAN></SPAN></DIV>}
address@hidden,Background=[#FFFFF0],Link=[#000080],VLink=[#330033],ALink=[#0000FF]}
+
address@hidden files and related items, in collating order}
address@hidden<Title.MSS>,SectionName=<Ttl>,SectionNumber=[0],NewSection=[T]}
address@hidden @Comment{The table of contents goes here in the collating order}
address@hidden<Front_Matter.MSS>,SectionName=<00>,SectionNumber=[0],NewSection=[T]}
address@hidden<01.MSS>,SectionName=<01>,SectionNumber=[1],NewSection=[T]}
address@hidden<02.MSS>,SectionName=<02>,SectionNumber=[2],NewSection=[T]}
address@hidden<03A.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[T]}
address@hidden<03B.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[F]}
address@hidden<03C.MSS>,SectionName=<03>,SectionNumber=[3],NewSection=[F]}
address@hidden<04A.MSS>,SectionName=<04>,SectionNumber=[4],NewSection=[T]}
address@hidden<04B.MSS>,SectionName=<04>,SectionNumber=[4],NewSection=[F]}
address@hidden<05.MSS>,SectionName=<05>,SectionNumber=[5],NewSection=[T]}
address@hidden<06.MSS>,SectionName=<06>,SectionNumber=[6],NewSection=[T]}
address@hidden<07.MSS>,SectionName=<07>,SectionNumber=[7],NewSection=[T]}
address@hidden<08.MSS>,SectionName=<08>,SectionNumber=[8],NewSection=[T]}
address@hidden<09.MSS>,SectionName=<09>,SectionNumber=[9],NewSection=[T]}
address@hidden<10.MSS>,SectionName=<10>,SectionNumber=[10],NewSection=[T]}
address@hidden<11.MSS>,SectionName=<11>,SectionNumber=[11],NewSection=[T]}
address@hidden<12.MSS>,SectionName=<12>,SectionNumber=[12],NewSection=[T]}
address@hidden<13A.MSS>,SectionName=<13>,SectionNumber=[13],NewSection=[T]}
address@hidden<13B.MSS>,SectionName=<13>,SectionNumber=[13],NewSection=[F]}
address@hidden, the "Standard Libraries" separator page}
address@hidden<LIBRARY.MSS>,SectionName=<Lib>,SectionNumber=[0],NewSection=[T]}
address@hidden A; all of the files starting with "Pre_" are part of Annex A.}
address@hidden<PRE.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[T]}
address@hidden<PRE_Standard.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Ada.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Chars.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Strings.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Math.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<Real_Attribs.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_IO.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Cmdln.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Dirs.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Environ.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Containers.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Con2.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden<PRE_Locales.MSS>,SectionName=<A>,SectionNumber=[A],NewSection=[F]}
address@hidden normative annexes:}
address@hidden<Interface.MSS>,SectionName=<B>,SectionNumber=[B],NewSection=[T]}
address@hidden<SP.MSS>,SectionName=<C>,SectionNumber=[C],NewSection=[T]}
address@hidden<RT.MSS>,SectionName=<D>,SectionNumber=[D],NewSection=[T]}
address@hidden<DS.MSS>,SectionName=<E>,SectionNumber=[E],NewSection=[T]}
address@hidden<InfoSys.MSS>,SectionName=<F>,SectionNumber=[F],NewSection=[T]}
address@hidden<Numerics.MSS>,SectionName=<G>,SectionNumber=[G],NewSection=[T]}
address@hidden<Safety.MSS>,SectionName=<H>,SectionNumber=[H],NewSection=[T]}
address@hidden don't use Annex I, as ISO used to require skipping I and O}
address@hidden<Obsolescent.MSS>,SectionName=<J>,SectionNumber=[J],NewSection=[T]}
address@hidden annexes:}
address@hidden<Attribs.MSS>,SectionName=<K>,SectionNumber=[K],NewSection=[T]}
address@hidden<Pragmas.MSS>,SectionName=<L>,SectionNumber=[L],NewSection=[T]}
address@hidden<Impldef.MSS>,SectionName=<M>,SectionNumber=[M],NewSection=[T]}
address@hidden<Glossary.MSS>,SectionName=<N>,SectionNumber=[N],NewSection=[T]}
address@hidden don't use Annex O, as ISO used to require skipping I and O}
address@hidden<Syntax.MSS>,SectionName=<P>,SectionNumber=[P],NewSection=[T]}
address@hidden<Langdef.MSS>,SectionName=<Q>,SectionNumber=[Q],NewSection=[T]}
address@hidden<Index.MSS>,SectionName=<IDX>,SectionNumber=[0],NewSection=[T]}
+
diff --git a/packages/ada-ref-man/source_2012/rt.mss 
b/packages/ada-ref-man/source_2012/rt.mss
new file mode 100755
index 0000000..aa8a54b
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/rt.mss
@@ -0,0 +1,6683 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/rt.mss,v $ }
address@hidden $Revision: 1.120 $ $Date: 2016/02/12 05:25:38 $ $Author: randy $ 
}
address@hidden(realtime, Root="ada.mss")
address@hidden: 2016/02/12 05:25:38 $}
+
address@hidden Systems}
+
address@hidden
address@hidden systems}
address@hidden systems}
+This Annex specifies additional characteristics of Ada implementations
+intended for real-time systems software. To conform to this Annex, an
+implementation shall also conform to the Systems Programming Annex.
address@hidden
+
address@hidden
+
+The metrics are documentation requirements; an implementation shall
+document the values of the language-defined metrics for at least one
+configuration @Redundant[of hardware or an underlying system] supported by
+the implementation, and shall document the details of that configuration.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Values of all @address@hidden're going to document the
+individual metrics sections.}
address@hidden,Kind=[Added],address@hidden,
+Text=[The details of the configuration used to generate the values of all
+metrics.]}]}
address@hidden
+The actual values of the metrics are likely to depend on hardware
+configuration details that are variable and generally outside the control
+of a compiler vendor.
address@hidden
+
+The metrics do not necessarily yield a simple number.
address@hidden some, a range is more suitable, for others a formula
+dependent on some parameter is appropriate, and for
+others,
+it may be more suitable to break the metric into several cases.]
+Unless specified otherwise, the metrics in this annex are expressed in
+processor clock cycles.
+For metrics that require documentation of an upper bound,
+if there is no upper bound,
+the implementation shall report that the metric is unbounded.
address@hidden
+There are several good reasons to specify metrics in seconds; there are however
+equally good reasons to specify them in processor clock cycles. In
+defining the metrics, we have tried to strike a balance on a case-by-case
+basis.
+
+It has been suggested that all metrics should be given names,
+so that @lquotes@;address@hidden@; could be formulated and published
+by vendors.
+However the paragraph number can serve that purpose.
address@hidden
+
address@hidden
+
address@hidden
+
+The specification of the metrics makes a distinction between upper bounds
+and simple execution times. Where something is just specified as @lquotes@;the
+execution time address@hidden@; a piece of code, this leaves one
+the freedom
+to choose a nonpathological case. This kind of metric is of the form
address@hidden@;there exists a program such that the value of the metric is 
address@hidden@;.
+Conversely, the meaning of upper bounds is @lquotes@;there is no program such
+that the value of the metric is greater than address@hidden@;.
+This kind of metric can only be partially tested, by finding the value
+of V for one or more test programs.
+
+The metrics do not cover the whole language; they are limited
+to features that are specified in @RefSec{Systems Programming}
+and in this Annex. The metrics are intended
+to provide guidance to potential users as to whether a particular
+implementation of such a feature is going to be adequate for a
+particular real-time application. As such, the metrics are aimed
+at known implementation choices that can result in significant
+performance differences.
+
+The purpose of the metrics is not necessarily to provide fine-grained
+quantitative results or to serve as a comparison between different
+implementations on the same or different platforms. Instead, their
+goal is rather qualitative; to define a standard set of approximate values
+that can be measured and used to estimate the general suitability of an
+implementation, or to evaluate the comparative utility of certain features
+of an implementation for a particular real-time application.
+
address@hidden
+
address@hidden
address@hidden to Ada 83}
+This Annex is new to Ada 95.
address@hidden
+
+
address@hidden Priorities}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} specifies
+the priority model for real-time systems.
+In addition, the methods for specifying priorities are defined.]
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 2
+through 6 were moved to @RefSec{Obsolescent Features}.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],KeepNext=[T],Text=[The form of a
address@hidden Priority is as follows:]}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden<Version=[3],InitialVersion=[0],@ChgDeleted{Version=[3],
address@hidden @prag(Priority)(@Syn2{expression});]}>
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],KeepNext=[T],Text=[The form of a
address@hidden Interrupt_Priority is as follows:]}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden<Version=[3],InitialVersion=[0],@ChgDeleted{Version=[3],
address@hidden @prag(Interrupt_Priority)[(@Syn2{expression})];]}>
address@hidden
+
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,address@hidden type],
+  Sec=(Priority pragma argument)}
address@hidden type],
+  Sec=(Interrupt_Priority pragma argument)}
+The expected type for the @nt{expression} in a Priority
+or Interrupt_Priority pragma is Integer.]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[For a task type (including the
+anonymous type of a @nt{single_task_declaration}), protected type (including 
the
+anonymous type of a @nt{single_protected_declaration}), or subprogram,
+the following language-defined representation aspects may be specified:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden aspect Priority is
+an @nt{expression}, which shall be of type address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Priority],
+    address@hidden,Text=[Priority of a task object or type, or
+      priority of a protected object or type; the priority is not in the
+      interrupt range.]}]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden aspect
+Interrupt_Priority is an @nt{expression}, which shall be of type
address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Interrupt_Priority],
+    address@hidden,Text=[Priority of a task object or type, or
+      priority of a protected object or type; the priority is in the
+      interrupt range.]}]}
+
address@hidden
address@hidden
+
+
address@hidden
+
address@hidden,Kind=[Deleted],ARef=[AI05-0229-1]}
address@hidden,Text=[A Priority pragma is allowed only immediately
+within a @nt{task_definition}, a @nt{protected_definition}, or the
address@hidden of a @nt{subprogram_body}. An Interrupt_Priority pragma is
+allowed only immediately within a @nt{task_definition} or a
address@hidden At most one such pragma shall appear within a given
+construct.]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[If the],Old=[For a]} Priority @Chg{Version=[3],New=[aspect
+is specified for a subprogram],Old=[pragma that appears in the
address@hidden of a @nt{subprogram_body}]}, the @nt{expression} shall be
+static, and its value shall be in the range of System.Priority.
address@hidden
+This value is needed before it gets elaborated, when the environment task
+starts executing.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Text=[At most one of the Priority and Interrupt_Priority
+aspects may be specified for a given entity.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[This includes specifying via pragmas
+  (see @RefSecNum{Pragmas Priority and Interrupt_Priority}). Note that
+  @RefSecNum{Operational and Representation Aspects} prevents multiple
+  specifications of a single representation aspect by any means.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Text=[Neither of the Priority or Interrupt_Priority
+aspects shall be specified for a synchronized interface type.]}
+
address@hidden
+
address@hidden
+
address@hidden@keepnext@;The following declarations exist in package System:
address@hidden
address@hidden Any_Priority @key{is} Integer @key{range} 
@RI{implementation-defined};
address@hidden Priority @key{is} Any_Priority
+   @key{range} Any_Priority'First .. @RI{implementation-defined};
address@hidden Interrupt_Priority @key{is} Any_Priority
+   @key{range} Priority'Last+1 .. Any_Priority'Last;
+
+Default_Priority : @key{constant} Priority := (Priority'First + 
Priority'Last)/2;
address@hidden
address@hidden declarations of Any_Priority and Priority.}
+
+The full range of priority values supported by an implementation is specified
+by the subtype Any_Priority. The subrange of priority values that are high
+enough to require the blocking of one or more interrupts is specified by the
+subtype address@hidden @Redundant[The subrange of priority values below
address@hidden@!Priority'First is specified by the subtype address@hidden
+
address@hidden,Kind=[Deleted],ARef=[AI05-0229-1]}
address@hidden,Text=[The priority specified by a Priority or
+Interrupt_Priority pragma is the value of the @nt{expression} in the pragma, if
+any. If there is no @nt{expression} in an Interrupt_Priority pragma, the
+priority value is Interrupt_Priority'Last.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,New=[The],Old=[A]} Priority
address@hidden,New=[aspect],Old=[pragma]} has no effect
+if it @Chg{Version=[3],New=[is specified for],Old=[it occurs
+in the @nt{declarative_part} of the @nt{subprogram_body} of]} a
+subprogram other than the main address@hidden,New=[; the Priority
+value is not associated with any task],Old=[]}.
+
address@hidden priority}
address@hidden
address@hidden inheritance}
address@hidden priority}
address@hidden priority}
+A @i{task priority} is an integer value that indicates a degree of urgency
+and is the basis for resolving competing demands of tasks for
+resources. Unless otherwise specified, whenever tasks compete
+for processors or other implementation-defined resources, the
+resources are allocated to the task with the highest priority
+value.
+The @i{base priority} of a task is the priority with which it was
+created, or to which it was later set by Dynamic_Priorities.Set_Priority
+(see @RefSecNum{Dynamic Priorities}). At all times, a task also has
+an @i{active priority}, which generally reflects its base priority
+as well as any priority it inherits from other sources.
address@hidden inheritance} is the process by which the priority of a
+task or other entity (e.g. a protected object;
+see @RefSecNum{Priority Ceiling Locking}) is used in the evaluation of another
+task's active priority.
address@hidden execution resources.}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The effect of specifying @Chg{Version=[3],New=[a Priority or
+Interrupt_Priority aspect for a protected type or
address@hidden,Old=[such a pragma
+in a @nt{protected_definition}]}
+is discussed in @RefSecNum{Priority Ceiling Locking}.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0081-1]}
address@hidden, Sec=(of a task object)}
+The @nt{expression} @Chg{Version=[3],New=[specified for the],Old=[in a]}
+Priority or Interrupt_Priority @Chg{Version=[3],New=[aspect of a
address@hidden,New=[ type],Old=[]}],Old=[pragma that
+appears in a @nt{task_definition}]} is evaluated
address@hidden,New=[],Old=[for ]}each
address@hidden,New=[time an],Old=[task]}
address@hidden,New=[ of the task type is created],Old=[]}
+(see @RefSecNum{Task Units and Task Objects}).
+For @Chg{Version=[3],New=[the],Old=[a]} Priority 
@Chg{Version=[3],New=[aspect],Old=[pragma]},
+the value of the @nt{expression} is converted to the subtype Priority;
+for @Chg{Version=[3],New=[the],Old=[an]}
+Interrupt_Priority @Chg{Version=[3],New=[aspect],Old=[pragma]}, this value
+is converted to the subtype Any_Priority.
+The priority value is then associated with the task
address@hidden,New=[],Old=[whose @Chg{Version=[3],New=[task declaration
+specifies the aspect],address@hidden contains the pragma]}]}.
address@hidden,address@hidden subtype conversion],Sec=(Priority aspect)}
address@hidden subtype conversion],Sec=(Interrupt_Priority aspect)}],
address@hidden subtype conversion],Sec=(pragma Priority)}
address@hidden subtype conversion],Sec=(pragma Interrupt_Priority)}]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+Likewise, the priority value is associated with the environment task if the
address@hidden,New=[aspect is specified for],Old=[pragma appears in the
address@hidden of]} the main subprogram.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The initial value of a task's base priority is specified by default or
+by means of a Priority or Interrupt_Priority
address@hidden,New=[aspect],Old=[pragma]}.
address@hidden a task is created,
+its base priority can be changed only by a call to
+Dynamic_Priorities.Set_Priority (see @RefSecNum{Dynamic Priorities}).]
+The initial base priority of a task in the absence of
address@hidden,New=[an aspect],Old=[a pragma]} is the
+base priority of the task that creates it at the time of creation
+(see @RefSecNum{Task Units and Task Objects}).
+If @Chg{Version=[3],New=[the aspect],Old=[a pragma]} Priority
address@hidden,New=[is not specified for],Old=[does not apply to]} the
+main subprogram, the initial base priority of the environment task is
+System.Default_Priority.
address@hidden task's active priority is used when the task competes for
+processors.
+Similarly, the task's active priority is used
+to determine the task's position in any queue when Priority_Queuing is
+specified (see @RefSecNum{Entry Queuing Policies}).]
+
address@hidden@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00357-01]}
+At any time, the active priority of a task is the maximum of all the
+priorities the task is inheriting at that instant. For a task that is not
+held (see @RefSecNum{Asynchronous Task Control}), its base priority is
address@hidden,New=[],Old=[always ]}a source of priority inheritance
address@hidden,New=[unless otherwise
+specified for a particular task dispatching policy],Old=[]}.
+Other sources of priority inheritance are specified under the following
+conditions:
address@hidden
+Other parts of the annex, e.g.
address@hidden Task Control}, define
+other sources of priority inheritance.
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0072],ARef=[AI95-00092-01]}
+During activation, a task being activated inherits the active priority
address@hidden,Old=[of the]} its activator (see
address@hidden Execution - Task Activation})@Chg{New=[ had at the time
+the activation was initiated],Old=[]}.
+
address@hidden,Kind=[Revised],Ref=[8652/0072],ARef=[AI95-00092-01]}
+During rendezvous, the task accepting the entry call inherits the
address@hidden,Old=[active ]}priority of the @Chg{New=[entry call],Old=[caller]}
+(see @RefSecNum{Entry address@hidden and @RefSecNum{Entry Queuing 
Policies}],Old=[]}).
+
+During a protected action on a protected object, a task inherits the ceiling
+priority of the protected object (see @RefSecNum{Intertask Communication} and
address@hidden Ceiling Locking}).
+
address@hidden
+
+In all of these cases, the priority ceases to be
+inherited as soon as the condition calling for the inheritance no longer
+exists.
+
address@hidden
+
address@hidden
+
+The range of System.Interrupt_Priority shall include at least one value.
+
+The range of System.Priority shall include at least 30 values.
+
address@hidden
+
address@hidden
+
+The priority expression can include references to
+discriminants of the enclosing type.
+
+It is a consequence of the active priority rules that at the point when
+a task stops inheriting a priority from another source, its active priority
+is re-evaluated. This is in addition to other instances described in this
+Annex for such re-evaluation.
+
address@hidden,Kind=[Revised],ARef=[AI05-0248-1]}
+An implementation may provide a
address@hidden,New=[nonstandard],Old=[non-standard]} mode in which tasks
+inherit priorities under conditions other than those specified above.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The use of a Priority or Interrupt_Priority
address@hidden,New=[aspect],Old=[pragma]} does not
+require the package System to be named in a @nt{with_clause} for the
+enclosing @nt{compilation_unit}.
address@hidden
+
address@hidden
+
address@hidden
address@hidden to Ada 83}
+The priority of a task is per-object and not per-type.
+
+Priorities need not be static anymore (except for the main subprogram).
+
address@hidden
+
address@hidden
+
+The description of the Priority pragma has been moved to this annex.
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0072],ARef=[AI95-00092-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that dynamic
+  priority changes are not transitive - that is, they don't apply to tasks
+  that are being activated by or in rendezvous with the task that had its
+  priority changed.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00357-01]}
+  @ChgAdded{Version=[2],Text=[Generalized the definition of priority
+  inheritance to take into account the differences between the existing and
+  new dispatching policies.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Aspects Priority and Interrupt_Priority are new; @nt{pragma}s
+  Priority and Interrupt_Priority are now obsolescent.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0081-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified when the 
Priority
+  and Interrupt_Priority aspect expressions are evaluated.]}
address@hidden
+
+
address@hidden Scheduling}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00321-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]}
+describes the rules that determine which task is
+selected for execution when more than one task is ready
+(see @Chg{Version=[2],address@hidden and Synchronization}],
address@hidden Execution - Task Activation}]})address@hidden,
+New=[],Old=[ The rules have two parts: the task dispatching model
+(see @RefSecNum{The Task Dispatching Model}),
+and a specific task dispatching policy
+(see @RefSecNum{Task Dispatching Pragmas}).]}]
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00321-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[This introduction is simplified in order to
+  reflect the rearrangement and expansion of this 
@Chg{Version=[3],New=[subclause],Old=[clause]}.]}
address@hidden
+
+
address@hidden Task Dispatching Model}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00321-01]}
address@hidden task dispatching model specifies @Chg{Version=[2],
+New=[task],Old=[preemptive]} scheduling, based on conceptual
+priority-ordered ready queues.]
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The following
+language-defined library package exists:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0166-1]}
address@hidden,address@hidden<package> Ada.Dispatching 
@key<is>@ChildUnit{Parent=[Ada],Child=[Dispatching]}
+  @key<pragma> 
@Chg{Version=[3],New=[Preelaborate],Old=[Pure]}(Dispatching);@Chg{Version=[3],New=[],Old=[
+  @AdaExcDefn{Dispatching_Policy_Error} : @key<exception>;
address@hidden<end> Ada.Dispatching;]}]}
+
address@hidden,Kind=[Added],ARef=[AI05-0166-1]}
address@hidden,Text=[  @key<procedure> @AdaSubDefn{Yield};]}
+
address@hidden,Kind=[Added],ARef=[AI05-0166-1]}
address@hidden,Text=[  @AdaExcDefn{Dispatching_Policy_Error} : @key<exception>;
address@hidden<end> Ada.Dispatching;]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Text=[Dispatching serves as the parent of other
+language-defined library units concerned with task dispatching.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00321-01]}
+A task @Chg{Version=[2],New=[can become],Old=[runs (that is, it becomes]} a
address@hidden address@hidden,New=[],Old=[)]} only @Chg{Version=[2],
+New=[if],Old=[when]} it is ready (see @Chg{Version=[2],address@hidden and 
Synchronization}],
address@hidden Execution - Task Activation}]}) and
+the execution resources required by that task are available.
+Processors are allocated to tasks based on each task's active priority.
+
+It is implementation defined whether, on a multiprocessor, a task that
+is waiting for access to a protected object keeps its processor busy.
address@hidden, on a multiprocessor, a task that
+is waiting for access to a protected object keeps its processor busy.}
+
address@hidden,Kind=[Revised],ARef=[AI95-00321-01]}
address@hidden dispatching}
address@hidden, task}
address@hidden dispatching point}
address@hidden point}
address@hidden dispatching} is the process by which one ready task is selected
+for execution on a processor. This selection is done at certain points
+during the execution of a task called @i{task dispatching points}.
+A task reaches a task dispatching point whenever it becomes blocked,
+and @Chg{Version=[2],New=[when it terminates],Old=[whenever it becomes ready.
+In addition, the completion of an @nt{accept_statement}
+(see @RefSecNum{Entries and Accept Statements}), and task termination are
+task dispatching points for the executing task]}.
address@hidden task dispatching points are defined
+throughout this address@hidden,New=[ for specific policies],Old=[]}.]
address@hidden
+On multiprocessor systems, more than one task can be chosen, at the
+same time, for execution on more than one processor, as explained below.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00321-01]}
address@hidden queue}
address@hidden (of a queue)}
address@hidden (of a queue)}
address@hidden task}
address@hidden dispatching policy}
address@hidden policy for tasks}
address@hidden dispatching policies} are specified in terms of conceptual
address@hidden address@hidden,New=[ and],Old=[,]} task address@hidden,
+New=[],Old=[, and task preemption]}.
+A ready queue is an ordered list of ready tasks.
+The first position in a queue is called the
address@hidden of the queue}, and the last position is called the
address@hidden of the queue}.
+A task is @i{ready} if it is in a ready queue,
+or if it is running.
+Each processor has one ready queue for each priority value. At any instant,
+each ready queue of a processor contains exactly the set of tasks of that
+priority that are ready for execution on that
+processor, but are not running on any processor; that is, those tasks
+that are ready, are not running on any processor, and can be
+executed using that processor and other available resources.
+A task can be on the ready queues of more than one processor.
address@hidden
+The core language defines a ready task as one that is not
+blocked. Here we refine this definition and
+talk about ready queues.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00321-01]}
address@hidden task}
+Each processor also has one @i{running task},
+which is the task currently being executed by that processor.
+Whenever a task running on a processor reaches a task dispatching
address@hidden,New=[ it goes back to one or more ready queues; a],
+Old=[, one]} task @Chg{Version=[2],New=[(possibly the same task) ],Old=[]}is
address@hidden,New=[then ],Old=[]}selected to run on that processor.
+The task selected is the one at the head of the highest priority
+nonempty ready queue;
+this task is then removed from all ready queues to which it
+belongs.
address@hidden
+There is always at least one task to run,
+if we count the idle task.
address@hidden
+
address@hidden,Kind=[Deleted],ARef=[AI95-00321-01]}
address@hidden,Kind=[AddedNormal],ARef=[AI05-0166-1]}
address@hidden,address@hidden resource}
+A preemptible resource is a resource that while allocated
+to one task can be allocated (temporarily) to another
+instead.
+Processors are preemptible resources. Access to a protected object
+(see @RefSecNum{Protected Subprograms and Protected Actions})
+is a nonpreemptible resource.
address@hidden task}
+When a higher-priority task is dispatched to the processor, and the previously
+running task is placed on the appropriate ready queue, the latter task
+is said to be @i{preempted}.]}
address@hidden,Text=[A call of Yield is a task dispatching point. Yield
+is a potentially blocking operation (see @RefSecNum{Protected Subprograms and 
Protected Actions}).]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Deleted]}
+  @ChgDeleted{Version=[2],Text=[A processor that is executing a task is 
available
+  to execute tasks of higher priority, within the set of tasks that that
+  processor is able to execute. Write access to a protected object, on the 
other
+  hand, cannot be granted to a new task before the old task has released it.]}
address@hidden
+
address@hidden,Kind=[Deleted],ARef=[AI95-00321-01]}
address@hidden,address@hidden dispatching point}
address@hidden point}
+A new running task is also selected whenever there is a nonempty ready queue
+with a higher priority than the priority of the running
+task, or when the task dispatching policy requires a
+running task to go back to a ready queue.
address@hidden are also task dispatching points.]]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Deleted]}
+  @ChgDeleted{Version=[2],Text=[Thus, when a task becomes ready, this is a task
+  dispatching point for all running tasks of lower priority.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00321-01]}
+An implementation is allowed to define additional resources as execution
+resources, and to define the corresponding allocation policies for them.
+Such resources may have an address@hidden,New=[-],Old=[ ]}defined
+effect on task address@hidden,New=[],
+Old=[ (see @RefSecNum{Task Dispatching Pragmas})]}.
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[The @Chg{Version=[2],New=[effect],Old=[affect]} of
address@hidden,New=[-],Old=[ ]}defined
+execution resources on task dispatching.]}
+
+An implementation may place implementation-defined restrictions on
+tasks whose active priority is in the Interrupt_Priority range.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+For example, on some operating systems,
+it might be necessary to disallow them altogether.
+This permission applies to tasks whose priority is set to interrupt
+level for any reason: via @Chg{Version=[3],New=[an aspect],Old=[a pragma]},
+via a call to Dynamic_Priorities.Set_Priority,
+or via priority inheritance.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00321-01]}
address@hidden was moved up from the previous section.}
address@hidden,address@hidden optimization purposes,]
+an implementation may alter the points at which task dispatching occurs, in an
+implementation-defined manner. However, a @nt{delay_statement} always
+corresponds to at least one task dispatching point.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,New=[Clause],Old=[Section]} @RefSecNum{Tasks and Synchronization}
+specifies under which circumstances a task becomes ready.
+The ready state is affected by the rules for
+task activation and termination, delay statements, and entry calls.
address@hidden
+When a task is not ready, it is said to be blocked.
+
+An example of a possible implementation-defined execution
+resource is a page of physical memory, which needs to be loaded
+with a particular page of virtual memory before a task can
+continue execution.
+
+The ready queues are purely conceptual; there is no requirement that such
+lists physically exist in an implementation.
+
+While a task is running, it is not on any ready queue. Any time
+the task that is running on a processor is added to a ready queue,
+a new running task is selected for that processor.
+
+In a multiprocessor system, a task can be on the ready queues of more than
+one processor. At the extreme, if several processors share the same set of
+ready tasks, the contents of their ready queues is identical, and so
+they can be viewed as sharing one ready queue, and can be implemented that
+way.
address@hidden, the dispatching model covers
+multiprocessors where dispatching is implemented using a single
+ready queue, as well as those with separate dispatching domains.]
+
+The priority of a task is determined by rules specified in this subclause, and
+under @RefSec{Task Priorities}, @RefSec{Priority Ceiling Locking}, and
address@hidden Priorities}.
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00321-01]}
address@hidden note is moved up from the next subclause.}
address@hidden,Text=[The setting of a task's base priority as a result
+of a call to Set_Priority does not always take effect immediately when
+Set_Priority is called. The effect of setting the task's base priority is
+deferred while the affected task performs a protected action.]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00321-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[This description is simplified to describe only
+  the parts of the dispatching model common to all policies. In particular,
+  rules about preemption are moved elsewhere. This makes
+  it easier to add other policies (which 
@Chg{Version=[3],New=[might],Old=[may]}
+  not involve preemption).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0166-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  Procedure Yield is added to Dispatching.
+  If Dispatching is referenced in a @nt{use_clause}, and an
+  entity @i<E> with a @nt{defining_identifier} of Yield is
+  defined in a package that is also referenced in a @nt{use_clause}, the entity
+  @i<E> may no longer be use-visible, resulting in errors. This should be rare
+  and is easily fixed if it does occur.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0166-1],ARef=[AI12-0005-1]}
+  @ChgAdded{Version=[4],Text=[Package Dispatching was a Pure package, but
+  now is Preelaborated with the addition of Yield. This is incompatible as
+  Dispatching can no longer be depended upon from a Pure package. This
+  should happen rarely in practice as the only contents was the exception
+  Dispatching_Policy_Error and none of the child packages that could raise
+  that exception are pure.]}
address@hidden
+
+
address@hidden,
+New=[Task Dispatching Pragmas],
+Old=[The Standard Task Dispatching Policy]}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]}
+allows a single task
+dispatching policy to be defined for all priorities, or the range of priorities
+to be split into subranges that are assigned individual dispatching
+policies.]]}
address@hidden
+
address@hidden
address@hidden
address@hidden@Keepnext@;The form of a @nt{pragma} Task_Dispatching_Policy is 
as follows:
address@hidden
+
address@hidden@key{pragma} @prag(Task_Dispatching_Policy)(@address@hidden);'
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The form of a
address@hidden Priority_Specific_Dispatching is as follows:]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden<Version=[2],@ChgAdded{Version=[2],address@hidden 
@prag<Priority_Specific_Dispatching> (@*
+@ @ @ @ @ @address@hidden, @address@hidden, @address@hidden);'}>
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,Text=[The expected type for @address@hidden
+and @address@hidden is Integer.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00321-01],ARef=[AI95-00355-01]}
+The @address@hidden @Chg{Version=[2],New=[used in a @nt{pragma}
+Task_Dispatching_Policy shall be the name of a task dispatching policy],
+Old=[shall either be FIFO_Within_Priorities or
+an implementation-defined @Syn2{identifier}]}.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Implementation-defined @address@hidden allowed
+in a @nt{pragma} Task_Dispatching_Policy.]}]}
+
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,Text=[The @address@hidden
+used in a @nt{pragma}
+Priority_Specific_Dispatching shall be the name of a task dispatching policy.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,Text=[Both @address@hidden@nt{expression} and
address@hidden@address@hidden shall be static expressions in the range
+of System.Any_Priority; @address@hidden@nt{expression} shall have a
+value greater than or equal to @address@hidden@nt{expression}.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,address@hidden Task_Dispatching_Policy specifies the
+single task dispatching policy.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,address@hidden Priority_Specific_Dispatching specifies
+the task dispatching policy for the specified range of priorities. Tasks with
+base priorities within the range of priorities specified in a
+Priority_Specific_Dispatching pragma have their active priorities determined
+according to the specified dispatching policy. Tasks with active priorities
+within the range of priorities specified in a Priority_Specific_Dispatching
+pragma are dispatched according to the specified dispatching policy.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00355-01]}
+  @ChgAdded{Version=[2],Text=[Each ready queue is managed by exactly one
+  policy. Anything else would be chaos. The ready queue is determined by
+  the active priority. However, how the active priority is calculated is
+  determined by the policy; in order to break out of this circle, we have
+  to say that the active priority is calculated by the method determined
+  by the policy of the base priority.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0262-1]}
address@hidden,Text=[If a partition contains one or more
+Priority_Specific_Dispatching address@hidden,New=[,],Old=[]}
+the dispatching policy for priorities not
+covered by any Priority_Specific_Dispatching pragmas is
+FIFO_Within_Priorities.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00355-01]}
address@hidden pragma], Sec=(Task_Dispatching_Policy)}
address@hidden, configuration], Sec=(Task_Dispatching_Policy)}
+A Task_Dispatching_Policy pragma is a configuration address@hidden,
+New=[ A Priority_Specific_Dispatching pragma is a configuration pragma.
address@hidden pragma], Sec=(Priority_Specific_Dispatching)}
address@hidden, configuration], Sec=(Priority_Specific_Dispatching)}],Old=[]}
+
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,Text=[The priority ranges specified in more than one
+Priority_Specific_Dispatching pragma within the same partition shall not be
+overlapping.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,Text=[If a partition contains one or more
+Priority_Specific_Dispatching pragmas it shall not contain a
+Task_Dispatching_Policy pragma.]}
+
address@hidden,Kind=[Deleted],ARef=[AI95-00333-01]}
address@hidden,Text=[If the FIFO_Within_Priorities policy is specified
+for a partition, then the Ceiling_Locking policy
+(see @RefSecNum{Priority Ceiling Locking}) shall also be specified for
+the partition.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00355-01]}
address@hidden dispatching policy}
address@hidden @i{task dispatching policy} specifies the details of task
+dispatching that are not covered by the basic task dispatching model.
+These rules govern when tasks are inserted into and
+deleted from the ready address@hidden,New=[],Old=[,
+and whether a task is inserted at the head or the tail of the
+queue for its active priority]}.]
address@hidden,New=[A single],Old=[The]} task dispatching policy is
+specified by a Task_Dispatching_Policy 
@Chg{Version=[2],New=[],Old=[configuration ]}pragma.
address@hidden,New=[Pragma Priority_Specific_Dispatching assigns distinct
+dispatching policies to subranges of System.Any_Priority.],
address@hidden no such pragma appears in any of the program
+units comprising a partition, the task dispatching policy for
+that partition is unspecified.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,address@hidden neither @nt{pragma} applies
+to any of the program units comprising a partition, the task dispatching policy
+for that partition is unspecified.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0262-1]}
address@hidden,Text=[If a partition contains one or more
+Priority_Specific_Dispatching address@hidden,New=[,],Old=[]}
+a task dispatching point occurs for the
+currently running task of a processor whenever there is a nonempty ready queue
+for that processor with a higher priority than the priority of the running
+task.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[If we have priority specific dispatching then we
+  want preemption across the entire range of priorities. That prevents higher
+  priority tasks from being blocked by lower priority tasks that have a
+  different policy. On the other hand, if we have a single policy for the
+  entire partition, we want the characteristics of that policy to apply for
+  preemption; specifically, we @Chg{Version=[3],New=[might],Old=[may]}
+  not require any preemption. Note that policy
+  Non_Preemptive_FIFO_Within_Priorities is not allowed in a priority specific
+  dispatching pragma.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00355-01]}
address@hidden,Text=[A task that has its base priority changed may move
+from one dispatching policy to another. It is immediately subject
+to the new dispatching policy.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Once subject to the new dispatching policy, it
+  may be immediately preempted or dispatched, according the rules of the new
+  policy.]}
address@hidden
+
address@hidden following stuff is moved to the next subclause}
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 7
+through 13 were moved to D.2.3.>address@hidden message should be deleted if the
+paragraphs are ever renumbered.}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00321-01]}
address@hidden,Type=[Leading],Text=[The language defines only one task
+dispatching policy, FIFO_Within_Priorities; when this policy is in effect,
+modifications to the ready queues occur only as follows:]}
+
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00321-01]}
address@hidden,Text=[When a blocked task becomes ready,
+it is added at the tail of the ready queue for its active priority.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00321-01]}
address@hidden,Text=[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.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00321-01]}
address@hidden,Text=[When the setting of the base priority of a
+running task takes effect, the task is added to the tail of the ready queue for
+its active priority.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00321-01]}
address@hidden,Text=[When a task executes a @nt{delay_statement} that
+does not result in blocking, it is added to the tail of the ready queue for its
+active priority.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[If the delay does result in blocking,
+  the task moves to the @lquotes@;delay address@hidden@;,
+  not to the ready queue.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00321-01]}
address@hidden,address@hidden dispatching point}
address@hidden point}
+Each of the events specified above is a task dispatching point
+(see @RefSecNum{The Task Dispatching Model}).]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00321-01]}
address@hidden,Text=[In addition, when a task is preempted, it is
+added at the head of the ready queue for its active priority.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00333-01],ARef=[AI95-00355-01]}
address@hidden,Text=[An implementation shall allow, for a single
+partition, both the locking policy (see @RefSecNum{Priority Ceiling Locking})
+to be specified as Ceiling_Locking
+and also one or more Priority_Specific_Dispatching pragmas to be given.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 14
+through 16 were moved to D.2.3.>address@hidden message should be deleted if the
+paragraphs are ever renumbered.}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00321-01]}
address@hidden,Type=[Leading],address@hidden inversion}
address@hidden inversion} is the duration for which a task remains at the
+head of the highest priority ready queue while the processor executes
+a lower priority task. The implementation shall document:]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00321-01]}
address@hidden,Text=[The maximum priority inversion a user task can experience 
due to activity
+of the implementation (on behalf of lower priority tasks), and]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00321-01]}
address@hidden,Text=[whether execution of a task can be preempted by
+the implementation processing of delay
+expirations for lower priority tasks, and if so, for how long.]}
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Implementation-defined aspects of priority inversion.]}]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00256-01]}
+Implementations are allowed to define other task dispatching policies, but
+need not support more than one @Chg{Version=[2],New=[task dispatching],
+Old=[such]} policy per partition.
+
address@hidden,Kind=[Revised],ARef=[AI95-00355-01]}
address@hidden,New=[An implementation need not support @nt{pragma}
+Priority_Specific_Dispatching if it is infeasible to support it in the
+target environment.],
address@hidden optimization purposes,]
+an implementation may alter the points at which task dispatching occurs,
+in an implementation defined manner.
+However, a @nt{delay_statement} always corresponds to at least one task
+dispatching point.]}
+
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[Implementation defined task
address@hidden,New=[ policies],Old=[]}.]}
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 19
+through 21 were deleted.>address@hidden message should be deleted if the
+paragraphs are ever renumbered.}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00321-01]}
address@hidden,Text=[If the active priority of a running task is
+lowered due to loss of inherited priority (as it is on completion of a
+protected operation) and there is a ready task of the same active priority that
+is not running, the running task continues to run (provided that there is no
+higher priority task).]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00321-01]}
address@hidden,Text=[The setting of a task's base priority as a result
+of a call to Set_Priority does not always take effect immediately when
+Set_Priority is called. The effect of setting the task's base priority is
+deferred while the affected task performs a protected action.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00321-01]}
address@hidden,Text=[Setting the base priority of a ready task causes
+the task to move to the end of the queue for its active priority,
+regardless of whether the active priority of the task actually changes.]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00333-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @B[Amendment Correction:] It is no longer required to specify Ceiling_Locking
+  with the language-defined task dispatching policies; we only require that
+  implementations @i<allow> them to be used together.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00355-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],address@hidden Priority_Specific_Dispatching is
+  new; it allows @Chg{Version=[3],New=[the specification of],Old=[specifying]}
+  different policies for different priorities.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00256-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that an implementation need support
+  only one task dispatching policy (of any kind, language-defined or otherwise)
+  per partition.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00321-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],Text=[This description is simplified to describe only
+  the rules for the Task_Dispatching_Policy pragma that are common to
+  all policies. In particular, rules about preemption are moved elsewhere. This
+  makes it easier to add other policies (which
+  @Chg{Version=[3],New=[might],Old=[may]} not involve preemption).]}
address@hidden
+
+
address@hidden,Name=[Preemptive Dispatching]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00321-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]}
+defines a preemptive task dispatching policy.]]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Text=[The @address@hidden
+FIFO_Within_Priorities is a task dispatching
address@hidden,address@hidden dispatching policy],
+Sec=(FIFO_Within_Priorities)address@hidden task dispatching policy}],
+Old=[]}]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00321-01]}
address@hidden,Text=[When FIFO_Within_Priorities is in effect,
+modifications to the ready queues occur only as follows:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00321-01]}
address@hidden,Text=[When a blocked task becomes ready, it is added at
+the tail of the ready queue for its active priority.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[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.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[When the setting of the base priority of a running task 
takes effect, the
+task is added to the tail of the ready queue for its active priority.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[When a task executes a @nt{delay_statement} that
+does not result in blocking, it is added to the tail of the ready queue for
+its active priority.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If the delay does result in blocking,
+  the task moves to the @lquotes@;delay address@hidden@;,
+  not to the ready queue.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00321-01]}
address@hidden,address@hidden dispatching point}
address@hidden point}
+Each of the events specified above is a task dispatching point
+(see @RefSecNum{The Task Dispatching Model}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00321-01]}
address@hidden,Text=[A task dispatching point occurs for the currently
+running task of a processor whenever there is a nonempty ready queue for that
+processor with a higher priority than the priority of the running task. The
+currently running task is said to be @i<preempted> and it is added at the head
+of the ready queue for its active address@hidden,Sec=[a running task]}]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00333-01]}
address@hidden,Text=[An implementation shall allow, for a single
+partition, both the task dispatching policy to be specified as
+FIFO_Within_Priorities and also the locking policy (see
address@hidden Ceiling Locking}) to be specified as Ceiling_Locking.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is the preferred combination of the
+  FIFO_Within_Priorities policy with a locking policy, and we want that
+  combination to be portable.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00321-01]}
address@hidden,Type=[Leading],address@hidden inversion}
address@hidden inversion} is the duration for which a task remains at the
+head of the highest priority nonempty ready queue while the processor executes
+a lower priority task. The implementation shall document:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The maximum priority inversion a user task
+can experience due to activity
+of the implementation (on behalf of lower priority tasks), and]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The maximum priority inversion a user task can experience from
+the implementation.]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[whether execution of a task can be preempted
+by the implementation processing of delay
+expirations for lower priority tasks, and if so, for how long.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The amount of time that a task can be preempted for processing on
+behalf of lower-priority tasks.]}]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00321-01]}
address@hidden,Text=[If the active priority of a running task is
+lowered due to loss of
+inherited priority (as it is on completion of a protected
+operation) and there is a ready task of the same active priority
+that is not running,
+the running task continues to run (provided that there is no higher
+priority task).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00321-01]}
address@hidden,Text=[Setting the base priority of a ready task causes
+the task to move to the tail of the queue for its active priority,
+regardless of whether the active priority of the task actually changes.]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00321-01]}
+  @ChgAdded{Version=[2],Text=[This subclause is new; it mainly consists of
+  text that was found in @RefSecNum{The Task Dispatching Model} and
+  @RefSecNum{Task Dispatching Pragmas} in Ada 95. This was
+  separated out so the definition of additional policies was easier.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00333-01]}
+  @ChgAdded{Version=[2],Text=[We require that implementations allow
+  this policy and Ceiling_Locking together.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00355-01]}
+  @ChgAdded{Version=[2],Text=[We explicitly defined FIFO_Within_Priorities
+  to be a task dispatching policy.]}
address@hidden
+
+
address@hidden,Name=[Non-Preemptive Dispatching]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00298-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]}
+defines a non-preemptive task dispatching policy.]]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00298-01],ARef=[AI95-00355-01]}
address@hidden,Text=[The @address@hidden
+Non_Preemptive_FIFO_Within_Priorities is a task dispatching
address@hidden,address@hidden dispatching policy],
+Sec=(address@hidden@address@hidden)address@hidden@address@hidden task disp. 
policy}],
+Old=[]}]}
+
address@hidden,Kind=[Added],ARef=[AI05-0166-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The following
+language-defined library package exists:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden<package> Ada.Dispatching.Non_Preemptive 
@key<is>@ChildUnit{Parent=[Ada.Dispatching],Child=[Non_Preemptive]}
+  @key<pragma> Preelaborate(Non_Preemptive);
+  @key<procedure> @AdaSubDefn{Yield_To_Higher};
+  @key<procedure> @AdaSubDefn{Yield_To_Same_Or_Higher} @key<renames> Yield;
address@hidden<end> Ada.Dispatching.Non_Preemptive;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0166-1],ARef=[AI05-0264-1]}
address@hidden,Text=[A call of Yield_To_Higher is a task dispatching
+point for this policy. If the task at the head of the highest priority ready
+queue has a higher active priority than the calling task, then the calling task
+is preempted.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[For language-defined policies other than
+  Non_Preemptive_FIFO_Within_Priorities, a higher priority task should never be
+  on a ready queue while a lower priority task is executed. Thus, for such
+  policies, Yield_To_Higher does nothing.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[Yield_To_Higher is @i<not> a potentially blocking
+  operation; it can be used during a protected operation. That is allowed,
+  as under the predefined Ceiling_Locking policy any
+  task with a higher priority than the protected operation cannot call the
+  operation (that would violate the locking policy). An
+  implementation-defined locking policy may need to define the semantics of
+  Yield_To_Higher differently.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Text=[Non_Preemptive_FIFO_Within_Priorities shall not be
+specified as the @address@hidden of @nt{pragma}
+Priority_Specific_Dispatching (see
address@hidden Dispatching Pragmas}).]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The non-preemptive nature of this policy could
+cause the policies of higher priority tasks to malfunction, missing deadlines
+and having unlimited priority inversion. That would render the use of such
+policies impotent and misleading. As such, this policy only makes sense
+for a complete system.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00298-01]}
address@hidden,Text=[When Non_Preemptive_FIFO_Within_Priorities is in
+effect, modifications to the ready queues occur only as follows:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00298-01]}
address@hidden,Text=[When a blocked task becomes ready, it is added at
+the tail of the ready queue for its active priority.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[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.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[When the setting of the base priority of a running task 
takes effect, the
+task is added to the tail of the ready queue for its active priority.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[When a task executes a @nt{delay_statement} that
+does not result in blocking, it is added to the tail of the ready queue for
+its active priority.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[If the delay does result in blocking,
+  the task moves to the @lquotes@;delay address@hidden@;,
+  not to the ready queue.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0166-1]}
address@hidden,Text=[For this policy, @Chg{Version=[3],New=[blocking
+or termination of a task, ],address@hidden,New=[],Old=[ non-blocking]}
address@hidden@Chg{Version=[3],New=[, a call to Yield_To_Higher, and
+a call to Yield_To_Same_Or_Higher or Yield are],Old=[ is]}
+the address@hidden,New=[],Old=[ non-blocking event that is a]}
+task dispatching @Chg{Version=[3],New=[points],Old=[point]} (see
address@hidden Task Dispatching Model})address@hidden dispatching point}
address@hidden point}]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0166-1]}
+  @ChgAdded{Version=[3],Text=[A @nt{delay_statement} is always a task
+  dispatching point even if it is not blocking. Similarly, a call to
+  Yield_To_Higher is never blocking, but it is a task dispatching point
+  In each of these cases, they can cause the current task to stop running (it 
is
+  still ready). Otherwise, the running task continues to run until it is 
blocked.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00333-01]}
address@hidden,Text=[An implementation shall allow, for a single
+partition, both the task dispatching policy to be specified as
+Non_Preemptive_FIFO_Within_Priorities and also the locking policy (see
address@hidden Ceiling Locking}) to be specified as Ceiling_Locking.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is the preferred combination of the
+  Non_Preemptive_FIFO_Within_Priorities policy with a locking policy, and we
+  want that combination to be portable.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00298-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1],ARef=[AI05-0269-1]}
address@hidden,Text=[Since implementations are allowed to round all
+ceiling priorities in subrange System.Priority to System.Priority'Last (see
address@hidden Ceiling Locking}), an implementation may allow a
address@hidden,New=[ of a partition using the
+Non_Premptive_FIFO_Within_Priorities policy],Old=[]} to
+execute within a protected object without raising its active priority provided
+the associated protected unit does not contain @Chg{Version=[3],New=[any
+subprograms with aspects Interrupt_Handler or Attach_Handler specified, nor
+does the unit have aspect],Old=[pragma]} Interrupt_Priority
address@hidden,New=[ specified. When the locking policy
+(see @RefSecNum{Priority Ceiling Locking}) is
+Ceiling_Locking, an implementation taking advantage of this permission shall
+ensure that a call to Yield_to_Higher that occurs within a protected action 
uses
+the ceiling priority of the protected object (rather than the active priority 
of
+the task) when determining whether to preempt the task],Old=[,
+Interrupt_Handler, or Attach_Handler]}.]}
address@hidden
+  @ChgRef{Version=[3],Kind=[Added],ARef=[AI05-0269-1]}
+  @ChgAdded{Version=[3],Text=[We explicitly require that the ceiling priority 
be
+  used in calls to Yield_to_Higher in order to prevent a risk of priority
+  inversion and consequent loss of mutual exclusion when Yield_to_Higher is 
used
+  in a protected object. This requirement might lessen the value of the
+  permission (as the current Ceiling_Priority will have to be maintained in the
+  TCB), but loss of mutual exclusion cannot be tolerated. The primary benefit 
of
+  the permission (eliminating the need for preemption at the end of a protected
+  action) is still available. As noted above, an implementation-defined locking
+  policy will need to specify the semantics of Yield_to_Higher, including this
+  case.]}
address@hidden
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00298-01],ARef=[AI95-00355-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Policy Non_Preemptive_FIFO_Within_Priorities is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0166-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Package
+  Dispatching.Non_Preemptive is new.]}
address@hidden
+
+
address@hidden@Comment{For printed RM Ada 2012}
address@hidden,Name=[Round Robin Dispatching]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]}
+defines the task dispatching
+policy Round_Robin_Within_Priorities and the package Round_Robin.]]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Text=[The @address@hidden
+Round_Robin_Within_Priorities is a task dispatching
address@hidden,address@hidden dispatching policy],
+Sec=(Round_Robin_Within_Priorities)address@hidden task dispatching policy}],
+Old=[]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The following
+language-defined library package exists:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden System;
address@hidden Ada.Real_Time;
address@hidden Ada.Dispatching.Round_Robin @address@hidden,Child=[Round_Robin]}
+  @AdaObjDefn{Default_Quantum} : @key{constant} Ada.Real_Time.Time_Span :=
+             @RI[implementation-defined];
+  @key{procedure} @AdaSubDefn{Set_Quantum} (Pri     : @key{in} System.Priority;
+                         Quantum : @key{in} Ada.Real_Time.Time_Span);
+  @key{procedure} @AdaSubDefn{Set_Quantum} (Low, High : @key{in} 
System.Priority;
+                         Quantum   : @key{in} Ada.Real_Time.Time_Span);
+  @key{function} @AdaSubDefn{Actual_Quantum} (Pri : System.Priority)
+             @key{return} Ada.Real_Time.Time_Span;
+  @key{function} @AdaSubDefn{Is_Round_Robin} (Pri : System.Priority) 
@key{return} Boolean;
address@hidden Ada.Dispatching.Round_Robin;]}
address@hidden
address@hidden,Kind=[Added],address@hidden,
+Text=[The value of Default_Quantum in Dispatching.Round_Robin.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Text=[When task dispatching policy Round_Robin_Within_Priorities 
is the single
+policy in effect for a partition, each task with priority in the range of
+System.Interrupt_Priority is dispatched according to policy
+FIFO_Within_Priorities.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Text=[The procedures Set_Quantum set the required Quantum
+value for a single priority level Pri or a range of priority levels Low .. 
High.
+If no quantum is set for a Round Robin priority level, Default_Quantum is 
used.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Text=[The function Actual_Quantum returns the actual
+quantum used by the implementation for the priority level Pri.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The function Is_Round_Robin returns True if
+priority Pri is covered by task dispatching policy
+Round_Robin_Within_Priorities; address@hidden,New=[,],Old=[]}
+it returns False.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Text=[A call of Actual_Quantum or Set_Quantum raises
+exception Dispatching.Dispatching_Policy_Error if a predefined policy other
+than Round_Robin_Within_Priorities applies to the specified priority
+or any of the priorities in the specified range.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Type=[Leading],Text=[For Round_Robin_Within_Priorities,
+the dispatching rules for FIFO_Within_Priorities apply with the following
+additional rules:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[When a task is added or moved to the tail of the
+ready queue for its base priority, it has an execution time budget equal to the
+quantum for that priority level. This will also occur when a blocked task
+becomes executable again.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[When a task is preempted (by a higher priority
+task) and is added to the head of the ready queue for its priority level, it
+retains its remaining budget.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[While a task is executing, its budget is decreased
+by the amount of execution time it uses. The accuracy of this accounting is the
+same as that for execution time clocks (see @RefSecNum{Execution Time}).]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Note that this happens even when the task
+  is executing at a higher, inherited priority, and even if that higher
+  priority is dispatched by a different policy than round robin.]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[When a task has exhausted its budget and is without
+an inherited priority (and is not executing within a protected operation), it
+is moved to the tail of the ready queue for its priority level. This is a task
+dispatching point.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[In this case, it will be given
+  a budget as described in the first bullet.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The rules for FIFO_Within_Priority (to which
+  these bullets are added) say that a task that has its base priority set to a
+  Round Robin priority is moved to the tail of the ready queue for its new
+  priority level, and then will be given a budget as described in the first
+  bullet. That happens whether or not the task's original base priority was
+  a Round Robin priority.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00333-01],ARef=[AI95-00355-01]}
address@hidden,Text=[An implementation shall allow, for a single
+partition, both the task dispatching policy to be specified as
+Round_Robin_Within_Priorities and also the locking policy (see
address@hidden Ceiling Locking}) to be specified as Ceiling_Locking.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is the preferred combination of the
+  Round_Robin_Within_Priorities policy with a locking policy, and we
+  want that combination to be portable.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Text=[An implementation shall document the quantum values
+supported.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The quantum values supported for round robin dispatching.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Text=[An implementation shall document the accuracy with
+which it detects the exhaustion of the budget of a task.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The accuracy of the detection of the exhaustion of the budget of a task
+for round robin dispatching.]}]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Text=[Due to implementation constraints, the quantum
+value returned by Actual_Quantum might not be identical to that set with
+Set_Quantum.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00355-01]}
address@hidden,Text=[A task that executes continuously with an inherited
+priority will not be subject to round robin dispatching.]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00355-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Policy Round_Robin_Within_Priorities and package
+  Dispatching.Round_Robin are new.]}
address@hidden
+
+
address@hidden@Comment{For printed RM Ada 2005}
address@hidden,Name=[Earliest Deadline First Dispatching]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Text=[The deadline of a task is an indication of the
+urgency of the task; it represents a point on an ideal physical time line.
+The deadline might affect how resources are allocated to the task.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+defines a package for representing the
+deadline of a task and a dispatching policy that defines Earliest Deadline
+First (EDF) dispatching. @Chg{Version=[3],New=[An aspect],Old=[A pragma]}
+is defined to assign an initial deadline to a task.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[2],Text=[This @Chg{Version=[3],New=[aspect],Old=[pragma]}
+  is the only way of assigning an
+  initial deadline to a task so that its activation can be controlled by EDF
+  scheduling. This is similar to the way
+  @Chg{Version=[3],New=[aspect],Old=[pragma]} Priority is used to give an
+  initial priority to a task.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[To predict the behavior of a multi-tasking program
+it is necessary to control access to the processor which is preemptive, and
+shared objects which are usually non-preemptive and embodied in protected
+objects. Two common dispatching policies for the processor are fixed priority
+and EDF. The most effective control over shared objects is via preemption
+levels. With a pure priority scheme a single notion of priority is used for
+processor dispatching and preemption levels. With EDF and similar schemes
+priority is used for preemption levels (only), with another measure used for
+dispatching. T.P. Baker showed (@i<Real-Time Systems>, March 1991, vol. 3, num.
+1, @i<Stack-Based Scheduling of Realtime Processes>) that for EDF a newly
+released task should only preempt the currently running task if it has an
+earlier deadline and a higher preemption level than any currently
address@hidden@;address@hidden protected object. The rules of this
address@hidden,New=[subclause],Old=[clause]} implement
+this scheme including the case where the newly released task should execute
+before some existing tasks but not preempt the currently executing task.]}
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 3
+through 6 were moved to @RefSec{Obsolescent Features}.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Keepnext=[T],address@hidden,New=[The
+form of a @nt{pragma} Relative_Deadline is as follows:],Old=[]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden<Version=[3],InitialVersion=[2],@ChgDeleted{Version=[3],
address@hidden,address@hidden @prag<Relative_Deadline> 
(@address@hidden);],Old=[]}'}>
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[The expected type for
address@hidden@nt{expression} is Real_Time.Time_Span.],Old=[]}]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[A Relative_Deadline pragma
+is allowed only immediately within a @nt{task_definition} or
+the @nt{declarative_part} of a @nt{subprogram_body}. At most one such pragma
+shall appear within a given construct.],Old=[]}]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Text=[The @address@hidden
+EDF_Across_Priorities is a task dispatching
address@hidden,address@hidden dispatching policy],
+Sec=(EDF_Across_Priorities)address@hidden task dispatching policy}],
+Old=[]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The following
+language-defined library package exists:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Real_Time;
address@hidden Ada.Task_Identification;
address@hidden Ada.Dispatching.EDF @address@hidden,Child=[EDF]}
+  @key{subtype} @AdaSubtypeDefn{Name=[Deadline],Of=[Time]} @key{is} 
Ada.Real_Time.Time;
+  @AdaObjDefn{Default_Deadline} : @key{constant} Deadline :=
+              Ada.Real_Time.Time_Last;
+  @key{procedure} @AdaSubDefn{Set_Deadline} (D : @key{in} Deadline;
+              T : @key{in} Ada.Task_Identification.Task_Id :=
+              Ada.Task_Identification.Current_Task);
+  @key{procedure} @AdaSubDefn{Delay_Until_And_Set_Deadline} (
+              Delay_Until_Time : @key{in} Ada.Real_Time.Time;
+              Deadline_Offset : @key{in} Ada.Real_Time.Time_Span);
+  @key{function} @AdaSubDefn{Get_Deadline} (T : 
Ada.Task_Identification.Task_Id :=
+              Ada.Task_Identification.Current_Task) @key{return} Deadline;
address@hidden Ada.Dispatching.EDF;]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[For a task type (including the
+anonymous type of a @nt{single_task_declaration}) or subprogram, the following
+language-defined representation aspect may be specified:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden aspect
+Relative_Deadline is an @nt{expression}, which shall be of
+type address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Relative_Deadline],
+    address@hidden,Text=[Task parameter used in Earliest Deadline
+      First Dispatching.]}]}
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Text=[The Relative_Deadline aspect shall not be specified
+on a task interface type.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Text=[If the EDF_Across_Priorities policy is specified
+for a partition, then the Ceiling_Locking policy (see
address@hidden Ceiling Locking}) shall also be
+specified for the partition.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Text=[If the EDF_Across_Priorities policy appears in a
+Priority_Specific_Dispatching pragma
+(see @RefSecNum{Task Dispatching Pragmas})
+in a partition, then the
+Ceiling_Locking policy (see @RefSecNum{Priority Ceiling Locking}) shall also
+be specified for the partition.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Unlike the other language-defined dispatching
+  policies, the semantic description of EDF_Across_Priorities assumes
+  Ceiling_Locking (and a ceiling priority) in order to make the mapping between
+  deadlines and priorities work. Thus, we require both policies to be specified
+  if EDF is used in the partition.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,address@hidden,New=[The],Old=[A]}
+Relative_Deadline @Chg{Version=[3],New=[aspect],Old=[pragma]} has no effect
+if it @Chg{Version=[3],New=[is specified for],
+Old=[occurs in the @nt{declarative_part} of the @nt{subprogram_body} of]} a
+subprogram other than the main subprogram.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Text=[The initial absolute deadline of a task
address@hidden,New=[for which aspect],Old=[containing
+pragma]} address@hidden,New=[ is specified],Old=[]} is
+the value of Real_Time.Clock +
address@hidden,New=[the @nt{expression} that is the value of the
+aspect],address@hidden@nt{expression}]}, where
address@hidden,New=[this entire expression, including ],Old=[]}the
+call of address@hidden,New=[, is evaluated],Old=[ is made]}
+between task creation and the start of its activation. If
address@hidden,New=[the aspect],Old=[there is no]}
+Relative_Deadline @Chg{Version=[3],New=[is not specified,],Old=[pragma]}
+then the initial absolute deadline of a task is the
+value of Default_Deadline. The environment task is also given
+an initial deadline by this address@hidden,New=[, using the value of
+the Relative_Deadline aspect of the main subprogram (if any)],Old=[]}.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The environment task is a normal task by
+  @RefSecNum{Program Execution}, so of course this rule applies to it.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Text=[The procedure Set_Deadline changes the absolute
+deadline of the task to D. The function Get_Deadline returns the absolute
+deadline of the task.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Text=[The procedure Delay_Until_And_Set_Deadline delays
+the calling task until time Delay_Until_Time. When the task becomes runnable
+again it will have deadline Delay_Until_Time + Deadline_Offset.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Text=[On a system with a single processor, the setting of
+the deadline of a task to the new value occurs immediately at the first point
+that is outside the execution of a protected action. If the task is currently
+on a ready queue it is removed and re-entered on to the ready queue determined
+by the rules defined below.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Text=[When EDF_Across_Priorities is specified for
+priority range @i<Low>address@hidden<High> all ready queues in this range are 
ordered by
+deadline. The task at the head of a queue is the one with the earliest
+deadline.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Type=[Leading],Text=[A task dispatching point occurs
+for the currently running task @i<T> to
+which policy EDF_Across_Priorities applies:]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[when a change to the deadline of @i<T> occurs;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[there is a task on the ready queue for the
+active priority of @i<T> with a deadline earlier than the deadline of @i<T>; 
or]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[there is a nonempty ready queue for that processor
+with a higher priority than the active priority of the running task.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[In these cases, the currently running task is said
+to be preempted and is returned to
+the ready queue for its active priority.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Type=[Leading],Text=[For a task @i<T> to which policy
+EDF_Across_Priorities applies, the base priority is not a source of
+priority inheritance; the active priority when first activated or
+while it is blocked is defined as the maximum of the following:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[the lowest priority in the range specified as
+EDF_Across_Priorities that includes the base priority of @i<T>;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[the priorities, if any, currently inherited by
address@hidden<T>;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised], ARef=[AI05-0055-1]}
address@hidden,Text=[the highest priority @i<P>, if any, less than the
+base priority of @i<T> such that one or more tasks are executing within a
+protected object with ceiling priority @i<P> and task @i<T>
+has an earlier deadline than all such address@hidden,New=[;
+and furthermore @i<T> has an earlier deadline than all other tasks on
+ready queues with priorities in the given EDF_Across_Priorities range that
+are strictly less than @i<P>],Old=[]}.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The active priority of @i<T> might be lower than
+its base priority.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Text=[When a task @i<T> is first activated or becomes
+unblocked, it is added to the ready queue corresponding to this active
+priority. Until it becomes blocked again, the active priority of @i<T>
+remains no less than this value; it will exceed this value only while it is
+inheriting a higher priority.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[These rules ensure that a task executing in
+  a protected object is preempted only by a task with a shorter deadline and a
+  higher base priority. This matches the traditional preemption level
+  description without the need to define a new kind of protected object
+  locking.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Text=[When the setting of the base priority of a ready
+task takes effect and the new priority is in a range specified as
+EDF_Across_Priorities, the task is added to the ready queue
+corresponding to its new active priority, as determined above.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Text=[For all the operations defined in Dispatching.EDF,
+Tasking_Error is raised if the task identified by T has terminated.
+Program_Error is raised if the value of T is Null_Task_Id.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+If EDF_Across_Priorities is specified for priority range 
@i<Low>address@hidden<High>, it
+is a bounded error to declare a protected object with ceiling priority
address@hidden<Low> or to assign the value @i<Low> to attribute 'Priority. In 
either case
+either Program_Error is raised or the ceiling of the protected
+object is assigned the value @i<Low>+1.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,address@hidden(erroneous execution),Sec=(cause)}
+If a value of Task_Id is passed as a parameter to any of the subprograms
+of this package and the corresponding task object no longer exists,
+the execution of the program is erroneous.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Text=[On a multiprocessor, the implementation shall
+document any conditions that cause the completion of the setting of the 
deadline
+of a task to be delayed later than what is specified for a single processor.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Any conditions that cause the completion of the setting of the deadline
+of a task to be delayed for a multiprocessor.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[If two adjacent priority ranges, @i<A>address@hidden<B> and
address@hidden<B>address@hidden<C> are specified to have policy
address@hidden,New=[,],Old=[]} then
+this is not equivalent to this policy being
+specified for the single range, @i<A>address@hidden<C>.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00357-01]}
address@hidden,Text=[The above rules implement the preemption-level
+protocol (also called Stack Resource Policy protocol) for resource sharing
+under EDF dispatching. The preemption-level for a task is denoted by its base
+priority. The definition of a ceiling preemption-level for a protected object
+follows the existing rules for ceiling locking.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00357-01]}
+  @ChgAdded{Version=[2],Text=[An implementation may support additional
+  dispatching policies by replacing absolute deadline with an alternative
+  measure of urgency.]}
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00357-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Policy EDF_Across_Priorities and package Dispatching.EDF are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Aspect Relative_Deadline is new; @nt{pragma} Relative_Deadline
+  is now obsolescent.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0055-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Corrected definition
+  of active priority to avoid deadline inversion in an unusual case.]}
address@hidden
+
+
address@hidden Ceiling Locking}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} specifies
+the interactions between priority task
+scheduling and protected object ceilings. This interaction is based on
+the concept of the @i{ceiling priority} of a protected object.]
address@hidden
+
address@hidden
address@hidden
address@hidden@Keepnext@;The form of a @nt{pragma} Locking_Policy is as follows:
address@hidden
+
address@hidden@key{pragma} @prag(Locking_Policy)(@address@hidden);'
address@hidden
+
address@hidden
+
+The @address@hidden shall either be Ceiling_Locking
+or an implementation-defined @Syn2{identifier}.
address@hidden @address@hidden allowed
+in a @nt{pragma} Locking_Policy.}
+
address@hidden
+
address@hidden
+
address@hidden pragma], Sec=(Locking_Policy)}
address@hidden, configuration], Sec=(Locking_Policy)}
+A Locking_Policy pragma is a configuration pragma.
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0073],ARef=[AI95-00091-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00327-01]}
address@hidden policy}
address@hidden locking policy specifies the details of protected object
+locking. @Chg{Version=[2],New=[All protected objects have a priority.
+The locking policy specifies the meaning of
+the priority of a],Old=[These rules specify whether or not]} protected 
@Chg{Version=[2],
+New=[object],Old=[objects have
+priorities]}, and the relationships between these priorities and
+task priorities. In addition, the policy specifies the state of a task
+when it executes a protected action, and how its active priority is
+affected by the locking.]
+The @i{locking policy} is specified by a Locking_Policy pragma. For
+implementation-defined locking policies, the @Chg{Version=[2],New=[meaning of
+the priority of],Old=[effect of a Priority or
+Interrupt_Priority pragma on]} a protected object is
+implementation defined.
+If no Locking_Policy pragma @Chg{New=[applies to],Old=[appears in]} any
+of the program units comprising a partition, the locking policy for that
+partition, as well as the @Chg{Version=[2],New=[meaning of
+the priority of],Old=[effect of specifying either a Priority or
+Interrupt_Priority pragma for]} a protected object, are implementation defined.
address@hidden,address@hidden,Sec=[of a protected object]}],Old=[]}
+
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The locking policy if no Locking_Policy pragma applies to any unit of
+a partition.]}]}
+
address@hidden,Kind=[Added],ARef=[AI95-00327-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0229-1]}
address@hidden,Text=[The @nt{expression} @Chg{Version=[3],New=[specified
+for the],Old=[of a]} Priority or Interrupt_Priority
address@hidden,New=[aspect],Old=[pragma]}
+(see @RefSecNum{Task Priorities}) is evaluated as part of the creation
+of the corresponding
+protected object and converted to the subtype System.Any_Priority or
+System.Interrupt_Priority, respectively. The value of the expression is the
+initial priority of the corresponding protected object. If no Priority or
+Interrupt_Priority @Chg{Version=[3],New=[aspect is specified for],Old=[pragma
+applies to]} a protected object, the initial priority
+is specified by the locking policy.
address@hidden,address@hidden subtype conversion],Sec=(Priority aspect)}
address@hidden subtype conversion],Sec=(Interrupt_Priority aspect)}],
address@hidden subtype conversion],Sec=(pragma Priority)}
address@hidden subtype conversion],Sec=(pragma Interrupt_Priority)}]}]}
+
address@hidden@;There is one predefined locking policy, Ceiling_Locking; this 
policy is
+defined as follows:@Chg{Version=[3],address@hidden policy],
+Sec=(Ceiling_Locking)address@hidden locking policy}],
+Old=[]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00327-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden priority], Sec=(of a protected object)}
+Every protected object has a @i{ceiling priority}, which
+is determined by either a Priority or Interrupt_Priority
address@hidden,New=[aspect],Old=[pragma]} as
+defined in @RefSecNum{Task address@hidden,New=[, or by
+assignment to the Priority attribute as described
+in @RefSecNum{Dynamic Priorities for Protected Objects}],Old=[]}.
+The ceiling priority of a protected object (or ceiling, for short) is an
+upper bound on the active priority a task can have when
+it calls protected operations of that protected object.
+
address@hidden,Kind=[Revised],ARef=[AI95-00327-01]}
+The @Chg{Version=[2],New=[initial ceiling priority of a],address@hidden
+of a Priority or Interrupt_Priority pragma is evaluated as part of the 
creation of the corresponding]}
+protected object
address@hidden,New=[is
+equal to the initial priority for that object.],Old=[and converted
+to the subtype System.Any_Priority or System.Interrupt_Priority, respectively.
+The value of the @nt{expression} is the ceiling priority of
+the corresponding protected object.
address@hidden subtype conversion],Sec=(pragma Priority)}
address@hidden subtype conversion],Sec=(pragma Interrupt_Priority)}]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00327-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0051-1]}
+If an Interrupt_Handler or Attach_Handler @Chg{Version=[3],New=[aspect],
+Old=[pragma]} (see @RefSecNum{Protected Procedure Handlers})
address@hidden,New=[is specified for a protected subprogram of a
+protected type that does not have @Chg{Version=[4],New=[either ],Old=[]}the
+],Old=[appears in a @nt{protected_definition} without an]}
address@hidden,New=[Priority or ],Old=[]}Interrupt_Priority
address@hidden,New=[aspect specified],Old=[pragma]}, the
address@hidden,New=[initial],Old=[ceiling]} priority of protected objects
+of that type is implementation defined,
+but in the range of the subtype System.Interrupt_Priority.
address@hidden ceiling priorities.}
+
address@hidden,Kind=[Revised],ARef=[AI95-00327-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+If @Chg{Version=[3],New=[neither aspect],Old=[no @nt{pragma}]}
address@hidden,New=[ nor],Old=[,]}
address@hidden,New=[],Old=[, Interrupt_Handler,
+or Attach_Handler]} is specified
address@hidden,New=[for a protected type, and no protected subprogram
+of the type has aspect Interrupt_Handler or
+Attach_Handler specified],Old=[in the
address@hidden, then the
address@hidden,New=[initial],Old=[ceiling]} priority of the corresponding
+protected object is System.Priority'Last.
+
+While a task executes a protected action, it inherits the ceiling
+priority of the corresponding protected object.
+
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+When a task calls a protected operation, a check is made that its active
+priority is not higher than the ceiling of the corresponding protected object;
+Program_Error is raised if this check fails.
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00327-01]}
address@hidden,Type=[Leading],Text=[Following any change of priority,
+it is a bounded error for the active priority of any task with a call queued on
+an entry of a protected object to be higher than the ceiling priority of the
+protected object.
address@hidden(bounded error),Sec=(cause)}
+In this case one of the following applies:]}
+
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Text=[at any time prior to executing the entry body
+Program_Error is raised in the calling task;
address@hidden,Sec=(raised by failure of run-time check)}]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[when the entry is open the entry body is executed
+at the ceiling priority of the protected object;]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[when the entry is open the entry body is executed
+at the ceiling priority of the protected object and then Program_Error is
+raised in the calling task; or
address@hidden,Sec=(raised by failure of run-time check)}]}
+
address@hidden,Kind=[Added]}
address@hidden,Text=[when the entry is open the entry body
+is executed at the ceiling priority of the protected object that was in effect
+when the entry call was queued.]}
address@hidden
address@hidden
address@hidden,address@hidden note was moved along with the above rules}
address@hidden,Text=[Note that the error is @lquotes@;address@hidden@;
+on the task that did the entry call, not the task that changed the
+priority of the task or protected object.
+This seems to make sense for the case of changing the priority of a task
+blocked on a call, since if the Set_Priority had happened a
+little bit sooner, before the task queued a call,
+the entry-calling task would get the error.
+Similarly, there is no reason not to raise the priority of a
+task that is executing in an @nt{abortable_part}, so long as its
+priority is lowered before it gets to the end and needs to cancel the
+call.
+The priority might need to be lowered to allow it to remove the call
+from the entry queue,
+in order to avoid violating the ceiling.
+This seems relatively harmless, since there is an error,
+and the task is about to start raising an exception anyway.]}
address@hidden
address@hidden
+
address@hidden
+
+The implementation is allowed to round all ceilings in a certain
+subrange of System.Priority or System.Interrupt_Priority up to
+the top of that subrange, uniformly.
address@hidden
+For example, an implementation might use Priority'Last for all ceilings
+in Priority, and Interrupt_Priority'Last for all ceilings in
+Interrupt_Priority.
+This would be equivalent to having two ceiling priorities for protected 
objects,
address@hidden@;address@hidden@; and @lquotes@;address@hidden@;, and is an 
allowed behavior.
+
+Note that the implementation cannot choose a subrange that crosses the
+boundary between normal and interrupt priorities.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00256-01]}
+Implementations are allowed to define other locking policies,
+but need not support more than one @Chg{Version=[2],New=[locking],Old=[such]}
+policy per partition.
+
address@hidden implementations are allowed to place restrictions
+on code that runs at an interrupt-level active priority
+(see @RefSecNum{Protected Procedure Handlers}
+and @RefSecNum{The Task Dispatching Model}),
+the implementation may implement a language feature in terms
+of a protected object with an implementation-defined ceiling,
+but the ceiling shall be no less than Priority'Last.]
address@hidden ceiling of any protected object used internally by the
+implementation.}
address@hidden
+This permission follows from the fact that
+the implementation can place restrictions on interrupt
+handlers and on any other code that runs at an interrupt-level
+active priority.
+
+The implementation might protect a storage pool with a
+protected object whose ceiling is Priority'Last, which would cause
address@hidden to fail when evaluated at interrupt priority.
+Note that the ceiling of such an object has to be at least
+Priority'Last,
+since there is no permission for @nt{allocator}s to fail when evaluated at
+a noninterrupt priority.
address@hidden
+
address@hidden
+
address@hidden
+
+The implementation should use names that end with
address@hidden@;address@hidden@; for implementation-defined locking policies.
+
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Names that end with @lquotes@;address@hidden@; should be used for
+implementation-defined locking policies.]}]}
+
address@hidden
+
address@hidden
+
+While a task executes in a protected action, it can be preempted
+only by tasks whose active priorities are higher than the
+ceiling priority of the protected object.
+
+If a protected object has a ceiling priority in the range
+of Interrupt_Priority, certain interrupts are blocked while
+protected actions of that object execute. In the extreme, if
+the ceiling is Interrupt_Priority'Last, all blockable interrupts
+are blocked during that time.
+
+The ceiling priority of a protected object has to be in the
+Interrupt_Priority range if one of its procedures is to be used as
+an interrupt handler (see @RefSecNum{Interrupt Support}).
+
+When specifying the ceiling of a protected object, one should
+choose a value that is at least as high as the highest active priority
+at which tasks can be executing when they call
+protected operations of that object. In determining this
+value the following factors, which can affect active priority,
+should be considered: the effect of Set_Priority, nested
+protected operations, entry calls, task activation, and other
+implementation-defined factors.
+
+Attaching a protected procedure whose ceiling is below the
+interrupt hardware priority to an interrupt causes the execution of the
+program to be erroneous
+(see @RefSecNum{Protected Procedure Handlers}).
+
+On a single processor implementation, the ceiling priority
+rules guarantee that there is no possibility of deadlock involving
+only protected subprograms (excluding the case where a protected operation
+calls another protected operation on the same protected object).
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00327-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  All protected objects now have a priority, which
+  is the value of the Priority attribute of
+  @RefSecNum{Dynamic Priorities for Protected Objects}. How this value
+  is interpreted depends on the locking policy; for instance, the ceiling
+  priority is derived from this value when the locking policy is
+  Ceiling_Locking.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0073],ARef=[AI95-00091-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the wording to
+  reflect that pragma Locking_Policy cannot be inside of a program unit.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00256-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that an implementation need support
+  only one locking policy (of any kind, language-defined or otherwise)
+  per partition.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00327-01]}
+  @ChgAdded{Version=[2],Text=[The bounded error for the priority of a task
+  being higher than the ceiling of an object it is currently in was moved here
+  from @RefSecNum{Dynamic Priorities}, so that it applies no matter how the
+  situation arises.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[Revised to use aspects Priority and
+  Interrupt_Priority as @nt{pragma}s
+  Priority and Interrupt_Priority are now obsolescent.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0051-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that the 
Priority
+  aspect can be used to set the initial ceiling priority of a protected object
+  that contains an interrupt handler.]}
address@hidden
+
+
address@hidden@Comment{For printed RM Ada 2005}
address@hidden Queuing Policies}
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0074],ARef=[AI95-00068-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden@Defn{queuing policy}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} specifies
+a mechanism for a user to choose an entry
address@hidden policy}. It also defines @Chg{New=[two],Old=[one]}
+such address@hidden,Old=[y]}. Other policies are implementation defined.]
address@hidden queuing policies.}
address@hidden
+
address@hidden
address@hidden
address@hidden@Keepnext@;The form of a @nt{pragma} Queuing_Policy is as follows:
address@hidden
+
address@hidden@key{pragma} @prag(Queuing_Policy)(@address@hidden);'
address@hidden
+
address@hidden
+
+The @address@hidden shall be either FIFO_Queuing,
+Priority_Queuing or an implementation-defined @Syn2{identifier}.
+
address@hidden
+
address@hidden
+
address@hidden pragma], Sec=(Queuing_Policy)}
address@hidden, configuration], Sec=(Queuing_Policy)}
+A Queuing_Policy pragma is a configuration pragma.
+
address@hidden
+
address@hidden
+
address@hidden policy}
address@hidden @i{queuing policy} governs the order in which tasks are queued
+for entry service, and the order in which different entry queues are
+considered for service.]
+The queuing policy is specified by a Queuing_Policy pragma.
address@hidden
+The queuing policy includes entry queuing order,
+the choice among open alternatives of a @nt{selective_accept},
+and the choice among queued entry calls of
+a protected object when more than one @nt{entry_barrier} @nt{condition} is 
True.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00355-01]}
+Two queuing policies, FIFO_Queuing and Priority_Queuing,
+are language defined. If no Queuing_Policy pragma
address@hidden,New=[applies to],Old=[appears in]} any of the program units
+comprising the partition, the queuing policy for that partition
+is address@hidden,address@hidden policy],
+Sec=(FIFO_Queuing)address@hidden queuing policy}],
+Old=[]} The rules for this policy are specified in
address@hidden Calls} and @RefSecNum{Selective Accept}.
+
address@hidden@Keepnext@;The Priority_Queuing policy is defined as
+follows:@Chg{Version=[3],address@hidden policy],
+Sec=(Priority_Queuing)address@hidden queuing policy}],
address@hidden
+
address@hidden of an entry call}
+The calls to an entry @Redundant[(including a member of an entry family)]
+are queued in an order consistent with the priorities of the calls. The
address@hidden of an entry call} is initialized from the active
+priority of the calling task at the time
+the call is made, but can change later. Within the same priority,
+the order is consistent with the calling (or requeuing,
+or priority setting) time (that is, a FIFO order).
+
address@hidden,Kind=[Revised],Ref=[8652/0075],ARef=[AI95-00205-01]}
+After a call is first queued, changes to the active priority of a task do
+not affect the priority of the call, unless the base priority of the task is
address@hidden while the task is blocked on an entry call],Old=[]}.
+
+When the base priority of a task is set (see @RefSecNum{Dynamic Priorities}),
+if the task is blocked on an entry call, and the call is queued,
+the priority of the call is updated to the new active priority of the
+calling task. This causes the call to be removed from and then reinserted in
+the queue at the new active priority.
address@hidden
+A task is blocked on an entry call if the entry call is simple,
+conditional, or timed.
+If the call came from the @nt{triggering_statement} of an
address@hidden, or a requeue thereof,
+then the task is not blocked on that call;
+such calls do not have their priority updated.
+Thus, there can exist many queued calls from a given task
+(caused by many nested ATC's),
+but a task can be blocked on only one call at a time.
+
+A previous version of Ada 9X required queue reordering in the
address@hidden case as well.
+If the call corresponds to a @lquotes@;address@hidden@; entry call, then the 
task
+is blocked while queued, and it makes good sense to move it up in the
+queue if its priority is raised.
+
+However, if the entry call is @lquotes@;asynchronous,@rquotes@; that is, it is
+due to an @nt{asynchronous_select} whose @nt{triggering_statement}
+is an entry call, then the task is not waiting for this
+entry call, so the placement of the entry call on the
+queue is irrelevant to the rate at which the task proceeds.
+
+Furthermore, when an entry is used for @nt{asynchronous_select}s,
+it is almost certain to be a @lquotes@;address@hidden@; entry or have
+only one caller at a time. For example, if the entry is
+used to notify tasks of a mode switch, then all tasks on the
+entry queue would be signaled when the mode changes. Similarly,
+if it is indicating some interrupting event such as a control-C,
+all tasks sensitive to the interrupt will want to be informed
+that the event occurred. Hence, the order on such a queue is
+essentially irrelevant.
+
+Given the above, it seems an unnecessary semantic and implementation
+complexity to specify that asynchronous queued calls are moved in
+response to dynamic priority changes. Furthermore, it is somewhat
+inconsistent, since the call was originally queued based on the active
+priority of the task, but dynamic priority changes are changing the base
+priority of the task, and only indirectly the active priority. We say
+explicitly that asynchronous queued calls are not affected by normal
+changes in active priority during the execution of an
address@hidden Saying that, if a change in the base priority
+affects the active priority, then we do want the calls reordered, would
+be inconsistent.
+It would also require the implementation to maintain a readily
+accessible list of all queued calls which would not otherwise be
+necessary.
+
+Several rules were removed or simplified when we changed the rules so
+that calls due to @nt{asynchronous_select}s are never moved due to
+intervening changes in active priority, be they due to protected
+actions, some other priority inheritance, or changes in the base
+priority.
address@hidden
+
+When more than one @nt{condition} of an @nt{entry_barrier} of a protected
+object becomes True, and more than one of the respective queues is nonempty,
+the call with the highest priority is selected. If more than one such
+call has the same priority, the call that is queued on the entry whose
+declaration is first in textual order in the @nt{protected_definition} is
+selected. For members of the same entry family,
+the one with the lower family index is selected.
+
+If the expiration time of two or more open
address@hidden is the same and no other
address@hidden are open, the
address@hidden of the @nt{delay_alternative} that is
+first in textual order in the @nt{selective_accept} is executed.
+
+When more than one alternative of a @nt{selective_accept} is
+open and has queued calls, an alternative whose queue has the highest-priority
+call at its head is selected.
+If two or more open alternatives have equal-priority queued calls,
+then a call on the entry in the @nt{accept_alternative} that is
+first in textual order in the @nt{selective_accept}
+is selected.
+
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00256-01]}
+Implementations are allowed to define other queuing policies, but
+need not support more than one @Chg{Version=[2],New=[queuing],Old=[such]}
+policy per partition.
address@hidden
+  @ChgRef{Version=[1],Kind=[Added],Ref=[8652/0116],ARef=[AI95-00069-01]}
+  @ChgRef{Version=[2],Kind=[RevisedAdded],ARef=[AI95-00256-01]}
+  @ChgAdded{Version=[1],Text=[This rule is really redundant, as
+  @RefSecNum(Pragmas and Program Units) allows an implementation to limit the
+  use of configuration pragmas to an empty environment. In that case, there
+  would be no way to have multiple policies in a address@hidden,New=[],
+  Old=[ In any case, the
+  wording here really ought to be "...more than one queuing policy per
+  partition.", since this part of the rule applies to all queuing policies, not
+  just implementation-defined ones.]}]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00188-02]}
address@hidden,Text=[Implementations are allowed to defer the reordering
+of entry queues following a change of base priority of a task blocked on the
+entry call if it is not practical to reorder the queue immediately.]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[Priority change is immediate, but the effect of the
+change on entry queues can be deferred. That is necessary in order to implement
+priority changes on top of a non-Ada kernel.]}
address@hidden
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[The reordering should occur as soon as the blocked
+task can itself perform the reinsertion into the entry queue.]}
address@hidden
address@hidden
+
address@hidden
+
+The implementation should use names that end with
address@hidden@;address@hidden@; for implementation-defined queuing policies.
+
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Names that end with @lquotes@;address@hidden@; should be used for
+implementation-defined queuing policies.]}]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0074],ARef=[AI95-00068-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the number of
+  queuing policies defined.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0075],ARef=[AI95-00205-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected so that a call 
of
+  Set_Priority in an abortable part does not change the priority of the
+  triggering entry call.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00188-02]}
+  @ChgAdded{Version=[2],Text=[Added a permission to defer queue reordering
+  when the base priority of a task is changed. This is a counterpart to
+  stronger requirements on the implementation of priority change.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00256-01]}
+  @ChgAdded{Version=[2],Text=[Clarified that an implementation need support
+  only one queuing policy (of any kind, language-defined or otherwise)
+  per partition.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00355-01]}
+  @ChgAdded{Version=[2],Text=[Fixed wording to make clear that @nt{pragma}
+  never appears inside of a unit; rather it @lquotes@;applies address@hidden 
the
+  unit.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Priorities}
+
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00327-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],address@hidden 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+  describes how the
+  priority of an entity can be modified or queried at run time.]]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00327-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[This 
@Chg{Version=[3],New=[subclause],Old=[clause]}
+  is turned into two subclauses. This 
@Chg{Version=[3],New=[subclause],Old=[clause]} introduction is new.]}
address@hidden
+
+
address@hidden,Name=[Dynamic Priorities for Tasks]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} describes
+how the base priority of a task can be modified or queried at run time.]
address@hidden
+
address@hidden
address@hidden@Keepnext@;The following language-defined library package exists:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00362-01]}
address@hidden System;
address@hidden Ada.Task_Identification; @RI{-- See @RefSecNum[The Package 
Task_Identification]}
address@hidden Ada.Dynamic_Priorities @address@hidden,address@hidden,New=[
+    @key[pragma] Preelaborate(Dynamic_Priorities);],Old=[]}
+
+    @key[procedure] @AdaSubDefn{Set_Priority}(Priority : @key[in] 
System.Any_Priority;
+                           T : @key[in] Ada.Task_Identification.Task_Id :=
+                           Ada.Task_Identification.Current_Task);
+
+    @key[function] @AdaSubDefn{Get_Priority} (T : 
Ada.Task_Identification.Task_Id :=
+                           Ada.Task_Identification.Current_Task)
+                           @key[return] System.Any_Priority;
+
address@hidden Ada.Dynamic_Priorities;
address@hidden
address@hidden
+
address@hidden
+The procedure Set_Priority sets the base priority of the specified task
+to the specified Priority value.
+Set_Priority has no effect if the task is terminated.
+
+The function Get_Priority returns T's current base priority.
address@hidden,Sec=(raised by failure of run-time check)}
+Tasking_Error is raised if the task is terminated.
address@hidden
+There is no harm in setting the priority of a terminated task.
+A previous version of Ada 9X made this a run-time error.
+However, there is little difference between setting the priority of a
+terminated task, and setting the priority of a task that is about to
+terminate very soon;
+neither case should be an error.
+Furthermore, the run-time check is not necessarily feasible to implement
+on all systems, since priority changes might be deferred due to
+inter-processor communication overhead,
+so the error might not be detected until after Set_Priority has
+returned.
+
+However, we wish to allow implementations to avoid storing 
@lquotes@;address@hidden@;
+information about terminated tasks.
+Therefore, we make Get_Priority of a terminated task raise an exception;
+the implementation need not continue to store the priority of a task
+that has terminated.
address@hidden
+
address@hidden,Sec=(raised by failure of run-time check)}
+Program_Error is raised by Set_Priority and Get_Priority if T is equal
+to Null_Task_Id.
+
address@hidden,Kind=[Revised],ARef=[AI95-00188-02]}
address@hidden,New=[On a system with a single processor, the setting of],
+Old=[Setting]} the @Chg{Version=[2],New=[],Old=[task's ]}base
address@hidden,New=[ of a task @i{T}],Old=[]}
+to the new value @Chg{Version=[2],
+New=[occurs immediately at the first point when @i{T} is
+outside the execution of],Old=[takes place as soon
+as is practical but not while the task is performing]} a
+protected address@hidden,New=[],Old=[.
+This setting occurs no later then the next abort completion point of
+the task T
+(see @RefSecNum{Abort of a Task - Abort of a Sequence of Statements})]}.
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00188-02]}
address@hidden,New=[The priority change is immediate if the target task
+is on a delay queue or a ready queue outside of a protected action.
+However, consider when],Old=[When]}
+Set_Priority is called by a task T1 to set the priority of T2,
+if T2 is blocked, waiting on an entry call queued on a protected object,
+the entry queue needs to be reordered.
+Since T1 might have a priority that is higher than the ceiling of the
+protected object, T1 cannot, in general, do the reordering.
+One way to implement this is to wake T2 up and have T2 do the work.
+This is similar to the disentangling of queues that needs to happen when
+a high-priority task aborts a lower-priority task,
+which might have a call queued on a protected object with a low
address@hidden,New=[ We have an @ImplPermName in
address@hidden Queuing Policies} to allow this implementation. We could
+have required an immediate priority change if on a ready queue during a
+protected action, but that would have required extra checks for ceiling
+violations to meet @BoundedName requirements of
address@hidden Ceiling Locking} and potentially could cause a protected
+action to be abandoned in the middle (by raising Program_Error). That seems
+bad.],Old=[]}
address@hidden
address@hidden
address@hidden@;A previous version of Ada 9X made it a run-time error
+for a high-priority task to set the priority of a lower-priority
+task that has a queued call on a protected object with a low ceiling.
+This was changed because:
address@hidden
+The check was not feasible to implement on all systems,
+since priority changes might be deferred due to
+inter-processor communication overhead.
+The calling task would continue to execute without finding out whether
+the operation succeeded or not.
+
+The run-time check would tend to cause intermittent system failures @em
+how is the caller supposed to know whether the other task happens to
+have a queued call at any given time? Consider for example an
+interrupt that needs to trigger a priority change in some task.
+The interrupt handler could not safely call Set_Priority without knowing
+exactly what the other task is doing,
+or without severely restricting the ceilings used in the system.
+If the interrupt handler wants to hand the job off to a third task whose
+job is to call Set_Priority, this won't help, because one would normally
+want the third task to have high priority.
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00327-01]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+If a task is blocked on a protected entry call, and the call is queued,
+it is a bounded error to raise its base priority
+above the ceiling priority of the corresponding
+protected object.
+When an entry call is cancelled, it is a bounded error
+if the priority of the calling task is higher than
+the ceiling priority of the corresponding
+protected object.
address@hidden,Sec=(raised by failure of run-time check)}
+In either of these cases,
+either Program_Error is raised in the task that called the entry,
+or its priority is temporarily lowered,
+or both, or neither.]}
address@hidden
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden,Text=[Note that the error is @lquotes@;address@hidden@; on the 
task that did the entry call,
+not the task that called Set_Priority.
+This seems to make sense for the case of a task blocked on a call,
+since if the Set_Priority had happened a
+little bit sooner, before the task queued a call,
+the entry-calling task would get the error.
+In the other case, there is no reason not to raise the priority of a
+task that is executing in an @nt{abortable_part}, so long as its
+priority is lowered before it gets to the end and needs to cancel the
+call.
+The priority might need to be lowered to allow it to remove the call
+from the entry queue,
+in order to avoid violating the ceiling.
+This seems relatively harmless, since there is an error,
+and the task is about to start raising an exception anyway.]}
address@hidden
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraph 11 was
+deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered.}
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)}
+If any subprogram in this package is called with a parameter T that
+specifies a task object that no longer exists, the execution of the
+program is erroneous.
address@hidden
+Note that this rule overrides the above rule saying that
+Program_Error is raised on Get_Priority of a terminated task.
+If the task object still exists, and the task is terminated,
+Get_Priority raises Program_Error.
+However, if the task object no longer exists,
+calling Get_Priority causes erroneous execution.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00188-02]}
address@hidden,Text=[On a multiprocessor, the implementation shall
+document any conditions that cause the completion of the setting of the
+priority of a task to be delayed later than what is specified for a
+single processor.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[Any conditions that cause the completion of the setting of the priority
+of a task to be delayed for a multiprocessor.]}]}
address@hidden
+
address@hidden
address@hidden@;The implementation shall document the following metric:
address@hidden
+The execution time of a call to Set_Priority, for the nonpreempting case,
+in processor clock cycles. This is measured for a call that modifies the
+priority of a ready task that is not running (which
+cannot be the calling one), where the new
+base priority of the affected task is lower than the active priority of the
+calling task, and the affected task is not on any entry queue and is not
+executing a protected operation.
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The metrics for Set_Priority.]}]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00321-01]}
+Setting a task's base priority affects task dispatching. First, it can
+change the task's active priority. Second, under the @Chg{Version=[2],
+New=[FIFO_Within_Priorities],Old=[standard
+task dispatching]} policy it always causes the task to move to
+the tail of the ready queue corresponding to its active priority,
+even if the new base priority is unchanged.
+
+Under the priority queuing policy, setting a task's base
+priority has an effect on a queued entry call
+if the task is blocked waiting for the call. That is, setting the
+base priority of a task causes the priority of a queued entry
+call from that task to be updated and the call to be removed and
+then reinserted in the entry queue at the new priority
+(see @RefSecNum{Entry Queuing Policies}),
+unless the call originated from the @nt{triggering_statement} of an
address@hidden
+
+The effect of two or more Set_Priority calls executed in parallel on
+the same task is defined as executing these calls in some serial order.
+
address@hidden
+This follows from the general reentrancy requirements stated near the
+beginning of @RefSec{Predefined Language Environment}.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0092-1]}
+The rule for when Tasking_Error is raised for Set_Priority or Get_Priority is
+different from the rule for when Tasking_Error is raised on an
+entry call (see @RefSecNum{Entry Calls}). In particular,
address@hidden,New=[],Old=[setting or ]}querying the priority of
+a completed or an abnormal
+task is allowed, so long as the task is not yet
address@hidden,New=[, and setting the priority of a task
+is allowed for any task state (including for terminated tasks)],Old=[]}.
+
+Changing the priorities of a set of tasks can be performed by a
+series of calls to Set_Priority for each task separately. For
+this to work reliably, it should be done within a protected
+operation that has high enough ceiling priority to guarantee that
+the operation completes without being preempted by any of the
+affected tasks.
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00188-02]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @b[Amendment Correction:] Priority changes are
+  now required to be done immediately so long as the target task is not on an
+  entry queue.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00362-01]}
+  @ChgAdded{Version=[2],Text=[Dynamic_Priorities is now Preelaborated,
+  so it can be used in preelaborated units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00327-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[This Ada 95 @Chg{Version=[3],New=[subclause],
+  Old=[clause]} was @Chg{Version=[3],New=[moved down a level],Old=[turned
+  into a subclause]}. The paragraph numbers are the same as those for
+  @RefSecNum{Dynamic Priorities} in Ada 95.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00321-01]}
+  @ChgAdded{Version=[2],Text=[There is no @lquotes@;address@hidden policy
+  anymore, so that phrase was replaced by the name of a specific policy in
+  the notes.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00327-01]}
+  @ChgAdded{Version=[2],Text=[The bounded error for the priority of a task
+  being higher than the ceiling of an object it is currently in was moved
+  to @RefSecNum{Priority Ceiling Locking}, so that it applies no matter how
+  the situation arises.]}
address@hidden
+
+
address@hidden@Comment{For printed RM Ada 2005}
address@hidden,Name=[Dynamic Priorities for Protected Objects]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00327-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+specifies how the priority of a protected object can be modified or
+queried at run time.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00327-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The following attribute
+is defined for @PrefixType{a @nt{prefix} P that denotes a protected object}:]}
+
address@hidden(Description)
address@hidden,Kind=[AddedNormal],ChginAnnex=[T],
+  Leading=<F>, Prefix=<P>, AttrName=<Priority>, ARef=[AI95-00327-01],
+  address@hidden,New=[Denotes a non-aliased component of the
+  protected object P. This component is of type System.Any_Priority and its
+  value is the priority of P. P'Priority denotes a variable if and only if P
+  denotes a variable. A reference to this attribute shall appear only
+  within the body of P.],Old=[]}]}
address@hidden
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00327-01]}
address@hidden,Text=[The initial value of this attribute is
+the initial value of the priority of the protected address@hidden, and can
+be changed by an assignment].]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00327-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[If the locking policy Ceiling_Locking (see
address@hidden Ceiling Locking}) is in address@hidden,New=[,],Old=[]}
+then the ceiling priority of a protected object @i<P> is set to the value of
address@hidden<P>'Priority at the end of each protected action of @i<P>.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00445-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Text=[If the locking policy Ceiling_Locking is in effect,
+then for a protected object @i<P> with either an Attach_Handler or
+Interrupt_Handler @Chg{Version=[3],New=[aspect specified
+for],Old=[pragma applying to]} one of its procedures, a check is made
+that the value to be assigned to @i<P>'Priority is in the range
+System.Interrupt_Priority. If the check fails, Program_Error is
address@hidden,Sec=(raised by failure of run-time check)}]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00327-01]}
address@hidden,Type=[Leading],Text=[The implementation shall document
+the following metric:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Type=[Leading],Text=[The difference in execution time of
+calls to the following procedures in protected object P:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<protected> P @key<is>
+   @key<procedure> Do_Not_Set_Ceiling (Pr : System.Any_Priority);
+   @key<procedure> Set_Ceiling (Pr : System.Any_Priority);
address@hidden<end> P;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<protected body> P @key<is>
+   @key<procedure> Do_Not_Set_Ceiling (Pr : System.Any_Priority) @key<is>
+   @key<begin>
+      @key<null>;
+   @key<end>;
+   @key<procedure> Set_Ceiling (Pr : System.Any_Priority) @key<is>
+   @key<begin>
+      P'Priority := Pr;
+   @key<end>;
address@hidden<end> P;]}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The metrics for setting the priority of a protected object.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00327-01]}
address@hidden,Text=[Since P'Priority is a normal variable, the value
+following an assignment to the attribute immediately reflects the new value
+even though its impact on the ceiling priority of P is postponed until
+completion of the protected action in which it is executed.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00327-01],ARef=[AI95-00445-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The ability to dynamically change and query the priority of a protected
+  object is new.]}
address@hidden
+
+
address@hidden@Comment{For printed RM Ada 2005}
address@hidden Abort}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} specifies
+requirements on the immediacy with which an aborted construct is completed.]
address@hidden
+
address@hidden
+
+On a system with a single processor, an aborted construct is completed
+immediately at the first point that is outside the execution of an
+abort-deferred operation.
+
address@hidden
+
address@hidden
+On a multiprocessor, the implementation shall document any conditions that
+cause the completion of an aborted construct to be delayed later than
+what is specified for a single processor.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[On a multiprocessor, any conditions that
+cause the completion of an aborted construct to be delayed later than
+what is specified for a single processor.]}]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[On a multiprocessor, any conditions that
+cause the completion of an aborted construct to be delayed later than
+what is specified for a single processor.]}]}
address@hidden
+
address@hidden
address@hidden@;The implementation shall document the following metrics:
address@hidden
+The execution time, in processor clock cycles, that it takes for an
address@hidden to cause the completion of the aborted task.
+This is measured in a situation where a task T2 preempts task T1
+and aborts T1. T1 does not have any finalization code. T2 shall
+verify that T1 has terminated, by means of the Terminated attribute.
+
+On a multiprocessor, an upper bound in seconds,
+on the time that the completion of an aborted task can be delayed beyond
+the point that it is required for a single processor.
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+An upper bound on the execution time of an
address@hidden, in processor clock cycles. This is measured
+between a point immediately before a task
+T1 executes a protected operation Pr.Set that makes the @nt{condition}
+of an @nt{entry_barrier} Pr.Wait @Chg{Version=[2],
+New=[True],Old=[true]}, and the point where task T2 resumes
+execution immediately after an entry call to Pr.Wait in an
address@hidden T1 preempts T2 while
+T2 is executing the abortable part, and then blocks itself so that
+T2 can execute. The execution time of T1 is measured separately,
+and subtracted.
+
+An upper bound on the execution time of an
address@hidden,
+in the case that no asynchronous transfer of control takes
+place. This is measured between a point immediately before a task
+executes the @nt{asynchronous_select} with a nonnull abortable
+part, and the point where the task continues execution immediately after
+it. The execution time of the abortable part is subtracted.
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The metrics for aborts.]}]}
address@hidden
+
address@hidden
+
+Even though the @nt{abort_statement} is included in the list of
+potentially blocking operations
+(see @RefSecNum{Protected Subprograms and Protected Actions}),
+it is recommended that this statement be implemented in a way that
+never requires the task executing the @nt{abort_statement} to
+block.
+
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The @nt{abort_statement} should not require the task executing the
+statement to block.]}]}
+
+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.
+
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[On a multi-processor,
+the delay associated with aborting a task on another processor
+should be bounded.]}]}
+
address@hidden
+
address@hidden
+
+Abortion does not change the active or base priority of the aborted task.
+
+Abortion cannot be more immediate than is allowed by the rules for
+deferral of abortion during finalization and in protected actions.
+
address@hidden
+
+
address@hidden Restrictions}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} defines
+restrictions that can be used with a
+pragma Restrictions (see @RefSecNum{Pragma Restrictions and Pragma Profile}) 
to facilitate the
+construction of highly efficient tasking run-time systems.]
address@hidden
+
address@hidden
address@hidden@;The following @address@hidden are language defined:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0013-1],ARef=[AI05-0216-1]}
address@hidden,Sec=(No_Task_Hierarchy)address@hidden,address@hidden 
restriction}],
+   Old=[]}No_Task_Hierarchy @address@hidden,
+  New=[No task depends on a master other than the library-level 
master],Old=[All
+  (nonenvironment) tasks depend directly on
+  the environment task of the partition]}.
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0216-1]}
address@hidden,Text=[This is equivalent to saying @ldquote@;no task
+   depends on a master other than the
+   master that is the execution of the body of the environment task of the
+   address@hidden, but it is much easier to understand. This is a
+   post-compilation check, which can be checked at compile-time.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0013-1]}
address@hidden,Text=[This disallows any function returning an
+    object with a task part or coextension, even if called at the library 
level,
+    as such a task would temporarily depend on a nested master (the master
+    of the return statement), which is disallowed by this restriction.]}
address@hidden
+
address@hidden,Kind=[Revised],Ref=[8652/0042],ARef=[AI95-00130-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00360-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0013-1]}
address@hidden,Sec=(No_Nested_Finalization)address@hidden,address@hidden 
restriction}],
+   Old=[]}No_Nested_Finalization @\Objects
+  @Chg{Version=[2],New=[of a type that needs finalization (see
+  @RefSecNum{Assignment and Finalization})],Old=[with
+  address@hidden, protected, or task],Old=[]} parts]}
+  @Chg{Version=[3],New=[are],Old=[and
+  access types that designate @Chg{Version=[2],New=[a type that needs
+  finalization],Old=[such address@hidden,],Old=[]}]} shall be]}
+  declared only at library address@hidden,New=[ If an access type
+  does not have library-level accessibility, then there are
+  no @nt{allocator}s of the type where the type determined by the
+  @nt{subtype_mark} of the @nt{subtype_indication} or
+  @nt{qualified_expression} needs finalization.],Old=[]}
+    @begin{Ramification}
address@hidden,Kind=[Deleted],Ref=[8652/0042],ARef=[AI95-00130-01]}
+    @ChgNote{This is no longer true.}
+    @ChgDeleted{Version=[1],Text=[Note that protected types with entries and
+    interrupt-handling protected types have nontrivial finalization actions.
+    However, this restriction does not restrict those things.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0013-1]}
+    @ChgAdded{Version=[3],Text=[The second sentence prevents the declaration
+    of objects of access types which would require nested finalization. It
+    also prevents the declarations of coextensions that need
+    finalization in a nested scope. The latter cannot be done by preventing
+    the declaration of the objects, as it is not necessarily known if the
+    coextension type needs finalization (it could be a limited view).]}
+    @end{Ramification}
+
address@hidden,Kind=[Revised],ARef=[AI05-0211-1]}
address@hidden,Sec=(No_Abort_Statements)address@hidden,address@hidden 
restriction}],
+   Old=[]}No_Abort_Statements @\There are no @nt{abort_statement}s, and there
address@hidden,New=[is no use of a @nt{name} denoting],Old=[are no calls on]}
+Task_Identification.Abort_Task.
+
address@hidden,Sec=(No_Terminate_Alternatives)address@hidden,address@hidden 
restriction}],
+   Old=[]}No_Terminate_Alternatives @\There are no @nt{selective_accept}s with
+                        @nt{terminate_alternative}s.
+
address@hidden,Sec=(No_Task_Allocators)address@hidden,address@hidden 
restriction}],
+   Old=[]}No_Task_Allocators @\There are no @nt{allocator}s for task types or 
types
+                        containing task subcomponents.
+
address@hidden,Kind=[Added],ARef=[AI05-0224-1]}
address@hidden,NoPrefix=[T],Text=[In the case of an initialized
+   @nt{allocator} of an access type whose designated type is class-wide and
+   limited, a check is made that the specific type of the allocated object has
+   no task subcomponents. Program_Error is raised if this check
+   address@hidden,Sec=(raised by failure of run-time check)}]}
+   @Comment{We don't index this "check" as it doesn't have a name.}
+
address@hidden,Sec=(No_Implicit_Heap_Allocations)address@hidden,address@hidden 
restriction}],
+   Old=[]}No_Implicit_Heap_Allocations @\There are no operations that 
implicitly require
+                        heap storage allocation to be performed by the
+                        implementation. The operations that implicitly
+                        require heap storage allocation are
+                        implementation defined.
address@hidden operations that implicitly
+require heap storage allocation.}
+
address@hidden,Kind=[Revised],ARef=[AI95-00327-01]}
+No_Dynamic_Priorities @\There are no semantic dependences on the package
+                address@hidden,New=[, and no occurrences
+                of the attribute Priority],Old=[]}.
address@hidden,Sec=(No_Dynamic_Priorities)address@hidden,address@hidden 
restriction}],
+Old=[]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00305-01],ARef=[AI95-00394-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0013-1],ARef=[AI05-0211-1]}
address@hidden,address@hidden,
+   Sec=(No_Dynamic_Attachment)address@hidden,address@hidden restriction}],
+   Old=[]}No_Dynamic_Attachment],
address@hidden,Sec=(No_Asynchronous_Control)}No_Asynchronous_Control]}
+    @\There
+    @Chg{Version=[2],New=[is no @Chg{Version=[3],New=[use of a @nt{name}
+    denoting],Old=[call to]} any of the operations defined
+    in package Interrupts (Is_Reserved, Is_Attached, Current_Handler,
+    Attach_Handler, Exchange_Handler, Detach_Handler, and Reference).],
+    Old=[are no semantic dependences on the package 
Asynchronous_Task_Control.]}
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0013-1]}
address@hidden,Text=[This includes 'Access and 'Address of any
+    of these operations, as well as inherited versions of these operations.]}
address@hidden
+
+
address@hidden,Kind=[Added],ARef=[AI12-0055-1]}
address@hidden,address@hidden,Sec=(No_Dynamic_CPU_Assignment)address@hidden 
restriction}
+   No_Dynamic_CPU_Assignment @\No task has the CPU aspect specified to be
+    a non-static expression.
+    Each task (including the environment task) that has the CPU aspect
+    specified as Not_A_Specific_CPU will be assigned to a particular
+    implementation-defined CPU. The same is true for the environment task
+    when the CPU aspect is not specified. @Redundant[Any other task without
+    a CPU aspect will activate and execute on the same processor as its
+    activating task.]]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The processor of a task without a CPU aspect is
+   defined in @RefSecNum{Multiprocessor Implementation}, and this restriction
+   guarantees that the activator always has a CPU assigned.]}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[This restriction prevents any migration of tasks.]}
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If no CPU aspects are specified, then the program
+   will run on a single CPU, as all of the tasks will be activated directly or
+   indirectly by the environment task, and the rules require the same CPU to be
+   used as the activating task. ]}
address@hidden
address@hidden,Kind=[Added],address@hidden,
+Text=[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.]}]}
+
address@hidden,Kind=[Added],ARef=[AI95-00305-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0013-1]}
address@hidden,address@hidden,Sec=(No_Local_Protected_Objects)address@hidden,address@hidden
 restriction}],
+   Old=[]}No_Local_Protected_Objects @\Protected
+   objects @Chg{Version=[3],New=[are],Old=[shall be]} declared only at
+   library level.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00297-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0013-1]}
address@hidden,address@hidden,Sec=(No_Local_Timing_Events)address@hidden,address@hidden
 restriction}],
+   Old=[]}No_Local_Timing_Events @\Timing_Events
+   @Chg{Version=[3],New=[are],Old=[shall be]} declared only at library level.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00305-01]}
address@hidden,address@hidden,Sec=(No_Protected_Type_Allocators)address@hidden,address@hidden
 restriction}],
+   Old=[]}No_Protected_Type_Allocators @\There
+   are no @nt{allocator}s for protected types or types
+   containing protected type subcomponents.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0224-1]}
address@hidden,NoPrefix=[T],Text=[In the case of an initialized
+   @nt{allocator} of an access type whose designated type is class-wide and
+   limited, a check is made that the specific type of the allocated object has
+   no protected subcomponents. Program_Error is raised if this check
+   address@hidden,Sec=(raised by failure of run-time check)}]}
+   @Comment{We don't index this "check" as it doesn't have a name.}
+
address@hidden,Kind=[Added],ARef=[AI95-00305-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0211-1]}
address@hidden,address@hidden,Sec=(No_Relative_Delay)address@hidden,address@hidden
 restriction}],
+   Old=[]}No_Relative_Delay @\There
+   are no @address@hidden,New=[, and there is no
+   use of a @nt{name} that denotes the Timing_Events.Set_Handler
+   subprogram that has a Time_Span parameter],Old=[]}.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00305-01]}
address@hidden,address@hidden changed due to insertion above}
address@hidden,address@hidden,Sec=(No_Requeue_Statements)address@hidden,address@hidden
 restriction}],
+   Old=[]}No_Requeue_Statements @\There
+   are no @nt{requeue_statement}s.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00305-01]}
address@hidden,address@hidden changed due to insertion above}
address@hidden,address@hidden,Sec=(No_Select_Statements)address@hidden,address@hidden
 restriction}],
+   Old=[]}No_Select_Statements @\There
+   are no @nt{select_statement}s.]}
+
address@hidden,Kind=[Added],ARef=[AI95-00394-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0211-1]}
address@hidden,address@hidden,Sec=(No_Specific_Termination_Handlers)address@hidden,address@hidden
 restriction}],
+   Old=[]}No_Specific_Termination_Handlers @\There
+  @Chg{Version=[3],New=[is no use of a @nt{name} denoting],Old=[are no calls 
to]}
+  the Set_Specific_Handler and Specific_Handler subprograms
+  in Task_Termination.]}
+
address@hidden,Kind=[Added],ARef=[AI12-0117-1]}
address@hidden,address@hidden,Sec=(No_Tasks_Unassigned_To_CPU)address@hidden 
restriction}
+   No_Tasks_Unassigned_To_CPU @\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.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If this restriction is used in a context for which
+restriction No_Dynamic_CPU_Assignment is in effect, then no runtime check
+is needed when specifying the CPU aspect. If the restriction is used with
+the Ravenscar profile, no runtime checks are needed.]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00305-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0013-1]}
address@hidden,address@hidden,Sec=(Simple_Barriers)address@hidden,address@hidden
 restriction}],
+   Old=[]}Simple_Barriers @\The
+   Boolean expression in @Chg{Version=[3],New=[each],Old=[an]} entry barrier
+   @Chg{Version=[3],New=[is],Old=[shall be]} either a static
+   @Chg{Version=[3],New=[],Old=[Boolean ]}expression or a
+   @Chg{Version=[3],New=[name that statically denotes a],Old=[Boolean]}
+   component of the enclosing protected object.]}
+
address@hidden
+
address@hidden@;The following @address@hidden are
+language defined:
address@hidden
address@hidden,Sec=(Max_Select_Alternatives)address@hidden,address@hidden 
restriction}],
+   Old=[]}Max_Select_Alternatives @\Specifies the maximum number of 
alternatives
+                in a @nt{selective_accept}.
+
address@hidden,Sec=(Max_Task_Entries)address@hidden,address@hidden 
restriction}],
+   Old=[]}Max_Task_Entries @\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.
+    @Redundant[A value of zero indicates that no rendezvous
+    are possible.]
+
+Max_Protected_Entries @\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.
address@hidden,Sec=(Max_Protected_Entries)address@hidden,address@hidden 
restriction}],
+Old=[]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[Deleted],Ref=[8652/0076],ARef=[AI95-00067-01]}
address@hidden,Kind=[AddedNormal],ARef=[AI95-00305-01]}
address@hidden,Type=[Leading],Text=[The following
address@hidden@nt{identifier} is language defined:address@hidden ChgAdded so
+we get conditional address@hidden,New=[],Old=[If the following restrictions
+are violated, the behavior is implementation defined.
address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+If an implementation chooses to detect such a violation,
+Storage_Error should be raised.]}
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI95-00305-01],ARef=[AI95-00394-01]}
address@hidden,address@hidden,Sec=(No_Task_Termination)address@hidden,address@hidden
 restriction}],
+   Old=[]}No_Task_Termination @\All
+   tasks are nonterminating. It is implementation-defined what happens if
+   a task attempts to terminate. If there is a fall-back handler (see C.7.3)
+   set for the partition it should be called when the first task attempts to
+   terminate.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[When restriction No_Task_Termination applies to a partition, what
+  happens when a task terminates.]}]}
address@hidden
+
address@hidden@;The following @address@hidden are
+language defined:
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0076],ARef=[AI95-00067-01]}
address@hidden,Sec=(Max_Storage_At_Blocking)address@hidden,address@hidden 
restriction}],
+   Old=[]}Max_Storage_At_Blocking @\Specifies
+  the maximum portion @redundant[(in storage elements)]
+  of a task's Storage_Size that can be retained by a blocked address@hidden
+  If an implementation chooses to detect a violation of this
+  restriction, Storage_Error should be raised;
+  @IndexCheck{Storage_Check}
+  @Defn2{Term=[Storage_Error],Sec=(raised by failure of run-time check)}
+  otherwise, the behavior is implementation defined],Old=[]}.
address@hidden,Kind=[Added],address@hidden,
+Text=[The behavior when restriction Max_Storage_At_Blocking is violated.]}]}
+
address@hidden,Kind=[Revised],Ref=[8652/0076],ARef=[AI95-00067-01]}
address@hidden,Sec=(Max_Asynchronous_Select_Nesting)address@hidden,address@hidden
 restriction}],
+   Old=[]}Max_Asynchronous_Select_Nesting @\Specifies
+  the maximum dynamic nesting level of @nt{asynchronous_select}s.
+  A value of zero prevents the use of any @address@hidden@Chg{New=[ and,
+  if a program contains an @address@hidden, it is illegal.
+  @ChgNote{Part of the previous rule is redundant, but it is a different part
+  [all of it for Old; from "prevents" to "and," for New] for each. So we omit 
it.}
+  If an implementation chooses to detect a violation of this
+  restriction for values other than zero, Storage_Error should be raised;
+  @IndexCheck{Storage_Check}
+  @Defn2{Term=[Storage_Error],Sec=(raised by failure of run-time check)}
+  otherwise, the behavior is implementation defined],Old=[]}.
address@hidden,Kind=[Added],address@hidden,
+Text=[The behavior when restriction Max_Asynchronous_Select_Nesting is 
violated.]}]}
+
address@hidden,Kind=[Revised],Ref=[8652/0076],ARef=[AI95-00067-01]}
address@hidden,Sec=(Max_Tasks)address@hidden,address@hidden restriction}],
+   Old=[]}Max_Tasks @\Specifies the maximum
+  number of task creations that may be executed over the lifetime of a
+  partition, not counting the creation of the environment address@hidden
+  A value of zero prevents any task creation and, if a program contains a
+  task creation, it is illegal. If an implementation chooses to detect a
+  violation of this restriction, Storage_Error should be raised;
+  @IndexCheck{Storage_Check}
+  @Defn2{Term=[Storage_Error],Sec=(raised by failure of run-time check)}
+  otherwise, the behavior is implementation defined],Old=[]}.
+  @begin{Ramification}
+     Note that this is not a limit on the
+     number of tasks active at a given time;
+     it is a limit on the total number of task creations that occur.
+  @end{Ramification}
+  @begin{ImplNote}
+     We envision an implementation approach that places TCBs or pointers
+     to them in a fixed-size table, and never reuses table elements.
+  @end{ImplNote}
address@hidden,Kind=[Added],address@hidden,
+Text=[The behavior when restriction Max_Tasks is violated.]}]}
+
address@hidden,Kind=[Added],ARef=[AI95-00305-01]}
address@hidden,address@hidden,
+Sec=(Max_Entry_Queue_Length)address@hidden,address@hidden restriction}],
+Old=[]}Max_Entry_Queue_Length @\Max_Entry_Queue_Length
+  defines the maximum number of calls
+  that are queued on an entry. Violation of this restriction
+  results in the raising of Program_Error at the point of the call or
+  address@hidden,Sec=(raised by failure of run-time check)}]}
+
address@hidden,Kind=[Added],ARef=[AI05-0189-1]}
address@hidden,address@hidden,
+Sec=(No_Standard_Allocators_After_Elaboration)address@hidden restriction}
+No_Standard_Allocators_After_Elaboration @\Specifies that an @nt{allocator} 
using
+a standard storage pool (see @RefSecNum{Storage Management}) shall not occur
+within a parameterless library subprogram, nor within the
address@hidden of a task body. For the purposes of this rule, an
address@hidden of a type derived from a formal access type does not use a 
standard
+storage pool.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0189-1],ARef=[AI05-0262-1]}
address@hidden,NoPrefix=[T],Text=[At run time, Storage_Error is raised if
+an @nt{allocator} using a standard storage pool is evaluated after the 
elaboration of
+the @nt{library_item}s of the partition has address@hidden,
+Sec=(raised by failure of run-time check)}]}
address@hidden
+
+It is implementation defined whether the use of pragma Restrictions
+results in a reduction in executable program size, storage requirements,
+or execution time. If possible, the implementation should provide
+quantitative descriptions of such effects for each restriction.
address@hidden,Kind=[Revised],InitialVersion=[0],
address@hidden,
+New=[Whether the use of],Old=[Implementation-defined aspects of]}
+pragma address@hidden,New=[ results in a reduction in
+program code or data size or execution time],Old=[]}.]}
address@hidden
+
address@hidden
+When feasible, the implementation should take advantage of the specified
+restrictions to produce a more efficient implementation.
+
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[When feasible, specified restrictions should be used to produce a more
+efficient implementation.]}]}
address@hidden
+
address@hidden
+The above Storage_Checks can be suppressed with pragma Suppress.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00360-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] The No_Nested_Finalization is now defined in terms
+  of types that need finalization. These types include a variety of
+  language-defined types that @i<might> be implemented with a controlled type.
+  If the restriction No_Nested_Finalization (see
+  @RefSecNum{Tasking Restrictions}) applies to the partition, and one of these
+  language-defined types does not have a controlled part, it will not be
+  allowed in local objects in Ada 2005 whereas it would be allowed in original
+  Ada 95. Such code is not portable, as other Ada compilers may have had a
+  controlled part, and thus would be illegal under the restriction.]}
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00297-01],ARef=[AI95-00305-01],ARef=[AI95-00394-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Restrictions No_Dynamic_Attachment, No_Local_Protected_Objects,
+  No_Protected_Type_Allocators, No_Local_Timing_Events, No_Relative_Delay,
+  No_Requeue_Statement, No_Select_Statements, No_Specific_Termination_Handlers,
+  No_Task_Termination, Max_Entry_Queue_Length, and Simple_Barriers are newly
+  added to Ada.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0042],ARef=[AI95-00130-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that
+  No_Nested_Finalization covered task and protected parts as well.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0076],ARef=[AI95-00067-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Changed the description of
+  Max_Tasks and Max_Asynchronous_Select_Nested to eliminate conflicts with the
+  High Integrity Annex (see @RefSecNum{High Integrity Restrictions}).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00327-01]}
+  @ChgAdded{Version=[2],Text=[Added using of the new Priority attribute to
+  the restriction No_Dynamic_Priorities.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00394-01]}
+  @ChgAdded{Version=[2],Text=[Restriction No_Asynchronous_Control is now
+  obsolescent.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0013-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Changed so that coextensions of types that require nested finalization are
+  also prohibited; this is done by prohibiting @nt{allocator}s rather than
+  objects of specific access types. It seems unlikely that any program 
depending
+  on this restriction would violate it in this blatant manner, so it is 
expected
+  that very few programs will be affected by this change.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0211-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:>
+  The restriction No_Relative_Delay was changed to include the Timing_Events
+  routine that uses a relative delay. This means that a program that uses
+  that routine and this restriction will now be rejected. However, such a
+  program violates the spirit and intent of the restriction and as such the
+  program should never have been allowed. Moreover, it is unlikely that
+  any program depending on this restriction would violate it in such an obvious
+  manner, so it is expected that very few programs will be affected by this
+  change.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0211-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> A number of restrictions 
were
+  changed from "no calls" on some subprogram to "no use of a @nt{name} that
+  denotes" that subprogram. This closes a hole where renames, uses as the 
prefix
+  of 'Access, and the like, would not be rejected by the restriction, possibly
+  allowing backdoor access to the prohibited subprogram. A program that
+  uses one of these restrictions and using such backdoor access will now be
+  rejected; however, it is extremely unlikely that any program that relies
+  on these restrictions would also use an end-run around the restriction, so
+  it is expected that very few programs will be affected by this change.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0189-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Restriction No_Standard_Allocators_After_Elaboration is newly
+  added to Ada.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0013-1],ARef=[AI05-0216-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Improved the wording
+  of various restrictions to make it clearer that they prohibit
+  things that would otherwise be legal, and to word them as
+  definitions, not @LegalityTitle;.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0192-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Added wording to explain
+  how No_Task_Allocators and No_Protected_Type_Allocators are checked
+  for class-wide types. This might be an extension if the compiler
+  assumed the worst in the past (it is now a runtime check).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0055-1]}
+  @ChgAdded{Version=[4],address@hidden to Ada 2012}
+  @b{Corrigendum:} Restriction No_Dynamic_CPU_Assignment is newly
+  added to Ada, for use as part of the Ravenscar profile
+  (see @RefSecNum{The Ravenscar Profile}).]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0117-1]}
+  @ChgAdded{Version=[4],address@hidden:} Restriction
+  No_Tasks_Unassigned_To_CPU is newly added to Ada; it ensures that no
+  task is running on an implementation-defined CPU so that task scheduling
+  can be analyzed.]}
address@hidden
+
+
+
address@hidden Time}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} specifies
+a high-resolution, monotonic clock package.]
address@hidden
+
address@hidden
address@hidden@;The following language-defined library package exists:
address@hidden
address@hidden Ada.Real_Time @address@hidden,Child=[Real_Time]}
+
+  @key[type] @AdaTypeDefn{Time} @key[is] @key[private];
+  @AdaObjDefn{Time_First} : @key[constant] Time;
+  @AdaObjDefn{Time_Last} : @key[constant] Time;
+  @AdaObjDefn{Time_Unit} : @key[constant] := 
@RI{implementation-defined-real-number};
+
+
+
+  @key[type] @AdaTypeDefn{Time_Span} @key[is] @key[private];
+  @AdaObjDefn{Time_Span_First} : @key[constant] Time_Span;
+  @AdaObjDefn{Time_Span_Last} : @key[constant] Time_Span;
+  @AdaObjDefn{Time_Span_Zero} : @key[constant] Time_Span;
+  @AdaObjDefn{Time_Span_Unit} : @key[constant] Time_Span;
+
+
+  @AdaObjDefn{Tick} : @key[constant] Time_Span;
+  @key[function] @AdaSubDefn{Clock} @key[return] Time;
+
+
+  @key[function] "+" (Left : Time; Right : Time_Span) @key[return] Time;
+  @key[function] "+" (Left : Time_Span; Right : Time) @key[return] Time;
+  @key[function] "-" (Left : Time; Right : Time_Span) @key[return] Time;
+  @key[function] "-" (Left : Time; Right : Time) @key[return] Time_Span;
+
+
+  @key[function] "<" (Left, Right : Time) @key[return] Boolean;
+  @key[function] "<="(Left, Right : Time) @key[return] Boolean;
+  @key[function] ">" (Left, Right : Time) @key[return] Boolean;
+  @key[function] ">="(Left, Right : Time) @key[return] Boolean;
+
+
+  @key[function] "+" (Left, Right : Time_Span) @key[return] Time_Span;
+  @key[function] "-" (Left, Right : Time_Span) @key[return] Time_Span;
+  @key[function] "-" (Right : Time_Span) @key[return] Time_Span;
+  @key[function] "*" (Left : Time_Span; Right : Integer) @key{return} 
Time_Span;
+  @key[function] "*" (Left : Integer; Right : Time_Span) @key{return} 
Time_Span;
+  @key[function] "/" (Left, Right : Time_Span) @key[return] Integer;
+  @key[function] "/" (Left : Time_Span; Right : Integer) @key[return] 
Time_Span;
+
+  @key[function] "@key[abs]"(Right : Time_Span) @key[return] Time_Span;
+
address@hidden, Kind=[Deleted]}
address@hidden<>,Old=<@ @;@comment{Empty paragraph to hang junk paragraph 
number from original RM}>]
+
+  @key[function] "<" (Left, Right : Time_Span) @key[return] Boolean;
+  @key[function] "<="(Left, Right : Time_Span) @key[return] Boolean;
+  @key[function] ">" (Left, Right : Time_Span) @key[return] Boolean;
+  @key[function] ">="(Left, Right : Time_Span) @key[return] Boolean;
+
+
+  @key[function] @AdaSubDefn{To_Duration} (TS : Time_Span) @key[return] 
Duration;
+  @key[function] @AdaSubDefn{To_Time_Span} (D : Duration) @key[return] 
Time_Span;
+
+
address@hidden,Kind=[Revised],ARef=[AI95-00386-01]}
+  @key[function] @AdaSubDefn{Nanoseconds}  (NS : Integer) @key{return} 
Time_Span;
+  @key[function] @AdaSubDefn{Microseconds} (US : Integer) @key{return} 
Time_Span;
+  @key[function] @AdaSubDefn{Milliseconds} (MS : Integer) @key{return} 
Time_Span;@Chg{Version=[2],New=[
+  @key[function] @AdaSubDefn{Seconds}      (S  : Integer) @key{return} 
Time_Span;
+  @key[function] @AdaSubDefn{Minutes}      (M  : Integer) @key{return} 
Time_Span;],Old=[]}
+
+
+  @key[type] @AdaTypeDefn{Seconds_Count} @key[is] @key[range] 
@RI{implementation-defined};
+
+  @key{procedure} @AdaSubDefn{Split}(T : @key{in} Time; SC : @key{out} 
Seconds_Count; TS : @key{out} Time_Span);
+  @key{function} @AdaSubDefn{Time_Of}(SC : Seconds_Count; TS : Time_Span) 
@key{return} Time;
+
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden Ada.Real_Time;
address@hidden
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Implementation-defined aspects of package Real_Time.]}]}
+
address@hidden time}
+In this Annex, @i{real time} is defined to be the physical time as observed
+in the external environment.
+The type Time is a @i{time type} as defined by
address@hidden Statements, Duration, and Time};
address@hidden of this type may be used in a
address@hidden
+Values of this type
+represent segments of an ideal time line. The set of values of
+the type Time corresponds one-to-one with an
+implementation-defined range of mathematical integers.
address@hidden
+Informally, real time is defined to be the International Atomic Time (TAI)
+which is monotonic and nondecreasing. We use it here for the purpose of
+discussing rate of change and monotonic behavior only. It does not imply
+anything about the absolute value of Real_Time.Clock, or about Real_Time.Time
+being synchronized with TAI. It is also used for real time in the metrics,
+for comparison purposes.
address@hidden
address@hidden
+The specification of TAI as @lquotes@;real address@hidden@; does not preclude 
the
+use of a simulated TAI clock for simulated execution environments.
address@hidden
+
address@hidden
address@hidden
+The Time value I represents the half-open real time
+interval that starts with E+I*Time_Unit and is limited by E+(I+1)*Time_Unit,
+where Time_Unit is an implementation-defined real number and E is an
+unspecified origin point, the @i{epoch}, that is the same
+for all values of the type Time.
+It is not specified by the language whether the time values are
+synchronized with any standard time reference.
address@hidden example, E can correspond to the time of system
+initialization or it can correspond to the epoch of some time standard.]
address@hidden
+E itself does not have to be a proper time value.
+
+This half-open interval I consists of all
+real numbers R such that E+I*Time_Unit <= R < E+(I+1)*Time_Unit.
address@hidden
+
+Values of the type Time_Span represent length of real time
+duration.
+The set of values of this type corresponds one-to-one
+with an implementation-defined range of mathematical integers.
+The Time_Span value corresponding to the integer I
+represents the real-time duration I*Time_Unit.
address@hidden
+The purpose of this type is similar to Standard.Duration; the idea is to
+have a type with a higher resolution.
address@hidden
address@hidden
+We looked at many possible names for this type: Real_Time.Duration,
+Fine_Duration, Interval, Time_Interval_Length, Time_Measure, and more.
+Each of these names had some problems, and we've finally settled for Time_Span.
address@hidden
+
+Time_First and Time_Last are the smallest and largest values of the
+Time type, respectively.
+Similarly, Time_Span_First and Time_Span_Last are the smallest and
+largest values of the Time_Span type, respectively.
+
+A value of type Seconds_Count represents an elapsed time,
+measured in seconds,
+since the epoch.
+
address@hidden
+
address@hidden
+
+Time_Unit is the smallest amount of real time representable by the Time type;
+it is expressed in seconds. Time_Span_Unit is the difference between
+two successive values of the Time type. It is also the smallest positive
+value of type Time_Span. Time_Unit and Time_Span_Unit represent
+the same real time duration.
address@hidden tick}
+A @i{clock tick} is a real time interval during
+which the clock value (as observed by calling the Clock function) remains
+constant. Tick is the average length of such intervals.
+
address@hidden,Kind=[Revised],ARef=[AI95-00432-01]}
+The function To_Duration converts the value TS to a value of type
+Duration. Similarly, the function To_Time_Span converts the value D
+to a value of type Time_Span. For @Chg{Version=[2],New=[To_Duration],
+Old=[both operations]}, the result is
+rounded to the nearest @Chg{Version=[2],New=[value of type Duration],
+Old=[exactly representable value]} (away from zero if exactly
+halfway between two @Chg{Version=[2],New=[],
+Old=[exactly representable ]}values)address@hidden,New=[ If the result
+is outside the range of Duration, Constraint_Error is raised. For To_Time_Span,
+the value of D is first rounded to the nearest integral multiple of Time_Unit,
+away from zero if exactly halfway between two multiples. If the
+rounded value is outside the range of Time_Span, Constraint_Error is
+raised. Otherwise, the value is converted to the type Time_Span.],Old=[]}
+
+To_Duration(Time_Span_Zero) returns 0.0,
+and To_Time_Span(0.0) returns Time_Span_Zero.
+
address@hidden,Kind=[Revised],ARef=[AI95-00386-01],ARef=[AI95-00432-01]}
+The functions Nanoseconds, Microseconds, @Chg{Version=[2],New=[],
+Old=[and address@hidden,New=[, Seconds, and Minutes],Old=[]}
+convert the input
+parameter to a value of the type Time_Span. NS, 
US,@Chg{Version=[2],New=[],Old=[ and]}
address@hidden,New=[, S, and M],Old=[]} are interpreted as a number of
+nanoseconds, microseconds,@Chg{Version=[2],New=[],Old=[ and]}
address@hidden,New=[, seconds, and minutes],Old=[]}
address@hidden,New=[ The input parameter is first converted to
+seconds and rounded to the nearest integral multiple of Time_Unit, ],
+Old=[The result is rounded to the nearest exactly
+representable value (]}away from zero if exactly halfway between two
address@hidden,New=[multiples. If the rounded value
+is outside the range of Time_Span, Constraint_Error is raised.
+Otherwise, the rounded value is converted to the type Time_Span],
+Old=[exactly representable values)]}.
address@hidden
+  @ChgRef{Version=[2],Kind=[Deleted],ARef=[AI95-00432-01]}
+  @ChgDeleted{Version=[2],Text=[The above does not imply that the Time_Span
+  type will have to accommodate Integer'Last of milliseconds; Constraint_Error
+  is allowed to be raised.]}
address@hidden
+
+The effects of the operators on Time and Time_Span are as for the
+operators defined for integer types.
address@hidden
+  Though time values are modeled by integers, the types Time and
+  Time_Span need not be implemented as integers.
address@hidden
+
+The function Clock returns
+the amount of time since the epoch.
+
+The effects of the Split and Time_Of operations are defined as follows,
+treating values of type
+Time, Time_Span, and Seconds_Count as mathematical integers.
+The effect of Split(T,SC,TS) is to set SC and TS to values
+such that T*Time_Unit = SC*1.0 + TS*Time_Unit, and 0.0 <= TS*Time_Unit < 1.0.
+The value returned by Time_Of(SC,TS) is the value T such that T*Time_Unit =
+SC*1.0 + TS*Time_Unit.
address@hidden
+
address@hidden
+
+The range of Time values shall be sufficient to uniquely
+represent the range of real times from program start-up to 50 years later.
+Tick shall be no greater than 1 millisecond.
+Time_Unit shall be less than or equal to 20 microseconds.
address@hidden
+The required range and accuracy of Time are such that
+32-bits worth of seconds and 32-bits worth of ticks in a second could be
+used as the representation.
address@hidden
+
+Time_Span_First shall be no greater than @en@;3600 seconds, and
+Time_Span_Last shall be no less than 3600 seconds.
address@hidden
+This is equivalent to @PorM one hour and there is still room for
+a two-microsecond resolution.
address@hidden
+
address@hidden jump}
+A @i{clock jump} is the difference between two successive distinct values of
+the clock (as observed by calling the Clock function). There shall be no
+backward clock jumps.
+
address@hidden
+
address@hidden
+
+The implementation shall document the values of Time_First, Time_Last,
address@hidden, address@hidden, address@hidden, and Tick.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The values of Time_First, Time_Last,
address@hidden, address@hidden, address@hidden, and Tick
+for package Real_Time.]}]}
+
+The implementation shall document the properties of the underlying
+time base used for the clock and for type Time,
+such as the range of values supported
+and any relevant aspects of the underlying hardware
+or operating system facilities used.
address@hidden,Kind=[Added],address@hidden,
+Text=[The properties of the underlying
+time base used in package Real_Time.]}]}
address@hidden
+If there is an underlying operating system,
+this might include information about which system call is used
+to implement the clock.
+Otherwise, it might include information about which
+hardware clock is used.
address@hidden
+
+The implementation shall document whether or not there is any synchronization
+with external time references, and if such synchronization exists, the sources
+of synchronization information, the frequency of synchronization, and the
+synchronization method applied.
address@hidden,Kind=[Added],address@hidden,
+Text=[Any synchronization of package Real_Time with external time 
references.]}]}
+
address@hidden,Kind=[Revised]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The implementation shall document any aspects of the @Chg{New=[], Old=[the]}
address@hidden typo as noted at Potsdam ARG meeting}
+external environment that could interfere with the clock behavior as defined
+in this @Chg{Version=[3],New=[subclause],Old=[clause]}.
address@hidden,Kind=[Added],address@hidden,
+Text=[Any aspects of the external environment that could interfere with
+package Real_Time.]}]}
address@hidden
+For example, the implementation is allowed to rely on the time services of
+an underlying operating system, and this operating system clock can
+implement time zones or allow the clock to be reset by an operator.
+This dependence has to be documented.
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+For the purpose of the metrics defined in this 
@Chg{Version=[3],New=[subclause],Old=[clause]},
+real time is defined to be the International Atomic Time (TAI).
+
address@hidden@;The implementation shall document the following metrics:
address@hidden
+An upper bound on the real-time duration of a clock tick. This is a value
+D such that if t1 and t2 are any real times such that t1 < t2 and
address@hidden = address@hidden then t2 @en@; t1 <= D.
+
+An upper bound on the size of a clock jump.
+
address@hidden rate}
+An upper bound on the @i{drift rate} of Clock with respect to real time.
+This is a real number D such that
address@hidden
+E*(address@hidden@;D) <= (address@hidden @en@; address@hidden) <= E*(1+D)
+        provided that: address@hidden + E*(1+D) <= Time_Last.
address@hidden
+
+where address@hidden is the value of Clock at time t, and E is a real
+time duration not less than 24 hours. The value of E used for
+this metric shall be reported.
address@hidden
+This metric is intended to provide a measurement
+of the long term (cumulative) deviation; therefore, 24
+hours is the
+lower bound on the measurement period. On some implementations,
+this is also the maximum period, since the language does not
+require that the range of the type Duration be more than 24 hours.
+On those implementations that support longer-range Duration, longer
+measurements should be performed.
address@hidden
+
+An upper bound on the execution time of a call to the Clock
+function, in processor clock cycles.
+
+Upper bounds on the execution times of the operators of the types Time
+and Time_Span, in processor clock cycles.
address@hidden
+A fast implementation of the Clock function involves repeated
+reading until you get the same value twice.
+It is highly improbable that more than three reads will be necessary.
+Arithmetic on time values should not be significantly slower
+than 64-bit arithmetic in the underlying machine instruction set.
address@hidden
address@hidden
address@hidden,Kind=[Added],address@hidden,
+Text=[The metrics for package Real_Time.]}]}
address@hidden
+
address@hidden
+Implementations targeted to machines with word size smaller than 32
+bits need not support the full range and granularity of the
+Time and Time_Span types.
address@hidden
+These requirements are based on machines with a word size of 32 bits.
+
+Since the range and granularity are implementation defined, the supported
+values need to be documented.
address@hidden
address@hidden
+
address@hidden
+
+When appropriate, implementations should provide configuration mechanisms to
+change the value of Tick.
address@hidden,Kind=[Added],address@hidden,
+Text=[When appropriate, mechanisms to change the value of Tick should be
+provided.]}]}
address@hidden
+This is often needed when the compilation system was originally targeted to a
+particular processor with a particular interval timer, but the customer
+uses the same processor with a different interval timer.
address@hidden
address@hidden
+Tick is a deferred constant and not a named number
+specifically for this purpose.
address@hidden
address@hidden
+This can be achieved either by pre-run-time configuration
+tools, or by having Tick be initialized
+(in the package private part)
+by a function call residing in a board specific module.
address@hidden
+
+It is recommended that Calendar.Clock and Real_Time.Clock be implemented
+as transformations of the same time base.
address@hidden,Kind=[Added],address@hidden,
+Text=[Calendar.Clock and Real_Time.Clock should be transformations of the
+same time base.]}]}
+
+It is recommended that the @lquotes@;address@hidden@; time base which exists 
in the
+underlying system be available to the application through
+Clock. @lquotes@;address@hidden@; may mean highest accuracy or largest range.
address@hidden,Kind=[Added],address@hidden,
+Text=[The @lquotes@;address@hidden@; time base which exists in the
+underlying system should be available to the application through
+Real_Time.Clock.]}]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+The rules in this @Chg{Version=[3],New=[subclause],Old=[clause]} do not imply
+that the implementation can protect the user from operator or installation
+errors which could result in the clock being set incorrectly.
+
+Time_Unit is the granularity of the Time type. In contrast,
+Tick represents the granularity of Real_Time.Clock.
+There is no requirement that these be the same.
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00386-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  Functions Seconds and Minutes are @Chg{Version=[3],New=[],Old=[newly ]}added
+  to Real_Time. If
+  Real_Time is referenced in a @nt{use_clause}, and an entity @i<E> with a
+  @nt{defining_identifier} of Seconds or Minutes is defined in a package that
+  is also referenced in a @nt{use_clause}, the entity @i<E> may no longer be
+  use-visible, resulting in errors. This should be rare and is easily fixed if
+  it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00432-01]}
+  @ChgAdded{Version=[2],Text=[Added wording explaining how and when many of
+  these functions can raise Constraint_Error. While there always was an
+  intent to raise Constraint_Error if the values did not fit, there never
+  was any wording to that effect, and since Time_Span was a private type,
+  the normal numeric type rules do not apply to it.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Accuracy}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} specifies
+performance requirements for the @nt{delay_statement}.
+The rules apply both to @address@hidden@!statement} and to
address@hidden@address@hidden Similarly, they apply equally to a
+simple @address@hidden and to one which appears in a
address@hidden@!alternative}.]
address@hidden
+
address@hidden
address@hidden@;The effect of the @nt{delay_statement} for Real_Time.Time is
+defined in terms of Real_Time.Clock:
address@hidden
+
+If address@hidden is a value of Clock read before a task executes a
address@hidden with duration D, and address@hidden is a value of
+Clock read after the task resumes execution following that
address@hidden, then address@hidden @en@; address@hidden >= D.
+
+If C is a value of Clock read after a task resumes execution following a
address@hidden with Real_Time.Time value T, then C >= T.
address@hidden
+
address@hidden blocking operation],Sec=(delay_statement)}
address@hidden, potentially],Sec=(delay_statement)}
+A simple @nt{delay_statement} with a negative or zero value for the
+expiration time does not cause the calling task to be blocked; it is
+nevertheless a potentially blocking operation
+(see @RefSecNum{Protected Subprograms and Protected Actions}).
+
address@hidden,Kind=[Revised],ARef=[AI05-0004-1]}
+When a @nt{delay_statement} appears in a @nt{delay_alternative} of a
address@hidden the selection of the entry call is attempted,
+regardless of the specified expiration time.
+When a @nt{delay_statement} appears in a
address@hidden,address@hidden,address@hidden,
+and a call is queued on one of the open entries, the selection of that
+entry call proceeds, regardless of the value of the delay expression.
address@hidden
+The effect of these requirements is that one has to always attempt a 
rendezvous,
+regardless of the value of the delay expression. This can be tested by
+issuing a @nt{timed_entry_call} with an expiration time
+of zero, to an open entry.
address@hidden
+
address@hidden
+
address@hidden
+
+The implementation shall document the minimum value of the delay expression
+of a @nt{delay_relative_statement} that causes the task to actually be blocked.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The minimum value of the delay expression of a
address@hidden that causes a task to actually be blocked.]}]}
+
+The implementation shall document the minimum difference between the value of
+the delay expression of a @nt{delay_until_statement} and the value of
+Real_Time.Clock, that causes the task to actually be blocked.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Implementation-defined aspects of @nt{delay_statement}s.]}]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The minimum difference between the value of the delay expression of a
address@hidden and the value of Real_Time.Clock, that causes the
+task to actually be blocked.]}]}
+
address@hidden
+
address@hidden
address@hidden@;The implementation shall document the following metrics:
address@hidden
+An upper bound on the execution time, in processor clock cycles, of a
address@hidden whose requested value of the delay expression
+is less than or equal to zero.
+
+An upper bound on the execution time, in processor clock cycles, of a
address@hidden whose requested value of the delay expression is
+less than or equal to the value of Real_Time.Clock at the
+time of executing the statement. Similarly, for Calendar.Clock.
+
address@hidden
address@hidden duration}
+An upper bound on the @i{lateness} of a @nt{delay_relative_statement},
+for a positive value of the delay expression, in a situation
+where the task has sufficient priority to preempt the processor as
+soon as it becomes ready, and does not need to
+wait for any other execution resources. The upper bound is
+expressed as a function of the value of the delay expression.
+The lateness is obtained by subtracting the value of the delay expression
+from the @i{actual duration}. The actual duration is measured from a point
+immediately before a task executes the @nt{delay_statement} to a point
+immediately after the task resumes execution following this statement.
+
+An upper bound on the lateness of a @nt{delay_until_statement}, in a
+situation where the value of the requested expiration time is after the time
+the task begins executing the statement, the task has sufficient priority
+to preempt the processor as soon as it becomes ready, and
+it does not need to wait for any other execution resources. The upper
+bound is expressed as a function of the difference between the requested
+expiration time and the clock value at the time the statement begins
+execution. The lateness of a @nt{delay_until_statement} is obtained by
+subtracting the requested expiration time from the real time that the task
+resumes execution following this statement.
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The metrics for delay statements.]}]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00355-01]}
address@hidden,Text=[The execution time of a @nt{delay_statement} that
+does not cause the task to be blocked (e.g. @lquotes@;@key[delay]
+0.0;@rquotes@; ) is of interest in situations where delays are used to achieve
+voluntary round-robin task dispatching among equal-priority tasks.]}
+
address@hidden
+
address@hidden
+
+The rules regarding a @nt{timed_entry_call} with a very small positive
+Duration value, have been tightened to always require the check whether
+the rendezvous is immediately possible.
+
address@hidden
+
address@hidden
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00355-01]}
+  @ChgAdded{Version=[2],Text=[The note about @lquotes@;voluntary
+  address@hidden, while still true, has been deleted as potentially
+  confusing as it is describing a different kind of round-robin than is defined
+  by the round-robin dispatching policy.]}
+
address@hidden
+
+
address@hidden Task Control}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} describes
+a language-defined private semaphore
+(suspension object), which can be used for @i{two-stage suspend}
+operations and as a simple building block for implementing higher-level
+queues.]
address@hidden
+
address@hidden
+
address@hidden@;The following language-defined package exists:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00362-01]}
address@hidden Ada.Synchronous_Task_Control @address@hidden,address@hidden,New=[
+  @key[pragma] Preelaborate(Synchronous_Task_Control);],Old=[]}
+
+  @key{type} @AdaTypeDefn{Suspension_Object} @key{is} @key{limited} 
@key{private};
+  @key{procedure} @AdaSubDefn{Set_True}(S : @key{in} @key{out} 
Suspension_Object);
+  @key{procedure} @AdaSubDefn{Set_False}(S : @key{in} @key{out} 
Suspension_Object);
+  @key{function} @AdaSubDefn{Current_State}(S : Suspension_Object) 
@key{return} Boolean;
+  @key{procedure} @AdaSubDefn{Suspend_Until_True}(S : @key{in} @key{out} 
Suspension_Object);
address@hidden
+     ... -- @RI{not specified by the language}
address@hidden Ada.Synchronous_Task_Control;
address@hidden
+
+The type Suspension_Object is a by-reference address@hidden
address@hidden,Kind=[Revised],address@hidden is a real term now, let's get it 
right}
+The implementation can ensure this by, for example, making the full view
address@hidden,New=[an explicitly],Old=[a]}
+limited record address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0168-1]}
address@hidden,Type=[Leading],Text=[The following language-defined package
+exists:]}
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0168-1]}
address@hidden,address@hidden Ada.Synchronous_Task_Control.EDF 
@address@hidden,Child=[EDF]}
+   @key{procedure} @AdaSubDefn{Suspend_Until_True_And_Set_Deadline}
+      (S  : @key{in out} Suspension_Object;
+       TS : @key{in}     Ada.Real_Time.Time_Span);
address@hidden Ada.Synchronous_Task_Control.EDF;]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+An object of the type Suspension_Object has two visible states:
address@hidden,New=[True],Old=[true]} and
address@hidden,New=[False],Old=[false]}. Upon initialization,
+its value is set to @Chg{Version=[2],New=[False],Old=[false]}.
address@hidden
+This object is assumed to be private to the declaring task, i.e. only that
+task will call Suspend_Until_True on this object, and the count of callers is
+at most one. Other tasks can, of course, change and query the state of this
+object.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+The operations Set_True and Set_False are atomic with respect to each other
+and with respect to Suspend_Until_True; they set the state to
address@hidden,New=[True],Old=[true]} and
address@hidden,New=[False],Old=[false]} respectively.
+
+Current_State returns the current state of the object.
address@hidden
+This state can change immediately after the operation returns.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+The procedure Suspend_Until_True blocks the calling task until the
+state of the object S is @Chg{Version=[2],New=[True],Old=[true]}; at that
+point the task becomes ready
+and the state of the object becomes @Chg{Version=[2],New=[False],Old=[false]}.
+
address@hidden blocking operation],Sec=(Suspend_Until_True)}
address@hidden, potentially],Sec=(Suspend_Until_True)}
address@hidden,Sec=(raised by failure of run-time check)}
+Program_Error is raised upon calling Suspend_Until_True if another
+task is already waiting on that suspension object.
+Suspend_Until_True is a potentially blocking operation
+(see @RefSecNum{Protected Subprograms and Protected Actions}).
+
address@hidden,Kind=[Added],ARef=[AI05-0168-1],ARef=[AI05-0269-1]}
address@hidden,Text=[The procedure Suspend_Until_True_And_Set_Deadline
+blocks the calling task until the state of the object S is True; at that point
+the task becomes ready with a deadline of Ada.Real_Time.Clock + TS, and the
+state of the object becomes False. Program_Error is raised upon calling
+Suspend_Until_True_And_Set_Deadline if another task is already waiting on that
+suspension object. Suspend_Until_True_And_Set_Deadline is a potentially 
blocking
+operation.]}
address@hidden
+
address@hidden
+
+The implementation is required to allow the calling of Set_False and
+Set_True during any protected action, even one that has its ceiling priority
+in the Interrupt_Priority range.
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0168-1]}
address@hidden,Text=[More complex schemes, such as setting the deadline
+relative to when Set_True is called, can be programmed using a protected
+object.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00362-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Synchronous_Task_Control is now Preelaborated,
+  so it can be used in preelaborated units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0168-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}Child
+  package Ada.Synchronous_Task_Control.EDF is new.]}
address@hidden
+
+
address@hidden,Name=[Synchronous Barriers]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0174-1],ARef=[AI05-0299-1]}
address@hidden,Text=[This subclause introduces a language-defined package to
+synchronously release a group of tasks after the number of blocked tasks 
reaches
+a specified count value.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0174-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The following
+language-defined library package exists:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Synchronous_Barriers 
@address@hidden,Child=[Synchronous_Barriers]}
+   @key[pragma] Preelaborate(Synchronous_Barriers);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[subtype] 
@AdaSubtypeDefn{Name=[Barrier_Limit],Of=[Positive]} @key[is] Positive 
@key[range] 1 .. @RI<implementation-defined>;]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The value of Barrier_Limit'Last in Synchronous_Barriers.]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Synchronous_Barrier} 
(Release_Threshold : Barrier_Limit) @key[is limited private];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Wait_For_Release} 
(The_Barrier : @key[in out] Synchronous_Barrier;
+                               Notified    :    @key[out] Boolean);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   -- @RI{not specified by the language}
address@hidden Ada.Synchronous_Barriers;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0174-1]}
address@hidden,Text=[Type Synchronous_Barrier needs finalization (see
address@hidden and Finalization}).]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0174-1]}
address@hidden,Text=[Each call to Wait_For_Release blocks the calling
+task until the number of blocked tasks associated with the Synchronous_Barrier
+object is equal to Release_Threshold, at which time all blocked tasks are 
released.
+Notified is set to True for one of the released tasks, and set to False for all
+other released tasks.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0174-1]}
address@hidden,Text=[The mechanism for determining which task sets
+Notified to True is implementation defined.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0174-1]}
address@hidden,Text=[Once all tasks have been released, a
+Synchronous_Barrier object may be reused to block another Release_Threshold 
number
+of tasks.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0174-1]}
address@hidden,Text=[As the first step of the finalization of a
+Synchronous_Barrier, each blocked task is unblocked and Program_Error is raised
+at the place of the call to Wait_For_Release.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0174-1]}
address@hidden,Text=[It is implementation defined whether an abnormal
+task which is waiting on a Synchronous_Barrier object is aborted immediately or
+aborted when the tasks waiting on the object are released.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[When an aborted task that is waiting on a Synchronous_Barrier is 
aborted.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0174-1]}
address@hidden,Text=[Wait_For_Release is a potentially blocking operation
+(see @RefSecNum{Protected Subprograms and Protected Actions}).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0174-1]}
address@hidden,Text=[It is a bounded error to call Wait_For_Release on a
+Synchronous_Barrier object after that object is finalized. If the error is
+detected, Program_Error is raised. Otherwise, the call proceeds normally, which
+may leave a task blocked forever.]}
address@hidden
+
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0174-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The package Ada.Synchronous_Barriers is new.]}
address@hidden
+
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden Task Control}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} introduces
+a language-defined package to do asynchronous suspend/resume on tasks.
+It uses a conceptual @i{held priority} value to represent the task's
address@hidden state.]
address@hidden
+
address@hidden
+
address@hidden@;The following language-defined library package exists:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00362-01]}
address@hidden Ada.Task_Identification;
address@hidden Ada.Asynchronous_Task_Control 
@address@hidden,address@hidden,New=[
+  @key[pragma] Preelaborate(Asynchronous_Task_Control);],Old=[]}
+  @key{procedure} @AdaSubDefn{Hold}(T : @key[in] 
Ada.Task_Identification.Task_Id);
+  @key{procedure} @AdaSubDefn{Continue}(T : @key[in] 
Ada.Task_Identification.Task_Id);
+  @key{function} @AdaSubDefn{Is_Held}(T : Ada.Task_Identification.Task_Id)
+   @key{return} Boolean;
address@hidden Ada.Asynchronous_Task_Control;
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00357-01]}
address@hidden state], Sec=(held)}
address@hidden priority}
address@hidden task}
+After the Hold operation has been applied to a task, the task becomes
address@hidden For each processor there is a conceptual @i{idle task},
+which is always ready. The base priority of the idle task is below
address@hidden@!Priority'First. The @i{held priority} is a
+constant of the type @Chg{Version=[2],New=[Integer],Old=[integer]}
+whose value is below the base priority of the idle task.
address@hidden
+The held state should not be confused with the blocked state as defined
+in @RefSecNum{Task Execution - Task Activation}; the task is still ready.
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00357-01]}
address@hidden,Text=[For any priority below System.Any_Priority'First,
+the task dispatching policy is FIFO_Within_Priorities.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This applies even if a Task_Dispatching_Policy
+  specifies the policy for all of the priorities of the partition.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[A task at the held priority never runs, so it is
+  not necessary to implement FIFO_Within_Priorities for systems that have only
+  one policy (such as EDF_Across_Priorities).]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00357-01]}
+The Hold operation sets the state of T to held. For a held
address@hidden,New=[, the active
+priority is reevaluated as if the base priority of the task were the held
+priority],Old=[: the task's own base priority does not constitute an
+inheritance source
+(see @RefSecNum{Task Priorities}), and the value of the held priority
+is defined to be such a source instead]}.
address@hidden
+For example, if T is currently inheriting priorities from other sources (e.g.
+it is executing in a protected action), its active priority does not change,
+and it continues to execute until it leaves the protected action.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00357-01]}
+The Continue operation resets the state of T to not-held;
address@hidden,New=[its],Old=[T's]} active priority
+is then reevaluated as @Chg{Version=[2],New=[determined by the
+task dispatching policy associated with its base priority.],Old=[described in
address@hidden Priorities}.
address@hidden time, T's base priority is taken into account.]]}
+
+The Is_Held function returns True if and only if T is in the held state.
address@hidden
+Note that the state of T can be changed immediately after Is_Held returns.
address@hidden
+
+As part of these operations, a check is made that the task
+identified by
+T is not terminated.
address@hidden,Sec=(raised by failure of run-time check)}
+Tasking_Error is raised if the check fails.
address@hidden,Sec=(raised by failure of run-time check)}
+Program_Error is raised if the value of T is Null_Task_Id.
+
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)}
+If any operation in this package is called with a parameter T that
+specifies a task object that no longer exists, the execution of the
+program is erroneous.
address@hidden
+
address@hidden
+
+An implementation need not support Asynchronous_Task_Control if it is
+infeasible to support it in the target environment.
address@hidden
+A direct implementation of the Asynchronous_Task_Control semantics using
+priorities is not necessarily efficient enough.
+Thus, we envision implementations that use some other mechanism to set
+the @lquotes@;address@hidden@; state.
+If there is no other such mechanism,
+support for Asynchronous_Task_Control might be infeasible,
+because an implementation in terms of priority would require one idle
+task per processor.
+On some systems, programs are not supposed to know how many processors
+are available,
+so creating enough idle tasks would be problematic.
address@hidden
+
address@hidden
+
address@hidden
+
+It is a consequence of the priority rules that held tasks cannot be dispatched
+on any processor in a partition (unless they are inheriting
+priorities) since their priorities are defined to be
+below the priority of any idle task.
+
+The effect of calling Get_Priority and Set_Priority on a Held task is the
+same as on any other task.
+
+Calling Hold on a held task or Continue on a non-held task has no effect.
+
address@hidden@;The rules affecting queuing are derived from the above rules, in
+addition to the normal priority rules:
address@hidden
+
+When a held task is on the ready queue, its priority is so low as to never
+reach the top of the queue as long as there are other tasks on that queue.
+
+If a task is executing in a protected action, inside a rendezvous, or is
+inheriting priorities from other sources (e.g. when activated), it
+continues to execute until it is no longer executing the corresponding
+construct.
+
+If a task becomes held while waiting (as a caller) for a rendezvous to
+complete, the active priority of the accepting task is not affected.
+
address@hidden,Kind=[Revised],Ref=[8652/0077],ARef=[AI95-00111-01]}
+If a task becomes held while waiting in a @nt{selective_accept},
+and address@hidden,Old=[]} entry call is issued to one of the open entries,
+the corresponding @address@hidden@!alternative}],Old=[accept body]}
+executes. When the rendezvous completes, the active
+priority of the accepting task is lowered to the held priority
+(unless it is still inheriting from other sources), and the task does
+not execute until another Continue.
+
+The same holds if the held task is the only task on a protected entry queue
+whose barrier becomes open. The corresponding entry body executes.
+
address@hidden
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00362-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Asynchronous_Task_Control is now Preelaborated,
+  so it can be used in preelaborated units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0077],ARef=[AI95-00111-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected to eliminate the
+  use of the undefined term @lquotes@;accept address@hidden@;.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00357-01]}
+  @ChgAdded{Version=[2],Text=[The description of held tasks was changed to
+  reflect that the calculation of active priorities depends on the
+  dispatching policy of the base priority. Thus, the policy of the held
+  priority was specified in order to avoid surprises (especially when using
+  the EDF policy).]}
address@hidden
+
+
address@hidden Optimizations and Determinism Rules}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} describes
+various requirements for
+improving the response and determinism in a real-time system.]
address@hidden
+
address@hidden
+
+If the implementation blocks interrupts (see @RefSecNum{Interrupt Support}) not
+as a result of direct user
+action (e.g. an execution of a protected action) there shall be an upper
+bound on the duration of this blocking.
address@hidden
+The implementation shall not allow itself to be interrupted when it is in a
+state where it is unable to support all the language-defined operations
+permitted in the execution of interrupt handlers.
+(see @RefSecNum{Protected Subprograms and Protected Actions}).
address@hidden
+
+The implementation shall recognize entry-less protected types.
+The overhead of acquiring the execution resource of an object of such a type
+(see @RefSecNum{Protected Subprograms and Protected Actions}) shall be
+minimized. In particular, there should not be any overhead due to evaluating
address@hidden @nt{condition}s.
address@hidden
+Ideally the overhead should just be a spin-lock.
address@hidden
+
+Unchecked_Deallocation shall be supported for terminated tasks that are
+designated by access types, and shall have the effect of releasing all
+the storage associated with the task. This includes any run-time system
+or heap storage that has been implicitly allocated for the task by the
+implementation.
+
address@hidden
+
address@hidden
+
+The implementation shall document the
+upper bound on the duration of interrupt blocking caused by the
+implementation. If this is different for different interrupts or
+interrupt priority levels, it should be documented for each case.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[The upper bound on the duration of interrupt blocking caused by
+the implementation.]}]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The upper bound on the duration of interrupt blocking caused by
+the implementation.]}]}
+
address@hidden
+
address@hidden
address@hidden@;The implementation shall document the following metric:
address@hidden
+The overhead associated with obtaining
+a mutual-exclusive access to an entry-less protected object. This shall be
+measured in the following way:
+
address@hidden@address@hidden@;For a protected object of the form:
address@hidden
address@hidden Lock @key{is}
+   @key{procedure} Set;
+   @Key{function} Read @Key{return} Boolean;
address@hidden
+   Flag : Boolean := False;
address@hidden Lock;
+
address@hidden body} Lock @key{is}
+   @key{procedure} Set @key{is}
+   @key{begin}
+      Flag := True;
+   @key{end} Set;
+   @Key{function} Read @Key{return} Boolean
+   @key{Begin}
+      @key{return} Flag;
+   @key{end} Read;
address@hidden Lock;
address@hidden
+
address@hidden@;The execution time, in processor clock cycles, of a call to
+Set. This shall be measured between the point just before
+issuing the call, and the point just after the call
+completes.
+The function Read shall be called later to verify that Set was indeed
+called (and not optimized away). The
+calling task shall have
+sufficiently high priority as to not be preempted during the measurement
+period. The protected object shall have sufficiently high ceiling priority
+to allow the task to call Set.
+
address@hidden@;For a multiprocessor, if supported, the metric shall be 
reported for the
+case where no contention (on the execution resource) exists
address@hidden tasks executing on other processors].
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The metrics for entry-less protected objects.]}]}
address@hidden
+
+
address@hidden,InitialVersion=[2],New=[The Ravenscar Profile],Old=[Run-time 
Profiles]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0246-1],ARef=[AI05-0299-1]}
address@hidden,address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]}
address@hidden,New=[defines the Ravenscar address@hidden,
+Old=[specifies a mechanism for defining run-time profiles.]}]]}
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 2
+and 3 were moved to @RefSec{Pragma Restrictions and Pragma 
Profile}.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0246-1]}
address@hidden,Type=[Leading],Keepnext=[T],address@hidden,New=[The
+form of a @nt{pragma} Profile is as follows:],Old=[]}]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden<Version=[3],InitialVersion=[2],@ChgDeleted{Version=[3],
address@hidden,address@hidden @prag<Profile> (@address@hidden {, 
@address@hidden);],Old=[]]'}>
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0246-1]}
address@hidden,Text=[The @address@hidden
address@hidden,New=[Ravenscar is a usage profile (see @RefSecNum{Pragma 
Restrictions and Pragma Profile}).
+For usage profile Ravenscar, there shall be no],Old=[shall be the name
+of a run-time profile. The semantics of any]}
address@hidden@address@hidden@address@hidden,New=[],Old=[
+are defined by
+the run-time profile specified by the @address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0246-1]}
address@hidden,Type=[Leading],address@hidden,New=[The
+usage profile Ravenscar is equivalent to the following set of
+pragmas:],Old=[A profile is equivalent to the set of configuration
+pragmas that is defined for each run-time profile.]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01],ARef=[AI95-00297-01],ARef=[AI95-00394-01],ARef=[AI05-0171-1],ARef=[AI05-0246-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0055-1],ARef=[AI12-0073-1]}
address@hidden,Text=[
address@hidden Task_Dispatching_Policy (FIFO_Within_Priorities);
address@hidden Locking_Policy (Ceiling_Locking);
address@hidden Detect_Blocking;
address@hidden Restrictions (
+              No_Abort_Statements,
+              address@hidden,New=[,
+              No_Dynamic_CPU_Assignment],Old=[]},
+              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,
+              Max_Entry_Queue_Length => 1,
+              Max_Protected_Entries => 1,
+              Max_Task_Entries => 0,
+              No_Dependence => Ada.Asynchronous_Task_Control,
+              No_Dependence => Ada.Calendar,
+              No_Dependence => Ada.Execution_Time.Group_Budgets,
+              No_Dependence => address@hidden,New=[,
+              No_Dependence => Ada.Synchronous_Barriers,],Old=[]}
+              No_Dependence => address@hidden,New=[,
+              No_Dependence => 
System.Multiprocessors.Dispatching_Domains],Old=[]});]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The Ravenscar profile is named for the location
+of the meeting that defined its initial version. The name is now in widespread
+use, so we stick with existing practice, rather than using a more descriptive
address@hidden This is another example of Ada's lousy marketing sense; casual
+readers, especially those outside of Ada, have no conception of what
address@hidden@;address@hidden@; is, and thus are much less likely to 
investigate
+it to find out how it can help them.}]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01]}
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0246-1]}
address@hidden,address@hidden,New=[],address@hidden pragma], Sec=(Profile)}
address@hidden, configuration], Sec=(Profile)}
+A @nt{pragma} Profile is a configuration pragma.
+There may be more than one @nt{pragma} Profile for a partition.]}]}
address@hidden
address@hidden
address@hidden,Noparanum=[T],address@hidden@i<Paragraph 7 was
+deleted.>address@hidden message should be deleted if the paragraphs
+are ever renumbered.}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0171-1],ARef=[AI05-0229-1]}
address@hidden,Kind=[Deleted],ARef=[AI12-0055-1]}
address@hidden,address@hidden,New=[],Old=[A task shall only be
+on the ready queues of one processor, and the
+processor to which a task belongs shall be defined statically.
+Whenever a task running on a processor reaches a task dispatching point,
+it goes back to the ready queues of the same processor. A task with
+a CPU value of Not_A_Specific_CPU will execute on an implementation
+defined processor. @Redundant[A task without a CPU aspect will activate and
+execute on the same processor as its activating task.]]}]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgRef{Version=[4],Kind=[DeletedNoDelMsg]}
+  @ChgAdded{Version=[3],address@hidden,New=[],Old=[The processor of a
+  task without a CPU aspect is defined in @RefSecNum{Multiprocessor 
Implementation}.]}]}
address@hidden
address@hidden@ChgImplDef{Version=[3],Kind=[Added],address@hidden,
+Text=[The processor on which a task with a CPU value of a Not_A_Specific_CPU
+will execute when the Ravenscar profile is in effect.]}]}}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0171-1]}
address@hidden,Text=[On a multiprocessor system, an implementation should
+support a fully partitioned approach. Each processor should have separate and
+disjoint ready queues.]}
+
address@hidden,Kind=[Added],address@hidden,
+Text=[On a multiprocessor system, each processor should have a separate
+and disjoint ready queue.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01],ARef=[AI05-0246-1]}
address@hidden,Text=[The effect of the Max_Entry_Queue_Length => 1
+restriction applies only to protected entry queues due to the accompanying
+restriction of Max_Task_Entries => 0.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0055-1]}
address@hidden,Text=[When the Ravenscar profile is in effect (via the
+effect of the No_Dynamic_CPU_Assignment restriction), all of the tasks in the
+partition will execute on a single CPU unless the programmer explicitly uses
+aspect CPU to specify the CPU assignments for tasks. The use of multiple CPUs
+requires care, as many guarantees of single CPU scheduling no longer apply.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0055-1]}
address@hidden,Text=[It is not recommended to specify the CPU of a task
+to be Not_A_Specific_CPU when the Ravenscar profile is in effect. How a
+partition executes strongly depends on the assignment of tasks to CPUs.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00249-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0246-1]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @Chg{Version=[3],New=[The Ravenscar profile is new; it was moved here by Ada
+  2012],address@hidden Profile is new]}.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0171-1]}
+  @ChgAdded{Version=[3],Text=[How Ravenscar behaves on a multiprocessor
+  system is now defined.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0073-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  The Ravenscar profile no longer allows the use of package 
Synchronous_Barriers,
+  as this package violates the fundamental Ravenscar requirement that each
+  waiting point can only block (and release) a single task. This is 
incompatible
+  with the published Ada 2012 standard, but it is unlikely that any existing
+  Ravenscar runtime ever usefully supported barriers.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0055-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:>The Ravenscar profile (via 
the
+  effect of the new restriction No_Dynamic_CPU_Assignment) no longer allows
+  setting the CPU aspect of a task to a non-static value. While this was
+  allowed, an implementation would have had to come up with a creative
+  interpretation of the Ada 2012 requirement to define the association of
+  tasks to processors statically. As such, the new check is more likely to
+  catch bugs than break a working program.]}
address@hidden
+
+
address@hidden the following to the previous subclause...
address@hidden@Comment{For printed RM Ada 2005}
address@hidden,Name=[The Ravenscar Profile]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]}
+defines the Ravenscar address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01]}
address@hidden,Text=[The @address@hidden
+Ravenscar is a run-time profile.
+For run-time profile Ravenscar, there shall be no
address@hidden@nt{pragma_argument_association}s.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01]}
address@hidden,Type=[Leading],Text=[The run-time profile
+Ravenscar is equivalent to the following set of pragmas:]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01],ARef=[AI95-00297-01],ARef=[AI95-00394-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0171-1]}
address@hidden,Text=[
address@hidden Task_Dispatching_Policy (FIFO_Within_Priorities);
address@hidden Locking_Policy (Ceiling_Locking);
address@hidden Detect_Blocking;
address@hidden Restrictions (
+              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,
+              Max_Entry_Queue_Length => 1,
+              Max_Protected_Entries => 1,
+              Max_Task_Entries => 0,
+              No_Dependence => Ada.Asynchronous_Task_Control,
+              No_Dependence => Ada.Calendar,
+              No_Dependence => Ada.Execution_Time.Group_Budgets,
+              No_Dependence => Ada.Execution_Time.Timers,
+              No_Dependence => address@hidden,New=[,
+              No_Dependence => 
System.Multiprocessors.Dispatching_Domains],Old=[]});]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The Ravenscar profile is named for the location
+of the meeting that defined its initial version. The name is now in widespread
+use, so we stick with existing practice, rather than using a more descriptive
address@hidden This is another example of Ada's lousy marketing sense; casual
+readers, especially those outside of Ada, have no conception of what
address@hidden@;address@hidden@; is, and thus are much less likely to 
investigate
+it to find out how it can help them.}]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0171-1]}
address@hidden,Text=[A task shall only be on the ready queues of one
+processor, and the
+processor to which a task belongs shall be defined statically.
+Whenever a task running on a processor reaches a task dispatching point,
+it goes back to the ready queues of the same processor. A task with
+a CPU value of Not_A_Specific_CPU will execute on an implementation
+defined processor. @Redundant[A task without a CPU aspect will activate and
+execute on the same processor as its activating task.]]}
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal]}
+  @ChgAdded{Version=[3],Text=[The processor of a task without an aspect CPU is
+  defined in @RefSecNum{Multiprocessor Implementation}.]}
address@hidden
address@hidden,Kind=[Added],address@hidden,
+Text=[The processor on which a task with a CPU value of a Not_A_Specific_CPU
+will execute when the Ravenscar profile is in effect.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0171-1]}
address@hidden,Text=[On a multiprocessor system, an implementation should
+support a fully partitioned approach. Each processor should have separate and
+disjoint ready queues.]}
+
address@hidden,Kind=[Added],address@hidden,
+Text=[On a multiprocessor system, each processor should have a separate
+and disjoint ready queue.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00249-01]}
address@hidden,Text=[
+The effect of the Max_Entry_Queue_Length => 1 restriction applies
+only to protected entry queues due to the accompanying restriction of
+Max_Task_Entries => 0.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00249-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The Ravenscar profile is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0171-1]}
+  @ChgAdded{Version=[3],Text=[How Ravenscar behaves on a multiprocessor
+  system is now defined.]}
address@hidden
+end commented out address@hidden of original Ravenscar}
+
+
address@hidden@Comment{For printed RM Ada 2005}
address@hidden,Name=[Execution Time]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+describes a language-defined package to measure execution time.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The following
+language-defined library package exists:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Task_Identification;
address@hidden Ada.Real_Time; @key{use} Ada.Real_Time;
address@hidden Ada.Execution_Time @address@hidden,Child=[Execution_Time]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{CPU_Time} @key{is private};
+   @AdaObjDefn{CPU_Time_First} : @key{constant} CPU_Time;
+   @AdaObjDefn{CPU_Time_Last}  : @key{constant} CPU_Time;
+   @AdaObjDefn{CPU_Time_Unit}  : @key{constant} := 
@RI{implementation-defined-real-number};
+   @AdaObjDefn{CPU_Tick} : @key{constant} Time_Span;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Clock}
+     (T : Ada.Task_Identification.Task_Id
+          := Ada.Task_Identification.Current_Task)
+     @key{return} CPU_Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "+"  (Left : CPU_Time; Right : 
Time_Span) @key{return} CPU_Time;
+   @key{function} "+"  (Left : Time_Span; Right : CPU_Time) @key{return} 
CPU_Time;
+   @key{function} "-"  (Left : CPU_Time; Right : Time_Span) @key{return} 
CPU_Time;
+   @key{function} "-"  (Left : CPU_Time; Right : CPU_Time)  @key{return} 
Time_Span;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} "<"  (Left, Right : CPU_Time) 
@key{return} Boolean;
+   @key{function} "<=" (Left, Right : CPU_Time) @key{return} Boolean;
+   @key{function} ">"  (Left, Right : CPU_Time) @key{return} Boolean;
+   @key{function} ">=" (Left, Right : CPU_Time) @key{return} Boolean;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Split}
+     (T : @key{in} CPU_Time; SC : @key{out} Seconds_Count; TS : @key{out} 
Time_Span);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Time_Of} (SC : Seconds_Count;
+                     TS : Time_Span := Time_Span_Zero) @key{return} CPU_Time;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0170-1]}
address@hidden,Text=[   @AdaObjDefn{Interrupt_Clocks_Supported} : 
@key[constant] Boolean := @RI<implementation-defined>;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0170-1]}
address@hidden,Text=[   @AdaObjDefn{Separate_Interrupt_Clocks_Supported} : 
@key[constant] Boolean :=
+     @RI<implementation-defined>;]}
+
address@hidden,Kind=[Added],ARef=[AI05-0170-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Clock_For_Interrupts} 
@key[return] CPU_Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   ... -- @RI[not specified by the language]
address@hidden Ada.Execution_Time;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0170-1],ARef=[AI05-0269-1]}
address@hidden,address@hidden time],Sec=[of a task]}
address@hidden time],Sec=[of a task]}
+The @i<execution time> or CPU time of a given task is defined as the time 
spent by
+the system executing that task, including the time spent executing run-time or
+system services on its behalf. The mechanism used to measure execution time is
+implementation defined. @Chg{Version=[3],New=[The Boolean constant 
Interrupt_Clocks_Supported is
+set to True if the implementation separately accounts for the execution time
+of interrupt handlers. If it is set to False it],Old=[It]} is implementation
+defined which task, if any, is charged the execution time that is consumed by
+interrupt address@hidden,New=[. The Boolean constant
+Separate_Interrupt_Clocks_Supported is set to True if the implementation
+separately accounts for the execution time of individual interrupt
+handlers (see @RefSecNum{Execution Time of Interrupt Handlers})],Old=[ and
+run-time services on behalf of the system]}.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The implementation-defined properties above
+  and of the values declared in the package are repeated in @DocReqTitle,
+  so we don't mark them as implementation-defined.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[The type CPU_Time represents the execution time of
+a task. The set of values of this type corresponds one-to-one with an
+implementation-defined range of mathematical integers.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[The CPU_Time value I represents the half-open
+execution-time interval that starts with I*CPU_Time_Unit and is limited by
+(I+1)*CPU_Time_Unit, where CPU_Time_Unit is an implementation-defined
+real number. For each task, the execution time value is set to zero at
+the creation of the task.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Since it is implementation-defined which task
+  is charged execution time for system services, the execution time value
+  may become nonzero even before the start of the activation of the task.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[CPU_Time_First and CPU_Time_Last are the smallest
+and largest values of the CPU_Time type, respectively.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0170-1]}
address@hidden,Text=[The execution time value for the
+function Clock_For_Interrupts is initialized to zero.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,address@hidden clock tick}
+CPU_Time_Unit is the smallest amount of execution time representable
+by the CPU_Time type; it is expressed in seconds. A @i<CPU clock tick> is an
+execution time interval during which the clock value (as observed by
+calling the Clock function) remains constant. CPU_Tick is the average
+length of such intervals.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[The effects of the operators on CPU_Time and
+Time_Span are as for the operators defined for integer types.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[The function Clock returns the current execution
+time of the task identified by T; Tasking_Error is raised if that task has
+terminated; Program_Error is raised if the value of T is
+Task_Identification.Null_Task_Id.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[The effects of the Split and Time_Of operations are 
defined as
+follows, treating values of type CPU_Time, Time_Span, and
+Seconds_Count as mathematical integers. The effect of Split (T, SC,
+TS) is to set SC and TS to values such that T*CPU_Time_Unit = SC*1.0 +
+TS*CPU_Time_Unit, and 0.0 <= TS*CPU_Time_Unit < 1.0. The value
+returned by Time_Of(SC,TS) is the execution-time value T such that
+T*CPU_Time_Unit=SC*1.0 + TS*CPU_Time_Unit.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0170-1]}
address@hidden,Text=[The function Clock_For_Interrupts returns the total
+cumulative time spent executing within all interrupt handlers. This time is not
+allocated to any task execution time clock. If Interrupt_Clocks_Supported is 
set
+to False the function raises Program_Error.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,address@hidden(erroneous execution),Sec=(cause)}
+For a call of Clock, if the task identified by T no longer exists, the
+execution of the program is erroneous.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[The range of CPU_Time values shall be sufficient
+to uniquely represent the range of execution times from the task start-up to 50
+years of execution time later. CPU_Tick shall be no greater than 1
+millisecond.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[The implementation shall document the values of
+CPU_Time_First, CPU_Time_Last, CPU_Time_Unit, and CPU_Tick.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The values of CPU_Time_First, CPU_Time_Last, CPU_Time_Unit, and CPU_Tick
+of package Execution_Time.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[The implementation shall document the properties of
+the underlying mechanism used to measure execution times, such as the range of
+values supported and any relevant aspects of the underlying hardware or
+operating system facilities used.]}
address@hidden,Kind=[Revised],InitialVersion=[2],
address@hidden,
+Text=[The properties of the mechanism used to implement
+package address@hidden,New=[,
+including the values of the constants defined in the package],Old=[]}.]}]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The implementation
+shall document the following metrics:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text={An upper bound on the execution-time duration of a
+clock tick. This is a value D such that if t1 and t2 are any execution times of
+a given task such that t1 < t2 and address@hidden = address@hidden then
+t2 @en@; t1 <= D.}}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[An upper bound on the size of a clock jump. A clock
+jump is the difference between two successive distinct values of an
+execution-time clock (as observed by calling the Clock function with the same
+Task_Id).]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[An upper bound on the execution time of a call to
+the Clock function, in processor clock cycles.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Upper bounds on the execution times of the
+operators of the type CPU_Time, in processor clock cycles.]}
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The metrics for execution time.]}]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[Implementations targeted to machines with word size
+smaller than 32 bits need not support the full range and granularity of the
+CPU_Time type.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[When appropriate, implementations should provide
+configuration mechanisms to change the value of CPU_Tick.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[When appropriate, implementations should provide
+configuration mechanisms to change the value of Execution_Time.CPU_Tick.]}]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00307-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The package Execution_Time is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0170-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  Function Clock_For_Interrupts, and constants Interrupt_Clocks_Supported and
+  Separate_Interrupt_Clocks_Supported are added to Execution_Time.
+  If Execution_Time is referenced in a @nt{use_clause}, and an
+  entity @i<E> with a @nt{defining_identifier} of one of the added entities
+  is defined in a package that is also referenced in a @nt{use_clause}, the 
entity
+  @i<E> may no longer be use-visible, resulting in errors. This should be rare
+  and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0170-1]}
+  @ChgAdded{Version=[3],Text=[If Interrupt_Clocks_Supported is True, it is
+  now possible to determine the execution time of interrupt handlers. This
+  is not an inconsistency, as not charging any task for such time was a
+  legitimate implementation for Ada 2005.]}
address@hidden
+
+
address@hidden,Name=[Execution Time Timers]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+describes a language-defined package
+that provides a facility for calling a handler when a task has used a defined
+amount of CPU time.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The following
+language-defined library package exists:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden System;
address@hidden Ada.Execution_Time.Timers @address@hidden,Child=[Timers]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Timer} (T : @key{not null 
access constant}
+                       Ada.Task_Identification.Task_Id) @key{is}
+      @key{tagged limited private};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{type} @AdaTypeDefn{Timer_Handler} @key{is}
+      @key{access protected procedure} (TM : @key{in out} Timer);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{Min_Handler_Ceiling} : @key{constant} 
System.Any_Priority :=
+   @RI[implementation-defined];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} @AdaSubDefn{Set_Handler} (TM      : 
@key{in out} Timer;
+                          In_Time : @key{in} Time_Span;
+                          Handler : @key{in} Timer_Handler);
+   @key{procedure} @AdaSubDefn{Set_Handler} (TM      : @key{in out} Timer;
+                          At_Time : @key{in} CPU_Time;
+                          Handler : @key{in} Timer_Handler);
+   @key{function} @AdaSubDefn{Current_Handler} (TM : Timer) @key{return} 
Timer_Handler;
+   @key{procedure} @AdaSubDefn{Cancel_Handler} (TM        : @key{in out} Timer;
+                             Cancelled :    @key{out} Boolean);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{function} @AdaSubDefn{Time_Remaining} (TM : Timer) 
@key{return} Time_Span;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaExcDefn{Timer_Resource_Error} : @key{exception};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   ... -- @RI{not specified by the language}
address@hidden Ada.Execution_Time.Timers;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[The type Timer represents an execution-time event
+for a single task and is capable of detecting execution-time overruns. The
+access discriminant T identifies the task concerned. The type Timer needs
+finalization (see @RefSecNum{Assignment and Finalization}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[An object of type Timer is said to be @i<set> if it
+is associated with a nonnull value of type Timer_Handler and @i<cleared>
+otherwise. All Timer objects are initially cleared.
address@hidden,Sec=[execution timer object]}
address@hidden,Sec=[execution timer object]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[The type Timer_Handler identifies a protected
+procedure to be executed by the implementation when the timer expires. Such a
+protected procedure is called a @i<handler>.
address@hidden,Sec=[execution timer]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Type Timer is tagged. This makes it possible to
+  share a handler between several events. In simple cases, 'Access can be used
+  to compare the parameter with a specific timer object (this works because a
+  tagged type is a by-reference type). In more complex cases, a type extension
+  of type Timer can be declared; a double type conversion can be used to access
+  the extension data. An example of how this can be done can be found for the
+  similar type Timing_Event, see @RefSecNum{Timing Events}.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[When a Timer object is created, or upon the first
+call of a Set_Handler procedure with the timer as parameter, the resources
+required to operate an execution-time timer based on the associated
+execution-time clock are allocated and initialized. If this operation would
+exceed the available resources, Timer_Resource_Error is raised.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The procedures Set_Handler associate the handler
+Handler with the timer address@hidden,New=[:],Old=[;]}
+if Handler is @key[null], the timer is address@hidden,New=[;],Old=[,]}
address@hidden,New=[,],Old=[]} it is set. The first procedure
+Set_Handler loads the timer TM with an interval specified by the Time_Span
+parameter. In this mode, the timer TM @i<expires> when the execution time of 
the
+task identified by address@hidden has increased by In_Time; if In_Time is less
+than or equal to zero, the timer expires immediately. The second procedure
+Set_Handler loads the timer TM with the absolute value specified by At_Time. In
+this mode, the timer TM expires when the execution time of the task identified
+by address@hidden reaches At_Time; if the value of At_Time has already been
+reached when Set_Handler is called, the timer expires
address@hidden, Sec=[execution timer]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Since an access-to-constant can designate a
+  variable, the Task_Id value designated by the discriminant of a Timer
+  object can be changed after the object is created. Thus, an implementation
+  cannot use the value of the Task_Id other than where this Standard specifies.
+  For instance, the Task_Id should be read when the timer is set, but it
+  should not be used when the timer expires (as it may designate a different
+  task at that point).]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[A call of a procedure Set_Handler for a timer that
+is already set replaces the handler and the (absolute or relative) execution
+time; if Handler is not @b<null>, the timer remains set.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[When a timer expires, the associated handler is
+executed, passing the timer as parameter. The initial action of the execution
+of the handler is to clear the event.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The function Current_Handler returns the handler
+associated with the timer TM if that timer is set;
address@hidden,New=[,],Old=[]} it returns @b<null>.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The procedure Cancel_Handler clears the timer if it
+is set. Cancelled is assigned True if the timer was set prior to it being
+cleared; address@hidden,New=[,],Old=[]}
+it is assigned False.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The function Time_Remaining returns the execution
+time interval that remains until the timer TM would expire, if that timer is
+set; address@hidden,New=[,],Old=[]} it returns Time_Span_Zero.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[The constant Min_Handler_Ceiling is the
+minimum ceiling priority required for a protected object with a handler to
+ensure that no ceiling violation will occur when that handler is invoked.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[As part of the finalization of an object of type
+Timer, the timer is cleared.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[For all the subprograms defined in this package,
+Tasking_Error is raised if the task identified by address@hidden has 
terminated, and
+Program_Error is raised if the value of address@hidden is
+Task_Identification.Null_Task_Id.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[An exception propagated from a handler invoked as
+part of the expiration of a timer has no effect.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,address@hidden(erroneous execution),Sec=(cause)}
+For a call of any of the subprograms defined in this package, if the task
+identified by address@hidden no longer exists, the execution of the program is
+erroneous.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[For a given Timer object, the implementation shall
+perform the operations declared in this package atomically with respect to any
+of these operations on the same Timer object. The replacement of a handler by a
+call of Set_Handler shall be performed atomically with respect to the execution
+of the handler.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This prevents various race conditions. In
+  particular it ensures that if an event occurs when Set_Handler is changing
+  the handler then either the new or old handler is executed in response to the
+  appropriate event. It is never possible for a new handler to be executed in
+  response to an old event]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[When an object of type Timer is finalized, the
+system resources used by the timer shall be deallocated.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[Implementations may limit the number of timers that
+can be defined for each task. If this limit is address@hidden,New=[,],Old=[]}
+then Timer_Resource_Error is raised.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00307-01]}
address@hidden,Text=[A Timer_Handler can be associated with several
+Timer objects.]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00307-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The package Execution_Time.Timers is new.]}
address@hidden
+
+
address@hidden@Comment{For printed RM Ada 2005}
address@hidden@Comment{For ISO version of Ada 2012 Standard}
address@hidden,Name=[Group Execution Time Budgets]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+describes a language-defined package to
+assign execution time budgets to groups of tasks.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The following
+language-defined library package exists:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0169-1]}
address@hidden,address@hidden System;@Chg{Version=[3],New=[
address@hidden System.Multiprocessors;],Old=[]}
address@hidden Ada.Execution_Time.Group_Budgets 
@address@hidden,Child=[Group_Budgets]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0092-1],ARef=[AI05-0169-1]}
address@hidden,Text=[  @key{type} @address@hidden,New=[(CPU : 
System.Multiprocessors.CPU :=
+                             System.Multiprocessors.CPU'First)
+   ],Old=[]} @key{is tagged limited private};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[  @key{type} @AdaTypeDefn{Group_Budget_Handler} @key{is 
access}
+       @key{protected procedure} (GB : @key{in out} Group_Budget);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[  @key{type} @AdaTypeDefn{Task_Array} @key{is array} 
(Positive @key{range} <>) @key{of}
+                                  Ada.Task_Identification.Task_Id;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[  @AdaObjDefn{Min_Handler_Ceiling} : @key{constant} 
System.Any_Priority :=
+    @RI[implementation-defined];]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The value of Min_Handler_Ceiling in Execution_Time.Group_Budgets.]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[  @key{procedure} @AdaSubDefn{Add_Task} (GB : @key{in out} 
Group_Budget;
+                      T  : @key{in} Ada.Task_Identification.Task_Id);
+  @key{procedure} @AdaSubDefn{Remove_Task} (GB: @key{in out} Group_Budget;
+                         T  : @key{in} Ada.Task_Identification.Task_Id);
+  @key{function} @AdaSubDefn{Is_Member} (GB : Group_Budget;
+                      T : Ada.Task_Identification.Task_Id) @key{return} 
Boolean;
+  @key{function} @AdaSubDefn{Is_A_Group_Member}
+     (T : Ada.Task_Identification.Task_Id) @key{return} Boolean;
+  @key{function} @AdaSubDefn{Members} (GB : Group_Budget) @key{return} 
Task_Array;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[  @key{procedure} @AdaSubDefn{Replenish} (GB : @key{in 
out} Group_Budget; To : @key{in} Time_Span);
+  @key{procedure} @AdaSubDefn{Add} (GB : @key{in out} Group_Budget; Interval : 
@key{in} Time_Span);
+  @key{function} @AdaSubDefn{Budget_Has_Expired} (GB : Group_Budget) 
@key{return} Boolean;
+  @key{function} @AdaSubDefn{Budget_Remaining} (GB : Group_Budget) 
@key{return} Time_Span;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[  @key{procedure} @AdaSubDefn{Set_Handler} (GB      : 
@key{in out} Group_Budget;
+                         Handler : @key{in} Group_Budget_Handler);
+  @key{function} @AdaSubDefn{Current_Handler} (GB : Group_Budget)
+     @key{return} Group_Budget_Handler;
+  @key{procedure} @AdaSubDefn{Cancel_Handler} (GB        : @key{in out} 
Group_Budget;
+                            Cancelled : @key{out} Boolean);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[  @AdaExcDefn{Group_Budget_Error} : @key{exception};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+    --  @RI{not specified by the language}
address@hidden Ada.Execution_Time.Group_Budgets;]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[The type Group_Budget represents an execution time
+budget to be used by a group of tasks. The type Group_Budget
+needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization}). A task can belong
+to at most one group. Tasks of any priority can be added to a group.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[An object of type Group_Budget has an associated
+nonnegative value of type Time_Span known as its @i<budget>, which is
+initially Time_Span_Zero. The type Group_Budget_Handler identifies a protected
+procedure to be executed by the implementation when the budget is
address@hidden<exhausted>, that is, reaches zero. Such a protected procedure is 
called a
address@hidden<handler>address@hidden@Defn2{Term=[exhaust],Sec=[a budget]}
address@hidden,Sec=[group budget]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[An object of type Group_Budget also includes a
+handler, which is a value of type Group_Budget_Handler. The handler of the
+object is said to be @i<set> if it is not null and @i<cleared> otherwise. The
+handler of all Group_Budget objects is initially cleared.
address@hidden,Sec=[group budget object]}
address@hidden,Sec=[group budget object]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]} @ChgAdded{Version=[2],Text=[Type
+  Group_Budget is tagged. This makes it possible to share a handler between
+  several events. In simple cases, 'Access can be used to compare the parameter
+  with a specific group budget object (this works because a tagged type is a
+  by-reference type). In more complex cases, a type extension of type
+  Group_Budget can be declared; a double type conversion can be used to access
+  the extension data. An example of how this can be done can be found for the
+  similar type Timing_Event, see @RefSecNum{Timing Events}.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[The procedure Add_Task adds the task identified by
+T to the group GB; if that task is already a member of some other group,
+Group_Budget_Error is raised.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[The procedure Remove_Task removes the task
+identified by T from the group GB; if that task is not a member of the group
+GB, Group_Budget_Error is raised. After successful execution of this procedure,
+the task is no longer a member of any group.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The function Is_Member returns True if the task
+identified by T is a member of the group GB;
address@hidden,New=[,],Old=[]} it
address@hidden,New=[returns],Old=[return]} False.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The function Is_A_Group_Member returns True if the
+task identified by T is a member of some group;
address@hidden,New=[,],Old=[]} it returns False.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[The function Members returns an array of values of
+type Task_Identification.Task_Id identifying the members of the group GB. The
+order of the components of the array is unspecified.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0092-1],ARef=[AI05-0169-1]}
address@hidden,Text=[The procedure Replenish loads the group budget GB
+with To as the Time_Span value. The exception Group_Budget_Error is raised if
+the Time_Span value To is nonpositive. Any execution @Chg{Version=[3],New=[on
+CPU ],Old=[]}of any member of the
+group of tasks results in the budget counting down, unless exhausted. When the
+budget becomes exhausted (reaches Time_Span_Zero), the associated handler is
+executed if the handler of group budget GB is set. Nevertheless, the tasks
+continue to execute.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[The procedure Add modifies the budget of the group
+GB. A positive value for Interval increases the budget. A negative value for
+Interval reduces the budget, but never below Time_Span_Zero. A zero value for
+Interval has no effect. A call of procedure Add that results in the value of
+the budget going to Time_Span_Zero causes the associated handler to be executed
+if the handler of the group budget GB is set.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The function Budget_Has_Expired returns True if the
+budget of group GB is exhausted (equal to Time_Span_Zero);
address@hidden,New=[,],Old=[]} it returns False.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[The function Budget_Remaining returns the remaining
+budget for the group GB. If the budget is exhausted it returns Time_Span_Zero.
+This is the minimum value for a budget.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The procedure Set_Handler associates the handler
+Handler with the Group_Budget address@hidden,New=[:],Old=[;]}
+if Handler is @b<null>, the handler of
+Group_Budget is address@hidden,New=[;],Old=[,]}
address@hidden,New=[,],Old=[]} it is set.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[A call of Set_Handler for a Group_Budget that
+already has a handler set replaces the handler; if Handler is not @b<null>, the
+handler for Group_Budget remains set.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The function Current_Handler returns the handler
+associated with the group budget GB if the handler for that group budget is
+set; address@hidden,New=[,],Old=[]} it returns @b<null>.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The procedure Cancel_Handler clears the handler for
+the group budget if it is set. Cancelled is assigned True if the handler for
+the group budget was set prior to it being cleared;
address@hidden,New=[,],Old=[]} it is assigned False.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[The constant Min_Handler_Ceiling is the
+minimum ceiling priority required for a protected object with a handler to
+ensure that no ceiling violation will occur when that handler is invoked.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[The precision of the accounting of task execution
+time to a Group_Budget is the same as that defined for execution-time clocks
+from the parent package.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[As part of the finalization of an object of type
+Group_Budget all member tasks are removed from the group identified by that
+object.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[If a task is a member of a Group_Budget when it
address@hidden,New=[,],Old=[]} then
+as part of the finalization of the task it is removed from the group.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[For all the operations defined in this package,
+Tasking_Error is raised if the task identified by T has terminated, and
+Program_Error is raised if the value of T is
+Task_Identification.Null_Task_Id.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[An exception propagated from a handler invoked when
+the budget of a group of tasks becomes exhausted has no effect.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,address@hidden(erroneous execution),Sec=(cause)}
+For a call of any of the subprograms defined in this package, if the task
+identified by T no longer exists, the execution of the program is erroneous.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[For a given Group_Budget object, the implementation
+shall perform the operations declared in this package atomically with respect
+to any of these operations on the same Group_Budget object. The replacement of
+a handler, by a call of Set_Handler, shall be performed atomically with respect
+to the execution of the handler.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This prevents various race conditions. In
+  particular it ensures that if the budget is exhausted when Set_Handler
+  is changing the handler then either the new or old handler is executed
+  and the exhausting event is not lost.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[Clearing or setting of the handler of a group
+budget does not change the current value of the budget. Exhaustion or loading
+of a budget does not change whether the handler of the group budget is set or
+cleared.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00354-01]}
address@hidden,Text=[A Group_Budget_Handler can be associated with
+several Group_Budget objects.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00354-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The package Execution_Time.Group_Budgets is new.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0169-1]}
address@hidden,address@hidden with Ada 2005}
+A Group_Budget is now defined to work on a single processor.
+If an implementation managed to make this package work for
+programs running on a multiprocessor system, and a program
+depends on that fact, it could fail when ported to Ada 2012.
+We believe it is unlikely that such an implementation exists
+because of the difficulty of signalling other processors when
+the time reaches zero; in any case, depending on such an
+implementation is not portable.]}
address@hidden
+
+
address@hidden,Name=[Execution Time of Interrupt Handlers]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0170-1]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+describes a language-defined package to
+measure the execution time of interrupt handlers.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0170-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The following
+language-defined library package exists:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Interrupts;
address@hidden Ada.Execution_Time.Interrupts @address@hidden,Child=[Interrupts]}
+   @key{function} @AdaSubDefn{Clock} (Interrupt : Ada.Interrupts.Interrupt_Id)
+        @key{return} CPU_Time;
+   @key{function} @AdaSubDefn{Supported} (Interrupt : 
Ada.Interrupts.Interrupt_Id)
+        @key{return} Boolean;
address@hidden Ada.Execution_Time.Interrupts;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0170-1]}
address@hidden,Text=[The execution time or CPU time of a given interrupt
+Interrupt is defined as the time spent by the system executing interrupt
+handlers identified by Interrupt, including the time spent executing run-time 
or
+system services on its behalf. The mechanism used to measure execution time is
+implementation defined. Time spent executing interrupt handlers is distinct 
from
+time spent executing any task.]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The implementation-defined mechanism here is the
+same as that covered by the @DocReqTitle of @RefSecNum{Execution Time}, so we
+don't repeat that requirement here.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0170-1]}
address@hidden,Text=[For each interrupt, the execution time value
+is initially set to zero.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0170-1]}
address@hidden,Text=[The function Clock returns the current cumulative
+execution time of the interrupt identified by Interrupt. If
+Separate_Interrupt_Clocks_Supported is set to False the function raises
+Program_Error.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0170-1],ARef=[AI05-0264-1]}
address@hidden,Text=[The function Supported returns True if the
+implementation is monitoring the execution time of the interrupt identified by
+Interrupt; otherwise, it returns False. For any Interrupt_Id Interrupt for 
which
+Supported(Interrupt) returns False, the function Clock(Interrupt) will return a
+value equal to Ada.Execution_Time.Time_Of(0).]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0170-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The package Execution_Time.Interrupts is new.]}
address@hidden
+
+
address@hidden,Name=[Timing Events]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+describes a language-defined package to
+allow user-defined protected procedures to be executed at a specified time
+without the need for a task or a delay statement.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The following
+language-defined library package exists:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Real_Time.Timing_Events 
@address@hidden,Child=[Timing_Events]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[  @key{type} @AdaTypeDefn{Timing_Event} @key{is tagged 
limited private};
+  @key{type} @AdaTypeDefn{Timing_Event_Handler}
+       @key{is access protected procedure} (Event : @key{in out} 
Timing_Event);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[  @key{procedure} @AdaSubDefn{Set_Handler} (Event   : 
@key{in out} Timing_Event;
+                         At_Time : @key{in} Time;
+                         Handler : @key{in} Timing_Event_Handler);
+  @key{procedure} @AdaSubDefn{Set_Handler} (Event   : @key{in out} 
Timing_Event;
+                         In_Time : @key{in} Time_Span;
+                         Handler : @key{in} Timing_Event_Handler);
+  @key{function} @AdaSubDefn{Current_Handler} (Event : Timing_Event)
+       @key{return} Timing_Event_Handler;
+  @key{procedure} @AdaSubDefn{Cancel_Handler} (Event     : @key{in out} 
Timing_Event;
+                            Cancelled : @key{out} Boolean);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[  @key{function} @AdaSubDefn{Time_Of_Event} (Event : 
Timing_Event) @key{return} Time;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+  ... -- @RI[not specified by the language]
address@hidden Ada.Real_Time.Timing_Events;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Text=[The type Timing_Event represents a time in the future
+when an event is to occur. The type Timing_Event
+needs address@hidden<needs finalization>,Sec=<language-defined type>}
+(see @RefSecNum{Assignment and Finalization}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Text=[An object of type Timing_Event is said to be
address@hidden<set> if it is associated with a nonnull value of type 
Timing_Event_Handler
+and @i<cleared> otherwise. All Timing_Event objects are initially cleared.
address@hidden,Sec=[timing event object]}
address@hidden,Sec=[timing event object]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Text=[The type Timing_Event_Handler identifies a
+protected procedure to be executed by the implementation when the timing event
+occurs. Such a protected procedure is called a @i{handler}.
address@hidden,Sec=[timing event]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Type=[Leading],Text=[Type Timing_Event is tagged. This
+  makes it possible to share a handler between several events. In simple cases,
+  'Access can be used to compare the parameter with a specific timing event
+  object (this works because a tagged type is a by-reference type). In more
+  complex cases, a type extension of type Timing_Event can be declared; a
+  double type conversion can be used to access the extension data. For
+  example:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Toaster_Timing_Event @key{is new} Timing_Event 
@key{with record}
+   Slot : Natural;
address@hidden record};]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[...]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden body} Toaster @key{is}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key{procedure} Timer (Event : @key{in out} 
Timing_Event) @key{is}
+   @key{begin}
+      Pop_Up_Toast (Toaster_Timing_Event(Timing_Event'Class(Event)).Slot);
+   @key{end} Timer;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   ...
address@hidden Toaster;]}
address@hidden
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The extra conversion to the class-wide type
+  is necessary to make the conversions legal. While this usage is clearly
+  ugly, we think that the need for this sort of usage will be rare, so
+  we can live with it. It's certainly better than having no way to associate
+  data with an event.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The procedures Set_Handler associate the handler
+Handler with the event address@hidden,New=[:],Old=[;]} if Handler
+is @key{null}, the event is address@hidden,New=[;],Old=[,]}
address@hidden,New=[,],Old=[]} it is set. The first procedure
+Set_Handler sets the execution time for the event to be At_Time. The second
+procedure Set_Handler sets the execution time for the event to be
+Real_Time.Clock + In_Time.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Text=[A call of a procedure Set_Handler for an event that
+is already set replaces the handler and the time of execution; if Handler is
+not @key{null}, the event remains set.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Text=[As soon as possible after the time set for the
+event, the handler is executed, passing the event as parameter. The handler is
+only executed if the timing event is in the set state at the time of execution.
+The initial action of the execution of the handler is to clear the event.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The second sentence of this paragraph is because
+  of a potential race condition. The time might expire and yet before the
+  handler is executed, some task could call Cancel_Handler (or equivalently
+  call Set_Handler with a @key{null} parameter) and thus clear the handler.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Text=[If the Ceiling_Locking policy (see
address@hidden Ceiling Locking}) is in effect when a procedure
+Set_Handler is called, a check is made that the ceiling priority of
address@hidden is Interrupt_Priority'Last. If the check fails, Program_Error
+is raised.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0094-1],ARef=[AI05-0264-1]}
address@hidden,Text=[If a procedure Set_Handler is called with zero or
+negative In_Time or with At_Time indicating a time in the
address@hidden,New=[,],Old=[]} then the handler
+is executed @Chg{Version=[3],New=[as soon as possible after the completion of],
+Old=[immediately by the task executing]} the call of address@hidden,
+New=[],Old=[ The timing event Event is cleared.]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0094-1]}
address@hidden,Text=[The handler will still be executed. Under no
+circumstances is a scheduled call of a handler lost.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0094-1]}
address@hidden,Text=[We say @ldquote@;as soon as address@hidden
+so that we do not deadlock if we are executing the handler when Set_Handler is
+called. In that case, the current invocation of the handler must complete
+before the new handler can start executing.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The function Current_Handler returns the handler
+associated with the event Event if that event is set;
address@hidden,New=[,],Old=[]} it returns @key{null}.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The procedure Cancel_Handler clears the event if it
+is set. Cancelled is assigned True if the event was set prior to it being
+cleared; address@hidden,New=[,],Old=[]} it is assigned False.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The function Time_Of_Event returns the time of the
+event if the event is set;
address@hidden,New=[,],Old=[]} it returns Real_Time.Time_First.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Text=[As part of the finalization of an object
+of type Timing_Event, the Timing_Event is cleared.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is the only finalization defined by the
+  language that has a visible effect; but an implementation may have other
+  finalization that it needs to perform. Implementations need to ensure that
+  the event is cleared before anything else is finalized that would prevent
+  a set event from being triggered.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Text=[If several timing events are set for the same time,
+they are executed in FIFO order of being set.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Text=[An exception propagated from a handler invoked by a
+timing event has no effect.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Text=[For a given Timing_Event object, the implementation
+shall perform the operations declared in this package atomically with respect
+to any of these operations on the same Timing_Event object. The replacement of
+a handler by a call of Set_Handler shall be performed atomically with respect
+to the execution of the handler.]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This prevents various race conditions. In
+  particular it ensures that if an event occurs when Set_Handler is changing
+  the handler then either the new or old handler is executed in response to the
+  appropriate event. It is never possible for a new handler to be executed in
+  response to an old event.]}
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Type=[Leading],Text=[The implementation shall document
+the following metric:]}
address@hidden
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0210-1]}
address@hidden,Text=[An upper bound on the lateness of the execution of
+a handler. That is, the maximum time between @Chg{Version=[3],New=[the time 
specified
+for the event and ],Old=[]}when a handler is actually
address@hidden,New=[invoked assuming no other handler or task is executing
+during this interval],Old=[executed and the time specified when the event was
+set]}.]}
+
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The metrics for timing events.]}]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Text=[The protected handler procedure should be executed
+directly by the real-time clock interrupt mechanism.]}
+
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[For a timing event, the handler should be executed directly by the
+real-time clock interrupt mechanism.]}]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Text=[Since a call of Set_Handler is not a potentially
+blocking operation, it can be called from within a handler.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00297-01]}
address@hidden,Text=[A Timing_Event_Handler can be associated with several
+Timing_Event objects.]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00297-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  The package Real_Time.Timing_Events is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0094-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Reworded to eliminate a
+  deadlock condition if the event time is in the past and a handler is 
currently
+  executing. This is technically an inconsistency, but only if a program is
+  depending on deadlocking; since it is impossible to imagine how that could
+  be useful, we have not documented this as an inconsistency.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0210-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Clarified the metric for 
lateness
+  of a timing event to exclude interference from other handlers and tasks.
+  This change might change the documentation of an implementation, but not
+  the implementation itself, so there is no inconsistency.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,Name=[Multiprocessor Implementation]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0171-1]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+allows implementations on multiprocessor platforms to be configured.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0171-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The following
+language-defined library package exists:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden System.Multiprocessors 
@address@hidden,Child=[Multiprocessors]}
+   @key[pragma] Preelaborate(Multiprocessors);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{CPU_Range} @key[is range] 0 .. 
@RI<implementation-defined>;
+   @AdaObjDefn{Not_A_Specific_CPU} : @key[constant] CPU_Range := 0;
+   @key[subtype] @AdaSubtypeDefn{Name=[CPU],Of=[CPU_Range]} @key[is] CPU_Range 
@key[range] 1 .. CPU_Range'Last;]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The value of CPU_Range'Last in System.Multiprocessors.]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Number_Of_CPUs} @key[return] 
CPU;
address@hidden System.Multiprocessors;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0171-1]}
address@hidden,Text=[A call of Number_Of_CPUs returns the number of
+processors available to the program. Within a given partition, each call on
+Number_Of_CPUs will return the same value.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[For a task type (including the
+anonymous type of a @nt{single_task_declaration}) or subprogram, the following
+language-defined representation aspect may be specified:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden aspect CPU is an @nt{expression},
+which shall be of type address@hidden
+
address@hidden,Kind=[AddedNormal],Aspect=[CPU],
+  address@hidden,Text=[Processor on which a given task should
+    run.]}]}
+
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0171-1],ARef=[AI05-0229-1]}
address@hidden,Text=[If the CPU aspect is specified for a subprogram,
+the @nt{expression} shall be static.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0229-1]}
address@hidden,Text=[The CPU aspect shall not be specified on a task
+interface type.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0171-1],ARef=[AI05-0229-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0081-1]}
address@hidden,Text=[The @nt{expression} specified for the CPU aspect
+of a address@hidden,New=[ type],Old=[]} is evaluated
address@hidden,New=[],Old=[for ]}each
address@hidden,New=[time an],Old=[task]} object
address@hidden,New=[of the task type is created ],Old=[]}(see
address@hidden Units and Task Objects}). The CPU value is then associated with
+the task address@hidden,New=[],Old=[ whose task declaration specifies
+the aspect]}.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0171-1],ARef=[AI05-0229-1]}
address@hidden,Text=[The CPU aspect has no effect if it is specified for
+a subprogram other than the main subprogram;
+the CPU value is not associated with any task.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0171-1],ARef=[AI05-0229-1]}
address@hidden,Text=[The CPU value is associated with the environment
+task if the CPU aspect is specified for the main subprogram.
+If the CPU aspect is not specified for the main subprogram it is implementation
+defined on which processor the environment task executes.]}
address@hidden,Kind=[Added],address@hidden,
+Text=[The processor on which the environment task executes in the absence of a
+value for the aspect CPU.]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0171-1],ARef=[AI05-0264-1]}
address@hidden,Text=[The CPU value determines the processor on which the
+task will activate and execute; the task is said to be assigned to that
+processor. If the CPU value is Not_A_Specific_CPU, then the task is not 
assigned
+to a processor. A task without a CPU aspect specified will activate and 
execute on the
+same processor as its activating task if the activating task is assigned a
+processor. If the CPU value is not in the range of
+System.Multiprocessors.CPU_Range or is greater than Number_Of_CPUs the task is
+defined to have failed, and it becomes a completed task (see
address@hidden Execution - Task Activation}).]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0171-1],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The package System.Multiprocessors and the CPU aspect are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0081-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified when the CPU
+  aspect expression is evaluated.]}
address@hidden
+
+
address@hidden@Comment{For printed version of Ada 2012 RM}
address@hidden,Name=[Multiprocessor Dispatching Domains]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+allows implementations on multiprocessor
+platforms to be partitioned into distinct dispatching domains during program
+startup.]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The following
+language-defined library package exists:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden Ada.Real_Time;
address@hidden Ada.Task_Identification;
address@hidden System.Multiprocessors.Dispatching_Domains 
@address@hidden,Child=[Dispatching_Domains]}]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaExcDefn{Dispatching_Domain_Error} : 
@key[exception];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{Dispatching_Domain} (<>) 
@key[is limited private];]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @AdaObjDefn{System_Dispatching_Domain} : @key[constant] 
Dispatching_Domain;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0033-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Create} 
(address@hidden,New=[],Old=[, Last]} : address@hidden,New=[; Last : 
CPU_Range],Old=[]}) @key[return] Dispatching_Domain;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Get_First_CPU} (Domain : 
Dispatching_Domain) @key[return] CPU;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI12-0033-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Get_Last_CPU}  (Domain : 
Dispatching_Domain) @key[return] @Chg{Version=[4],New=[CPU_Range],Old=[CPU]};]}
+
address@hidden,Kind=[Added],ARef=[AI12-0033-1]}
address@hidden,Text=[   @key[type] @AdaTypeDefn{CPU_Set} @key[is array](CPU 
@key[range] <>) @key[of] Boolean;]}
+
address@hidden,Kind=[Added],ARef=[AI12-0033-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Create} (Set : CPU_Set) 
@key[return] Dispatching_Domain;]}
+
address@hidden,Kind=[Added],ARef=[AI12-0033-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Get_CPU_Set} (Domain : 
Dispatching_Domain) @key[return] CPU_Set;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Get_Dispatching_Domain}
+      (T   : Ada.Task_Identification.Task_Id :=
+                 Ada.Task_Identification.Current_Task)
+           @key[return] Dispatching_Domain;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Assign_Task}
+      (Domain : @key[in out] Dispatching_Domain;
+       CPU    : @key[in]     CPU_Range := Not_A_Specific_CPU;
+       T      : @key[in]     Ada.Task_Identification.Task_Id :=
+                 Ada.Task_Identification.Current_Task);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Set_CPU}
+      (CPU : @key[in] CPU_Range;
+       T   : @key[in] Ada.Task_Identification.Task_Id :=
+                 Ada.Task_Identification.Current_Task);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Get_CPU}
+      (T   : Ada.Task_Identification.Task_Id :=
+                 Ada.Task_Identification.Current_Task)
+           @key[return] CPU_Range;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key[procedure] @AdaSubDefn{Delay_Until_And_Set_CPU}
+      (Delay_Until_Time : @key[in] Ada.Real_Time.Time; CPU : @key[in] 
CPU_Range);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden
+   ... -- @RI[not specified by the language]
address@hidden System.Multiprocessors.Dispatching_Domains;]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0082-1]}
address@hidden,address@hidden,New=[A @i{dispatching
address@hidden domain}],Old=[The type Dispatching_Domain]}
+represents a @Chg{Version=[4],New=[set],Old=[series]}
+of processors on which a task may execute. Each processor
+is contained within exactly one @Chg{Version=[4],New=[dispatching
+domain],Old=[Dispatching_Domain]}.
address@hidden,New=[An object of type Dispatching_Domain identifies a
+dispatching domain. ],Old=[]}System_Dispatching_Domain
address@hidden,New=[identifies a domain that ],Old=[]}contains the processor
+or processors on which the environment task executes. At program start-up all
+processors are contained within
address@hidden,New=[this domain],Old=[System_Dispatching_Domain]}.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Type=[Leading],Text=[For a task type (including the
+anonymous type of a @nt{single_task_declaration}), the following 
language-defined
+representation aspect may be specified:]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden value of
+aspect Dispatching_Domain is an @nt{expression}, which shall be of
+type Dispatching_Domains.Dispatching_Domain. This aspect is the domain to
+which the task (or all objects of the task type) are
address@hidden
+
address@hidden,Kind=[AddedNormal],Aspect=[Dispatching_Domain],
+  address@hidden,Text=[Domain (group of processors) on which a
+    given task should run.]}]}
+
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Text=[The Dispatching_Domain aspect shall not be specified
+for a task interface.]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0033-1]}
address@hidden,Text=[The expression specified for the Dispatching_Domain
+aspect of a task @Chg{Version=[4],New=[type ],Old=[]}is evaluated
address@hidden,New=[each time an object of the task type is created],Old=[for
+each task object]} (see @RefSecNum{Task Units and Task Objects}).
address@hidden,New=[If the identified dispatching domain is empty, then
+Dispatching_Domain_Error is raised; otherwise the newly created task is 
assigned
+to the domain identified by the value of the expression],Old=[The
+Dispatching_Domain value is then associated with the task object whose task
+declaration specifies the aspect]}.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Text=[If a task is not explicitly assigned to any domain,
+it is assigned to that of the activating task. A task always executes on some
+CPU in its domain.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0082-1]}
address@hidden,Text=[If both @Chg{Version=[4],New=[the dispatching
+domain],Old=[Dispatching_Domain]} and CPU are specified for
+a task, and the CPU value is not contained within the
address@hidden,New=[set],Old=[range]} of processors for
+the domain (and is not Not_A_Specific_CPU), the activation of the task is
+defined to have failed, and it becomes a completed task (see
address@hidden Execution - Task Activation}).]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0033-1]}
address@hidden,Text=[The function Create @Chg{Version=[4],New=[with First
+and Last parameters ],Old=[]}creates and returns a 
@Chg{Version=[4],New=[dispatching
+domain],Old=[Dispatching_Domain]} containing
+all the processors in the range First .. Last. @Chg{Version=[4],New=[The
+function Create with a Set parameter creates and returns a dispatching domain
+containing the processors for which Set(I) is True.],Old=[]} These processors
+are removed from System_Dispatching_Domain. A call of Create will raise
+Dispatching_Domain_Error if any designated processor is not currently in
+System_Dispatching_Domain, or if the system cannot support a distinct domain
+over the processors identified, or if a processor has a task assigned to it, or
+if the allocation would leave System_Dispatching_Domain empty. A call of Create
+will raise Dispatching_Domain_Error if the calling task is not the environment
+task, or if Create is called after the call to the main subprogram.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0033-1]}
address@hidden,Text=[The function Get_First_CPU returns the first CPU in
address@hidden,New=[, or CPU'First if Domain is empty],Old=[]};
+Get_Last_CPU returns the last @Chg{Version=[4],New=[CPU in Domain, or
+CPU_Range'First if Domain is empty. The function Get_CPU_Set(D) returns an 
array
+whose low bound is Get_First_CPU(D), whose high bound is Get_Last_CPU(D), with
+True values in the Set corresponding to the CPUs that are in the given
+Domain],Old=[one]}.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0082-1]}
address@hidden,Text=[The function Get_Dispatching_Domain returns the
address@hidden,New=[dispatching domain],Old=[Dispatching_Domain]} on
+which the task is assigned.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1],ARef=[AI05-0278-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0033-1]}
address@hidden,Text=[A call of the procedure Assign_Task assigns task T
+to the CPU within @Chg{Version=[4],New=[the dispatching 
domain],Old=[Dispatching_Domain]}
+Domain. Task T can now execute only on
address@hidden,New=[,],Old=[]} unless CPU designates
address@hidden,New=[],Old=[,]} in which case it can
+execute on any processor within Domain. The exception Dispatching_Domain_Error
+is propagated address@hidden,New=[ Domain is empty,],Old=[]}
+T is already assigned to
+a @Chg{Version=[4],New=[dispatching domain],Old=[Dispatching_Domain]} other
+than System_Dispatching_Domain, or if CPU is not one of the processors of 
Domain (and
+is not Not_A_Specific_CPU). A call of Assign_Task is a task dispatching point
+for task T unless T is inside of a protected action, in which case the effect 
on
+task T is delayed until its next task dispatching point. If T is the
+Current_Task the effect is immediate if T is not inside a protected action,
+otherwise the effect is as soon as practical. Assigning a task
address@hidden,New=[already assigned ],Old=[]}to System_Dispatching_Domain
address@hidden,New=[],Old=[that is already assigned ]}to that domain has no
+effect.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1],ARef=[AI05-0278-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0082-1]}
address@hidden,Text=[A call of procedure Set_CPU assigns task T to the
+CPU. Task T can now execute only on CPU, unless CPU designates
+Not_A_Specific_CPU, in which case it can execute on any processor within its
address@hidden,New=[dispatching domain],Old=[Dispatching_Domain]}. The
+exception Dispatching_Domain_Error is propagated if CPU is not one of the
+processors of the @Chg{Version=[4],New=[dispatching
+domain],Old=[Dispatching_Domain]} on which T is assigned (and is not
+Not_A_Specific_CPU). A call of Set_CPU is a task dispatching point for task T
+unless T is inside of a protected action, in which case the effect on task T is
+delayed until its next task dispatching point. If T is the Current_Task the
+effect is immediate if T is not inside a protected action, otherwise the effect
+is as soon as practical.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Text=[The function Get_CPU returns the processor assigned
+to task T, or Not_A_Specific_CPU if the task is not assigned to a processor.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0082-1]}
address@hidden,Text=[A call of Delay_Until_And_Set_CPU delays the calling
+task for the designated time and then assigns the task to the specified
+processor when the delay expires. The exception Dispatching_Domain_Error is
+propagated if P is not one of the processors of the calling task's
address@hidden,New=[dispatching domain],Old=[Dispatching_Domain]} (and is
+not Not_A_Specific_CPU).]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Text=[The implementation shall perform the operations
+Assign_Task, Set_CPU, Get_CPU and Delay_Until_And_Set_CPU atomically with
+respect to any of these operations on the same dispatching_domain, processor or
+task.]}
+
address@hidden,Kind=[Added],ARef=[AI12-0048-1]}
address@hidden,Text=[Any task that belongs to the system dispatching
+domain can execute on any CPU within that domain, unless the assignment of the
+task has been specified.]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[This ensures that priorities and deadlines are
+  respected within the system dispatching domain. There is no such guarantee
+  between different domains.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[We only need to talk about the system dispatching
+  domain here, because Assign_Task and Set_CPU already have such wording for
+  tasks that are assigned explicitly to a dispatching domain and specify
+  Not_a_Specific_CPU.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[If no dispatching domains are created, all tasks
+  can execute on all processors. (As always, implementation-defined dispatching
+  policies may have other rules, so a partition that does not specify any
+  language-defined dispatching policy may do anything at all and in particular
+  does not need to follow this rule.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal]}
+  @ChgAdded{Version=[4],Text=[A task can be assigned to a specific CPU by
+  specifying the aspect CPU for a task, or by calling a dynamic operation like
+  Set_CPU or Assign_Task.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Text=[Each dispatching domain should have separate and
+disjoint ready queues.]}
+
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Each dispatching domain should have separate and
+disjoint ready queues.]}]}
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0048-1]}
+  @ChgAdded{Version=[4],address@hidden@;Ready address@hidden here doesn't mean
+  the conceptual "ready queue" as defined in @RefSecNum{The Task Dispatching 
Model}
+  (one per processor); this rule is talking about the ready queues used by the
+  implementation.]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Text=[The implementation shall document the processor(s)
+on which the clock interrupt is handled and hence where delay queue and ready
+queue manipulations occur. For any Interrupt_Id whose handler can execute on
+more than one processor the implementation shall also document this set of
+processors.]}
+
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The processor(s) on which the clock interrupt is handled; the processors
+on which each Interrupt_Id can be handled.]}]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0167-1]}
address@hidden,Text=[An implementation may limit the number of
+dispatching domains that can be created and raise Dispatching_Domain_Error if 
an
+attempt is made to exceed this number.]}
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0167-1],ARef=[AI05-0278-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  The package System.Multiprocessors.Dispatching_Domains and the aspect
+  Dispatching_Domains are new.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI12-0033-1]}
address@hidden,address@hidden with Ada 2012}
address@hidden:} We now explicitly allow empty dispatching domains, as it
+would be difficult to avoid declaring them when a system is configured
+at runtime. Therefore, assigning a task to an empty domain now
+raises Dispatching_Domain_Error; creating such a domain should
+not raise Dispatching_Domain_Error. If an implementation does
+something different in these cases, and a program depends on
+that difference, the program could malfunction. This seems
+very unlikely (if no exception is ever raised, the task assigned
+to the empty domain could never run; if the exception is raised earlier,
+the program can't do anything useful).]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI05-0033-1]}
+  @ChgAdded{Version=[4],address@hidden with Ada address@hidden<Corrigendum:>
+  The subtypes of the parameter or result of several routines were changed
+  to support empty domains. These changes will cause rules requiring
+  subtype conformance to fail on these routines (such as 'Access). We
+  believe such uses are unlikely. In addition, type CPU_Set and function
+  Get_CPU_Set, along with an overloaded Create are newly added to this package.
+  If Multiprocessors.Dispatching_Domains is referenced in a @nt{use_clause},
+  and an entity @i<E> with the same @nt{defining_identifier} as a new entity
+  in this package is defined in a package that is also referenced in a
+  @nt{use_clause}, the entity @i<E> may no longer be use-visible, resulting
+  in errors. This should be rare and is easily fixed if it does occur.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0048-1]}
+  @ChgAdded{Version=[4],address@hidden:} Added wording to clarify that
+  all tasks can execute on all CPUs of the system dispatching domain by
+  default.]}
+
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0082-1]}
+  @ChgAdded{Version=[4],address@hidden:} Added a definition to clarify
+  that a "dispatching domain" is a concept which is identified by an
+  object of type Dispatching_Domain; more than one object might identify
+  the same dispatching domain (for instance, the result of function
+  Get_Dispatching_Domain is a different object but identifies the same
+  dispatching domain).]}
address@hidden
diff --git a/packages/ada-ref-man/source_2012/safety.mss 
b/packages/ada-ref-man/source_2012/safety.mss
new file mode 100755
index 0000000..7304c05
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/safety.mss
@@ -0,0 +1,1373 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/safety.mss,v $ }
address@hidden $Revision: 1.59 $ $Date: 2012/11/28 23:53:06 $ $Author: randy $ }
address@hidden(safety, Root="ada.mss")
+
address@hidden: 2012/11/28 23:53:06 $}
address@hidden,
+New=[High Integrity Systems], Old=[Safety and Security]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00347-01]}
address@hidden@Defn{safety-critical systems}
address@hidden systems}
+This Annex addresses requirements for @Chg{Version=[2],
+New=[high integrity ],Old=[]}systems @Chg{Version=[2],New=[(including],
+Old=[that are]} address@hidden,New=[-],Old=[ ]}critical
address@hidden,New=[systems and],Old=[or have]}
address@hidden,New=[-critical systems)],Old=[ constraints]}. It
+provides facilities and specifies documentation requirements that relate to
+several needs:
address@hidden
+Understanding program execution;
+
+Reviewing object code;
+
+Restricting language constructs whose usage might
+complicate the demonstration of program correctness
address@hidden
address@hidden following paragraph is missing a number in the original version.
+To give it a number in the new version, it is marked as an insertion.}
address@hidden,Kind=[Added]}
address@hidden,address@hidden@;]}Execution understandability
+is supported by pragma Normalize_Scalars, and also by
+requirements for the implementation to document the effect of a program
+in the presence of a bounded error or where the language rules leave
+the effect unspecified.
address@hidden
+
+The @nt[pragma]s Reviewable and Restrictions relate to the other
+requirements addressed by this Annex.
address@hidden
+
address@hidden
+The @attr[Valid] attribute (see @RefSecNum(The Valid Attribute)) is
+also useful in addressing these needs,
+to avoid problems that could otherwise arise from scalars
+that have values outside their declared range constraints.
address@hidden
+
+The Annex tries to provide high assurance rather than language features.
+However, it is not possible, in general, to test for high assurance. For any
+specific language feature, it is possible to demonstrate its presence by a
+functional test, as in the ACVC. One can also check for the presence of some
+documentation requirements, but it is not easy to determine objectively that
+the documentation is @lquotes@;address@hidden@;.
+
address@hidden
address@hidden
+
address@hidden
address@hidden to Ada 83}
+This Annex is new to Ada 95.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00347-01]}
+  @ChgAdded{Version=[2],Text=[The title of this annex was changed to better
+  reflect its purpose and scope. High integrity systems has become the standard
+  way of identifying systems that have high reliability requirements; it
+  subsumes terms such as safety and security. Moreover, the annex does not
+  include any security specific features and as such the previous title is
+  somewhat misleading.]}
address@hidden
+
address@hidden Normalize_Scalars}
address@hidden
+This pragma ensures that an otherwise
+uninitialized scalar object is set to a
+predictable value, but out of range if possible.
address@hidden
+The goal of the pragma is to reduce the impact of a bounded error
+that results from a reference to an uninitialized scalar object, by
+having such a reference violate a range check and thus raise
+Constraint_Error.
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden@Keepnext@;The form of a @nt{pragma} Normalize_Scalars is as 
follows:
address@hidden
+
address@hidden@key{pragma} @prag(Normalize_Scalars);'
address@hidden
+
address@hidden
address@hidden pragma], Sec=(Normalize_Scalars)}
address@hidden, configuration], Sec=(Normalize_Scalars)}
+Pragma Normalize_Scalars is a configuration pragma.
+It applies to all
address@hidden included in a partition.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+If a @nt{pragma} Normalize_Scalars applies,
+the implementation shall document the implicit initial @Chg{Version=[2],
+New=[values],Old=[value]} for scalar subtypes,
+and shall identify each case in which such a value is used
+and is not an invalid representation.
address@hidden,Kind=[AddedNormal],address@hidden,Text=[If
+a @nt{pragma} Normalize_Scalars applies, the implicit initial values of
+scalar subtypes shall be documented. Such a value should be an
+invalid representation when possible; any cases when is it not shall be
+documented.]}]}
address@hidden
+It's slightly inaccurate to say that the value is a
+representation, but the point should be clear anyway.
address@hidden
address@hidden
+
+By providing a type with a size specification so that spare bits are
+present, it is possible to force an implementation of Normalize_Scalars to use
+an out of range value. This can be tested for by ensuring that
+Constraint_Error is raised. Similarly, for an unconstrained integer type, in
+which no spare bit is surely present, one can check that the initialization
+takes place to the value specified in the documentation of the
+implementation. For a floating point type, spare bits might not
+be available, but a range constraint can provide the ability to use an out
+of range value.
+
+If it is difficult to document the general rule for the implicit initial
+value, the implementation might choose instead to record the value on
+the object code listing or similar output produced during compilation.
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+Whenever possible, the implicit initial @Chg{Version=[2],
+New=[values],Old=[value]} for a scalar subtype
+should be an invalid representation
+(see @RefSecNum{Data Validity}).
address@hidden
+
+  When an out of range value is used for the initialization,
+  it is likely that constraint checks will detect it.
+  In addition, it can be detected by the Valid attribute.
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This rule is included in the documentation
+  requirements, and thus does not need a separate summary item.]}
+
address@hidden
address@hidden
+
address@hidden
+The initialization requirement applies to
+uninitialized scalar objects that are subcomponents of composite
+objects, to allocated objects, and to stand-alone objects. It also
+applies to scalar @key{out} parameters. Scalar
+subcomponents of composite @key{out} parameters are initialized to the
+corresponding part of the actual, by virtue of
address@hidden(Parameter Associations).
+
+The initialization requirement does not apply to a scalar for which
+pragma Import has been specified,
+since initialization of an imported object is performed
+solely by the foreign language environment
+ (see @RefSecNum[Interfacing Aspects]).
+
+The use of pragma Normalize_Scalars in conjunction with
+Pragma Restrictions(No_Exceptions) may result in erroneous execution
+(see @RefSecNum[High Integrity Restrictions]).
address@hidden
+
+Since the effect of an access to an out of range value will often be to
+raise Constraint_Error, it is clear that suppressing the exception mechanism
+could result in erroneous execution. In particular, the assignment to an
+array, with the array index out of range, will result in a write to an
+arbitrary store location, having unpredictable effects.
+
address@hidden
address@hidden
+
address@hidden of Implementation Decisions}
+
address@hidden
address@hidden
+The implementation shall document the range of effects for each
+situation that the language rules identify as either a
+bounded error or as having an unspecified effect.
+If the implementation can constrain the effects of erroneous
+execution for a given construct,
+then it shall document such constraints.
address@hidden documentation might be provided either
+independently of any compilation unit or partition, or as part of an annotated
+listing for a given unit or partition.
+See also @RefSecNum(Conformity of an Implementation with the Standard), and
address@hidden(Structure).]
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Information regarding bounded errors and erroneous execution.]}]}
address@hidden,Kind=[AddedNormal],address@hidden,Text=[
+The range of effects for each bounded error and each unspecified effect.
+If the effects of a given erroneous construct are
+constrained, the constraints shall be documented.]}]}
+
address@hidden
+
address@hidden
+Among the situations to be
+documented are the conventions
+chosen for parameter passing, the methods used for the management of
+run-time storage, and the method used to evaluate numeric expressions if
+this involves extended range or extra precision.
address@hidden
+
+Look up @lquotes@;address@hidden@; and @lquotes@;erroneous address@hidden@;
+in the index for a list of the cases.
+
+The management of run-time storage is particularly important. For safety
+applications, it is often necessary to show that a program cannot raise
+Storage_Error, and for security applications that information cannot leak
+via the run-time system. Users are likely to prefer a simple storage model
+that can be easily validated.
+
+The documentation could helpfully take into account that users may well
+adopt a subset to avoid some forms of erroneous execution, for instance, not
+using the abort statement, so that the effects of a partly completed
address@hidden do not have to be considered in the validation of a
+program
+(see @RefSecNum{Abort of a Task - Abort of a Sequence of Statements}).
+For this reason documentation linked to an actual compilation may be
+most useful. Similarly, an implementation may be able to take into
+account use of the Restrictions pragma.
+
address@hidden
address@hidden
+
+
address@hidden Object Code}
+
address@hidden
+Object code review and validation are supported by
+pragmas Reviewable and Inspection_Point.
address@hidden
+
address@hidden Reviewable}
address@hidden
+This pragma directs the implementation to
+provide information to
+facilitate analysis and review of a program's
+object code, in particular to allow determination of
+ execution time and storage usage and to identify the
+correspondence between the source and object programs.
address@hidden
+
+Since the purpose of this pragma is to provide information to the user,
+it is hard to objectively test for conformity. In practice, users want
+the information in an easily understood and convenient form, but neither
+of these properties can be easily measured.
+
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden@Keepnext@;The form of a @nt{pragma} Reviewable is as follows:
address@hidden
+
address@hidden@key{pragma} @prag(Reviewable);'
address@hidden
+
address@hidden
address@hidden pragma], Sec=(Reviewable)}
address@hidden, configuration], Sec=(Reviewable)}
+Pragma Reviewable is a configuration pragma.
+It applies to all
address@hidden included in a partition.
address@hidden
+
address@hidden
address@hidden@;The implementation shall provide the following
+information for any compilation unit to which such a
+pragma applies:
address@hidden
+
+The list of requirements can be checked for, even if issues like
+intelligibility are not addressed.
+
address@hidden
address@hidden
+Where compiler-generated run-time checks remain;
address@hidden
+
+A constraint check which is implemented via a check on the upper and lower
+bound should clearly be indicated. If a check is implicit in the form of
+machine instructions used (such an overflow checking), this should also be
+covered by the documentation. It is particularly important to cover those
+checks which are not obvious from the source code, such as that for stack
+overflow.
+
address@hidden
+
+An identification of any construct with a language-defined check
+that is recognized prior to run time as certain to fail
+if executed
+(even if the generation of run-time checks has been suppressed);
address@hidden
+
+In this case, if the compiler determines that a check must fail, the user
+should be informed of this. However, since it is not in general possible to
+know what the compiler will detect, it is not easy to test for this. In
+practice, it is thought that compilers claiming conformity to this Annex
+will perform significant optimizations and therefore @i{will} detect such
+situations. Of course, such events could well indicate a programmer error.
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00209-01]}
+For each @Chg{Version=[2],New=[read of],Old=[reference to]} a scalar object,
+an identification of the @Chg{Version=[2],New=[read],Old=[reference]} as
+either @lquotes@;known to be initialized,@rquotes@; or
address@hidden@;possibly uninitialized,@rquotes@;
+independent of whether pragma Normalize_Scalars applies;
address@hidden
+
+This issue again raises the question as to what the compiler has determined.
+A lazy implementation could clearly mark all scalars as @lquotes@;possibly
address@hidden@;, but this would be very unhelpful to the user. It should be
+possible to analyze a range of scalar uses and note the percentage in each
+class. Note that an access marked @lquotes@;known to be address@hidden@; does 
not imply
+that the value is in range, since the initialization could be from an
+(erroneous) call of unchecked conversion, or by means external to the Ada
+program.
+
address@hidden
+
+Where run-time support routines are implicitly invoked;
address@hidden
+
+Validators will need to know the calls invoked in order to check for the
+correct functionality. For instance, for some safety applications, it may be
+necessary to ensure that certain sections of code can execute in a
+particular time.
+
address@hidden
+
address@hidden@Keepnext@;An object code listing, including:
address@hidden
+Machine instructions, with relative offsets;
address@hidden
+
+The machine instructions should be in a format that is easily understood,
+such as the symbolic format of the assembler. The relative offsets are
+needed in numeric format, to check any alignment restrictions that the
+architecture might impose.
+
address@hidden
+
+Where each data object is stored during its lifetime;
address@hidden
+
+This requirement implies that if the optimizer assigns a variable to a
+register, this needs to be evident.
+
address@hidden
+
+Correspondence with the source program, including an identification of the
+ code produced per declaration and per statement.
address@hidden
+
+This correspondence will be quite complex when extensive optimization is
+performed. In particular, address calculation to access some data structures
+could be moved from the actual access. However, when all the machine code
+arising from a statement or declaration is in one basic block, this must be
+indicated by the implementation.
+
address@hidden
address@hidden
+
+An identification of each construct for which the implementation detects
+the possibility of erroneous execution;
address@hidden
+
+This requirement is quite vague. In general, it is hard for compilers to detect
+erroneous execution and therefore the requirement will be rarely invoked. 
However,
+if the pragma Suppress is used and the compiler can show that a predefined
+exception will be raised, then such an identification would be useful.
+
address@hidden
+
address@hidden@;For each subprogram, block, task,
+or other construct implemented by
+reserving and subsequently freeing an area on a run-time stack,
+an identification
+of the length of the fixed-size portion of the area and an indication
+of whether the non-fixed size portion is reserved on the stack
+or in a dynamically-managed storage region.
address@hidden
+This requirement is vital for those requiring to show that the storage
+available to a program is sufficient. This is crucial in those cases in
+which the internal checks for stack overflow are suppressed (perhaps by
address@hidden Restrictions(No_Exceptions)).
address@hidden
address@hidden
+
address@hidden@;The implementation shall provide the following
+information for any partition to which the
+pragma applies:
address@hidden
+An object code listing of the entire partition, including
+initialization and finalization code as well as
+ run-time
+system components, and with an identification of those instructions and
+data that will be relocated at load time;
address@hidden
+The object code listing should enable a validator to estimate
+upper bounds for the time taken by critical parts of a program.
+Similarly, by an analysis of the entire partition, it should be possible
+to ensure that the storage requirements are suitably bounded,
+assuming that the partition was written in an appropriate
address@hidden
+
+A description of the run-time model relevant to the partition.
address@hidden
+For example,
+a description of the storage model is vital,
+since the Ada language does not explicitly define such a model.
address@hidden
address@hidden
address@hidden
+
address@hidden following paragraph is missing a number in the original version.
+To give it a number in the new version, it is marked as an insertion.}
address@hidden,Kind=[Added]}
address@hidden,address@hidden@;]}The implementation shall provide control- and 
data-flow
+information, both within each compilation unit and across
+the compilation units of the partition.
address@hidden
+
+This requirement is quite vague, since it is unclear what control and data
+flow information the compiler has produced. It is really a plea not to throw
+away information that could be useful to the validator. Note that the data
+flow information is relevant to the detection of @lquotes@;possibly 
address@hidden@;
+objects referred to above.
+
address@hidden
address@hidden
+The implementation should provide the above
+information in both a human-readable
+and machine-readable form,
+and should document the latter so as to ease further
+processing by automated tools.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The information produced by @nt{pragma} Reviewable should be
+provided in both a human-readable and machine-readable form, and the
+latter form should be documented.]}]}
+
+Object code listings should be provided both in a symbolic
+format and also in an appropriate numeric format (such as
+hexadecimal or octal).
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Object code listings should be provided both in a symbolic
+format and in a numeric format.]}]}
address@hidden
+
+This is to enable other tools to perform any analysis that the user
+needed to aid validation.
+The format should be in some agreed form.
+
address@hidden
address@hidden
+
address@hidden
+The order of elaboration of library units will be documented
+even in the absence of @nt[pragma] Reviewable
+(see @RefSecNum{Program Execution}).
address@hidden
+
address@hidden
+There might be some interactions between pragma Reviewable and compiler
+optimizations. For example,
+an implementation may disable some
+optimizations when pragma Reviewable is in force
+if it would be overly complicated to
+provide
+the detailed information to allow review of the optimized object code.
+See also @nt<pragma> Optimize (@RefSecNum{Pragmas}).
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00209-01]}
+  @ChgAdded{Version=[2],Text=[The wording was clarified that pragma Reviewable
+  applies to each read of an object, as it makes no sense to talk about the
+  state of an object that will immediately be overwritten.]}
address@hidden
+
address@hidden Inspection_Point}
address@hidden
+An occurrence of a pragma Inspection_Point identifies a set of objects each of
+whose values is to be
+available at the point(s) during program execution corresponding to the
+position of the pragma in the compilation unit.
+The purpose of such a pragma is to facilitate code validation.
address@hidden
+
+Inspection points are a high level equivalent of break points used by
+debuggers.
+
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden@Keepnext@;The form of a @nt{pragma} Inspection_Point is as 
follows:
address@hidden
+
address@hidden@key{pragma} @prag(Inspection_Point)[(@address@hidden {, 
@address@hidden)];'
address@hidden
+
address@hidden
+A pragma Inspection_Point is allowed wherever a
address@hidden
+or @nt[statement] is allowed.
+Each @SynI{object_}name shall statically denote the declaration of an object.
address@hidden
+
+The static denotation is required, since no dynamic evaluation of a name
+is involved in this pragma.
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0093],ARef=[AI95-00207-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
address@hidden point}
+An @i{inspection point} is a point in the object code
+corresponding to the occurrence of a pragma address@hidden in the
+compilation unit.
address@hidden object}
+An object is @i{inspectable} at an inspection point if the corresponding
+pragma Inspection_Point either has an argument denoting that object,
+or has no address@hidden and the @Chg{Version=[2],New=[declaration
+of the ],Old=[]}object is visible at the inspection point],Old=[]}.
address@hidden
+If a pragma Inspection_Point is in an in-lined subprogram, there
+might be numerous inspection points in the object code corresponding to
+the single occurrence of the pragma in the source; similar considerations
+apply if such a pragma is in a generic, or in a loop that has
+been @lquotes@;address@hidden@; by an optimizer.
+
address@hidden,Kind=[Added],Ref=[8652/0093],ARef=[AI95-00207-01]}
address@hidden,Text=[The short form of the pragma is a convenient shorthand for
+listing all objects which could be explicitly made inspectable by the long
+form of the pragma; thus only visible objects are made inspectable by it.
+Objects that are not visible at the point of the pragma are not made
+inspectable by the short form pragma. This is necessary so that implementations
+need not keep information about (or prevent optimizations on) a unit simply
+because some other unit @i<might> contain a short form Inspection_Point
+pragma.]}
address@hidden
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0093],ARef=[AI95-00207-01]}
+If the short form of the pragma is used, then address@hidden visible],Old=[]}
+objects are inspectable.
+This implies that @Chg{New=[global objects from other compilation units],
+Old=[objects out of scope at the point of the pragma]} are inspectable. A good
+interactive debugging system could provide information
+similar to a post-mortem dump at such inspection points. The annex does
+not require that any inspection facility is provided, merely that the
+information is available to understand the state of the machine at those
+points.
address@hidden
address@hidden
+
address@hidden
+Execution of a pragma Inspection_Point has no effect.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+Although an inspection point has no (semantic) effect,
+the removal or adding @Chg{Version=[2],New=[of ],Old=[]}a new point could
+change the machine code generated by the compiler.
+
address@hidden
address@hidden
+
address@hidden
+Reaching an inspection point is an external interaction
+with respect to the values
+of the inspectable objects at that point
+(see @RefSecNum{Conformity of an Implementation with the Standard}).
address@hidden
+The compiler is inhibited from moving an assignment to
+an inspectable variable past an inspection point for that variable.
+On the other hand, the evaluation of an expression that might raise
+an exception may be moved past an inspection point
+(see @RefSecNum[Exceptions and Optimization])address@hidden
address@hidden
+
address@hidden
+For each inspection point,
+ the implementation shall
+identify a mapping between each inspectable object and the machine resources
+(such as memory locations or registers) from which the object's value
+can be obtained.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Implementation-defined aspects of pragma Inspection_Point.]}]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[For each inspection point, a mapping between each inspectable object
+and the machine resources where the object's value can be obtained shall
+be provided.]}]}
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00209-01]}
+The implementation is not allowed to perform @lquotes@;dead store 
address@hidden@; on
+the last assignment to a variable prior to a point where the
+variable is inspectable.
+Thus an inspection point has the effect of an
+implicit @Chg{Version=[2],New=[read of],Old=[reference to]} each of its
+inspectable objects.
+
+Inspection points are useful in maintaining a correspondence between the
+state of the program in source code terms, and the machine state during
+the program's execution. Assertions about the values of program objects
+can be tested in machine terms at inspection points. Object code between
+inspection points can be processed by automated tools to
+verify programs mechanically.
address@hidden
+
+Although it is not a requirement of the annex, it would be useful if the
+state of the stack and heap could be interrogated. This would allow users
+to check that a program did not have a `storage leak'.
+
address@hidden
+
+The identification of the mapping from source program objects to machine
+resources is allowed to be in the form of an
+annotated object listing, in human-readable or tool-processable form.
address@hidden
+
+In principle, it is easy to check an implementation for this pragma, since
+one merely needs to check the content of objects against those values
+known from the source listing. In practice, one needs a tool similar
+to an interactive debugger to perform the check.
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],Ref=[8652/0093],ARef=[AI95-00207-01]}
address@hidden,address@hidden<Corrigendum:> Corrected the definition of
+the Inspection_Point pragma to apply to only variables visible at the point
+of the pragma. Otherwise, the compiler would have to assume that some
+other code somewhere could have a pragma Inspection_Point, preventing many
+optimizations (such as unused object elimination).]}
address@hidden
+
+
address@hidden,New=[High Integrity Restrictions],Old=[Safety and Security 
Restrictions]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} defines restrictions that 
can be used with pragma
+Restrictions (see @RefSecNum(Pragma Restrictions and Pragma Profile)); these
+facilitate the demonstration of program correctness by allowing
+tailored versions of the run-time system.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+Note that the restrictions are absolute. If a partition has 100 library
+units and just one needs Unchecked_Conversion, then the pragma cannot be
+used to ensure the other 99 units do not use Unchecked_Conversion. Note also
+that these are restrictions on all Ada code within a partition, and
+therefore it @Chg{Version=[3],New=[might],Old=[may]} not be evident
+from the specification of a package whether a restriction can be imposed.
+
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Deleted],ARef=[AI95-00347-01],ARef=[AI95-00394-01]}
address@hidden,Text=[The following restrictions,
+the same as in @RefSecNum{Tasking Restrictions},
+apply in this Annex:
+ address@hidden,
+ address@hidden,
+ address@hidden@!Allocation,
+ address@hidden@!Entries is 0,
+ address@hidden@address@hidden is 0, and
+ address@hidden is 0.
address@hidden last three restrictions are checked prior to program 
execution.]]}
+
address@hidden@ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00394-01]}
+The following @Chg{Version=[2],address@hidden@nt{identifier}s are
+language defined:],Old=[additional restrictions apply in this Annex.]}
+
address@hidden@address@hidden restriction:}
+
address@hidden
address@hidden@;@Defn2{Term=[restrictions],Sec=(No_Protected_Types)address@hidden,address@hidden
 restriction}],
+Old=[]}No_Protected_Types @\There
+are no declarations of protected types or protected objects.
address@hidden
+
address@hidden@address@hidden related restrictions:}
+
address@hidden
address@hidden,Sec=(No_Allocators)address@hidden,address@hidden restriction}],
+   Old=[]}No_Allocators @\There are no
+occurrences of an @nt{allocator}.
+
address@hidden,Kind=[Revised],Ref=[8652/0042],ARef=[AI95-00130]}
address@hidden,Sec=(No_Local_Allocators)address@hidden,address@hidden 
restriction}],
+Old=[]}No_Local_Allocators @address@hidden
+are prohibited in subprograms, generic subprograms,
+tasks, and entry address@hidden,Old=[; instantiations of generic packages
+are also prohibited in these contexts]}.
address@hidden
+Thus @nt{allocator}s are permitted only in expressions whose
+evaluation can only be performed before the main subprogram is invoked.
address@hidden
address@hidden
address@hidden,Kind=[Deleted],Ref=[8652/0042],ARef=[AI95-00130]}
address@hidden associated rule has been deleted.}
address@hidden,Text=[The reason for the prohibition against
+instantiations of
+generic packages is to avoid contract model violations.
+An alternative would be to prohibit @nt{allocator}s from generic
+packages, but it seems preferable to allow generality on the
+defining side and then place the restrictions on the usage (instantiation),
+rather than inhibiting what can be in the generic while
+liberalizing where they can be instantiated.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0152-1],ARef=[AI05-0262-1]}
address@hidden,address@hidden,Sec=(No_Anonymous_Allocators)address@hidden 
restriction}
+No_Anonymous_Allocators @\There are no @nt{allocator}s of anonymous access 
types.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0190-1]}
address@hidden,address@hidden,Sec=(No_Coextensions)address@hidden restriction}
+No_Coextensions @\There are no coextensions. See @RefSecNum{Operations of 
Access Types}.]}
+
address@hidden,Kind=[Added],ARef=[AI05-0190-1]}
address@hidden,address@hidden,
+Sec=(No_Access_Parameter_Allocators)address@hidden restriction}
+No_Access_Parameter_Allocators @address@hidden
+are not permitted as the actual parameter to an access parameter.
+See @RefSecNum{Subprogram Declarations}.]}
+
address@hidden,Kind=[Deleted],ARef=[AI95-00394-01]}
address@hidden can't reuse this paragraph for the above, because there is no
+way to have the hanging marker in both the added and deleted text (and since it
+isn't in Ada 2005 at all).}
address@hidden,address@hidden,
+Sec=(No_Unchecked_Deallocation)}No_Unchecked_Deallocation @\Semantic
+dependence on Unchecked_Deallocation is not allowed.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[This restriction would be useful in those
+  contexts in which heap storage is needed on program start-up, but need not be
+  increased subsequently. The danger of a dangling pointer can therefore be
+  avoided.]}
address@hidden
+
address@hidden@;Immediate_Reclamation @\Except for storage occupied by objects 
created by
address@hidden and not deallocated via unchecked deallocation, any storage
+reserved at run time for an object is immediately reclaimed when the
+object no longer exists.
address@hidden,Sec=(Immediate_Reclamation)address@hidden,address@hidden 
restriction}],
+Old=[]}
address@hidden
+Immediate reclamation would apply to storage created by the compiler, such
+as for a return value from a function whose size is not known at the
+call site.
address@hidden
address@hidden
+
address@hidden@address@hidden restriction:}
+
address@hidden
address@hidden@Defn2{Term=[restrictions],Sec=(No_Exceptions)address@hidden,address@hidden
 restriction}],
+   Old=[]}No_Exceptions @address@hidden
+and @nt{exception_handler}s are not allowed.
+No language-defined run-time checks are generated;
+however, a run-time check performed automatically by the hardware
+is permitted.
address@hidden
+
+This restriction mirrors a method of working that is quite common in the
+safety area. The programmer is required to show that exceptions cannot be
+raised. Then a simplified run-time system is used without exception
+handling. However, some hardware checks may still be enforced. If the
+software check would have failed, or if the hardware check actually fails,
+then the execution of the program is unpredictable.
+There are obvious dangers in this approach, but it is similar to
+programming at the assembler level.
+
address@hidden
address@hidden
+
address@hidden@address@hidden restrictions:}
+
address@hidden
address@hidden,Sec=(No_Floating_Point)address@hidden,address@hidden 
restriction}],
+   Old=[]}No_Floating_Point @\Uses of predefined floating point types and
+operations, and declarations of new floating point types, are
+not allowed.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+The intention is to avoid the use of floating point hardware at run time,
+but this is expressed in
+language terms. It is conceivable that floating point is used implicitly in
+some contexts, say fixed point type conversions of high accuracy. However,
+the @ImplReqTitle below make it clear that the restriction would apply
+to the @lquotes@;run-time address@hidden@; and hence not be allowed.
+This @Chg{Version=[2],New=[restriction],Old=[parameter]} could be used to
+inform a compiler that a variant of the architecture is being used which does
+not have floating point instructions.
+
address@hidden
+
address@hidden,Sec=(No_Fixed_Point)address@hidden,address@hidden restriction}],
+   Old=[]}No_Fixed_Point @\Uses of predefined fixed point types and
+operations, and declarations of new fixed point types, are
+not allowed.
address@hidden
+
+This restriction would have the side effect of prohibiting the
address@hidden
+As with the No_Floating_Point restriction, this might be used to
+avoid any question of rounding errors. Unless an Ada run-time is written in
+Ada, it seems hard to rule out implicit use of fixed point, since at the
+machine level, fixed point is virtually the same as integer arithmetic.
+
address@hidden
+
address@hidden,Kind=[Deleted],ARef=[AI95-00394-01]}
address@hidden,address@hidden,
+Sec=(No_Unchecked_Conversion)}No_Unchecked_Conversion @\Semantic dependence
+on the predefined generic Unchecked_Conversion is not allowed.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[DeletedNoDelMsg]}
+  @ChgDeleted{Version=[2],Text=[Most critical applications would require
+  some restrictions or additional validation checks on uses of unchecked
+  conversion. If the application does not require the functionality, then
+  this restriction provides a means of ensuring the design requirement has
+  been satisfied. The same applies to several of the following restrictions.]}
address@hidden
+
+No_Access_Subprograms @\The declaration of access-to-subprogram types
+is not allowed.
address@hidden,Sec=(No_Access_Subprograms)address@hidden,address@hidden 
restriction}],
+Old=[]}
address@hidden@ChgNote{Moved from above}
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[Most critical applications would require
+  some restrictions or additional validation checks on uses of
+  access-to-subprogram types. If the application does not require the
+  functionality, then this restriction provides a means of ensuring the design
+  requirement has been satisfied. The same applies to several of the following
+  restrictions, and to restriction No_Dependence => Ada.Unchecked_Conversion.]}
address@hidden
+
address@hidden,Sec=(No_Unchecked_Access)address@hidden,address@hidden 
restriction}],
+   Old=[]}No_Unchecked_Access @\The @attr[Unchecked_Access] attribute
+is not allowed.
+
address@hidden,Sec=(No_Dispatch)address@hidden,address@hidden restriction}],
+Old=[]}No_Dispatch @\Occurrences of T'Class are not allowed, for any
+(tagged)
+subtype T.
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01]}
address@hidden,Sec=(No_IO)address@hidden,address@hidden restriction}],
+   Old=[]}No_IO @\Semantic dependence on
+any of the library units
+Sequential_IO, Direct_IO, Text_IO, Wide_Text_IO, @Chg{Version=[2],
+New=[Wide_Wide_Text_IO, ],Old=[]}or Stream_IO is not allowed.
address@hidden
+
+Excluding the input-output facilities of an implementation may be needed
+in those environments which cannot support the supplied functionality.
+A program in such an environment is likely to require some low level
+facilities or a call on a non-Ada feature.
+
address@hidden
+
address@hidden,Sec=(No_Delay)address@hidden,address@hidden restriction}],
+Old=[]}No_Delay @address@hidden
+and semantic dependence on package Calendar
+are not allowed.
address@hidden
+This implies that @nt[delay_alternative]s in a
address@hidden are prohibited.
+
+The purpose of this restriction is to avoid the need for timing facilities
+within the run-time system.
+
address@hidden
+
address@hidden,Sec=(No_Recursion)address@hidden,address@hidden restriction}],
+   Old=[]}No_Recursion @\As part of the execution of a subprogram, the same
+subprogram is not invoked.
+
address@hidden,Sec=(No_Reentrancy)address@hidden,address@hidden restriction}],
+   Old=[]}No_Reentrancy @\During the execution of a subprogram by a task, no 
other
+task invokes the same subprogram.
+
address@hidden
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00394-01]}
address@hidden,Type=[Leading],Text=[An implementation of this Annex
+shall support:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,Text=[the restrictions defined in this subclause; and]}
+
address@hidden,Kind=[Added]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0189-1]}
address@hidden,Text=[the following restrictions defined in
address@hidden Restrictions}: No_Task_Hierarchy,
+No_Abort_Statement, address@hidden,New=[,
+No_Standard_Allocators_After_Elaboration], Old=[]}; and]}
+
address@hidden,Kind=[Added],ARef=[AI95-00347-01]}
address@hidden,Text=[the @key{pragma} Profile(Ravenscar); and]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00347-01]}
+  @ChgAdded{Version=[2],Text=[The reference to pragma Profile(Ravenscar) is
+  intended to show that properly restricted tasking is appropriate for use
+  in high integrity systems. The Ada 95
+  Annex seemed to suggest that tasking was inappropriate for such systems.]}
address@hidden
+
address@hidden,Kind=[Added]}
address@hidden,Type=[Leading],Text=[the following uses of
address@hidden@nt{identifier}s defined in
address@hidden address@hidden, which are checked
+prior to program execution]:]}
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[Max_Task_Entries => 0,]}
+
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[Max_Asynchronous_Select_Nesting => 0, and]}
+
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[Max_Tasks => 0.]}
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0263-1],ARef=[AI05-0272-1]}
+If an implementation supports @nt[pragma] Restrictions for a particular
+argument, then except for the restrictions No_Unchecked_Deallocation,
+No_Unchecked_Conversion, No_Access_Subprograms,
address@hidden,New=[],Old=[and ]}No_Unchecked_Access,
address@hidden,New=[No_Specification_of_Aspect, No_Use_of_Attribute,
+No_Use_of_Pragma, and the equivalent use of No_Dependence, ],Old=[]}the
+associated restriction applies to the run-time system.
address@hidden
+Permission is granted for the run-time system to use the specified
+otherwise-restricted features, since the use of these features may
+simplify the run-time system by allowing more of it to be written
+in Ada.
address@hidden
address@hidden
+
+The restrictions that are applied to the partition are also applied to the
+run-time system. For example, if No_Floating_Point is specified,
+then an implementation that uses floating point for implementing the delay
+statement (say) would require that No_Floating_Point is
+only used in conjunction with No_Delay. It is clearly important that
+restrictions are effective so that Max_Tasks=0 does imply that tasking is
+not used, even implicitly (for input-output, say).
+
+An implementation of tasking could be produced based upon a run-time
+system written in Ada in which the rendezvous was controlled by
+protected types. In this case, No_Protected_Types could only be used in
+conjunction with Max_Task_Entries=0. Other implementation dependencies
+could be envisaged.
+
+If the run-time system is not written in Ada, then the wording needs to be
+applied in an appropriate fashion.
+
address@hidden,Kind=[Revised],ARef=[AI05-0263-1]}
address@hidden,Text=["the equivalent use of No_Dependence" refers
+to @exam{No_Dependence => Ada.Unchecked_Conversion} and the like, not all
+uses of No_Dependence.]}
+
address@hidden
address@hidden
+
address@hidden
+If a pragma Restrictions(No_Exceptions) is specified, the implementation
+shall document the effects of all constructs where language-defined checks are
+still performed automatically (for example, an overflow check performed
+by the processor).
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Implementation-defined aspects of pragma Restrictions.]}]}
address@hidden,Kind=[AddedNormal],address@hidden,Text=[
+If a pragma Restrictions(No_Exceptions) is specified, the effects of all
+constructs where language-defined checks are still performed.]}]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+The documentation requirements here are quite difficult to satisfy. One
+method is to review the object code generated and determine the checks that
+are still present, either explicitly, or implicitly within the architecture.
+As another example from that of overflow, consider the question of
address@hidden,New=[dereferencing],Old=[deferencing]} a null pointer.
+This could be undertaken by a memory access trap
+when checks are performed. When checks are suppressed via the argument
+No_Exceptions, it would not be necessary to have the memory access trap
+mechanism enabled.
+
address@hidden
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)}
+Program execution is erroneous if pragma Restrictions(No_Exceptions)
+has been specified and the conditions arise under which a generated
+language-defined run-time check would fail.
address@hidden
+
+The situation here is very similar to the application of pragma Suppress.
+Since users are removing some of the protection the language
+provides, they had better be careful!
+
address@hidden
+
address@hidden(erroneous execution),Sec=(cause)}
+Program execution is erroneous if pragma Restrictions(No_Recursion)
+has been specified and a subprogram is invoked as part of its
+own execution,
+or if pragma Restrictions(No_Reentrancy) has been specified and
+during the execution of a subprogram by a task, another task invokes
+the same subprogram.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0005-1]}
+In practice, many implementations @Chg{Version=[3],New=[might],Old=[may]}
+not exploit the absence of recursion
+or need for reentrancy, in which case the program execution would be
+unaffected by the use of recursion or reentrancy, even though the program is
+still formally erroneous.
+
address@hidden
address@hidden
+
address@hidden can't find any reason in the normative wording for this item;
+therefore I've removed it. The notes below (commented out anyway) refer only
+to a nonstandard mode, which is irrelevant in the Standard.}
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Any restrictions on pragma Restrictions.]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00394-01]}
address@hidden,Text=[Uses of @address@hidden
+No_Dependence defined in @RefSecNum{Language-Defined Restrictions and 
Profiles}:
+No_Dependence => address@hidden@!Deallocation and No_Dependence =>
address@hidden@!Conversion may be appropriate for high-integrity systems.
+Other uses of No_Dependence can also be appropriate for high-integrity
+systems.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The specific mention of these two uses
+  is meant to replace the identifiers now banished to
+  @RefSec{Dependence Restriction Identifiers}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Restriction No_Dependence => 
Ada.Unchecked_Deallocation
+  would be useful in those
+  contexts in which heap storage is needed on program start-up, but need not be
+  increased subsequently. The danger of a dangling pointer can therefore be
+  address@hidden down from above.}
address@hidden
+
address@hidden
+
address@hidden
address@hidden
+The standard mode for pragma Restrictions is that a
+compilation unit
+(or a partition if at link time) is illegal
+if it makes use of a feature identified in the pragma.
+However, an implementation is allowed to have a mode of operation
+where it issues a warning message versus rejecting the unit or partition,
+and where the run-time system supplied for the partition
+includes support for the identified feature.
+
+An implementation need not independently support the restrictions
+identified above, but may instead require that if a particular
+restriction is identified in a @nt(pragma) Restrictions, then
+other restrictions (the exact set of which is implementation defined)
+need also to be identified.
+
+In such a case, if the additional
+restrictions are not specified in a @nt(pragma) Restrictions, and
+a unit or partition uses such a feature, the implementation should
address@hidden
+issue a warning that the pragma is being ignored (that is, the
+full RTS is being used),
+
+identify to the user the additional restrictions that need to be
+specified in the pragma in order to obtain the reduced RTS, and
+identify any constructs that would use any of the features so
+proscribed
address@hidden
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0042],ARef=[AI95-00130-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  No_Local_Allocators no longer prohibits generic instantiations.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01]}
+  @ChgAdded{Version=[2],Text=[Wide_Wide_Text_IO (which is new) is added to the
+  No_IO restriction.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00347-01]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[The title of this 
@Chg{Version=[3],New=[subclause],Old=[clause]} was changed to match the
+  change to the Annex title. Pragma Profile(Ravenscar) is part of this annex.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00394-01]}
+  @ChgAdded{Version=[2],Text=[Restriction No_Dependence is used instead of
+  special @i<restriction_>@nt<identifier>s. The old names are banished to
+  Obsolescent Features (see @RefSecNum{Dependence Restriction Identifiers}).]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00394-01]}
+  @ChgAdded{Version=[2],Text=[The bizarre wording @lquotes@;apply in this
+  address@hidden (which no one quite can explain the meaning of) is banished.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0152-1],ARef=[AI05-0190-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 95}Restrictions
+  No_Anonymous_Allocators, No_Coextensions, and No_Access_Parameter_Allocators
+  are new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0189-1]}
+  @ChgAdded{Version=[3],Text=[New restriction
+  No_Standard_Allocators_After_Elaboration is added to the list of
+  restrictions that are required by this annex.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0263-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Ada 2005 restriction 
No_Dependence
+  is added where needed (this was missed in Ada 2005).]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0272-1]}
+  @ChgAdded{Version=[3],Text=[Restrictions against individual aspects, pragmas,
+  and attributes do not apply to the run-time system, in order that an
+  implementation can use whatever aspects, pragmas, and attributes are needed
+  to do the job. For instance, attempting to write a run-time system for Linux
+  that does not use the Import aspect would be very difficult and probably is
+  not what the user is trying to prevent anyway.]}
address@hidden
+
+
address@hidden,Name=[Pragma Detect_Blocking]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00305-01]}
address@hidden,Text=[The following @nt{pragma} forces an implementation
+to detect potentially blocking operations within a protected operation.]}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00305-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The form of a
address@hidden Detect_Blocking is as follows:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[2],@ChgAdded{Version=[2],
address@hidden @prag<Detect_Blocking>;]}>
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00305-01]}
address@hidden,address@hidden pragma], Sec=(Detect_Blocking)}
address@hidden, configuration], Sec=(Detect_Blocking)}
+A @nt{pragma} Detect_Blocking is a configuration
+pragma.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00305-01]}
address@hidden,Text=[An implementation is required to detect a
+potentially blocking operation within a protected operation, and to raise
+Program_Error (see @RefSecNum{Protected Subprograms and Protected Actions}).]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00305-01]}
address@hidden,Text=[An implementation is allowed to reject a
address@hidden if a potentially blocking operation is present directly
+within an @nt{entry_body} or the body of a protected subprogram.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00305-01]}
address@hidden,Text=[An operation that causes a task to be blocked
+within a foreign language domain is not defined to be potentially blocking,
+and need not be detected.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00305-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Pragma Detect_Blocking is new.]}
address@hidden
+
address@hidden@Comment{For printed version of Ada 2005 RM}
address@hidden,Name=[Pragma Partition_Elaboration_Policy]}
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00265-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[This @Chg{Version=[3],New=[subclause],Old=[clause]}
+defines a @nt{pragma} for user control over elaboration policy.]}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00265-01]}
address@hidden,Type=[Leading],Keepnext=[T],Text=[The form of a
address@hidden Partition_Elaboration_Policy is as follows:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden<Version=[2],@ChgAdded{Version=[2],
address@hidden @prag<Partition_Elaboration_Policy> 
(@SynI<policy_>@Syn2<identifier>);]}>
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[The @SynI<policy_>@nt{identifier} shall be either
+Sequential, Concurrent or an implementation-defined identifier.]}
address@hidden,Kind=[AddedNormal],address@hidden,New=[Implementation-defined
address@hidden<policy_>@nt<identifier>s allowed in a @nt{pragma} 
Partition_Elaboration_Policy.],Old=[]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Note that the Ravenscar profile (see
address@hidden Ravenscar Profile}) has nothing to say about which
+Partition_Elaboration_Policy is used. This was intentionally omitted from the
+profile, as there was no agreement as to whether the Sequential policy should
+be required for Ravenscar programs. As such it was defined separately.]}
address@hidden
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00265-01]}
address@hidden,address@hidden pragma], Sec=(Partition_Elaboration_Policy)}
address@hidden, configuration], Sec=(Partition_Elaboration_Policy)}
+A @nt{pragma} Partition_Elaboration_Policy is a configuration pragma.
+It specifies the elaboration policy for a partition.
+At most one elaboration policy shall be specified for a partition.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00265-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[If the Sequential policy is
+specified for a address@hidden,New=[,],Old=[]} then pragma
+Restrictions (No_Task_Hierarchy) shall also be specified for the partition.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00265-01]}
address@hidden,address@hidden what this
+International Standard
+says elsewhere, this @nt{pragma} allows partition elaboration rules concerning
+task activation and interrupt attachment to be changed. If the
address@hidden@nt{identifier} is Concurrent, or if there is no pragma
+Partition_Elaboration_Policy defined for the partition, then the rules defined
+elsewhere in this Standard apply.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00265-01],ARef=[AI95-00421-01]}
address@hidden,Type=[Leading],Text=[If the partition elaboration policy
+is Sequential, then task activation and interrupt attachment are performed in
+the following sequence of steps:]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The activation of all library-level tasks and the
+  attachment of interrupt handlers are deferred until all library units are
+  elaborated.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The interrupt handlers are attached by the
+  environment task.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The environment task is suspended while the
+  library-level tasks are activated.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The environment task executes the main subprogram
+  (if any) concurrently with these executing tasks.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00265-01],ARef=[AI95-00421-01]}
address@hidden,Text=[If several dynamic interrupt handler attachments for
+the same interrupt are deferred, then the most recent call of
+Attach_Handler or Exchange_Handler determines which handler is attached.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00265-01],ARef=[AI95-00421-01]}
address@hidden,Text=[If any deferred task activation fails, Tasking_Error
+is raised at the beginning of the sequence of statements of the
+body of the environment task prior to calling the
+main subprogram.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00265-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[If the partition elaboration policy is Sequential
+and the Environment task becomes permanently blocked during
address@hidden,New=[,],Old=[]} then the partition is deadlocked and
+it is recommended that the partition be immediately terminated.]}
address@hidden,Kind=[Revised],InitialVersion=[2],
address@hidden,
+Text=[If the partition elaboration policy is Sequential
+and the Environment task becomes permanently blocked during
address@hidden,New=[,],Old=[]} then
+the partition should be immediately terminated.]}]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00265-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[If the partition elaboration policy is Sequential
+and any task activation address@hidden,New=[,],Old=[]} then an
+implementation may immediately terminate the active partition to mitigate the
+hazard posed by continuing to execute with a subset of the tasks being 
active.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00421-01]}
address@hidden,Text=[If any deferred task activation fails, the
+environment task is unable to handle the Tasking_Error exception and completes
+immediately. By contrast, if the partition elaboration policy is Concurrent,
+then this exception could be handled within a library unit.]}
address@hidden
+
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00265-01],ARef=[AI95-00421-01]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  @nt{Pragma} Partition_Elaboration_Policy is new.]}
address@hidden
+
+
+
+
diff --git a/packages/ada-ref-man/source_2012/sp.mss 
b/packages/ada-ref-man/source_2012/sp.mss
new file mode 100755
index 0000000..7f56599
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/sp.mss
@@ -0,0 +1,2670 @@
address@hidden $Source: e:\\cvsroot/ARM/Source/sp.mss,v $ }
address@hidden $Revision: 1.80 $ $Date: 2015/04/03 04:12:43 $ $Author: randy $ }
address@hidden(sysprog, Root="ada.mss")
address@hidden: 2015/04/03 04:12:43 $}
+
address@hidden Programming}
+
address@hidden
address@hidden@Defn{systems programming}
address@hidden programming}
address@hidden systems}
address@hidden systems}
address@hidden systems}
address@hidden systems}
+The Systems Programming Annex specifies additional capabilities
+provided for low-level programming. These capabilities are also
+required in many real-time, embedded, distributed, and information systems.]
address@hidden
+
address@hidden
address@hidden to Ada 83}
+This Annex is new to Ada 95.
address@hidden
+
address@hidden to Machine Operations}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} specifies rules 
regarding access to machine instructions
+from within an Ada program.]
address@hidden,Kind=[Revised],InitialVersion=[0],
address@hidden,
+New=[Implementation-defined intrinsic subprograms],
+Old=[Support for access to machine instructions]}.]}
address@hidden
+
address@hidden
address@hidden code insertion}
+The implementation shall support machine code insertions
+(see @RefSecNum{Machine Code Insertions}) or intrinsic subprograms
+(see @RefSecNum{Conformance Rules}) (or both).
+Implementation-defined attributes shall be provided to
+allow the use of Ada entities as operands.
address@hidden
+
address@hidden
+The machine code or intrinsics support should allow access to all
+operations normally available to assembly language programmers for the
+target environment,
+including privileged instructions, if any.
address@hidden,Kind=[Added],address@hidden,
+Text=[The machine code or intrinsics support should allow access to all
+operations normally available to assembly language programmers for the
+target environment.]}]}
address@hidden
+Of course, on a machine with protection, an attempt to execute a
+privileged instruction in user mode will probably trap.
+Nonetheless, we want implementations to provide access to them so that
+Ada can be used to write systems programs that run in privileged mode.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden to assembly language}
address@hidden, Sec=(interface to assembly)}
address@hidden programs}
address@hidden language}
+The @Chg{Version=[3],New=[support for ],Old=[]}interfacing 
@Chg{Version=[3],New=[aspects],Old=[pragmas]}
+(see @RefSecNum{Interface to Other Languages})
+should @Chg{Version=[3],New=[include],Old=[support]} interface to assembler;
+the default assembler should be associated with the convention
+identifier Assembler.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Interface to assembler should be supported; the default assembler
+should be associated with the convention identifier Assembler.]}]}
+
+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.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If an entity is exported to assembly language, then the implementation
+should allocate it at an addressable location even if not otherwise referenced
+from the Ada code. A call to a machine code or assembler subprogram should
+be treated as if it could read or update every object that is
+specified as exported.]}]}
address@hidden
+
address@hidden
+
+The implementation shall document the overhead associated with calling
+machine-code or intrinsic subprograms, as compared to a fully-inlined
+call, and to a regular out-of-line call.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The overhead of calling machine-code or intrinsic subprograms.]}]}
+
+The implementation shall document the types of
+the package System.Machine_Code usable for machine code
+insertions, and the attributes to be used in
+machine code insertions for references to Ada entities.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The types and attributes used in machine code insertions.]}]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The implementation shall document the subprogram calling conventions
+associated with the convention identifiers available for use
+with the @Chg{Version=[3],New=[Convention aspect],Old=[interfacing pragmas]}
+(Ada and Assembler, at a minimum),
+including register saving,
+exception propagation, parameter passing, and function value returning.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The subprogram calling conventions for all supported convention
+identifiers.]}]}
+
+For exported and imported subprograms,
+the implementation shall document the mapping
+between the Link_Name string, if specified, or
+the Ada designator, if not, and the external link name used
+for such a subprogram.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Implementation-defined aspects of access to machine operations.]}]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The mapping between the Link_Name or Ada designator and the external
+link name.]}]}
+
address@hidden
+
address@hidden
+
+The implementation should ensure that little or no overhead is associated
+with calling intrinsic and machine-code subprograms.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Little or no overhead should be associated
+with calling intrinsic and machine-code subprograms.]}]}
+
address@hidden@;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. Examples of such instructions
+include:
address@hidden
+
+Atomic read-modify-write operations @em e.g., test and set, compare and swap,
+decrement and test, enqueue/dequeue.
+
+Standard numeric functions @em e.g., @i{sin}, @i{log}.
+
+String manipulation operations @em e.g., translate and test.
+
+Vector operations @em e.g., compare vector against thresholds.
+
+Direct operations on I/O ports.
+
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Intrinsic subprograms should be provided to access any machine operations
+that provide special capabilities or efficiency not normally available.]}]}
+
address@hidden
+
address@hidden Representation Support}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+This @Chg{Version=[3],New=[subclause],Old=[clause]} specifies minimal 
requirements on the
address@hidden,New=[],Old=[implementation's ]}support for representation
+items and related features.
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden level of support], Sec=(required in Systems
+Programming Annex)}
+The implementation shall support at least the functionality
+defined by the recommended levels of support in @Chg{Version=[3],New=[Clause],
+Old=[Section]} @RefSecNum{Representation Issues}.
address@hidden
+
address@hidden Support}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} specifies
+the language-defined model for hardware interrupts
+in addition to mechanisms for handling interrupts.]
address@hidden,See=(interrupt)}
address@hidden
+
address@hidden
+
address@hidden
address@hidden @i{interrupt} represents a class of events that are detected by
+the hardware or the system software.]
address@hidden, Sec=(of an interrupt)}
+Interrupts are said to occur. An @i{occurrence} of an interrupt is
+separable into generation and delivery.
address@hidden, Sec=(of an interrupt)}
address@hidden of an interrupt is the event in the underlying hardware
+or system that makes the interrupt available to the program.
address@hidden, Sec=(of an interrupt)}
address@hidden is the action that invokes part of the program as
+response to the interrupt occurrence.
address@hidden interrupt occurrence}
+Between generation and delivery, the interrupt occurrence @Redundant[(or
+interrupt)] is @i{pending}.
address@hidden interrupt}
+Some or all interrupts may be @i{blocked}. When an interrupt is blocked, all
+occurrences of that interrupt are prevented from being delivered.
address@hidden, Sec=(to an interrupt)}
address@hidden interrupt}
+Certain interrupts are @i{reserved}. The set of reserved interrupts is
+implementation defined. A reserved interrupt is either an interrupt for
+which user-defined handlers are not supported, or one which
+already has an attached handler by some other implementation-defined means.
address@hidden address@hidden,Sec=[interrupt]}
+Program units can be connected to nonreserved interrupts. While
+connected, the program unit is said to be @i{attached} to that interrupt.
+The execution of that program unit, the @i{interrupt handler}, is invoked upon
+delivery of the interrupt occurrence.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Implementation-defined aspects of interrupts.]}]}
address@hidden
+  As an obsolescent feature,
+  interrupts may be attached to task entries by an address clause.
+  See @RefSecNum{Interrupt Entries}.
address@hidden
+
+While a handler is attached to an interrupt, it is called once for each
+delivered occurrence of that interrupt. While the handler executes, the
+corresponding interrupt is blocked.
+
+While an interrupt is blocked, all occurrences of that interrupt are prevented
+from being delivered. Whether such occurrences remain pending or are lost is
+implementation defined.
+
address@hidden treatment}
+Each interrupt has a @i{default treatment} which determines the system's
+response to an occurrence of that interrupt when no user-defined
+handler is attached. The set of possible default treatments is
+implementation defined, as is the method (if one exists) for configuring
+the default treatments for interrupts.
+
+An interrupt is delivered to the handler (or default treatment) that is in
+effect for that interrupt at the time of delivery.
+
+An exception propagated from a handler that is invoked by an
+interrupt has no effect.
+
address@hidden the Ceiling_Locking policy (see @RefSecNum{Priority Ceiling 
Locking}) is
+in effect, the interrupt handler executes with the active priority that is the
+ceiling priority of the corresponding protected object.]
+
address@hidden
+
address@hidden
+
+The implementation shall provide a mechanism to determine the minimum
+stack space that is needed
+for each interrupt handler and to reserve that space for
+the execution of the handler. @Redundant{This space should accommodate
+nested invocations of the handler where the system permits this.}
+
+If the hardware or the underlying system holds pending interrupt
+occurrences, the implementation shall provide for later delivery
+of these occurrences to the program.
+
+If the Ceiling_Locking policy is not in effect, the implementation
+shall provide means for the application to specify whether interrupts
+are to be blocked during protected actions.
+
address@hidden
+
address@hidden
address@hidden@;The implementation shall document the following items:
address@hidden
+This information may be different for different forms of interrupt handlers.
address@hidden
address@hidden
+For each interrupt, which interrupts are blocked from delivery when a handler
+attached to that interrupt executes (either as a result of an interrupt
+delivery or of an ordinary call on a procedure of the corresponding
+protected object).
+
+Any interrupts that cannot be blocked, and the effect of attaching
+handlers to such interrupts, if this is permitted.
+
+Which run-time stack an interrupt handler uses when it executes as a
+result of an interrupt delivery; if this is configurable, what is the
+mechanism to do so; how to specify how much space to reserve on that stack.
+
+Any implementation- or hardware-specific activity that happens
+before a user-defined interrupt handler gets control (e.g.,
+reading device registers, acknowledging devices).
+
+Any timing or other limitations imposed on the execution of interrupt handlers.
+
+The state (blocked/unblocked) of the nonreserved interrupts
+when the program starts; if some interrupts are unblocked, what
+is the mechanism a program can use to protect itself before it
+can attach the corresponding handlers.
+
+Whether the interrupted task is allowed to resume execution before the
+interrupt handler returns.
+
+The treatment of interrupt occurrences that are generated while
+the interrupt is blocked; i.e., whether one or more occurrences
+are held for later delivery, or all are lost.
+
+Whether predefined or implementation-defined exceptions are raised as a
+result of the occurrence of any interrupt, and the mapping between the
+machine interrupts (or traps) and the predefined
+exceptions.
+
+On a multi-processor, the rules governing the delivery of an interrupt
+to a particular processor.
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The treatment of interrupts.]}]}
address@hidden Bob Duff explanation, but this is just too much junk.}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+If the underlying system or hardware does not allow interrupts to be
+blocked, then no blocking is required @Redundant[as part of the execution of
+subprograms of a protected object @Chg{Version=[2],New=[for which],Old=[whose]}
+one of its subprograms is an interrupt handler].
+
+In a multi-processor with more than one interrupt subsystem, it is
+implementation defined whether (and how) interrupt sources from
+separate subsystems share the same Interrupt_Id type
+(see @RefSecNum{The Package Interrupts}).
+In particular, the meaning of a blocked or pending interrupt may then be
+applicable to one processor only.
address@hidden
+This issue is tightly related to the issue of scheduling on a
+multi-processor. In a sense, if a particular interrupt source is not
+available to all processors, the system is not truly homogeneous.
+
+One way to approach this problem is to assign sub-ranges within
+Interrupt_Id to each interrupt subsystem, such that @lquotes@;address@hidden@; 
interrupt
+sources (e.g. a timer) in different subsystems get a distinct id.
address@hidden
+
+Implementations are allowed to impose timing or other limitations on the
+execution of interrupt handlers.
address@hidden
+These limitations are often necessary to ensure proper behavior of the
+implementation.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
+Other forms of handlers are allowed to be supported, in which
address@hidden,New=[],Old=[,]} the rules of this
address@hidden,New=[subclause],address@hidden,New=[clause],Old=[subclause]}]}
+should be adhered to.
+
+The active priority of the execution of an interrupt handler is allowed to
+vary from one occurrence of the same interrupt to another.
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+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 @Chg{Version=[2],New=[finer-grained],Old=[a finer-grain]} control of
+interrupt blocking.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If the Ceiling_Locking policy is not in effect and the target system
+allows for finer-grained control of interrupt blocking, a means for the
+application to specify which interrupts are to be blocked during protected
+actions should be provided.]}]}
+
address@hidden
+
address@hidden
+
+The default treatment for an interrupt can be to keep the
+interrupt pending or to deliver it to an implementation-defined
+handler. Examples of actions that an implementation-defined
+handler is allowed to perform include aborting the partition, ignoring
+(i.e., discarding occurrences of) the interrupt, or queuing one
+or more occurrences of the interrupt for possible later delivery
+when a user-defined handler is attached to that interrupt.
+
+It is a bounded error to call Task_Identification.Current_Task
+(see @RefSecNum{The Package Task_Identification}) from an interrupt handler.
+
+The rule that an exception propagated from an interrupt handler has no effect
+is modeled after the rule about exceptions propagated out of task bodies.
+
address@hidden
+
address@hidden Procedure Handlers}
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 1
+through 6 were moved to @RefSec{Obsolescent Features}.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],KeepNext=[T],Text=[The form of a
address@hidden Interrupt_Handler is as follows:]}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden<Version=[3],InitialVersion=[0],@ChgDeleted{Version=[3],
address@hidden @prag(Interrupt_Handler)(@address@hidden);]}>
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],KeepNext=[T],Text=[The form of a
address@hidden Attach_Handler is as follows:]}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden<Version=[3],InitialVersion=[0],@ChgDeleted{Version=[3],
address@hidden @prag(Attach_Handler)(@address@hidden, @Syn2{expression});]}>
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Text=[For the Interrupt_Handler and Attach_Handler
+pragmas, the @address@hidden shall resolve to denote a protected
+procedure with a parameterless profile.]}
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Text=[For the Attach_Handler pragma, the expected type
+for the @nt{expression} is Interrupts.Interrupt_Id
+(see @RefSecNum{The Package Interrupts}).]}
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[For a parameterless protected
+procedure, the following language-defined representation aspects may be
+specified:]}
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden
+The type of aspect Interrupt_Handler is Boolean.
+If directly specified, the aspect_definition shall be a static expression.
address@hidden aspect is never inherited;] if not directly specified,
+the aspect is address@hidden
+
address@hidden,Kind=[AddedNormal],Aspect=[Interrupt_Handler],
+  address@hidden,Text=[Protected procedure may be attached to
+    interrupts.]}]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden
+The aspect Attach_Handler is an @nt{expression}, which shall be of type
+Interrupts.Interrupt_Id. @Redundant[This aspect is never
address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Attach_Handler],
+    address@hidden,Text=[Protected procedure is attached to an
+      interrupt.]}]}
+
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0033-1],ARef=[AI05-0229-1]}
address@hidden,New=[If either the],Old=[The]} Attach_Handler
address@hidden,New=[or Interrupt_Handler aspect are specified for a
+protected procedure, the],Old=[pragma is only allowed immediately within the
address@hidden where the corresponding subprogram is declared.
+The]} corresponding @address@hidden@!declaration}
+or @address@hidden@!declaration}
+shall be a address@hidden,New=[-],Old=[]}level
address@hidden,New=[ and shall not be declared within a
+generic body. @PDefn{generic contract issue}In addition
+to the places where @LegalityTitle normally apply
+(see @RefSecNum{Generic Instantiation}), this rule also applies
+in the private part of an instance of a generic unit],Old=[]}.
+
address@hidden
+In the case of a @nt{protected_type_declaration},
+an @nt{object_declaration} of an object of that type
+need not be at library level.
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0033-1],ARef=[AI05-0229-1]}
address@hidden,Text=[We cannot allow these aspects in protected
+declarations in a generic body, because legality rules are not checked for
+instance bodies, and these should not be allowed if the instance is not at the
+library level. The protected types can be declared in the private part if this
+is desired. Note that while the 'Access to use the handler would provide the
+check in the case of Interrupt_Handler, there is no other check for
+Attach_Handler. Since these aspects are so similar, we want the rules to be the
+same.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00253-01],ARef=[AI95-00303-01]}
address@hidden,Kind=[Deleted],ARef=[AI05-0033-1]}
address@hidden,Text=[The Interrupt_Handler pragma is only
+allowed immediately within @Chg{Version=[2],New=[the],Old=[a]}
address@hidden@Chg{Version=[2],New=[ where the
+corresponding subprogram is declared],Old=[]}.
+The address@hidden @address@hidden @Chg{Version=[2],New=[or
address@hidden@address@hidden ],Old=[]}shall
+be a address@hidden,New=[-],Old=[]}level
address@hidden,New=[],Old=[ In addition, any
address@hidden@!declaration} of such a type shall be a library level 
declaration.]}]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+If the @Chg{Version=[3],New=[],Old=[pragma ]}Interrupt_Handler
address@hidden,New=[aspect of a protected procedure is True],Old=[appears in a
address@hidden, then the
address@hidden,New=[],Old=[corresponding ]}procedure
address@hidden,New=[may],Old=[can]}
+be attached dynamically, as a handler, to
+interrupts (see @RefSecNum{The Package Interrupts}).
address@hidden procedures are allowed to be attached to multiple interrupts.]
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden, Sec=(of a protected object)}
address@hidden, Sec=(of a protected object)}
+The @nt{expression} @Chg{Version=[3],New=[specified for],Old=[in]} the
+Attach_Handler @Chg{Version=[3],New=[aspect of a protected procedure @i<P>
+is evaluated as part of the creation of the protected object that
+contains @i<P>.
+The value of the @nt{expression} identifies],Old=[pragma @Redundant[as 
evaluated at
+object creation time] specifies]} an interrupt. As part
+of the initialization of that object,
address@hidden,address@hidden<P> (],Old=[if the Attach_Handler pragma is
+specified, ]}the @SynI{handler}
address@hidden,New=[)],Old=[]}
+is attached to the @Chg{Version=[3],New=[identified],Old=[specified]} 
interrupt.
address@hidden
+A check is made that the corresponding interrupt is not reserved.
address@hidden,Sec=(raised by failure of run-time check)}
+Program_Error is raised if the check fails, and the existing treatment
+for the interrupt is not affected.
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden, Sec=(of a protected object)}
address@hidden
+If the Ceiling_Locking policy (see @RefSecNum{Priority Ceiling Locking}) is
+in address@hidden,New=[,],Old=[]} then upon the initialization of a
+protected object @Chg{Version=[3],New=[that contains a protected
+procedure ],address@hidden,New=[for which],Old=[that]} either
address@hidden,New=[the],Old=[an]}
address@hidden,New=[ aspect is specified],Old=[]} or
address@hidden,New=[the ],Old=[]} Interrupt_Handler
address@hidden,New=[aspect is True],Old=[pragma applies to one of its
+procedures]},
+a check is made that the @Chg{Version=[3],New=[initial ],Old=[]}ceiling
+priority @Chg{Version=[3],New=[of the object],Old=[defined in the
address@hidden is in the range of address@hidden
address@hidden,Sec=(raised by failure of run-time check)}
+If the check fails, Program_Error is raised.
+
address@hidden,Kind=[Revised],Ref=[8652/0068],ARef=[AI95-00121-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden, Sec=(of a protected object)}
+When a protected object is finalized, for any of its procedures that are
+attached to interrupts, the handler is detached. If the handler was
+attached by a procedure in the Interrupts package or if no user
+handler was previously attached to the interrupt, the default treatment is
+restored. @Chg{New=[If @Chg{Version=[3],New=[the],Old=[an]} address@hidden
address@hidden,New=[aspect],Old=[pragma]} was
address@hidden,New=[specified],Old=[used]} and the most recently
+attached handler for the same interrupt is the same as the one that was
+attached at the time the protected object was initialized],
+Old=[Otherwise, @Redundant[that is, if an
address@hidden pragma was specified]]}, the previous handler is
+restored.
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0068],ARef=[AI95-00121-01]}
address@hidden,Kind=[Revised],ARef=[AI95-00303-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden all protected objects for interrupt handlers are declared at the
address@hidden,New=[ ],Old=[-]}level],Old=[Since only library-level
+protected procedures can be attached as
+handlers using the Interrupts package]}, the finalization discussed above
+occurs only as part of the finalization of all library-level packages in
+a partition.
address@hidden, objects of a protected type containing
address@hidden,New=[procedures with ],Old=[]}an address@hidden
address@hidden,New=[aspect specified],Old=[pragma]} need not be at the library 
level.
+Thus, an implementation needs to be
+able to restore handlers during the execution of the address@hidden,
+New=[ (An object with an address@hidden 
@Chg{Version=[3],New=[aspect],Old=[pragma]}
+also need not be at the library level, but such
+a handler cannot be attached to an interrupt using the Interrupts package.)],
+Old=[]}],Old=[]}
address@hidden
+
+When a handler is attached to an interrupt, the interrupt is blocked
address@hidden(subject to the @ImplPermName in @RefSecNum{Interrupt Support})]
+during the execution of every protected action on the protected object
+containing the handler.
+
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)}
+If the Ceiling_Locking policy (see @RefSecNum{Priority Ceiling Locking}) is
+in effect and an interrupt is delivered to a handler, and the interrupt
+hardware priority is higher than the ceiling priority of the corresponding
+protected object, the execution of the program is erroneous.
+
address@hidden,Kind=[Added],Ref=[8652/0068],ARef=[AI95-00121-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI05-0229-1]}
address@hidden,address@hidden(erroneous execution),Sec=(cause)}
+If the handlers for a given interrupt attached via
address@hidden,New=[aspect],Old=[pragma]} Attach_Handler
+are not attached and detached in a stack-like (LIFO) order,
+program execution is erroneous. In particular, when a protected object is
+finalized, the execution is erroneous if any of the procedures of the
+protected object are attached to interrupts via
address@hidden,New=[aspect],Old=[pragma]} address@hidden and
+the most recently attached handler for the same interrupt is not the same as
+the one that was attached at the time the protected object was initialized.]}
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0068],ARef=[AI95-00121-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Text=[This simplifies implementation of the address@hidden
address@hidden,New=[aspect],Old=[pragma]} by not requiring a check that the
+current handler is the same as the one attached by the initialization of a
+protected object.]}
address@hidden
address@hidden
+
address@hidden
address@hidden@Keepnext@;The following metric shall be documented by the 
implementation:
address@hidden was @begin{enumerate}, which is wrong}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+The address@hidden,New=[-],Old=[ ]}case overhead for an interrupt
+handler that is a parameterless
+protected procedure, in clock cycles. This is the execution time not
+directly attributable to the handler procedure or the interrupted execution.
+It is estimated as C @en@; (A+B), where A is how long it takes to complete a 
given
+sequence of instructions without any interrupt, B is how long it takes to
+complete a normal call to a given protected procedure, and C is how long it
+takes to complete the same sequence of instructions when it is interrupted by
+one execution of the same procedure called via an interrupt.
address@hidden
+The instruction sequence and interrupt handler used to measure interrupt
+handling overhead should be chosen so as to maximize the execution time cost
+due to cache misses. For example, if the processor has cache memory and the
+activity of an interrupt handler could invalidate the contents of cache 
memory, the handler should be written such that it invalidates all of the cache 
memory.
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The metrics for interrupt handlers.]}]}
address@hidden was @end{enumerate}, which is wrong}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+When the @Chg{Version=[3],New=[aspects],Old=[pragmas]} Attach_Handler or
+Interrupt_Handler @Chg{Version=[3],New=[are specified for],Old=[apply to]}
+a protected procedure, the implementation is allowed to impose
+implementation-defined restrictions on the
+corresponding @address@hidden@!declaration} and @address@hidden
address@hidden
+The restrictions may be on the constructs that are allowed within them,
+and on ordinary calls (i.e. not via interrupts) on protected operations in
+these protected objects.
address@hidden
address@hidden,Kind=[Revised],InitialVersion=[2],
address@hidden,
+New=[Any restrictions on a protected procedure or its containing type when
address@hidden,New=[an aspect],Old=[a @nt{pragma}]}
+Attach_handler or Interrupt_Handler
address@hidden,New=[is specified],Old=[applies]}.],Old=[]}]}
+
+An implementation may use a different mechanism for invoking a protected
+procedure in response to a hardware interrupt than is used for a call
+to that protected procedure from a task.
address@hidden
+This is despite the fact that the priority of an interrupt handler
+(see @RefSecNum{Task Priorities}) is modeled after a hardware task calling the
+handler.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden
+Notwithstanding what this subclause says elsewhere,
+the Attach_Handler and Interrupt_Handler
address@hidden,New=[aspects],Old=[pragmas]} are allowed to be used
+for other, implementation defined, forms of interrupt handlers.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+For example, if an implementation wishes to allow interrupt
+handlers to have parameters, it is allowed to do so via these
address@hidden,New=[aspects],Old=[pragmas]};
+it need not invent implementation-defined
address@hidden,New=[aspects],Old=[pragmas]} for the purpose.
address@hidden
address@hidden,Kind=[Revised],InitialVersion=[2],
address@hidden,
+New=[Any other forms of interrupt handler supported by the
+Attach_Handler and Interrupt_Handler
address@hidden,New=[aspects],Old=[pragmas]}.],Old=[]}]}
+
address@hidden
+
address@hidden
+
+Whenever possible, the implementation should allow interrupt handlers to be
+called directly by the hardware.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Interrupt handlers should be called directly by the hardware.]}]}
+
+Whenever practical, the implementation should
+detect violations of any implementation-defined restrictions
+before run time.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Violations of any implementation-defined restrictions on interrupt
+handlers should be detected before run time.]}]}
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The Attach_Handler @Chg{Version=[3],New=[aspect may],Old=[pragma can]}
+provide static attachment of handlers to
+interrupts if the implementation supports preelaboration of protected
+objects. (See @RefSecNum{Preelaboration Requirements}.)
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
address@hidden,New=[A],Old=[The ceiling priority of a]}
+protected object that
address@hidden,New=[has a (protected) procedure],
+Old=[one of its procedures is]}
+attached to an interrupt should
address@hidden,New=[have a ceiling priority],
+Old=[be]} at least as high as the highest
+processor priority at which that interrupt will ever be delivered.
+
+Protected procedures can also be attached dynamically to interrupts
+via operations declared in the predefined package Interrupts.
+
+An example of a possible implementation-defined restriction is
+disallowing the use of the standard storage pools within the body of
+a protected procedure that is an interrupt handler.
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00253-01]}
+  @ChgAdded{Version=[2],address@hidden with Ada 95}
+  @b[Amendment Correction:] Corrected the wording so that the rules for the
+  use of Attach_Handler and Interrupt_Handler are identical. This means
+  that uses of pragma Interrupt_Handler outside of the target protected type
+  or single protected object are now illegal.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0068],ARef=[AI95-00121-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified the meaning of
+  @lquotes@;the previous address@hidden when finalizing protected objects
+  containing interrupt handlers.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00303-01]}
+  @ChgAdded{Version=[2],Text=[Dropped the requirement that an object of a
+  type containing an Interrupt_Handler pragma must be declared at the library
+  level. This was a generic contract model violation. This change is not
+  an extension, as an attempt to attach such a handler with a routine in
+  package Interrupts will fail an accessibility check anyway. Moreover,
+  implementations can retain the rule as an implementation-defined
+  restriction on the use of the type, as permitted by the @ImplPermTitle
+  above.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Aspects Interrupt_Handler and Attach_Handler are new; @nt{pragma}s
+  Interrupt_Handler and Attach_Handler are now obsolescent.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0033-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Added missing generic contract wording for the aspects Attach_Handler and
+  Interrupt_Handler.]}
address@hidden
+
+
+
address@hidden Package Interrupts}
+
address@hidden
+
address@hidden@Keepnext@;The following language-defined packages exist:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0167-1]}
address@hidden System;@ChildUnit{Parent=[Ada],address@hidden,New=[
address@hidden System.Multiprocessors;],Old=[]}
address@hidden Ada.Interrupts @key[is]
+   @key[type] @AdaTypeDefn{Interrupt_Id} @key[is] @RI{implementation-defined};
+   @key[type] @AdaTypeDefn{Parameterless_Handler} @key[is]
+      @key[access] @key[protected] @key[procedure];
+
address@hidden, Kind=[Deleted]}
address@hidden<>,Old=<@ @;@comment{Empty paragraph to hang junk paragraph 
number from original RM}>]
+
+   @key[function] @AdaSubDefn{Is_Reserved} (Interrupt : Interrupt_Id)
+      @key[return] Boolean;
+
+   @key[function] @AdaSubDefn{Is_Attached} (Interrupt : Interrupt_Id)
+      @key[return] Boolean;
+
+   @key[function] @AdaSubDefn{Current_Handler} (Interrupt : Interrupt_Id)
+      @key[return] Parameterless_Handler;
+
+   @key[procedure] @AdaSubDefn{Attach_Handler}
+      (New_Handler : @key[in] Parameterless_Handler;
+       Interrupt   : @key[in] Interrupt_Id);
+
+   @key[procedure] @AdaSubDefn{Exchange_Handler}
+      (Old_Handler : @key[out] Parameterless_Handler;
+       New_Handler : @key[in] Parameterless_Handler;
+       Interrupt   : @key[in] Interrupt_Id);
+
+   @key[procedure] @AdaSubDefn{Detach_Handler}
+      (Interrupt : @key[in] Interrupt_Id);
+
+   @key[function] @AdaSubDefn{Reference} (Interrupt : Interrupt_Id)
+      @key{return} System.Address;
+
address@hidden,Kind=[Added],ARef=[AI05-0167-1]}
address@hidden,Text=[   @key[function] @AdaSubDefn{Get_CPU} (Interrupt : 
Interrupt_Id)
+      @key{return} System.Multiprocessors.CPU_Range;]}
+
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden Ada.Interrupts;
+
+
address@hidden Ada.Interrupts.Names @address@hidden,Child=[Names]}
+   @RI{implementation-defined} : @key[constant] Interrupt_Id :=
+     @RI{implementation-defined};
+      . . .
+   @RI{implementation-defined} : @key[constant] Interrupt_Id :=
+     @RI{implementation-defined};
address@hidden Ada.Interrupts.Names;
address@hidden
+
address@hidden
+
address@hidden
+
+The Interrupt_Id type is an implementation-defined discrete type used to
+identify interrupts.
+
+The Is_Reserved function returns True if and only if the specified
+interrupt is reserved.
+
+The Is_Attached function returns True if and only if a user-specified
+interrupt handler is attached to the interrupt.
+
address@hidden,Kind=[Revised],Ref=[8652/0069],ARef=[AI95-00166-01]}
+The Current_Handler function returns a value that represents the
+attached handler of the interrupt. If no user-defined handler is attached to
+the interrupt, Current_Handler returns @address@hidden,
+Old=[a value that designates the default treatment; calling Attach_Handler
+or Exchange_Handler with this value restores the default treatment]}.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+The Attach_Handler procedure attaches the specified handler to the
+interrupt, overriding any existing treatment (including a user handler)
+in effect for that interrupt.
+If New_Handler is @key[null], the default treatment is restored.
address@hidden,Sec=(raised by failure of run-time check)}
+If New_Handler designates a protected procedure @Chg{Version=[3],New=[for],
+Old=[to]} which the @Chg{Version=[3],New=[aspect],
+Old=[pragma]}
address@hidden @Chg{Version=[3],New=[is False],Old=[does not apply]},
+Program_Error is raised. In
+this case, the operation does not modify the existing interrupt treatment.
+
address@hidden,Kind=[Revised],Ref=[8652/0069],ARef=[AI95-00166-01]}
+The Exchange_Handler procedure operates in the same manner as Attach_Handler
+with the addition that the value returned in Old_Handler designates the
+previous treatment for the specified address@hidden If the previous
+treatment is not a user-defined handler, @key[null] is returned.],Old=[]}
address@hidden
+Calling Attach_Handler or Exchange_Handler with this value for New_Handler
+restores the previous handler.
+
address@hidden,Kind=[Added],Ref=[8652/0069],ARef=[AI95-00166-01]}
address@hidden,Text=[If the application uses only parameterless procedures as
+handlers (other types of handlers may be provided by the implementation, but 
are not
+required by the standard), then if Old_Handler is not @key(null), it may be
+called to execute the previous handler. This provides a way to cascade
+application interrupt handlers. However, the default handler cannot be
+cascaded this way (Old_Handler must be @key(null) for the default handler).]}
address@hidden
+
+The Detach_Handler procedure restores the default treatment for the
+specified interrupt.
+
+For all operations defined in this package that take a parameter of type
+Interrupt_Id, with the exception of Is_Reserved and Reference, a check is
+made that the specified interrupt is not reserved.
address@hidden,Sec=(raised by failure of run-time check)}
+Program_Error is raised if this check fails.
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+If, by using the Attach_Handler, Detach_Handler, or Exchange_Handler
+procedures, an attempt is made to
+detach a handler that was attached statically (using the
address@hidden,New=[aspect],Old=[pragma]}
+Attach_Handler), the handler is not detached and Program_Error is
+raised.
address@hidden,Sec=(raised by failure of run-time check)}
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+The Reference function returns a value of type System.Address that can
+be used to attach a task address@hidden,New=[],Old=[,]} via an
+address clause (see @RefSecNum{Interrupt Entries}) to the interrupt
+specified by Interrupt. This function raises Program_Error if attaching
+task entries to interrupts (or to this particular interrupt) is not supported.
address@hidden,Sec=(raised by failure of run-time check)}
+
address@hidden,Kind=[Added],ARef=[AI05-0153-3]}
address@hidden,Text=[The function Get_CPU returns the processor on which
+the handler for Interrupt is executed. If the handler can execute on more than
+one processor the value System.Multiprocessors.Not_A_Specific_CPU is 
returned.]}
+
address@hidden
+
address@hidden
+
+At no time during attachment or exchange of handlers shall the current handler
+of the corresponding interrupt be undefined.
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+If the Ceiling_Locking policy (see @RefSecNum{Priority Ceiling Locking}) is
+in address@hidden,New=[,],Old=[]} the implementation shall document
+the default ceiling priority
+assigned to a protected object that contains
address@hidden,New=[a protected procedure that specifies ],Old=[]}either
+the Attach_Handler or
+Interrupt_Handler @Chg{Version=[3],New=[aspects],Old=[pragmas]},
+but @Chg{Version=[3],New=[does not specify],Old=[not]} the
+Interrupt_Priority @Chg{Version=[3],New=[aspect],Old=[pragma]}.
address@hidden default need not be the same for all interrupts.]
address@hidden,Kind=[RevisedAdded],InitialVersion=[2],
address@hidden,
+Text=[If the Ceiling_Locking policy is in effect, the default ceiling priority
+for a protected object that @Chg{Version=[3],New=[specifies],Old=[contains]}
+an interrupt handler @Chg{Version=[3],New=[aspect],Old=[pragma]}.]}]}
+
address@hidden
+
address@hidden
+
+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 address@hidden should be specified in a
+child package of Interrupts, with the same operations as in the
+predefined package Interrupts.
+
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If implementation-defined forms of interrupt handler procedures are
+supported, then for each such form of a
+handler, a type analogous to address@hidden should be specified in a
+child package of Interrupts, with the same operations as in the
+predefined package Interrupts.]}]}
+
address@hidden
+
address@hidden
+
+The package Interrupts.Names contains implementation-defined
+names (and constant values) for the interrupts that are supported by
+the implementation.
+
address@hidden
+
address@hidden
address@hidden@address@hidden of interrupt handlers:}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+Device_Priority : @key[constant]
+  @key[array] (1..5) of System.Interrupt_Priority := ( ... );@Softpage
address@hidden @key[type] Device_Interface
+  (Int_Id : Ada.Interrupts.Interrupt_Id) @Chg{Version=[3],New=[
+     @key[with] Interrupt_Priority => Device_Priority(Int_Id) ],address@hidden
+  @key[procedure] address@hidden,New=[
+     @key[with] Attach_Handler => Int_Id],Old=[;
+  @key[pragma] Attach_Handler(Handler, Int_Id)]};
+  ...
+  @Chg{Version=[3],New=[],address@hidden 
Interrupt_Priority(Device_Priority(Int_Id));
address@hidden Device_Interface;@Softpage
+  ...
+Device_1_Driver : Device_Interface(1);
+  ...
+Device_5_Driver : Device_Interface(5);
+  ...
address@hidden
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0069],ARef=[AI95-00166-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that the value
+  returned by Current_Handler and Exchange_Handler for the default treatment
+  is null.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0167-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  Function Get_CPU is added to Interrupts. If Interrupts is referenced in
+  a @nt{use_clause}, and an entity @i<E> with a @nt{defining_identifier} of
+  Get_CPU is defined in a package that is also referenced in a @nt{use_clause},
+  the entity @i<E> may no longer be use-visible, resulting in errors. This
+  should be rare and is easily fixed if it does occur.]}
address@hidden
+
+
+
address@hidden@Comment{For ISO version of Ada 2012 Standard}
address@hidden Requirements}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]} specifies
+additional implementation and documentation
+requirements for the Preelaborate pragma (see @RefSecNum{Elaboration 
Control}).]
address@hidden
+
address@hidden
+
+The implementation shall not incur any run-time overhead for the elaboration
+checks of subprograms and @ntf{protected_bodies} declared in preelaborated
+library units.
address@hidden,Sec=[implementation requirements]}
+
+The implementation shall not execute any memory write operations after
+load time for the elaboration of constant objects
+declared immediately within the
+declarative region of a preelaborated library package, so long as the
+subtype and initial expression (or default initial expressions if
+initialized by default) of the @nt<object_declaration> satisfy the
+following restrictions.
address@hidden time}
+The meaning of @i{load time} is implementation defined.
address@hidden
+On systems where the image of the partition is initially copied from
+disk to RAM, or from ROM to RAM, prior to starting execution of the
+partition,
+the intention is that @lquotes@;load address@hidden@; consist of this initial 
copying
+step.
+On other systems, load time and run time might actually be interspersed.
address@hidden
address@hidden
+Any @nt<subtype_mark> denotes a statically constrained subtype, with
+statically constrained subcomponents, if any;
+
address@hidden,Kind=[Added],ARef=[AI95-00161-01]}
address@hidden,Text=[no @nt{subtype_mark} denotes a controlled type, a
+private type, a private extension, a generic formal private type, a generic
+formal derived type, or a descendant of such a type;]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[For an
+  implementation that uses the registration method of finalization, a
+  controlled object will require some code executed to register the object
+  at the appropriate point. The other types are those that @i{might} have a
+  controlled component. None of these types were allowed in preelaborated
+  units in Ada 95. These types are covered by the @ImplAdviceTitle, of course,
+  so they should still execute as little code as possible.]}
address@hidden
+
+any @nt<constraint> is a static constraint;
+
+any @nt<allocator> is for an access-to-constant type;
+
+any uses of predefined operators appear only within static expressions;
+
+any @ntf<primaries> that are @nt<name>s, other than @nt<attribute_reference>s
+for the Access or Address attributes, appear only within static expressions;
address@hidden
+This cuts out @nt<attribute_reference>s that are not static, except for
+Access and Address.
address@hidden
+
+any @nt<name> that is not part of a static expression is an expanded
+name or @nt<direct_name> that statically denotes some entity;
address@hidden
+This cuts out @nt<function_call>s and @nt<type_conversion>s that are not
+static, including calls on attribute functions like 'Image and 'Value.
address@hidden
+
+any @nt<discrete_choice> of an @nt<array_aggregate> is static;
+
+no language-defined check associated with the elaboration of the
address@hidden<object_declaration> can fail.
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+The intent is that aggregates all of whose scalar subcomponents are 
address@hidden,New=[],Old=[,]}
+and all of whose access subcomponents are @key(null), allocators for
+access-to-constant types, or X'Access, will be supported with no run-time
+code generated.
address@hidden
address@hidden
+
address@hidden
+
address@hidden
+
+The implementation shall document any circumstances under which the
+elaboration of a preelaborated package causes code to be executed at run time.
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Any circumstances when the elaboration of a preelaborated package
+causes code to be executed.]}]}
+
+The implementation shall document whether the method used for initialization
+of preelaborated variables allows a partition to be restarted without
+reloading.
address@hidden,Kind=[Added],address@hidden,
+Text=[Whether a partition can be restarted without reloading.]}]}
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[Implementation-defined aspects of preelaboration.]}]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00114-01]}
+This covers the issue of the @Chg{Version=[2],New=[run-time system],Old=[RTS]}
+itself being restartable,
+so that need not be a separate @DocReqName.
address@hidden
+
address@hidden
+
address@hidden
+
+It is recommended that preelaborated 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 @ImplReqName@;s.
+
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Preelaborated packages should be implemented such that little or no
+code is executed at run time for the elaboration of entities.]}]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00161-01]}
+  @ChgAdded{Version=[2],Text=[Added wording to exclude the additional kinds
+  of types allowed in preelaborated units from the @ImplReqTitle.]}
address@hidden
+
+
address@hidden,New=[Aspect Discard_Names],
+Old=[Pragma Discard_Names]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI12-0072-1]}
address@hidden@Chg{Version=[4],New=[Specifying the aspect],Old=[A @nt{pragma}]}
+Discard_Names @Chg{Version=[4],New=[can],Old=[may]} be used to request a
+reduction in storage used for the names of
address@hidden,New=[],Old=[certain address@hidden,New=[ with
+runtime name text],Old=[]}.]
address@hidden
+
address@hidden
address@hidden,Kind=[Added],ARef=[AI12-0072-1]}
address@hidden,Text=[An entity with @i{runtime name text} is a
+nonderived enumeration first subtype, a tagged first subtype, or an
address@hidden with runtime name address@hidden name text],Sec=[entity with]}]}
+
address@hidden,Kind=[Added],ARef=[AI12-0072-1]}
address@hidden,Type=[Leading],Text=[For an entity with runtime name
+text, the following language-defined representation aspect may be specified:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden type of aspect Discard_Names
+is Boolean. If directly specified, the @nt{aspect_definition} shall be
+a static expression. If not specified (including by inheritance), the
+aspect is address@hidden
+
+  @ChgAspectDesc{Version=[4],Kind=[Added],Aspect=[Discard_Names],
+    address@hidden,Text=[Requests a reduction in storage for names associated
+          with an entity.]}]}
address@hidden
address@hidden
+
address@hidden
address@hidden
address@hidden@Keepnext@;The form of a @nt{pragma} Discard_Names is as follows:
address@hidden
+
address@hidden@key{pragma} @prag(Discard_Names)[([On => ] @Syn2[local_name])];'
+
address@hidden
+A @nt{pragma} Discard_Names is allowed only immediately within a
address@hidden, immediately within a @nt{package_specification},
+or as a configuration pragma.
address@hidden pragma], Sec=(Discard_Names)}
address@hidden, configuration], Sec=(Discard_Names)}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI12-0072-1]}
+The @nt{local_name} (if present) shall denote
address@hidden,New=[an entity with runtime name text],Old=[a nonderived
+enumeration @Redundant[first] subtype,
+a tagged @Redundant[first] subtype, or an exception]}.
+The pragma @Chg{Version=[4],New=[specifies that the aspect Discard_Names
+for],Old=[applies to]} the type or
address@hidden,New=[ has the value True],Old=[]}.
+Without a @nt{local_name}, the pragma @Chg{Version=[4],New=[specifies that],
+Old=[applies to]} all
address@hidden,New=[],Old=[such address@hidden,New=[ with
+runtime name text],Old=[]}
+declared after the pragma, within the same declarative
address@hidden,New=[ have the value True for aspect
+Discard_Names],Old=[]}.
+Alternatively, the pragma can be used as a configuration pragma.
address@hidden,New=[If the configuration pragma Discard_Names applies to a
+compilation unit, all entities with runtime name text declared in the
+compilation unit have the value True for the aspect Discard_Names.],Old=[If the
+pragma applies to a type, then it applies also to all descendants of the 
type]}.
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0072-1]}
+  @ChgAdded{Version=[4],Text=[If the aspect is specified for a type, then
+  it is inherited by all descendants of the type. The aspect cannot be
+  specified as False on a derived type (because specifying the aspect is
+  not allowed on derived enumeration types, and by rule applying to all
+  aspects for other types (see @RefSecNum{Aspect Specifications})).]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden pragma], Sec=(Discard_Names)}
address@hidden, representation], Sec=(Discard_Names)}
+If a @nt{local_name} is given, then
+a @nt{pragma} Discard_Names is a representation pragma.
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgRef{Version=[4],Kind=[Deleted],address@hidden now.}
+  @ChgDeleted{Version=[4],address@hidden,New=[Representation
+  pragmas automatically specify aspects of the same name,
+  so Discard_Names can be used as an @nt{aspect_mark} in an
+  @nt{aspect_specification} instead of using the pragma on individual
+  entities.],Old=[]}]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00285-01],ARef=[AI95-00400-01]}
address@hidden,Kind=[Revised],ARef=[AI12-0072-1]}
+If the @Chg{Version=[4],New=[aspect Discard_Names is True
+for],Old=[pragma applies to]} an enumeration type,
+then the semantics of the 
@Chg{Version=[2],New=[Wide_Wide_Image],Old=[Wide_Image]}
+and @Chg{Version=[2],New=[Wide_Wide_Value],Old=[Wide_Value]} attributes
+are implementation defined for that address@hidden; the
+semantics of address@hidden,New=[, Wide_Image,],Old=[ and]}
address@hidden,New=[, and Wide_Value],Old=[]} are still defined in
+terms of @Chg{Version=[2],New=[Wide_Wide_Image],Old=[Wide_Image]}
+and @Chg{Version=[2],New=[Wide_Wide_Value],Old=[Wide_Value]}].
+In addition, the semantics of Text_IO.Enumeration_IO are implementation
+defined.
+If the @Chg{Version=[4],New=[aspect Discard_Names is True
+for],Old=[pragma applies to]} a tagged type,
+then the semantics of the address@hidden@Chg{Version=[2],address@hidden@!Name],
address@hidden function
+are implementation defined for that address@hidden,address@hidden; the
+semantics of address@hidden@!Name and address@hidden@address@hidden are still
+defined in terms of address@hidden@address@hidden, Old=[]}.
+If the @Chg{Version=[4],New=[aspect Discard_Names is True
+for],Old=[pragma applies to]} an exception,
+then the semantics of the address@hidden@Chg{Version=[2],address@hidden@!Name],
address@hidden function
+are implementation defined for that address@hidden,address@hidden; the
+semantics of address@hidden@!Name and address@hidden@address@hidden
+are still defined in terms of address@hidden@address@hidden, Old=[]}.
+
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[The semantics of @Chg{Version=[4],New=[some attributes and functions of
+an entity for which aspect],Old=[pragma]}
address@hidden,New=[ is True],Old=[]}.]}
address@hidden
+  The Width attribute is still defined in terms of Image.
+
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00285-01]}
+  @ChgRef{Version=[4],Kind=[Revised],ARef=[AI12-0072-1]}
+  The semantics of S'@Chg{Version=[2],New=[Wide_Wide_Image],Old=[Wide_Image]}
+  and S'@Chg{Version=[2],New=[Wide_Wide_Value],Old=[Wide_Value]} are
+  implementation defined for any subtype of an enumeration type
+  @Chg{Version=[4],New=[for],Old=[to]} which
+  the @Chg{Version=[4],New=[aspect is True],Old=[pragma applies]}.
+  (The address@hidden,New=[, if used,],Old=[]} actually names
+  the first subtype, of course.)
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI12-0072-1]}
+If the @Chg{Version=[4],New=[aspect Discard_Names is True
+for],Old=[pragma applies to]} an entity, then the implementation should
+reduce the amount of storage used for storing names associated with that
+entity.
address@hidden,Kind=[Revised],InitialVersion=[2],
address@hidden,
+Text=[If @Chg{Version=[4],New=[aspect],address@hidden Discard_Names
address@hidden,New=[is True for],Old=[applies to]} an entity, then
+the amount of storage used for storing names associated with that entity
+should be reduced.]}]}
address@hidden
+A typical implementation of the Image attribute for enumeration types is
+to store a table containing the names of all the enumeration literals.
address@hidden,New=[Aspect],Old=[Pragma]} Discard_Names allows the
+implementation to avoid storing such a
+table without having to prove that the Image attribute is never used
+(which can be difficult in the presence of separate compilation).
+
+We did not specify the semantics of the Image attribute
address@hidden,New=[when aspect Discard_Names is True],Old=[in the presence
+of this pragma]} because different semantics might be desirable in
+different situations.
+In some cases, it might make sense to use the Image attribute to print
+out a useful value that can be used to identify the entity given
+information in compiler-generated listings.
+In other cases, it might make sense to get an error at compile time or
+at run time.
+In cases where memory is plentiful, the simplest implementation makes
+sense: ignore the @Chg{Version=[4],New=[aspect],Old=[pragma]}.
+Implementations that are capable of avoiding the extra storage in cases
+where the Image attribute is never used might also wish to ignore the
address@hidden,New=[aspect],Old=[pragma]}.
+
+The same applies to the Tags.Expanded_Name and Exceptions.Exception_Name
+functions.
address@hidden
address@hidden
+
address@hidden
+  
@ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00285-01],ARef=[AI95-00400-01]}
+  @ChgAdded{Version=[2],Text=[Updated the wording to reflect that the double
+  wide image and value functions are now the master versions that the others
+  are defined from.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0072-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Defined the pragma in 
terms of
+  the aspect Discard_Names, and added a missing definition of the meaning of
+  the configuration pragma. This is not intended to make any semantic change
+  (Ada 2012 has an aspect Discard_Names defined via blanket rules for
+  representation pragmas in @RefSecNum{Operational and Representation Aspects}
+  and @RefSecNum{Aspect Specifications}), just to clarify the meaning.]}
address@hidden
+
+
address@hidden Variable Control}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0229-1],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause defines],Old=[clause specifies]}
+representation @Chg{Version=[3],New=[aspects],Old=[pragmas]} that control the
+use of shared variables.]
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraphs 2
+through 6 were moved to @RefSec{Obsolescent Features}.>address@hidden message
+should be deleted if the paragraphs are ever renumbered.}
address@hidden
+
address@hidden
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[The form for pragmas Atomic,
+Volatile, Atomic_Components, and Volatile_Components is as follows:]}
address@hidden
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden<Version=[3],InitialVersion=[0],@ChgDeleted{Version=[3],
address@hidden @prag(Atomic)(@Syn2{local_name});]}>
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden<Version=[3],InitialVersion=[0],@ChgDeleted{Version=[3],
address@hidden @prag(Volatile)(@Syn2{local_name});]}>
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden<Version=[3],InitialVersion=[0],@ChgDeleted{Version=[3],
address@hidden @prag(Atomic_Components)(@address@hidden);]}>
+
address@hidden,Kind=[DeletedNoDelMsg]}
address@hidden<Version=[3],InitialVersion=[0],@ChgDeleted{Version=[3],
address@hidden @prag(Volatile_Components)(@address@hidden);]}>
+
address@hidden
+
address@hidden: @begin{Intro}, Replaced with below for Ada 2012}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[For an @nt{object_declaration}, a
address@hidden, or a @nt{full_type_declaration}, the following
+representation aspects may be specified:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden type of aspect Atomic is
address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Atomic],
+    address@hidden,Text=[Declare that a type, object, or component is
+      atomic.]}]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden type of aspect Independent is
address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Independent],
+    address@hidden,Text=[Declare that a type, object, or component
+      is independently addressable.]}]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden type of aspect Volatile is
address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Volatile],
+    address@hidden,Text=[Declare that a type, object, or component
+      is volatile.]}]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[For a @nt{full_type_declaration} of
+an array type (including the anonymous type of an @nt{object_declaration}
+of an anonymous array object), the following representation aspects may be
+specified:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden type of aspect
+Atomic_Components is address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Atomic_Components],
+    address@hidden,Text=[Declare that the components of
+      an array type or object are atomic.]}]}
+
address@hidden,Kind=[Added]}
address@hidden,address@hidden type of aspect
+Volatile_Components is address@hidden
+
+  @ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Volatile_Components],
+    address@hidden,Text=[Declare that the components of
+      an array type or object are volatile.]}]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Type=[Leading],Text=[For a @nt{full_type_declaration}
+(including the anonymous type of an @nt{object_declaration} of an anonymous
+array object), the following representation aspect may be specified:]}
+
address@hidden
address@hidden,Kind=[Added]}
address@hidden,address@hidden type of aspect
+Independent_Components is address@hidden
+
+  
@ChgAspectDesc{Version=[3],Kind=[AddedNormal],Aspect=[Independent_Components],
+    address@hidden,Text=[Declare that the components of an array
+      or record type, or an array object, are independently addressable.]}]}
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Text=[If any of these aspects are directly
+specified, the @nt{aspect_definition} shall be a static expression. If not
+specified (including by inheritance), each of these aspects is False.]}
+
address@hidden,Kind=[Revised],ARef=[AI95-00272-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden
+An @i{atomic} type is one @Chg{Version=[3],New=[for],Old=[to]} which
address@hidden,New=[the aspect],Old=[a pragma]} Atomic
address@hidden,New=[is True],Old=[applies]}.
+An @i{atomic} object (including a component)
+is one @Chg{Version=[3],New=[for],Old=[to]} which
address@hidden,New=[the aspect],Old=[a pragma]} Atomic
address@hidden,New=[is True],Old=[applies]},
+or a component of an array @Chg{Version=[3],New=[for],Old=[to]} which
address@hidden,New=[the aspect],Old=[a pragma]} Atomic_Components
address@hidden,New=[is True for the associated type],Old=[applies]},
+or any object of an atomic address@hidden,
+New=[, other than objects obtained by evaluating a slice],Old=[]}.
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00272-01]}
+  @ChgAdded{Version=[2],Text=[A slice of an atomic array object is not itself
+  atomic. That's necessary as executing a read or write of a dynamic number
+  of components in a single instruction is not possible on many targets.]}
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden
+A @i{volatile} type is one @Chg{Version=[3],New=[for],Old=[to]} which
address@hidden,New=[the aspect],Old=[a pragma]} Volatile
address@hidden,New=[is True],Old=[applies]}.
+A @i{volatile} object (including a component)
+is one @Chg{Version=[3],New=[for],Old=[to]} which
address@hidden,New=[the aspect],Old=[a pragma]} Volatile
address@hidden,New=[is True],Old=[applies]},
+or a component of an array @Chg{Version=[3],New=[for],Old=[to]} which
address@hidden,New=[the aspect],Old=[a pragma]} address@hidden
address@hidden,New=[is True for the associated type],Old=[applies]},
+or any object of a volatile type.
+In addition, every atomic type or object is also defined to be volatile.
+Finally, if an object is volatile, then so
+are all of its subcomponents @Redundant[(the same does not apply to atomic)].
+
address@hidden,Kind=[Added],ARef=[AI05-0009-1],ARef=[AI05-0229-1]}
address@hidden,Kind=[RevisedAdded],ARef=[AI12-0001-1]}
address@hidden,Text=[When True, the aspects Independent and
+Independent_Components @i<specify as independently addressable> the named 
object
+or component(s), or in the case of a type, all objects or components
+of that type. All atomic objects @Chg{Version=[4],New=[and aliased
+objects ],Old=[]}are considered to be specified as independently
address@hidden as independently address@hidden addressable],Sec=[specified]}]}
+
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[If the compiler cannot guarantee that an object
+(including a component) for which aspect Independent or aspect
+Independent_Components is True is independently addressable from
+any other nonoverlapping object, then the aspect specification
+must be rejected.]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[Similarly, an atomic object (including atomic
+components) is always independently addressable from any other nonoverlapping
+object. Any representation item which would prevent this from being true should
+be rejected, notwithstanding what this Standard says elsewhere (specifically,
+in the Recommended Level of Support).]}
address@hidden
+
address@hidden: @end{Intro}, Replaced with below for Ada 2012}
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraph 9
+was moved to @RefSec{Obsolescent Features}.>address@hidden message
+should be deleted if the paragraphs are ever address@hidden use
+this message rather than the "automatic one" to get rid of the resolution
+subheader}
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,Text=[The @nt{local_name} in an Atomic or Volatile
+pragma shall resolve to denote either an @nt{object_declaration}, a
+noninherited @address@hidden, or a @address@hidden
+The @address@hidden in an address@hidden or
address@hidden pragma shall resolve to denote the declaration of an array
+type or an array object of an anonymous type.]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0229-1]}
address@hidden,Text=[If aspect Independent_Components is specified for a
address@hidden, the declaration shall be that of an array or record
+type.]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Kind=[Revised],ARef=[AI12-0001-1]}
address@hidden
+It is illegal to @Chg{Version=[3],New=[specify],Old=[apply]}
+either @Chg{Version=[3],New=[of the aspects],Old=[an]} Atomic or
+Atomic_Components @Chg{Version=[3],New=[],Old=[pragma ]}to
address@hidden,New=[have the value True for ],Old=[]}an
+object or type if the implementation cannot support the indivisible
address@hidden,New=[and independent ],Old=[]}reads
+and updates required by the @Chg{Version=[3],New=[aspect],Old=[pragma]}
+(see below).
+
address@hidden,Kind=[Revised],ARef=[AI12-0001-1]}
+It is illegal to specify the Size attribute of an atomic object, the
+Component_Size attribute for an array type with atomic components, or the 
layout
+attributes of an atomic component, in a way that prevents the implementation
+from performing the required indivisible
address@hidden,New=[and independent ],Old=[]}reads and updates.
+
address@hidden,Kind=[Revised],ARef=[AI05-0142-4],ARef=[AI05-0218-1]}
+If an atomic object is passed as a parameter, then
address@hidden,New=[],Old=[the type of ]}the formal
+parameter shall either @Chg{Version=[3],New=[have an],Old=[be]} atomic
address@hidden,New=[type ],Old=[]}or allow pass by
address@hidden,New=[],Old=[ @Redundant[(that
+is, not be a nonatomic by-reference type)]]}. If an atomic object is used
+as an actual for a generic formal object of mode @key{in out}, then the
+type of the generic formal object shall be atomic. If the @nt<prefix> of
+an @nt<attribute_reference> for an Access attribute denotes an atomic
+object @Redundant[(including a component)], then the designated type of
+the resulting access type shall be atomic. If an atomic type is used as
+an actual for a generic formal derived type, then the ancestor of the
+formal type shall be address@hidden,New=[],Old=[ or allow pass by copy]}.
+Corresponding rules apply to volatile objects and types.
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0142-4]}
+  @ChgAdded{Version=[3],Text=[A formal parameter allows pass by copy
+  if it is not @key[aliased] and it is of a type that allows pass by copy (that
+  is, is not a by-reference type).]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0218-1]}
address@hidden,Text=[If a volatile type is used as an actual for a
+generic formal array type, then the element type of the formal type shall be
+volatile.]}
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
+If @Chg{Version=[3],New=[an aspect],Old=[a pragma]} Volatile,
+Volatile_Components, Atomic, or Atomic_Components
address@hidden,New=[is directly specified to have the value
+True for],Old=[applies to]} a stand-alone constant object, then
address@hidden,New=[the aspect],Old=[a pragma]} Import shall
+also @Chg{Version=[3],New=[be specified as True for],Old=[apply to]} it.
address@hidden
+Hence, no initialization expression is allowed for such a constant. Note
+that a constant that is atomic or volatile because of its type is allowed.
address@hidden
address@hidden
+Stand-alone constants that are explicitly specified as Atomic or Volatile
+only make sense if they are being manipulated outside the Ada program.
+From the Ada perspective the object is read-only. Nevertheless, if
+imported and atomic or volatile, the implementation should presume it
+might be altered externally.
+For an imported stand-alone constant that is not atomic or
+volatile, the implementation can assume that it will not be
+altered.
address@hidden
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0218-1]}
+  @ChgAdded{Version=[3],Text=[Volatile_Components and Atomic_Components 
actually
+  are aspects of the anonymous array type; this rule only applies when the
+  aspect is specified directly on the constant object and not when the (named)
+  array type has the aspect.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0009-1],ARef=[AI05-0229-1]}
address@hidden,Text=[It is illegal to specify the aspect Independent or
+Independent_Components as True for a component, object or type if the
+implementation cannot provide the independent addressability required by the
+aspect (see @RefSecNum{Shared Variables}).]}
+
address@hidden,Kind=[Added],ARef=[AI05-0009-1],ARef=[AI05-0229-1]}
address@hidden,Text=[It is illegal to specify a representation aspect for
+a component, object or type for which the aspect Independent or
+Independent_Components is True, in a way that prevents the implementation from
+providing the independent addressability required by the aspect.]}
+
address@hidden
+
address@hidden
address@hidden,Noprefix=[T],Noparanum=[T],address@hidden@i<Paragraph 14
+was moved to @RefSec{Obsolescent Features}.>address@hidden message
+should be deleted if the paragraphs are ever address@hidden use
+this message rather than the "automatic one" to get rid of the resolution
+subheader}
address@hidden
+
address@hidden
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI05-0229-1]}
address@hidden,address@hidden pragma], Sec=(Atomic)}
address@hidden, representation], Sec=(Atomic)}
address@hidden pragma], Sec=(Volatile)}
address@hidden, representation], Sec=(Volatile)}
address@hidden pragma], Sec=(Atomic_Components)}
address@hidden, representation], Sec=(Atomic_Components)}
address@hidden pragma], Sec=(Volatile_Components)}
address@hidden, representation], Sec=(Volatile_Components)}
+These @nt{pragma}s are representation pragmas
+(see @RefSecNum{Operational and Representation Aspects}).]}
address@hidden
+
address@hidden
+
+For an atomic object (including an atomic component) all reads and
+updates of the object as a whole are indivisible.
+
address@hidden,Kind=[Revised],ARef=[AI05-0117-1],ARef=[AI05-0275-1]}
address@hidden,New=[All tasks of the program (on all processors) that
+read or update volatile variables see the same order of
+updates to the variables. A use of an atomic variable or other mechanism may be
+necessary to avoid erroneous execution and to ensure that access to
+nonatomic volatile variables is sequential (see @RefSecNum{Shared 
Variables}).],
+Old=[For a volatile object all reads and updates of the object as a whole are
+performed directly to memory.]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0117-1],ARef=[AI05-0275-1]}
address@hidden,New=[To ensure this, on a multiprocessor, any read or
+update of an atomic object may require the use of an appropriate memory
+barrier.],Old=[This precludes any use of register temporaries,
+caches, and other similar optimizations for that object.]}
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI05-0275-1]}
address@hidden,Text=[From @RefSecNum{Shared Variables} it follows that
+(in non-erroneous programs) accesses to variables, including those shared by
+multiple tasks, are always sequential. This guarantees that no task will ever
+see partial updates of any variable. For volatile variables (including atomic
+variables), the above rule additionally specifies that all tasks see the same
+order of updates.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0275-1]}
address@hidden,Text=[If for a shared variable @i<X>, a read of @i<X>
+occurs sequentially after an update of @i<X>, then the read will return the
+updated value if @i<X> is volatile or atomic, but may or or may not return the
+updated value if @i<X> is nonvolatile. For nonvolatile accesses, a signaling
+action is needed in order to share the updated value.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI05-0275-1]}
address@hidden,Text=[Because accesses to the same atomic variable by
+different tasks establish a sequential order between the actions of those 
tasks,
+implementations may be required to emit memory barriers around such updates or
+use atomic instructions that imply such barriers.]}
address@hidden
+
address@hidden, Sec=(actions)}
+Two actions are sequential (see @RefSecNum{Shared Variables}) if each
+is the read or update of the same atomic object.
+
address@hidden type], Sec=(atomic or volatile)}
+If a type is atomic or volatile and it is not a by-copy type, then the type
+is defined to be a by-reference type. If any subcomponent of a type is
+atomic or volatile, then the type is defined to be a by-reference type.
+
+If an actual parameter is atomic or volatile, and the corresponding
+formal parameter is not, then the parameter is passed by copy.
address@hidden
+Note that in the case where such a parameter is normally passed by
+reference, a copy of the actual will have to be produced at the call-site,
+and a pointer to the copy passed to the formal parameter. If the actual
+is atomic, any copying has to use indivisible read on the way in, and
+indivisible write on the way out.
address@hidden
address@hidden
+It has to be known at compile time whether an atomic or a volatile parameter
+is to be passed by copy or by reference. For some types, it is unspecified
+whether parameters are passed by copy or by reference. The above rules
+further specify the parameter passing rules involving atomic and volatile
+types and objects.
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden effect], Sec=(volatile/atomic objects)}
+The external effect of a program
+(see @RefSecNum(Conformity of an Implementation with the Standard))
+is defined to include each read and update
+of a volatile or atomic object. The implementation shall not
+generate any memory reads or updates of atomic or volatile
+objects other than those specified by the program.
address@hidden
+The presumption is that volatile or atomic objects might reside in an
address@hidden@;address@hidden@; part of the address space where each read has a
+potential side effect, and at the very least might deliver a different value.
+
address@hidden@;The rule above and the definition of external effect are 
intended to
+prevent (at least) the following incorrect optimizations, where V is
+a volatile variable:
address@hidden
+X:= V; Y:=V; cannot be allowed to be translated as Y:=V; X:=V;
+
+Deleting redundant loads: X:= V; X:= V; shall read the value of V from
+memory twice.
+
+Deleting redundant stores: V:= X; V:= X; shall write into V twice.
+
+Extra stores: V:= X+Y; should not translate to something like V:= X; V:= V+Y;
+
+Extra loads: X:= V; Y:= X+Z; X:=X+B; should not translate to something like
+Y:= V+Z; X:= V+B;
+
+Reordering of loads from volatile variables: X:= V1; Y:= V2; (whether or not
+V1 = V2) should not translate to Y:= V2; X:= V1;
+
+Reordering of stores to volatile variables: V1:= X; V2:= X; should not
+translate to V2:=X; V1:= X;
address@hidden
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI05-0229-1]}
address@hidden,Kind=[Deleted],ARef=[AI12-0001-1]}
address@hidden,Text=[If @Chg{Version=[3],New=[the],Old=[a pragma]} Pack
address@hidden,New=[aspect is True for],Old=[applies to]} a type any of whose
+subcomponents are atomic,
+the implementation shall not pack the atomic subcomponents more tightly
+than that for which it can support indivisible reads and updates.]}
address@hidden
address@hidden,Kind=[Revised],ARef=[AI05-0009-1]}
address@hidden,Kind=[Deleted],ARef=[AI12-0001-1]}
address@hidden,address@hidden,New=[Usually, specifying aspect Pack for such a 
type
+will be illegal as the Recommended Level of Support cannot be achieved;
+otherwise, a],Old=[A]} warning might be appropriate if
+no packing whatsoever can be achieved.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00259-01]}
address@hidden,Text=[A load or store of a volatile object whose size is
+a multiple of System.Storage_Unit and whose alignment is nonzero, should be
+implemented by accessing exactly the bits of the object and no others.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[A load or store of a volatile object whose size is
+a multiple of System.Storage_Unit and whose alignment is nonzero, should be
+implemented by accessing exactly the bits of the object and no others.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[Since any object can be a volatile object,
+  including packed array components and bit-mapped record components, we
+  require the above only when it is reasonable to assume that the machine
+  can avoid accessing bits outside of the object.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This implies that the load or store of a
+  volatile object that meets the above requirement should not be combined
+  with that of any other object, nor should it access any bits not
+  belonging to any other object. This means that the suitability of the
+  implementation for memory-mapped I/O can be determined from its
+  documentation, as any cases where the implementation does not follow
+  @ImplAdviceTitle must be documented.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00259-01]}
address@hidden,Text=[A load or store of an atomic object should, where
+possible, be implemented by a single load or store instruction.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[A load or store of an atomic object should be implemented by a single
+load or store instruction.]}]}
+
address@hidden
+
address@hidden
+
+An imported volatile or atomic constant behaves as a constant (i.e.
+read-only) with respect to other parts of the Ada program, but can
+still be modified by an @lquotes@;external address@hidden@;
+
address@hidden,Kind=[AddedNormal],ARef=[AI12-0001-1]}
address@hidden,Text=[Specifying the Pack aspect cannot override the
+effect of specifying an Atomic or Atomic_Components aspect.]}
+
address@hidden
+
address@hidden
address@hidden with Ada 83}
+Pragma Atomic replaces Ada 83's pragma Shared.
+The name @lquotes@;address@hidden@; was confusing,
+because the pragma was not used to mark variables as shared.
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00259-01]}
+  @ChgAdded{Version=[2],Text=[Added @ImplAdviceTitle to clarify the meaning
+  of Atomic and Volatile in machine terms. The documentation that this
+  advice applies will make the use of Ada implementations more predictable
+  for low-level (such as device register) programming.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00272-01]}
+  @ChgAdded{Version=[2],Text=[Added wording to clarify that a slice of an
+  object of an atomic type is not atomic, just like a component of an atomic
+  type is not (necessarily) atomic.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0218-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada address@hidden<Correction:>
+  Plugged a hole involving volatile components of formal types when the formal
+  type's component has a nonvolatile type. This was done by making certain
+  actual types illegal for formal derived and formal array types; these types
+  were allowed for Ada 95 and Ada 2005.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0009-1],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],address@hidden to Ada 2005}
+  Aspects Independent and Independent_Components are new; they eliminate
+  ambiguity about independent addressability.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0229-1]}
+  @ChgAdded{Version=[3],Text=[Aspects Atomic, Atomic_Components, Volatile,
+  and Volatile_Components are
+  new; @nt{pragma}s Atomic, Atomic_Components, Volatile, and
+  Volatile_Components are now obsolescent.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0117-1],ARef=[AI05-0275-1]}
+  @ChgAdded{Version=[3],Text=[Revised the definition of volatile to
+  eliminate overspecification and simply focus on the root requirement (that
+  all tasks see the same view of volatile objects). This is not an
+  inconsistency; "memory" arguably includes on-chip caches so long as those are
+  kept consistent. Moreover, it is difficult to imagine a program that could 
tell
+  the difference.]}
+
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0142-4]}
+  @ChgAdded{Version=[3],Text=[Added wording to take explicitly aliased
+  parameters (see @RefSecNum{Subprogram Declarations}) into
+  account when determining the legality of parameter passing of volatile and
+  atomic objects.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[4],Kind=[AddedNormal],ARef=[AI12-0001-1]}
+  @ChgAdded{Version=[4],address@hidden<Corrigendum:> Clarified that aliased 
objects
+  are considered to be specified as independently addressable, and also
+  eliminated an unnecessary rule.]}
address@hidden
+
+
address@hidden,New=[Task Information],
+Old=[Task Identification and Attributes]}
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00266-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden @Chg{Version=[3],New=[subclause],Old=[clause]}
+describes operations and attributes that can be
+used to obtain the identity of a task. In addition,
+a package that associates user-defined information with a task is
address@hidden,New=[ Finally, a package that associates
+termination procedures with a task or set of tasks is defined.],Old=[]}]
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00266-02]}
+  @ChgRef{Version=[3],Kind=[Revised],ARef=[AI05-0299-1]}
+  @ChgAdded{Version=[2],Text=[The title and text here were updated to reflect
+  the addition of task termination procedures to this 
@Chg{Version=[3],New=[subclause],Old=[clause]}.]}
address@hidden
+
address@hidden Package Task_Identification}
+
address@hidden
address@hidden@Keepnext@;The following language-defined library package exists:
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00362-01]}
address@hidden Ada.Task_Identification @address@hidden,address@hidden,New=[
+   @key[pragma] Preelaborate(Task_Identification);],Old=[]}
+   @key[type] @AdaTypeDefn{Task_Id} @key[is] 
@key{private};@Chg{Version=[2],New=[
+   @key[pragma] Preelaborable_Initialization (Task_Id);],Old=[]}
+   @AdaSubDefn{Null_Task_Id} : @key{constant} Task_Id;
+   @key{function}  "=" (Left, Right : Task_Id) @key{return} Boolean;
+
address@hidden,Kind=[Revised],Ref=[8652/0070],ARef=[AI95-00101-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0189-1]}
+   @key{function}  @AdaSubDefn{Image}                  (T : Task_Id) 
@key{return} String;
+   @key[function]  @AdaSubDefn{Current_Task}     @key[return] 
Task_Id;@Chg{Version=[3],New=[
+   @key[function]  @AdaSubDefn{Environment_Task} @key[return] Task_Id;],Old=[]}
+   @Key[procedure] @AdaSubDefn{Abort_Task}             (T : @key[in] 
@Chg{New=[],address@hidden ]}Task_Id);
+
address@hidden,Kind=[Revised],ARef=[AI05-0189-1]}
+   @key[function]  @AdaSubDefn{Is_Terminated}          (T : Task_Id) 
@key{return} Boolean;
+   @key[function]  @AdaSubDefn{Is_Callable}            (T : Task_Id) 
@key{return} Boolean;@Chg{Version=[3],New=[
+   @key[function]  @AdaSubDefn{Activation_Is_Complete} (T : Task_Id) 
@key{return} Boolean;],Old=[]}
address@hidden
+   ... -- @RI{not specified by the language}
address@hidden Ada.Task_Identification;
address@hidden
address@hidden
+
address@hidden
+
+A value of the type Task_Id identifies an existent task. The constant
+Null_Task_Id does not identify any task. Each object of the type Task_Id
+is default initialized to the value of Null_Task_Id.
+
+The function "=" returns True if and only if Left and Right identify the same
+task or both have the value Null_Task_Id.
+
+The function Image returns an implementation-defined string that identifies
+T. If T equals Null_Task_Id, Image returns an empty string.
address@hidden result of the Task_Identification.Image attribute.}
+
+The function Current_Task returns a value that identifies the calling task.
+
address@hidden,Kind=[Added],ARef=[AI05-0189-1]}
address@hidden,Text=[The function Environment_Task returns a value that
+identifies the environment task.]}
+
+The effect of Abort_Task is the same as the @nt{abort_statement} for the
+task identified by T. @Redundant[In addition, if T identifies the
+environment task, the entire partition is aborted, See @RefSecNum{Partitions}.]
+
+The functions Is_Terminated and Is_Callable return the value of the
+corresponding attribute of the task identified by T.
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0115],ARef=[AI95-00206-01]}
address@hidden,Text=[These routines can be called with an argument
+identifying the environment task. Is_Terminated will always be False for such a
+call, but Is_Callable (usually True) could be False if the environment task is
+waiting for the termination of dependent tasks. Thus, a dependent task can use
+Is_Callable to determine if the main subprogram has completed.]}
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI05-0189-1]}
address@hidden,Text=[The function Activation_Is_Complete returns True if the
+task identified by T has completed its activation (whether successfully or 
not).
+It returns False otherwise. If T identifies the environment task,
+Activation_Is_Complete returns True after the elaboration of the
address@hidden of the partition has completed.]}
+
address@hidden@;For @PrefixType{a @nt<prefix> T that is of a task type
address@hidden(after any implicit dereference)]},
+the following attribute is defined:
address@hidden
+
address@hidden<T>, AttrName=<Identity>,
+  Text=[Yields a value of the type Task_Id that identifies
+    the task denoted by T.]}
+
address@hidden
address@hidden
+
address@hidden@;For @PrefixType{a @nt<prefix> E that denotes an
address@hidden<entry_declaration>},
+the following attribute is defined:
address@hidden
address@hidden,Kind=[Revised],ChginAnnex=[T],
+    Leading=<F>, Prefix=<E>, AttrName=<Caller>, ARef=[AI05-0262-1],
+    InitialVersion=[0], Text=[Yields a value of the type Task_Id that
+       identifies the task whose call is now being serviced. Use of this
+       attribute is allowed only inside an
+       @Chg{Version=[3],New=[],address@hidden
+       or address@hidden@Chg{Version=[3],New=[,
+       or @nt{entry_body} after the
+       @nt{entry_barrier}, ],Old=[]}corresponding
+       to the @nt{entry_declaration} denoted by E.]}
address@hidden
address@hidden
+
address@hidden,Sec=(raised by failure of run-time check)}
+Program_Error is raised if a value of Null_Task_Id is passed
+as a parameter to Abort_Task, Is_Terminated, and Is_Callable.
+
address@hidden blocking operation],Sec=(Abort_Task)}
address@hidden, potentially],Sec=(Abort_Task)}
+Abort_Task is a potentially blocking operation
+(see @RefSecNum{Protected Subprograms and Protected Actions}).
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],ARef=[AI95-00237-01]}
address@hidden,Kind=[Revised],ARef=[AI05-0004-1]}
address@hidden(bounded error),Sec=(cause)}
+It is a bounded error to call the Current_Task function from
+an @Chg{Version=[3],address@hidden,Old=[entry address@hidden,New=[,],Old=[ or 
an]}
+interrupt address@hidden,New=[, or finalization of a task attribute],Old=[]}.
address@hidden,Sec=(raised by failure of run-time check)}
+Program_Error is raised, or an implementation-defined value of the type
+Task_Id is returned.
address@hidden,Kind=[Revised],InitialVersion=[0],
+Text=[The value of Current_Task when in
+a protected address@hidden,New=[,],Old=[ or]} interrupt address@hidden,
+New=[, or finalization of a task attribute],Old=[]}.]}
address@hidden
+This value could be Null_Task_Id, or the ID of some user task, or that of
+an internal task created by the implementation.
address@hidden
address@hidden
address@hidden,Kind=[Revised],address@hidden really should reference AI05-0004, 
but we don't have that yet. And that hasn't been approved, either}
address@hidden,Text=[An entry barrier is syntactically part of an
address@hidden, so a call to Current_Task from an entry barrier is also
+covered by this rule.]}
address@hidden
+
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)}
+If a value of Task_Id is passed as a parameter to any of the operations
+declared in this package (or any language-defined child of this
+package), and the corresponding task object no longer exists,
+the execution of the program is erroneous.
address@hidden
+
address@hidden
+
+The implementation shall document the effect of calling Current_Task
+from an entry body or interrupt handler.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
+Text=[The effect of calling Current_Task from an
+entry body or interrupt handler.]}]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The effect of calling Current_Task from an
+entry body or interrupt handler.]}]}
address@hidden
+
address@hidden
+
+This package is intended for use in writing user-defined task scheduling
+packages and constructing server tasks. Current_Task can be used in
+conjunction with other operations requiring a task as an argument such
+as Set_Priority (see @RefSecNum{Dynamic Priorities}).
+
+The function Current_Task and the attribute Caller can return a
+Task_Id value that identifies the environment task.
+
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00362-01]}
+  @ChgAdded{Version=[2],Text=[Task_Identification is now preelaborated,
+  so it can be used in preelaborated units.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0070],ARef=[AI95-00101-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Corrected the mode of the
+  parameter to Abort_Task to @key{in}.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00237-01]}
+  @ChgAdded{Version=[2],Text=[Corrected the wording to include finalization
+  of a task attribute in the bounded error case; we don't want to specify
+  which task does these operations.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0189-1]}
+  @ChgAdded{Version=[3],address@hidden with Ada 2005}
+  Functions Environment_Task and Activation_Is_Complete are added to
+  Task_Identification. If Task_Identification is referenced in a 
@nt{use_clause}, and an
+  entity @i<E> with a @nt{defining_identifier} of Environment_Task or
+  Activation_Is_Complete is defined in a package that is also referenced in a
+  @nt{use_clause}, the entity @i<E> may no longer be use-visible, resulting in
+  errors. This should be rare and is easily fixed if it does occur.]}
address@hidden
+
+
address@hidden Package Task_Attributes}
+
address@hidden
address@hidden@Keepnext@;The following language-defined generic library package 
exists:
address@hidden
address@hidden Ada.Task_Identification; @key{use} Ada.Task_Identification;
address@hidden
+   @key{type} Attribute @key{is} @key{private};
+   Initial_Value : @key[in] Attribute;
address@hidden Ada.Task_Attributes @address@hidden,Child=[Task_Attributes]}
+
+   @key{type} @AdaTypeDefn{Attribute_Handle} @key{is} @key{access} @key{all} 
Attribute;
+
+   @key{function} @AdaSubDefn{Value}(T : Task_Id := Current_Task)
+     @key{return} Attribute;
+
+   @key{function} @AdaSubDefn{Reference}(T : Task_Id := Current_Task)
+     @key{return} Attribute_Handle;
+
+   @key{procedure} @AdaSubDefn{Set_Value}(Val : @key[in] Attribute;
+                       T : @key[in] Task_Id := Current_Task);
+   @key{procedure} @AdaSubDefn{Reinitialize}(T : @key[in] Task_Id := 
Current_Task);
+
address@hidden Ada.Task_Attributes;
address@hidden
+
address@hidden
+
address@hidden
+
+When an instance of Task_Attributes is elaborated in
+a given active partition, an object of the
+actual type corresponding to the formal type Attribute
+is implicitly created for each task (of that partition)
+that exists and is not yet terminated.
+This object acts as a user-defined attribute of the task.
+A task created previously
+in the partition and not yet terminated has this attribute
+from that point on. Each task subsequently created in the partition
+will have this attribute when created. In all these cases, the initial value
+of the given attribute is Initial_Value.
+
+The Value operation returns the value of the corresponding attribute of T.
+
+The Reference operation returns an access value that designates the
+corresponding attribute of T.
+
+The Set_Value operation performs any finalization on the old value of the
+attribute of T and assigns Val to that attribute
+(see @RefSecNum{Assignment Statements} and
address@hidden and Finalization}).
+
+The effect of the Reinitialize operation is the same as Set_Value where
+the Val parameter is replaced with Initial_Value.
address@hidden
+In most cases, the attribute memory can be reclaimed at this point.
address@hidden
+
address@hidden,Sec=(raised by failure of run-time check)}
+For all the operations declared in this package, Tasking_Error is raised
+if the task identified by T is terminated.
address@hidden,Sec=(raised by failure of run-time check)}
+Program_Error is raised if the value of T is Null_Task_Id.
+
address@hidden,Kind=[Added],ARef=[AI95-00237-01]}
address@hidden,Text=[After a task has terminated, all of its attributes
+are finalized, unless they have been finalized earlier. When the master of an
+instantiation of Ada.Task_Attributes is finalized, the corresponding attribute
+of each task is finalized, unless it has been finalized earlier.]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[This is necessary so that a task attribute does
+  not outlive its type. For instance, that's possible if the instantiation is
+  nested, and the attribute is on a library-level task.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[The task owning an attribute cannot, in general,
+  finalize that attribute. That's because the attributes are finalized 
@i<after>
+  the task is terminated; moreover, a task may have attributes as soon as it is
+  created; the task may never even have been activated.]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Added],Ref=[8652/0071],ARef=[AI95-00165-01]}
address@hidden,address@hidden(bounded error),Sec=(cause)}
+If the package Ada.Task_Attributes is instantiated with a controlled type and
+the controlled type has user-defined Adjust or Finalize operations that in
+turn access task attributes by any of the above operations, then a call of
+Set_Value of the instantiated package constitutes a bounded error. The call
+may perform as expected or may result in forever blocking the calling task and
+subsequently some or all tasks of the partition.]}
address@hidden
+
address@hidden
address@hidden(erroneous execution),Sec=(cause)}
+It is erroneous to dereference the access value returned by a given
+call on Reference after a subsequent call on Reinitialize for
+the same task attribute, or after the associated task terminates.
address@hidden
+  This allows the storage to be reclaimed for the object
+  associated with an attribute upon Reinitialize or task termination.
address@hidden
+
address@hidden(erroneous execution),Sec=(cause)}
+If a value of Task_Id is passed as a parameter to any of the operations
+declared in this package and the corresponding task object no longer exists,
+the execution of the program is erroneous.
+
address@hidden,Kind=[Added],Ref=[8652/0071],ARef=[AI95-00165-01]}
address@hidden,Kind=[RevisedAdded],ARef=[AI95-00237-01]}
address@hidden,address@hidden(erroneous execution),Sec=(cause)}
address@hidden,New=[An access],Old=[Accesses]} to @Chg{Version=[2],New=[a 
],Old=[]}task
address@hidden,New=[attribute],Old=[attributes]} via a value of type
+Attribute_Handle @Chg{Version=[2],New=[is],Old=[are]}
+erroneous if executed concurrently with @Chg{Version=[2],New=[another such 
access],
+Old=[each other]} or @Chg{Version=[2],New=[a call],Old=[with calls]} of any of 
the
+operations declared in package address@hidden,New=[ An access
+to a task attribute is erroneous if executed
+concurrently with or after the finalization of the task attribute.],Old=[]}]}
address@hidden
+  @ChgRef{Version=[1],Kind=[Added]}
+  @ChgAdded{Version=[1],Text=[There is no requirement of atomicity on accesses
+  via a value of type Attribute_Handle.]}
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Added]}
+  @ChgAdded{Version=[2],Text=[A task attribute can only be accessed after
+  finalization through a value of type Attribute_Handle. Operations in
+  package Task_Attributes cannot be used to access a task attribute after
+  finalization, because either the master of the instance has been or is in the
+  process of being left (in which case the instance is out of scope and thus
+  cannot be called), or the associated task is already terminated (in which
+  case Tasking_Error is raised for any attempt to call a task attribute
+  operation).]}
address@hidden
address@hidden
+
address@hidden
address@hidden,Kind=[Revised],Ref=[8652/0071],ARef=[AI95-00165-01]}
address@hidden a given attribute of a given task, the],Old=[The]} implementation
+shall perform @Chg{New=[the operations declared in this package],
+Old=[each of the above operations for a given attribute of a given task]}
+atomically with respect to any @Chg{New=[of these operations of],
+Old=[other of the above operations for]} the same attribute of the same task.
address@hidden granularity of any locking mechanism necessary to achieve such
+atomicity is implementation defined.],Old=[]}
address@hidden,Kind=[Added],address@hidden of
+locking for Task_Attributes.],Old=[]}]}
+
address@hidden
+Hence, other than by dereferencing an access value returned by
+Reference, an attribute of a given task can be safely read and updated
+concurrently by multiple tasks.
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00237-01]}
address@hidden,New=[After],Old=[When a]} task
address@hidden,New=[attributes are finalized],Old=[terminates]},
+the implementation shall @Chg{Version=[2],New=[],Old=[finalize
+all attributes of the task, and ]}reclaim any
address@hidden,New=[],Old=[other ]}storage associated with the attributes.
address@hidden
+
address@hidden
+
+The implementation shall document the limit on the number of attributes
+per task, if any, and the limit on the total storage for attribute values
+per task, if such a limit exists.
+
+In addition, if these limits can be configured, the implementation shall
+document how to configure them.
address@hidden,Kind=[Deleted],InitialVersion=[0],
address@hidden,
address@hidden on the number and size of task attributes, and how to configure 
them.],
+Old=[Implementation-defined aspects of Task_Attributes.]}]}]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[For package Task_Attributes, limits on the number and size of task
+attributes, and how to configure any limits.]}]}
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+The implementation shall document the following metrics: A task calling the
+following subprograms shall execute @Chg{Version=[2],New=[at],Old=[in]} a
+sufficiently high priority as to not
+be preempted during the measurement period. This period shall start just
+before issuing the call and end just after the call completes. If the
+attributes of task T are accessed by the measurement tests, no other task
+shall access attributes of that task during the measurement period.
+For all measurements described here, the Attribute type shall be a scalar
address@hidden,New=[type ],Old=[]}whose size is equal to the size of the
+predefined @Chg{Version=[2],New=[type Integer],Old=[integer size]}.
+For each measurement, two cases shall be documented: one
+where the accessed attributes are of the calling task @Redundant[(that is,
+the default value for the T parameter is used)], and the other, where T
+identifies another, nonterminated, task.
+
address@hidden@;The following calls (to subprograms in the Task_Attributes 
package)
+shall be measured:
address@hidden
+a call to Value, where the return value is Initial_Value;
+
+a call to Value, where the return value is not equal to Initial_Value;
+
+a call to Reference, where the return value designates a value equal to
+Initial_Value;
+
+a call to Reference, where the return value designates a value not equal
+to Initial_Value;
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+a call to Set_Value where the Val parameter is not equal to Initial_Value
+and the old attribute value is equal to address@hidden,New=[;],Old=[.]}
+
+a call to Set_Value where the Val parameter is not equal to Initial_Value
+and the old attribute value is not equal to Initial_Value.
+
address@hidden
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[The metrics for the Task_Attributes package.]}]}
address@hidden
+
address@hidden
+
+An implementation need not actually create the object corresponding
+to a task attribute
+until its value is set to something other than that of Initial_Value,
+or until Reference is called for the task attribute.
+Similarly, when the value of the attribute is
+to be reinitialized to that of Initial_Value,
+the object may instead be finalized and its storage reclaimed, to
+be recreated when needed later.
+While the object does not exist, the function Value may
+simply return Initial_Value, rather than implicitly creating the object.
address@hidden
+  The effect of this permission can only be observed if the assignment
+  operation for the corresponding type has side effects.
address@hidden
address@hidden
+  @ChgRef{Version=[2],Kind=[Revised],ARef=[AI95-00114-01]}
+  This permission means that even though every task has every
+  attribute, storage need only be allocated for those attributes
+  @Chg{Version=[2],New=[for which function Reference has been 
invoked],Old=[that
+  have been Reference'd]} or set to a value other than that
+  of Initial_Value.
address@hidden
+
+An implementation is allowed to place restrictions on the maximum number of
+attributes a task may have, the maximum size of each attribute, and the
+total storage size allocated for all the attributes of a task.
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[Revised],ARef=[AI95-00434-01]}
+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 @Chg{Version=[2],
+New=[],Old=[task's address@hidden,New=[ of a task],Old=[]},
+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.
+
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[If the target domain requires deterministic memory use at run
+time, storage for task attributes should be pre-allocated
+statically and the number of attributes pre-allocated should be documented.]}]}
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal]}
+  @ChgAdded{Version=[2],Text=[We don't mention @lquotes@;restrictions on the
+  size and address@hidden (that is, limits) in the text for the
+  Annex, because it is covered by the @DocReqName above, and we try not to
+  repeat requirements in the Annex (they're enough work to meet without
+  having to do things twice).]}
address@hidden
address@hidden
+
address@hidden,Kind=[Added],ARef=[AI95-00237-01]}
address@hidden,Text=[Finalization of task attributes and reclamation of
+associated storage should be performed as soon as possible after task
+termination.]}
address@hidden,Kind=[AddedNormal],address@hidden,
+Text=[Finalization of task attributes and reclamation of
+associated storage should be performed as soon as possible after task
+termination.]}]}
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00237-01]}
+  @ChgAdded{Version=[2],Text=[This is necessary because the normative wording
+  only says that attributes are finalized @lquotes@;address@hidden@;
+  task termination. Without this advice, waiting until the instance is
+  finalized would meet the requirements (it is after termination, but may be
+  a very long time after termination). We can't say anything more specific
+  than this, as we do not want to require the overhead of an interaction with
+  the tasking system to be done at a specific point.]}
address@hidden
address@hidden
+
+An attribute always exists (after instantiation), and has the initial value.
+It need not occupy memory until the first operation that potentially
+changes the attribute value. The same holds true after Reinitialize.
+
+The result of the Reference function should be used with care; it is always
+safe to use that result in the task body whose attribute is being
+accessed. However, when the result is being used by another task, the
+programmer must make sure that the task whose attribute is being accessed
+is not yet terminated. Failing to do so could make the program execution
+erroneous.
+
address@hidden,Kind=[DeletedNoDelMsg],ARef=[AI95-00434-01]}
address@hidden,Text=[As specified in
address@hidden Package Task_Identification}, if the parameter T (in a call
+on a subprogram of an instance of this package) identifies a nonexistent
+task, the execution of the program is erroneous.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],Ref=[8652/0071],ARef=[AI95-00165-01]}
+  @ChgAdded{Version=[2],address@hidden<Corrigendum:> Clarified that use of task
+  attribute operations from within a task attribute operation (by an Adjust
+  or Finalize call) is a bounded error, and that concurrent use of attribute
+  handles is erroneous.]}
+
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00237-01]}
+  @ChgAdded{Version=[2],Text=[Clarified the wording so that the finalization
+  takes place after the termination of the task or when the instance is
+  finalized (whichever is sooner).]}
address@hidden
+
address@hidden,Name=[The Package Task_Termination]}
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00266-02]}
address@hidden,KeepNext=[T],Type=[Leading],Text=[The following
+language-defined library package exists:]}
address@hidden
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<with> Ada.Task_Identification;
address@hidden<with> Ada.Exceptions;
address@hidden<package> Ada.Task_Termination 
@key<is>@ChildUnit{Parent=[Ada],Child=[Task_Termination]}
+   @key<pragma> Preelaborate(Task_Termination);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<type> @AdaTypeDefn{Cause_Of_Termination} @key<is> 
(Normal, Abnormal, Unhandled_Exception);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<type> @AdaTypeDefn{Termination_Handler} @key<is 
access protected procedure>
+     (Cause : @key<in> Cause_Of_Termination;
+      T     : @key<in> Ada.Task_Identification.Task_Id;
+      X     : @key<in> Ada.Exceptions.Exception_Occurrence);]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<procedure> 
@AdaSubDefn{Set_Dependents_Fallback_Handler}
+     (Handler: @key<in> Termination_Handler);
+   @key<function> @AdaSubDefn{Current_Task_Fallback_Handler} @key<return> 
Termination_Handler;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Text=[   @key<procedure> @AdaSubDefn{Set_Specific_Handler}
+     (T       : @key<in> Ada.Task_Identification.Task_Id;
+      Handler : @key<in> Termination_Handler);
+   @key<function> @AdaSubDefn{Specific_Handler} (T : 
Ada.Task_Identification.Task_Id)
+      @key<return> Termination_Handler;]}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,address@hidden<end> Ada.Task_Termination;]}
address@hidden
+
address@hidden
+
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00266-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0202-1]}
address@hidden,address@hidden address@hidden,Sec=[termination]}
+The type Termination_Handler identifies a protected
+procedure to be executed by the implementation when a task terminates. Such a
+protected procedure is called a @i<handler>. In all cases T identifies the task
+that is terminating. If the task terminates due to completing the last
+statement of its body, or as a result of waiting on a terminate alternative,
address@hidden,New=[and the finalization of the task completes normally, 
],Old=[]}then
+Cause is set to Normal and X is set to Null_Occurrence. If the task
+terminates because it is being aborted, then Cause is set to
address@hidden,New=[;],Old=[ and]} X is set to
address@hidden,New=[ if the finalization of the task completes 
normally],Old=[]}.
+If the task terminates because of an exception raised
+by the execution of its @nt{task_body}, then Cause is set to
address@hidden,New=[;],Old=[ and]} X is set to the
+associated exception address@hidden,New=[ if the finalization
+of the task completes normally],address@hidden,New=[ Independent of
+how the task completes, if finalization of the task propagates an exception,
+then Cause is either Unhandled_Exception or Abnormal, and X is an exception
+occurrence that identifies the Program_Error exception.],Old=[]}]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00266-02]}
address@hidden,address@hidden address@hidden handler],Sec=[fall-back]}
address@hidden address@hidden handler],Sec=[specific]}
address@hidden,Sec=[termination handler]}
address@hidden,Sec=[termination handler]}
+Each task has two termination handlers, a @i<fall-back handler> and a
address@hidden<specific handler>. The specific handler applies only to the task 
itself,
+while the fall-back handler applies only to the dependent tasks of the task.
+A handler is said to be @i<set> if it is associated
+with a nonnull value of type Termination_Handler, and @i<cleared> otherwise.
+When a task is created, its specific handler and fall-back handler are 
cleared.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00266-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The procedure Set_Dependents_Fallback_Handler
+changes the fall-back handler for the calling
address@hidden,New=[:],Old=[;]} if Handler is @key{null},
+that fall-back handler is address@hidden,New=[;],Old=[,]}
address@hidden,New=[,],Old=[]} it is set to be address@hidden
+If a fall-back handler had previously been set it is replaced.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00266-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The function Current_Task_Fallback_Handler returns
+the fall-back handler that is currently set for the calling task, if one is
+set; address@hidden,New=[,],Old=[]} it returns @key{null}.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00266-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The procedure Set_Specific_Handler changes the
+specific handler for the task identified by
address@hidden,New=[:],Old=[;]} if Handler is @key{null}, that
+specific handler is address@hidden,New=[;],Old=[,]}
address@hidden,New=[,],Old=[]} it is set to be address@hidden If
+a specific handler had previously been set it is replaced.]}
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0005-1]}
+  @ChgAdded{Version=[3],Text=[This package cannot portably be used to set
+  a handler on the program as a whole. It is possible to call
+  Set_Specific_Handler with the environment task's ID. But any call to the
+  handler would necessarily be a @BoundedName, as the handler is called
+  after the task's finalization has completed. In the case of the environment
+  task, that includes any possible protected objects, and calling a protected
+  object after it is finalized is a @BoundedName
+  (see @RefSecNum{Protected Units and Protected Objects}). This might work in
+  a particular implementation, but it cannot be depended upon.]}
address@hidden
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00266-02]}
address@hidden,Kind=[Revised],ARef=[AI05-0264-1]}
address@hidden,Text=[The function Specific_Handler returns the specific
+handler that is currently set for the task identified by T, if one is set;
address@hidden,New=[,],Old=[]} it returns @key{null}.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00266-02]}
address@hidden,Text=[As part of the finalization of a @nt{task_body},
+after performing the actions specified in
address@hidden and Finalization} for finalization of a
+master, the specific handler for the task, if one is set, is executed.
+If the specific handler is cleared, a search
+for a fall-back handler proceeds by recursively following the master
+relationship for the task. If a task is found whose fall-back handler is set,
+that handler is executed; otherwise, no handler is executed.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00266-02]}
address@hidden,Text=[For Set_Specific_Handler or
+Specific_Handler, Tasking_Error is raised if the task identified by T has
+already terminated. Program_Error is raised if the value of T is
+Ada.Task_Identification.Null_Task_Id.]}
+
address@hidden,Kind=[AddedNormal],ARef=[AI95-00266-02]}
address@hidden,Text=[An exception propagated from a handler that is
+invoked as part of the termination of a task has no effect.]}
+
address@hidden
+
address@hidden
address@hidden,Kind=[AddedNormal],ARef=[AI95-00266-02]}
address@hidden,Text=[For a call of Set_Specific_Handler or
+Specific_Handler, if the task identified by T no longer exists, the execution
+of the program is erroneous.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[2],Kind=[AddedNormal],ARef=[AI95-00266-02]}
+  @ChgAdded{Version=[2],address@hidden to Ada 95}
+  Package Task_Termination is new.]}
address@hidden
+
address@hidden
+  @ChgRef{Version=[3],Kind=[AddedNormal],ARef=[AI05-0202-1]}
+  @ChgAdded{Version=[3],address@hidden<Correction:> Specified what is passed 
to the
+  handler if the finalization of the task fails after it is completed. This was
+  not specified at all in Ada 2005, so there is a possibility that some program
+  depended on some other behavior of an implementation. But as this case is
+  very unlikely (and only occurs when there is already a significant bug in
+  the program - so should not occur in fielded systems), we're not listing
+  this as an inconsistency.]}
address@hidden
diff --git a/packages/ada-ref-man/source_2012/syntax.mss 
b/packages/ada-ref-man/source_2012/syntax.mss
new file mode 100755
index 0000000..c6a7c84
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/syntax.mss
@@ -0,0 +1,40 @@
address@hidden(syntax, Root="ada.mss")
+
address@hidden: 2012/11/28 23:53:06 $}
address@hidden Summary}
+
address@hidden: e:\\cvsroot/ARM/Source/syntax.mss,v $}
address@hidden: 1.20 $}
+
address@hidden@Defn2{Term=[syntax], Sec=(complete listing)}
address@hidden, Sec=(complete listing)}
address@hidden free grammar], Sec=(complete listing)}
address@hidden (Backus-Naur Form)], Sec=(complete listing)}
address@hidden Form (BNF)], Sec=(complete listing)}
+This Annex summarizes the complete syntax of the language.
+See @RefSecNum{Method of Description and Syntax Notation}
+for a description of the notation used.
+
address@hidden
+
address@hidden
address@hidden@Heading{Syntax Cross Reference}
+
address@hidden@Defn2{Term=[syntax], Sec=(cross reference)}
address@hidden, Sec=(cross reference)}
address@hidden free grammar], Sec=(cross reference)}
address@hidden (Backus-Naur Form)], Sec=(cross reference)}
address@hidden Form (BNF)], Sec=(cross reference)}
+
address@hidden,Kind=[AddedNormal]}
address@hidden,Kind=[Revised],ARef=[AI05-0299-1]}
address@hidden,Text=[In the following syntax cross reference, each
+syntactic category is followed by the
address@hidden,New=[subclause],Old=[clause]} number where it is defined.
+In addition, each syntactic category @i{S} is followed by a list of the
+categories that use @i{S} in their definitions. For example, the first
+listing below shows that @nt{abort_statement} appears in the definition of
address@hidden
address@hidden explanation is a simplified version of the Ada 83 one.}
address@hidden
+
diff --git a/packages/ada-ref-man/source_2012/title.mss 
b/packages/ada-ref-man/source_2012/title.mss
new file mode 100755
index 0000000..e9d8b1f
--- /dev/null
+++ b/packages/ada-ref-man/source_2012/title.mss
@@ -0,0 +1,289 @@
address@hidden(title, Root="ada.mss")
+
address@hidden: e:\\cvsroot/ARM/Source/title.mss,v $}
address@hidden: 1.70 $ $Date: 2016/02/12 05:25:38 $}
+
address@hidden
address@hidden@address@hidden@address@hidden,address@hidden/IEC JTC 1/SC 22 
N}],address@hidden STANDARD} ISO/IEC 8652:@Chg{Version=[2],New=[2007(E) Ed. 
3],Old=[1995(E)@Chg{Version=[1], New=[ with COR.1:2001], Old=[]}]}]}}}}
address@hidden draft text}
+
address@hidden@address@hidden@Chg{Version=[3],New=[Date: 2012-11-27],Old=[]}}}
+
address@hidden@address@hidden@address@hidden,address@hidden/IEC 
8652:2012(E)}],Old=[]}}}}
+
address@hidden@address@hidden@Chg{Version=[3],New=[ISO/IEC JTC 1/SC 22/WG 
9],Old=[]}}}
address@hidden
address@hidden
address@hidden@address@hidden@address@hidden Reference Manual}, ISO/IEC 
8652:@Chg{Version=[3],address@hidden,New=[202x(E)],Old=[2012(E)@Chg{Version=[4],
 New=[ with COR.1:2016],Old=[]}]}],address@hidden,New=[2007(E) Ed. 
3],Old=[1995(E)@Chg{Version=[1], New=[ with COR.1:2001], Old=[]}]}]}}}}
address@hidden
+
address@hidden@ @*
+@ @*
+@ @*
+
address@hidden header...
address@hidden
address@hidden@address@hidden@address@hidden ORGANIZATION FOR 
STANDARDIZATION}}}}
+
address@hidden@address@hidden@address@hidden ELECTROTECHNICAL COMMISSION}}}}
address@hidden
+End comment}
+
address@hidden@ @*
+@ @*
+
address@hidden
address@hidden@address@hidden@address@hidden@address@hidden technology @Em 
Programming languages @Em Ada}}}}}}
+@ @*
address@hidden@address@hidden de l'information @Em Langages de programmation 
@Em Ada}}
address@hidden
+
address@hidden@ @;@comment{A dummy paragraph containing just a blank}
+
address@hidden
address@hidden@ @*@;@comment{A dummy paragraph containing three blank lines}
+@ @*
+@ @*
+@ @*
+
address@hidden
+
address@hidden
address@hidden Moore wanted this deleted in the consolidated editions, as it is 
confusing.}
address@hidden@Chg{Version=[3],address@hidden of second edition (ISO/IEC 
8652:1995)}],address@hidden@ @address@hidden paragraph}],
+               address@hidden of first edition (ISO 8652:1987)]}]}]}
address@hidden
+
address@hidden@ @*
+
address@hidden
address@hidden
address@hidden@Heading{Ada Reference Manual}
address@hidden
address@hidden
address@hidden@Heading{Annotated Ada Reference Manual}
address@hidden
+
address@hidden@ @;@comment{A dummy paragraph containing just a blank}
+
address@hidden@address@hidden@Grow{ISO/IEC 
8652:@Chg{Version=[3],address@hidden,New=[202x],Old=[2012]}],Old=[1995]}(E)@Chg{Version=[5],New=<,
 Draft 8>,Old=[]}}}}
address@hidden@address@hidden@Chg{Version=[3],address@hidden,address@hidden,New=[],address@hidden
 Technical Corrigendum 1}]}],Old=[]}],address@hidden, address@hidden Technical 
Corrigendum 1}], Old=[]}]}}}
address@hidden@address@hidden@Chg{Version=[3],New=[],address@hidden, 
address@hidden Amendment 1}], Old=[]}]}}}
address@hidden
+
address@hidden@ @;@comment{A dummy paragraph containing just a blank}
+
address@hidden
address@hidden@address@hidden@Grow{Language and Standard Libraries}}}
+
address@hidden@Comment{The following puts the copyright near the bottom of the 
page}
+@ @address@hidden@address@hidden@address@hidden@*
+
address@hidden@;Copyright @Latin1(169) 1992, 1993, 1994, 1995  Intermetrics, 
Inc.
+
address@hidden@;@Chg{Version=[1], New=[Copyright @Latin1(169) 2000  The MITRE 
Corporation, Inc.], Old=[]}
+
address@hidden@;@Chg{Version=[2], New=[Copyright @Latin1(169) 2004, 2005, 2006  
AXE Consultants], Old=[]}
+
address@hidden@;@Chg{Version=[2], New=[Copyright @Latin1(169) 2004, 2005, 2006  
Ada-Europe], Old=[]}
+
address@hidden@;@Chg{Version=[3], New=[Copyright @Latin1(169) 2008, 2009, 2010, 
2011, address@hidden, New=[, 2013, 2014, 2015, address@hidden, 
New=[],Old=[]}],Old=[]}  AXE Consultants], Old=[]}
address@hidden
address@hidden
address@hidden following is not needed in the final Standard:
address@hidden
address@hidden@address@hidden@address@hidden
+
address@hidden@;This document is not an ISO International Standard. It is
+distributed for review and comment. It is subject to change without notice and
+may not be referred to as an International Standard.
+
address@hidden@;Recipients of this draft are invited to submit, with their 
comment,
+notification of any relevant patent rights of which they are aware and to
+provide supporting documentation.
address@hidden
+*End comment*}
address@hidden
+
address@hidden
address@hidden
address@hidden following puts the copyright near the bottom of the page}
address@hidden@ @address@hidden@address@hidden@*
+
address@hidden@;@b{Ada Reference Manual - Language and Standard Libraries}
+
address@hidden@;Copyright @Latin1(169) 1992, 1993, 1994, 1995, Intermetrics, 
Inc.
+
address@hidden@;This copyright is assigned to the U.S. Government.  All rights 
reserved.
+
address@hidden@;This document may be copied, in whole or in part, in any form 
or by any means,
+as is or with alterations, provided that (1) alterations are clearly marked as
+alterations and (2) this copyright notice is included unmodified in any copy.
+Compiled copies of standard library units and examples need not contain this
+copyright notice so long as the notice is included in all copies of source code
+and documentation.
+
address@hidden
+
address@hidden@;@ @;@comment{A dummy paragraph containing just a blank}
+
address@hidden@;@Chg{Version=[1], address@hidden Corrigendum 1}], Old=[]}
+
address@hidden@;@Chg{Version=[1], New=[Copyright @Latin1(169) 2000, The MITRE 
Corporation.  All Rights Reserved.], Old=[]}
+
address@hidden@;@Chg{Version=[1], New=[This document may be copied, in whole or 
in part, in any form or by any means,
+as is, or with alterations, provided that (1) alterations are clearly marked as
+alterations and (2) this copyright notice is included unmodified in any copy.
+Any other use or distribution of this document is prohibited without the prior
+express permission of MITRE.], Old=[]}
+
address@hidden@;@Chg{Version=[1], New=[You use this document on the condition 
that
+you indemnify and hold harmless MITRE, its Board of Trustees, officers, agents,
+and employees, from any and all liability or damages to yourself or your
+hardware or software, or third parties, including attorneys' fees, court costs,
+and other related costs and expenses, arising out of your use of this document
+irrespective of the cause of said liability.], Old=[]}
+
address@hidden@;@Chg{Version=[1], New=[MITRE MAKES THIS DOCUMENT AVAILABLE ON 
AN "AS IS" BASIS AND MAKES NO WARRANTY,
+EXPRESS OR IMPLIED, AS TO THE ACCURACY, CAPABILITY, EFFICIENCY MERCHANTABILITY,
+OR FUNCTIONING OF THIS DOCUMENT.  IN NO EVENT WILL MITRE BE LIABLE FOR ANY
+GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+EVEN IF MITRE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.], Old=[]}
+
address@hidden@;@ @;@comment{A dummy paragraph containing just a blank}
+
address@hidden@;@Chg{Version=[2], address@hidden 1}], Old=[]}
+
address@hidden@;@Chg{Version=[2], New=[Copyright @Latin1(169) 2004, 2005, 
address@hidden, New=[, 2007],Old=[]}, AXE Consultants.  All Rights Reserved.], 
Old=[]}
+
address@hidden@;@Chg{Version=[2], New=[This document may be copied, in whole or 
in part, in any form or by any means,
+as is, or with alterations, provided that (1) alterations are clearly marked as
+alterations and (2) this copyright notice is included unmodified in any copy.
+Any other use or distribution of this document is prohibited
+without the prior express permission of AXE.], Old=[]}
+
address@hidden@;@Chg{Version=[2], New=[You use this document on the condition 
that
+you indemnify and hold harmless AXE, its board, officers, agents, and
+employees, from any and all liability or damages to yourself or your hardware
+or software, or third parties, including attorneys' fees, court costs, and
+other related costs and expenses, arising out of your use of this document
+irrespective of the cause of said liability.], Old=[]}
+
address@hidden@;@Chg{Version=[2], New=[AXE MAKES THIS DOCUMENT AVAILABLE ON AN 
"AS IS" BASIS AND MAKES NO WARRANTY,
+EXPRESS OR IMPLIED, AS TO THE ACCURACY, CAPABILITY, EFFICIENCY MERCHANTABILITY,
+OR FUNCTIONING OF THIS DOCUMENT. IN NO EVENT WILL AXE BE LIABLE FOR ANY
+GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+EVEN IF AXE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.], Old=[]}
+
address@hidden@;@Chg{Version=[3], address@hidden Edition}], Old=[]}
+
address@hidden@;@Chg{Version=[3], New=[Copyright @Latin1(169) 2008, 2009, 2010, 
2011, 2012 AXE Consultants.  All Rights Reserved.], Old=[]}
+
address@hidden@;@Chg{Version=[3], New=[This document may be copied, in whole or 
in part, in any form or by any means,
+as is, or with alterations, provided that (1) alterations are clearly marked as
+alterations and (2) this copyright notice is included unmodified in any copy.
+Any other use or distribution of this document is prohibited
+without the prior express permission of AXE.], Old=[]}
+
address@hidden@;@Chg{Version=[3], New=[You use this document on the condition 
that
+you indemnify and hold harmless AXE, its board, officers, agents, and
+employees, from any and all liability or damages to yourself or your hardware
+or software, or third parties, including attorneys' fees, court costs, and
+other related costs and expenses, arising out of your use of this document
+irrespective of the cause of said liability.], Old=[]}
+
address@hidden@;@Chg{Version=[3], New=[AXE MAKES THIS DOCUMENT AVAILABLE ON AN 
"AS IS" BASIS AND MAKES NO WARRANTY,
+EXPRESS OR IMPLIED, AS TO THE ACCURACY, CAPABILITY, EFFICIENCY MERCHANTABILITY,
+OR FUNCTIONING OF THIS DOCUMENT. IN NO EVENT WILL AXE BE LIABLE FOR ANY
+GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+EVEN IF AXE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.], Old=[]}
+
address@hidden@;@Chg{Version=[4], address@hidden Corrigendum 1 for Ada 2012}], 
Old=[]}
+
address@hidden@;@Chg{Version=[4], New=[Copyright @Latin1(169) 2013, 2014, 2015, 
2016 AXE Consultants.  All Rights Reserved.], Old=[]}
+
address@hidden@;@Chg{Version=[4], New=[This document may be copied, in whole or 
in part, in any form or by any means,
+as is, or with alterations, provided that (1) alterations are clearly marked as
+alterations and (2) this copyright notice is included unmodified in any copy.
+Any other use or distribution of this document is prohibited
+without the prior express permission of AXE.], Old=[]}
+
address@hidden@;@Chg{Version=[4], New=[You use this document on the condition 
that
+you indemnify and hold harmless AXE, its board, officers, agents, and
+employees, from any and all liability or damages to yourself or your hardware
+or software, or third parties, including attorneys' fees, court costs, and
+other related costs and expenses, arising out of your use of this document
+irrespective of the cause of said liability.], Old=[]}
+
address@hidden@;@Chg{Version=[4], New=[AXE MAKES THIS DOCUMENT AVAILABLE ON AN 
"AS IS" BASIS AND MAKES NO WARRANTY,
+EXPRESS OR IMPLIED, AS TO THE ACCURACY, CAPABILITY, EFFICIENCY MERCHANTABILITY,
+OR FUNCTIONING OF THIS DOCUMENT. IN NO EVENT WILL AXE BE LIABLE FOR ANY
+GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+EVEN IF AXE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.], Old=[]}
+
address@hidden@;@Chg{Version=[5], address@hidden 202x version}], Old=[]}
+
address@hidden@;@Chg{Version=[5], New=[Copyright @Latin1(169) 2016 AXE 
Consultants.  All Rights Reserved.], Old=[]}
+
address@hidden@;@Chg{Version=[5], New=[This document may be copied, in whole or 
in part, in any form or by any means,
+as is, or with alterations, provided that (1) alterations are clearly marked as
+alterations and (2) this copyright notice is included unmodified in any copy.
+Any other use or distribution of this document is prohibited
+without the prior express permission of AXE.], Old=[]}
+
address@hidden@;@Chg{Version=[5], New=[You use this document on the condition 
that
+you indemnify and hold harmless AXE, its board, officers, agents, and
+employees, from any and all liability or damages to yourself or your hardware
+or software, or third parties, including attorneys' fees, court costs, and
+other related costs and expenses, arising out of your use of this document
+irrespective of the cause of said liability.], Old=[]}
+
address@hidden@;@Chg{Version=[5], New=[AXE MAKES THIS DOCUMENT AVAILABLE ON AN 
"AS IS" BASIS AND MAKES NO WARRANTY,
+EXPRESS OR IMPLIED, AS TO THE ACCURACY, CAPABILITY, EFFICIENCY MERCHANTABILITY,
+OR FUNCTIONING OF THIS DOCUMENT. IN NO EVENT WILL AXE BE LIABLE FOR ANY
+GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+EVEN IF AXE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.], Old=[]}
+
address@hidden@;@ @;@comment{A dummy paragraph containing just a blank}
+
address@hidden@;@Chg{Version=[2], address@hidden 2005 Consolidated Standard}], 
Old=[]}
+
address@hidden@;@Chg{Version=[2], New=[Copyright @Latin1(169) 2004, 2005, 2006, 
Ada-Europe.], Old=[]}
+
address@hidden@;@Chg{Version=[2], New=[This document may be copied, in whole or 
in
+part, in any form or by any means, as is, or with alterations, provided that
+(1) alterations are clearly marked as alterations and (2) this copyright notice
+is included unmodified in any copy. Any other use or distribution of this
+document is prohibited without the prior express permission of Ada-Europe.], 
Old=[]}
+
address@hidden@;@Chg{Version=[2], New=[You use this document on the condition 
that
+you indemnify and hold harmless Ada-Europe and its Board from any and all
+liability or damages to yourself or your hardware or software, or third
+parties, including attorneys' fees, court costs, and other related costs and
+expenses, arising out of your use of this document irrespective of the cause of
+said liability.], Old=[]}
+
address@hidden@;@Chg{Version=[2], New=[ADA-EUROPE MAKES THIS DOCUMENT AVAILABLE 
ON AN "AS IS" BASIS AND MAKES NO WARRANTY,
+EXPRESS OR IMPLIED, AS TO THE ACCURACY, CAPABILITY, EFFICIENCY MERCHANTABILITY,
+OR FUNCTIONING OF THIS DOCUMENT. IN NO EVENT WILL ADA-EUROPE BE LIABLE FOR ANY
+GENERAL, CONSEQUENTIAL, INDIRECT, INCIDENTAL, EXEMPLARY, OR SPECIAL DAMAGES,
+EVEN IF ADA-EUROPE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.], 
Old=[]}
address@hidden
+
address@hidden
address@hidden
address@hidden@address@hidden@address@hidden@b{Copyright Notice}}}}}
+
address@hidden@;This ISO document is a working draft or committee draft and is
+copyright-protected by ISO. While the reproduction of working drafts or
+committee drafts in any form for use by participants in the ISO standards
+development process is permitted without prior permission from ISO, neither 
this
+document nor any extract from it may be reproduced, stored, or transmitted in
+any form for any other purpose without prior written permission from ISO.
+
address@hidden@;Reproduction for sales purposes may be subject to royalty 
payments or a
+licensing agreement.
+
address@hidden@;Violators may be prosecuted.
address@hidden
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]